Annotation of sbbs/src/sbbs3/scfg/scfgxtrn.c, revision 1.1

1.1     ! root        1: /* scfgxtrn.c */
        !             2: 
        !             3: /* $Id: scfgxtrn.c,v 1.38 2006/05/25 07:35:26 rswindell Exp $ */
        !             4: 
        !             5: /****************************************************************************
        !             6:  * @format.tab-size 4          (Plain Text/Source Code File Header)                    *
        !             7:  * @format.use-tabs true       (see http://www.synchro.net/ptsc_hdr.html)              *
        !             8:  *                                                                                                                                                     *
        !             9:  * Copyright 2006 Rob Swindell - http://www.synchro.net/copyright.html         *
        !            10:  *                                                                                                                                                     *
        !            11:  * This program is free software; you can redistribute it and/or                       *
        !            12:  * modify it under the terms of the GNU General Public License                         *
        !            13:  * as published by the Free Software Foundation; either version 2                      *
        !            14:  * of the License, or (at your option) any later version.                                      *
        !            15:  * See the GNU General Public License for more details: gpl.txt or                     *
        !            16:  * http://www.fsf.org/copyleft/gpl.html                                                                                *
        !            17:  *                                                                                                                                                     *
        !            18:  * Anonymous FTP access to the most recent released source is available at     *
        !            19:  * ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net     *
        !            20:  *                                                                                                                                                     *
        !            21:  * Anonymous CVS access to the development source and modification history     *
        !            22:  * is available at cvs.synchro.net:/cvsroot/sbbs, example:                                     *
        !            23:  * cvs -d :pserver:[email protected]:/cvsroot/sbbs login                       *
        !            24:  *     (just hit return, no password is necessary)                                                     *
        !            25:  * cvs -d :pserver:[email protected]:/cvsroot/sbbs checkout src                *
        !            26:  *                                                                                                                                                     *
        !            27:  * For Synchronet coding style and modification guidelines, see                                *
        !            28:  * http://www.synchro.net/source.html                                                                          *
        !            29:  *                                                                                                                                                     *
        !            30:  * You are encouraged to submit any modifications (preferably in Unix diff     *
        !            31:  * format) via e-mail to [email protected]                                                                      *
        !            32:  *                                                                                                                                                     *
        !            33:  * Note: If this box doesn't appear square, then you need to fix your tabs.    *
        !            34:  ****************************************************************************/
        !            35: /****************************************************************************/
        !            36: /* Synchronet configuration utility                                                                            */
        !            37: /****************************************************************************/
        !            38: 
        !            39: #include "scfg.h"
        !            40: 
        !            41: char *daystr(char days);
        !            42: static void hotkey_cfg(void);
        !            43: 
        !            44: static char* mdaystr(long mdays)
        !            45: {
        !            46:        int             i;
        !            47:        char    tmp[16];
        !            48:        static  char str[256];
        !            49: 
        !            50:        if(mdays==0 || mdays==1)
        !            51:                return("Any");
        !            52: 
        !            53:        str[0]=0;
        !            54:        for(i=1;i<32;i++) {
        !            55:                if((mdays&(1<<i))==0)
        !            56:                        continue;
        !            57:                if(str[0])
        !            58:                        strcat(str," ");
        !            59:                sprintf(tmp,"%u",i);
        !            60:                strcat(str,tmp);
        !            61:        }
        !            62:        
        !            63:        return(str);
        !            64: }
        !            65: 
        !            66: static char* dropfile(int type, ulong misc)
        !            67: {
        !            68:        static char str[128];
        !            69:        char fname[64]="";
        !            70: 
        !            71:        switch(type) {
        !            72:                case XTRN_SBBS:
        !            73:                        strcpy(fname,"XTRN.DAT");
        !            74:                        break;
        !            75:                case XTRN_WWIV:
        !            76:                        strcpy(fname,"CHAIN.TXT");
        !            77:                        break;
        !            78:                case XTRN_GAP:
        !            79:                        strcpy(fname,"DOOR.SYS");
        !            80:                        break;
        !            81:                case XTRN_RBBS:
        !            82:                        strcpy(fname,"DORINFO#.DEF");
        !            83:                        break;
        !            84:                case XTRN_RBBS1:
        !            85:                        strcpy(fname,"DORINFO1.DEF");
        !            86:             break;
        !            87:                case XTRN_WILDCAT:
        !            88:                        strcpy(fname,"CALLINFO.BBS");
        !            89:                        break;
        !            90:                case XTRN_PCBOARD:
        !            91:                        strcpy(fname,"PCBOARD.SYS");
        !            92:                        break;
        !            93:                case XTRN_SPITFIRE:
        !            94:                        strcpy(fname,"SFDOORS.DAT");
        !            95:                        break;
        !            96:                case XTRN_UTI:
        !            97:                        strcpy(fname,"UTIDOOR.TXT");
        !            98:                        break;
        !            99:                case XTRN_SR:
        !           100:                        strcpy(fname,"DOORFILE.SR");
        !           101:                        break;
        !           102:                case XTRN_TRIBBS:
        !           103:                        strcpy(fname,"TRIBBS.SYS");
        !           104:                        break;
        !           105:         case XTRN_DOOR32:
        !           106:             strcpy(fname,"DOOR32.SYS");
        !           107:             break;
        !           108:        }
        !           109: 
        !           110:        if(misc&XTRN_LWRCASE)
        !           111:                strlwr(fname);
        !           112: 
        !           113:        switch(type) {
        !           114:                case XTRN_SBBS:
        !           115:                        sprintf(str,"%-15s %s","Synchronet",fname);
        !           116:                        break;
        !           117:                case XTRN_WWIV:
        !           118:                        sprintf(str,"%-15s %s","WWIV",fname);
        !           119:                        break;
        !           120:                case XTRN_GAP:
        !           121:                        sprintf(str,"%-15s %s","GAP",fname);
        !           122:                        break;
        !           123:                case XTRN_RBBS:
        !           124:                        sprintf(str,"%-15s %s","RBBS/QuickBBS",fname);
        !           125:                        break;
        !           126:                case XTRN_RBBS1:
        !           127:                        sprintf(str,"%-15s %s","RBBS/QuickBBS",fname);
        !           128:             break;
        !           129:                case XTRN_WILDCAT:
        !           130:                        sprintf(str,"%-15s %s","Wildcat",fname);
        !           131:                        break;
        !           132:                case XTRN_PCBOARD:
        !           133:                        sprintf(str,"%-15s %s","PCBoard",fname);
        !           134:                        break;
        !           135:                case XTRN_SPITFIRE:
        !           136:                        sprintf(str,"%-15s %s","SpitFire",fname);
        !           137:                        break;
        !           138:                case XTRN_UTI:
        !           139:                        sprintf(str,"%-15s %s","MegaMail",fname);
        !           140:                        break;
        !           141:                case XTRN_SR:
        !           142:                        sprintf(str,"%-15s %s","Solar Realms",fname);
        !           143:                        break;
        !           144:                case XTRN_TRIBBS:
        !           145:                        sprintf(str,"%-15s %s","TriBBS",fname);
        !           146:                        break;
        !           147:         case XTRN_DOOR32:
        !           148:             sprintf(str,"%-15s %s","Mystic",fname);
        !           149:             break;
        !           150:                default:
        !           151:                        strcpy(str,"None");
        !           152:                        break; 
        !           153:        }
        !           154:        return(str);
        !           155: }
        !           156: 
        !           157: void xprogs_cfg()
        !           158: {
        !           159:        static int xprogs_dflt;
        !           160:        int     i;
        !           161: 
        !           162: while(1) {
        !           163:        i=0;
        !           164:        strcpy(opt[i++],"Fixed Events");
        !           165:        strcpy(opt[i++],"Timed Events");
        !           166:        strcpy(opt[i++],"Native Program List");
        !           167:        strcpy(opt[i++],"External Editors");
        !           168:        strcpy(opt[i++],"Global Hot Key Events");
        !           169:        strcpy(opt[i++],"Online Programs (Doors)");
        !           170:        opt[i][0]=0;
        !           171:        SETHELP(WHERE);
        !           172: /*
        !           173: &Online External Programs:&
        !           174: 
        !           175: From this menu, you can configure external events, external editors, or
        !           176: online external programs (doors).
        !           177: */
        !           178:        switch(uifc.list(WIN_ORG|WIN_CHE|WIN_ACT,0,0,0,&xprogs_dflt,0
        !           179:                ,"External Programs",opt)) {
        !           180:                case -1:
        !           181:                        i=save_changes(WIN_MID);
        !           182:             if(i==-1)
        !           183:                 break;
        !           184:                        if(!i) {
        !           185:                                cfg.new_install=new_install;
        !           186:                 write_xtrn_cfg(&cfg,backup_level);
        !           187:                                write_main_cfg(&cfg,backup_level);
        !           188:                 refresh_cfg(&cfg);
        !           189:             }
        !           190:                        return;
        !           191:                case 0:
        !           192:                        fevents_cfg();
        !           193:                        break;
        !           194:                case 1:
        !           195:                        tevents_cfg();
        !           196:                        break;
        !           197:                case 2:
        !           198:                        natvpgm_cfg();
        !           199:                        break;
        !           200:                case 3:
        !           201:                        xedit_cfg();
        !           202:                        break;
        !           203:         case 4:
        !           204:             hotkey_cfg();
        !           205:             break;
        !           206:                case 5:
        !           207:                        xtrnsec_cfg();
        !           208:                        break; } }
        !           209: }
        !           210: 
        !           211: void fevents_cfg()
        !           212: {
        !           213:        static int event_dflt;
        !           214:        int i;
        !           215: 
        !           216: while(1) {
        !           217:        i=0;
        !           218:        sprintf(opt[i++],"%-32.32s%.40s","Logon Event",cfg.sys_logon);
        !           219:        sprintf(opt[i++],"%-32.32s%.40s","Logout Event",cfg.sys_logout);
        !           220:        sprintf(opt[i++],"%-32.32s%.40s","Daily Event",cfg.sys_daily);
        !           221:        opt[i][0]=0;
        !           222:        SETHELP(WHERE);
        !           223: /*
        !           224: &External Events:&
        !           225: 
        !           226: From this menu, you can configure the logon and logout events, and the
        !           227: system daily event.
        !           228: */
        !           229:        switch(uifc.list(WIN_ACT|WIN_SAV|WIN_CHE|WIN_BOT|WIN_RHT,0,0,60,&event_dflt,0
        !           230:                ,"Fixed Events",opt)) {
        !           231:                case -1:
        !           232:                        return;
        !           233:                case 0:
        !           234:                        SETHELP(WHERE);
        !           235: /*
        !           236: &Logon Event:&
        !           237: 
        !           238: This is the command line for a program that will execute during the
        !           239: logon sequence of every user. The program cannot have user interaction.
        !           240: The program will be executed after the LOGON message is displayed and
        !           241: before the logon user list is displayed. If you wish to place a program
        !           242: in the logon sequence of users that includes interaction or requires
        !           243: account information, you probably want to use an online external
        !           244: program configured to run as a logon event.
        !           245: */
        !           246:                        uifc.input(WIN_MID|WIN_SAV,0,0,"Logon Event"
        !           247:                                ,cfg.sys_logon,sizeof(cfg.sys_logon)-1,K_EDIT);
        !           248:                        break;
        !           249:                case 1:
        !           250:                        SETHELP(WHERE);
        !           251: /*
        !           252: &Logout Event:&
        !           253: 
        !           254: This is the command line for a program that will execute during the
        !           255: logout sequence of every user. This program cannot have user
        !           256: interaction because it is executed after carrier is dropped. If you
        !           257: wish to have a program execute before carrier is dropped, you probably
        !           258: want to use an &Online External Program& configured to run as a logoff
        !           259: event.
        !           260: */
        !           261:                        uifc.input(WIN_MID|WIN_SAV,0,0,"Logout Event"
        !           262:                                ,cfg.sys_logout,sizeof(cfg.sys_logout)-1,K_EDIT);
        !           263:                        break;
        !           264:                case 2:
        !           265:                        SETHELP(WHERE);
        !           266: /*
        !           267: &Daily Event:&
        !           268: 
        !           269: This is the command line for a program that will run after the first
        !           270: user that logs on after midnight, logs off (regardless of what node).
        !           271: */
        !           272:                        uifc.input(WIN_MID|WIN_SAV,0,0,"Daily Event"
        !           273:                                ,cfg.sys_daily,sizeof(cfg.sys_daily)-1,K_EDIT);
        !           274: 
        !           275:                        break; } }
        !           276: }
        !           277: 
        !           278: void tevents_cfg()
        !           279: {
        !           280:        static int dflt,dfltopt,bar;
        !           281:        char str[81],done=0,*p;
        !           282:        int j,k;
        !           283:        uint i;
        !           284:        static event_t savevent;
        !           285: 
        !           286: while(1) {
        !           287:        for(i=0;i<cfg.total_events && i<MAX_OPTS;i++)
        !           288:                sprintf(opt[i],"%-8.8s      %.50s",cfg.event[i]->code,cfg.event[i]->cmd);
        !           289:        opt[i][0]=0;
        !           290:        j=WIN_SAV|WIN_ACT|WIN_CHE|WIN_RHT;
        !           291:        if(cfg.total_events)
        !           292:                j|=WIN_DEL|WIN_GET;
        !           293:        if(cfg.total_events<MAX_OPTS)
        !           294:                j|=WIN_INS|WIN_INSACT|WIN_XTR;
        !           295:        if(savevent.code[0])
        !           296:                j|=WIN_PUT;
        !           297:        SETHELP(WHERE);
        !           298: /*
        !           299: &Timed Events:&
        !           300: 
        !           301: This is a list of the configured timed external events.
        !           302: 
        !           303: To add an event hit  INS .
        !           304: 
        !           305: To delete an event, select it and hit  DEL .
        !           306: 
        !           307: To configure an event, select it and hit  ENTER .
        !           308: */
        !           309:        i=uifc.list(j,0,0,45,&dflt,&bar,"Timed Events",opt);
        !           310:        if((signed)i==-1)
        !           311:                return;
        !           312:        if((i&MSK_ON)==MSK_INS) {
        !           313:                i=cfg.total_events;
        !           314:                SETHELP(WHERE);
        !           315: /*
        !           316: &Timed Event Internal Code:&
        !           317: 
        !           318: This is the internal code for the timed event.
        !           319: */
        !           320:                if(uifc.input(WIN_MID|WIN_SAV,0,0,"Event Internal Code",str,LEN_CODE
        !           321:                        ,K_UPPER)<1)
        !           322:             continue;
        !           323:                if((cfg.event=(event_t **)realloc(cfg.event
        !           324:                        ,sizeof(event_t *)*(cfg.total_events+1)))==NULL) {
        !           325:                        errormsg(WHERE,ERR_ALLOC,nulstr,cfg.total_events+1);
        !           326:                        cfg.total_events=0;
        !           327:                        bail(1);
        !           328:             continue; }
        !           329:                if((cfg.event[i]=(event_t *)malloc(sizeof(event_t)))==NULL) {
        !           330:                        errormsg(WHERE,ERR_ALLOC,nulstr,sizeof(event_t));
        !           331:                        continue; }
        !           332:                memset((event_t *)cfg.event[i],0,sizeof(event_t));
        !           333:                strcpy(cfg.event[i]->code,str);
        !           334:                cfg.event[i]->node=1;
        !           335:                cfg.event[i]->days=0xff;
        !           336:                cfg.total_events++;
        !           337:                uifc.changes=1;
        !           338:                continue; }
        !           339:        if((i&MSK_ON)==MSK_DEL) {
        !           340:                i&=MSK_OFF;
        !           341:                free(cfg.event[i]);
        !           342:                cfg.total_events--;
        !           343:                for(j=i;j<cfg.total_events;j++)
        !           344:                        cfg.event[j]=cfg.event[j+1];
        !           345:                uifc.changes=1;
        !           346:                continue; }
        !           347:        if((i&MSK_ON)==MSK_GET) {
        !           348:                i&=MSK_OFF;
        !           349:                savevent=*cfg.event[i];
        !           350:                continue; }
        !           351:        if((i&MSK_ON)==MSK_PUT) {
        !           352:                i&=MSK_OFF;
        !           353:                *cfg.event[i]=savevent;
        !           354:                uifc.changes=1;
        !           355:         continue; }
        !           356:        done=0;
        !           357:        while(!done) {
        !           358:                k=0;
        !           359:                sprintf(opt[k++],"%-32.32s%s","Internal Code",cfg.event[i]->code);
        !           360:                sprintf(opt[k++],"%-32.32s%.40s","Start-up Directory",cfg.event[i]->dir);
        !           361:                sprintf(opt[k++],"%-32.32s%.40s","Command Line",cfg.event[i]->cmd);
        !           362:                sprintf(opt[k++],"%-32.32s%s","Enabled"
        !           363:                        ,cfg.event[i]->misc&EVENT_DISABLED ? "No":"Yes");
        !           364:                sprintf(opt[k++],"%-32.32s%u","Execution Node",cfg.event[i]->node);
        !           365:                sprintf(opt[k++],"%-32.32s%s","Execution Days of Month"
        !           366:                        ,mdaystr(cfg.event[i]->mdays));
        !           367:                sprintf(opt[k++],"%-32.32s%s","Execution Days of Week",daystr(cfg.event[i]->days));
        !           368:         if(cfg.event[i]->freq) {
        !           369:             sprintf(str,"%u times a day",1440/cfg.event[i]->freq);
        !           370:             sprintf(opt[k++],"%-32.32s%s","Execution Frequency",str);
        !           371:         } else {
        !           372:             sprintf(str,"%2.2u:%2.2u"
        !           373:                 ,cfg.event[i]->time/60,cfg.event[i]->time%60);
        !           374:             sprintf(opt[k++],"%-32.32s%s","Execution Time",str);
        !           375:         }
        !           376:                sprintf(opt[k++],"%-32.32s%s","Requires Exclusive Execution"
        !           377:                        ,cfg.event[i]->misc&EVENT_EXCL ? "Yes":"No");
        !           378:                sprintf(opt[k++],"%-32.32s%s","Force Users Off-line For Event"
        !           379:                        ,cfg.event[i]->misc&EVENT_FORCE ? "Yes":"No");
        !           380:                sprintf(opt[k++],"%-32.32s%s","Native (32-bit) Executable"
        !           381:                        ,cfg.event[i]->misc&EX_NATIVE ? "Yes" : "No");
        !           382:                sprintf(opt[k++],"%-32.32s%s","Use Shell to Execute"
        !           383:                        ,cfg.event[i]->misc&XTRN_SH ? "Yes" : "No");
        !           384:                sprintf(opt[k++],"%-32.32s%s","Background Execution"
        !           385:                        ,cfg.event[i]->misc&EX_BG ? "Yes" : "No");
        !           386:                sprintf(opt[k++],"%-32.32s%s","Always Run After Init/Re-init"
        !           387:                        ,cfg.event[i]->misc&EVENT_INIT ? "Yes":"No");
        !           388: 
        !           389:                opt[k][0]=0;
        !           390:                SETHELP(WHERE);
        !           391: /*
        !           392: &Timed Event:&
        !           393: 
        !           394: This is the configuration menu for a timed event. An event is an
        !           395: external program that performs some type of automated function on the
        !           396: system. Use this menu to configure how and when this event will be
        !           397: executed.
        !           398: 
        !           399: If you need the BBS to swap out of memory for this event (to make more
        !           400: available memory), add the program name (first word of the command line)
        !           401: to &Global Swap List& from the &External Programs& menu.
        !           402: */
        !           403:                sprintf(str,"%s Timed Event",cfg.event[i]->code);
        !           404:                switch(uifc.list(WIN_SAV|WIN_ACT|WIN_L2R|WIN_BOT,0,0,70,&dfltopt,0
        !           405:                        ,str,opt)) {
        !           406:                        case -1:
        !           407:                                done=1;
        !           408:                                break;
        !           409:                        case 0:
        !           410:                                strcpy(str,cfg.event[i]->code);
        !           411:                                SETHELP(WHERE);
        !           412: /*
        !           413: &Timed Event Internal Code:&
        !           414: 
        !           415: Every timed event must have its own unique internal code for Synchronet
        !           416: to reference it by. It is helpful if this code is an abreviation of the
        !           417: command line.
        !           418: */
        !           419:                                uifc.input(WIN_MID|WIN_SAV,0,17,"Internal Code (unique)"
        !           420:                                        ,str,LEN_CODE,K_EDIT|K_UPPER);
        !           421:                                if(code_ok(str))
        !           422:                                        strcpy(cfg.event[i]->code,str);
        !           423:                                else {
        !           424:                                        uifc.helpbuf=invalid_code;
        !           425:                                        uifc.msg("Invalid Code");
        !           426:                                        uifc.helpbuf=0; }
        !           427:                 break;
        !           428:                        case 1:
        !           429:                                SETHELP(WHERE);
        !           430: /*
        !           431: &Timed Event Start-up Directory:&
        !           432: 
        !           433: This is the DOS drive/directory where the event program is located.
        !           434: If a path is specified here, it will be made the current directory
        !           435: before the event's command line is executed. This eliminates the need
        !           436: for batch files that just change the current drive and directory before
        !           437: executing the event.
        !           438: 
        !           439: If this option is not used, the current NODE's directory will be the
        !           440: current DOS drive/directory before the command line is executed.
        !           441: */
        !           442:                                uifc.input(WIN_MID|WIN_SAV,0,10,"Directory"
        !           443:                                        ,cfg.event[i]->dir,sizeof(cfg.event[i]->dir)-1,K_EDIT);
        !           444:                 break;
        !           445:                        case 2:
        !           446:                                SETHELP(WHERE);
        !           447: /*
        !           448: &Timed Event Command Line:&
        !           449: 
        !           450: This is the command line to execute upon this timed event.
        !           451: */
        !           452:                                uifc.input(WIN_MID|WIN_SAV,0,10,"Command"
        !           453:                                        ,cfg.event[i]->cmd,sizeof(cfg.event[i]->cmd)-1,K_EDIT);
        !           454:                                break;
        !           455: 
        !           456:                        case 3:
        !           457:                                k=cfg.event[i]->misc&EVENT_DISABLED ? 1:0;
        !           458:                                strcpy(opt[0],"Yes");
        !           459:                                strcpy(opt[1],"No");
        !           460:                                opt[2][0]=0;
        !           461:                                SETHELP(WHERE);
        !           462: /*
        !           463: `Event Enabled:`
        !           464: 
        !           465: If you want disable this event from executing, set this option to ~No~.
        !           466: */
        !           467:                                k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0
        !           468:                                        ,"Enabled",opt);
        !           469:                                if((k==0 && cfg.event[i]->misc&EVENT_DISABLED) 
        !           470:                                        || (k==1 && !(cfg.event[i]->misc&EVENT_DISABLED))) {
        !           471:                                        cfg.event[i]->misc^=EVENT_DISABLED;
        !           472:                                        uifc.changes=1; 
        !           473:                                }
        !           474:                 break;
        !           475: 
        !           476:                        case 4:
        !           477:                                SETHELP(WHERE);
        !           478: /*
        !           479: &Timed Event Node:&
        !           480: 
        !           481: This is the node number to execute the timed event.
        !           482: */
        !           483:                                sprintf(str,"%u",cfg.event[i]->node);
        !           484:                                uifc.input(WIN_MID|WIN_SAV,0,0,"Node Number"
        !           485:                                        ,str,3,K_EDIT|K_NUMBER);
        !           486:                                cfg.event[i]->node=atoi(str);
        !           487:                                break;
        !           488:                        case 5:
        !           489:                                SETHELP(WHERE);
        !           490: /*
        !           491: `Days of Month to Execute Event:`
        !           492: 
        !           493: Specifies the days of the month (`1-31`, separated by spaces) on which 
        !           494: to execute this event, or `Any` to execute event on any and all days of
        !           495: the month.
        !           496: */
        !           497:                                SAFECOPY(str,mdaystr(cfg.event[i]->mdays));
        !           498:                                uifc.input(WIN_MID|WIN_SAV,0,0,"Days of Month to Execute Event (or Any)"
        !           499:                                        ,str,16,K_EDIT);
        !           500:                                cfg.event[i]->mdays=0;
        !           501:                                for(p=str;*p;p++) {
        !           502:                                        if(!isdigit(*p))
        !           503:                                                continue;
        !           504:                                        cfg.event[i]->mdays|=(1<<atoi(p));
        !           505:                                        while(*p && isdigit(*p))
        !           506:                                                p++;
        !           507:                                }
        !           508:                                break;
        !           509:                        case 6:
        !           510:                                j=0;
        !           511:                                while(1) {
        !           512:                                        for(k=0;k<7;k++)
        !           513:                                                sprintf(opt[k],"%-30s %3s"
        !           514:                                                        ,wday[k],(cfg.event[i]->days&(1<<k)) ? "Yes":"No");
        !           515:                                        strcpy(opt[k++],"All");
        !           516:                                        strcpy(opt[k++],"None");
        !           517:                                        opt[k][0]=0;
        !           518:                                        SETHELP(WHERE);
        !           519: /*
        !           520: &Days of Week to Execute Event:&
        !           521: 
        !           522: These are the days of the week that this event will be executed.
        !           523: */
        !           524:                                        k=uifc.list(WIN_MID|WIN_SAV|WIN_ACT,0,0,0,&j,0
        !           525:                                                ,"Days of Week to Execute Event",opt);
        !           526:                                        if(k==-1)
        !           527:                                                break;
        !           528:                                        if(k==7)
        !           529:                                                cfg.event[i]->days=0xff;
        !           530:                                        else if(k==8)
        !           531:                                                cfg.event[i]->days=0;
        !           532:                                        else
        !           533:                                                cfg.event[i]->days^=(1<<k);
        !           534:                                        uifc.changes=1; 
        !           535:                                }
        !           536:                                break;
        !           537:                        case 7:
        !           538:                 if(cfg.event[i]->freq==0)
        !           539:                     k=0;
        !           540:                 else
        !           541:                     k=1;
        !           542:                 strcpy(opt[0],"Yes");
        !           543:                 strcpy(opt[1],"No");
        !           544:                 opt[2][0]=0;
        !           545:                 SETHELP(WHERE);
        !           546: /*
        !           547: &Execute Event at a Specific Time:&
        !           548: 
        !           549: If you want the system execute this event at a specific time, set
        !           550: this option to &Yes&. If you want the system to execute this event more
        !           551: than once a day at predetermined intervals, set this option to &No&.
        !           552: */
        !           553:                 k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0
        !           554:                     ,"Execute Event at a Specific Time",opt);
        !           555:                 if(k==0) {
        !           556:                     sprintf(str,"%2.2u:%2.2u",cfg.event[i]->time/60
        !           557:                         ,cfg.event[i]->time%60);
        !           558:                     SETHELP(WHERE);
        !           559: /*
        !           560: &Time to Execute Event:&
        !           561: 
        !           562: This is the time (in 24 hour HH:MM format) to execute the event.
        !           563: */
        !           564:                     if(uifc.input(WIN_MID|WIN_SAV,0,0
        !           565:                         ,"Time to Execute Event (HH:MM)"
        !           566:                         ,str,5,K_UPPER|K_EDIT)>0) {
        !           567:                         cfg.event[i]->freq=0;
        !           568:                         cfg.event[i]->time=atoi(str)*60;
        !           569:                         if((p=strchr(str,':'))!=NULL)
        !           570:                             cfg.event[i]->time+=atoi(p+1); } }
        !           571:                 else if(k==1) {
        !           572:                     sprintf(str,"%u"
        !           573:                         ,cfg.event[i]->freq && cfg.event[i]->freq<=1440
        !           574:                             ? 1440/cfg.event[i]->freq : 0);
        !           575:                     SETHELP(WHERE);
        !           576: /*
        !           577: &Number of Executions Per Day:&
        !           578: 
        !           579: This is the maximum number of times the system will execute this event
        !           580: per day.
        !           581: */
        !           582:                     if(uifc.input(WIN_MID|WIN_SAV,0,0
        !           583:                         ,"Number of Executions Per Day"
        !           584:                         ,str,4,K_NUMBER|K_EDIT)>0) {
        !           585:                         cfg.event[i]->time=0;
        !           586:                         k=atoi(str);
        !           587:                         if(k && k<=1440)
        !           588:                             cfg.event[i]->freq=1440/k;
        !           589:                         else
        !           590:                             cfg.event[i]->freq=0;
        !           591:                         }
        !           592:                     }
        !           593:                 break;
        !           594:                        case 8:
        !           595:                                k=cfg.event[i]->misc&EVENT_EXCL ? 0:1;
        !           596:                                strcpy(opt[0],"Yes");
        !           597:                                strcpy(opt[1],"No");
        !           598:                                opt[2][0]=0;
        !           599:                                SETHELP(WHERE);
        !           600: /*
        !           601: &Exclusive Event Execution:&
        !           602: 
        !           603: If this event must be run exclusively (all nodes inactive), set this
        !           604: option to &Yes&.
        !           605: */
        !           606:                                k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0,"Exclusive Execution"
        !           607:                                        ,opt);
        !           608:                                if(!k && !(cfg.event[i]->misc&EVENT_EXCL)) {
        !           609:                                        cfg.event[i]->misc|=EVENT_EXCL;
        !           610:                                        uifc.changes=1; }
        !           611:                                else if(k==1 && cfg.event[i]->misc&EVENT_EXCL) {
        !           612:                                        cfg.event[i]->misc&=~EVENT_EXCL;
        !           613:                                        uifc.changes=1; }
        !           614:                 break;
        !           615:                        case 9:
        !           616:                                k=cfg.event[i]->misc&EVENT_FORCE ? 0:1;
        !           617:                                strcpy(opt[0],"Yes");
        !           618:                                strcpy(opt[1],"No");
        !           619:                                opt[2][0]=0;
        !           620:                                SETHELP(WHERE);
        !           621: /*
        !           622: &Force Users Off-line for Event:&
        !           623: 
        !           624: If you want to have your users' on-line time reduced so the event can
        !           625: execute precisely on time, set this option to &Yes&.
        !           626: */
        !           627:                                k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0
        !           628:                                        ,"Force Users Off-line for Event",opt);
        !           629:                                if(!k && !(cfg.event[i]->misc&EVENT_FORCE)) {
        !           630:                                        cfg.event[i]->misc|=EVENT_FORCE;
        !           631:                                        uifc.changes=1; }
        !           632:                                else if(k==1 && cfg.event[i]->misc&EVENT_FORCE) {
        !           633:                                        cfg.event[i]->misc&=~EVENT_FORCE;
        !           634:                     uifc.changes=1; }
        !           635:                 break;
        !           636: 
        !           637:                        case 10:
        !           638:                                k=cfg.event[i]->misc&EX_NATIVE ? 0:1;
        !           639:                                strcpy(opt[0],"Yes");
        !           640:                                strcpy(opt[1],"No");
        !           641:                                opt[2][0]=0;
        !           642:                                SETHELP(WHERE);
        !           643: /*
        !           644: &Native (32-bit) Executable:&
        !           645: 
        !           646: If this event program is a native 32-bit executable,
        !           647: set this option to &Yes&.
        !           648: */
        !           649:                                k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0
        !           650:                                        ,"Native (32-bit)",opt);
        !           651:                                if(!k && !(cfg.event[i]->misc&EX_NATIVE)) {
        !           652:                                        cfg.event[i]->misc|=EX_NATIVE;
        !           653:                                        uifc.changes=TRUE;
        !           654:                 }
        !           655:                                else if(k==1 && cfg.event[i]->misc&EX_NATIVE) {
        !           656:                                        cfg.event[i]->misc&=~EX_NATIVE;
        !           657:                                        uifc.changes=TRUE;
        !           658:                 }
        !           659:                 break;
        !           660: 
        !           661:                        case 11:
        !           662:                                k=cfg.event[i]->misc&XTRN_SH ? 0:1;
        !           663:                                strcpy(opt[0],"Yes");
        !           664:                                strcpy(opt[1],"No");
        !           665:                                opt[2][0]=0;
        !           666:                                SETHELP(WHERE);
        !           667: /*
        !           668: `Use Shell to Execute Command:`
        !           669: 
        !           670: If this command-line requires the system command shell to execute, (Unix 
        !           671: shell script or DOS batch file), set this option to ~Yes~.
        !           672: */
        !           673:                                k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0
        !           674:                                        ,"Use Shell",opt);
        !           675:                                if(!k && !(cfg.event[i]->misc&XTRN_SH)) {
        !           676:                                        cfg.event[i]->misc|=XTRN_SH;
        !           677:                                        uifc.changes=TRUE;
        !           678:                 }
        !           679:                                else if(k==1 && cfg.event[i]->misc&XTRN_SH) {
        !           680:                                        cfg.event[i]->misc&=~XTRN_SH;
        !           681:                                        uifc.changes=TRUE;
        !           682:                 }
        !           683:                 break;
        !           684: 
        !           685:                        case 12:
        !           686:                                k=cfg.event[i]->misc&EX_BG ? 0:1;
        !           687:                                strcpy(opt[0],"Yes");
        !           688:                                strcpy(opt[1],"No");
        !           689:                                opt[2][0]=0;
        !           690:                                SETHELP(WHERE);
        !           691: /*
        !           692: &Execute Event in Background (Asynchronously):&
        !           693: 
        !           694: If you would like this event to run simultaneously with other events,
        !           695: set this option to &Yes&. Exclusive events will not run in the background.
        !           696: */
        !           697:                                k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0
        !           698:                                        ,"Background (Asynchronous) Execution",opt);
        !           699:                                if(!k && !(cfg.event[i]->misc&EX_BG)) {
        !           700:                                        cfg.event[i]->misc|=EX_BG;
        !           701:                                        uifc.changes=TRUE;
        !           702:                 }
        !           703:                                else if(k==1 && cfg.event[i]->misc&EX_BG) {
        !           704:                                        cfg.event[i]->misc&=~EX_BG;
        !           705:                     uifc.changes=TRUE;
        !           706:                 }
        !           707:                 break;
        !           708: 
        !           709:                        case 13:
        !           710:                                k=cfg.event[i]->misc&EVENT_INIT ? 0:1;
        !           711:                                strcpy(opt[0],"Yes");
        !           712:                                strcpy(opt[1],"No");
        !           713:                                opt[2][0]=0;
        !           714:                                SETHELP(WHERE);
        !           715: /*
        !           716: `Always Run After Initialization or Re-initialization:`
        !           717: 
        !           718: If you want this event to always run after the BBS is initialized or
        !           719: re-initialized, set this option to ~Yes~.
        !           720: */
        !           721:                                k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0
        !           722:                                        ,"Always Run After Initialization or Re-initialization",opt);
        !           723:                                if(!k && !(cfg.event[i]->misc&EVENT_INIT)) {
        !           724:                                        cfg.event[i]->misc|=EVENT_INIT;
        !           725:                                        uifc.changes=1; 
        !           726:                                }
        !           727:                                else if(k==1 && cfg.event[i]->misc&EVENT_INIT) {
        !           728:                                        cfg.event[i]->misc&=~EVENT_INIT;
        !           729:                     uifc.changes=1; 
        !           730:                                }
        !           731:                 break;
        !           732:                        } 
        !           733:                } 
        !           734:        }
        !           735: }
        !           736: 
        !           737: 
        !           738: void xtrn_cfg(uint section)
        !           739: {
        !           740:        static int ext_dflt,ext_bar,opt_dflt,time_dflt;
        !           741:        char str[128],code[9],done=0,*p;
        !           742:        int j,k;
        !           743:        uint i,n,xtrnnum[MAX_OPTS+1];
        !           744:        static xtrn_t savxtrn;
        !           745: 
        !           746: while(1) {
        !           747:        for(i=0,j=0;i<cfg.total_xtrns && j<MAX_OPTS;i++)
        !           748:                if(cfg.xtrn[i]->sec==section) {
        !           749:                        sprintf(opt[j],"%-25s",cfg.xtrn[i]->name);
        !           750:                        xtrnnum[j++]=i; }
        !           751:        xtrnnum[j]=cfg.total_xtrns;
        !           752:        opt[j][0]=0;
        !           753:        i=WIN_ACT|WIN_CHE|WIN_SAV|WIN_RHT;
        !           754:        if(j)
        !           755:                i|=WIN_DEL|WIN_GET;
        !           756:        if(cfg.total_xtrns<MAX_OPTS)
        !           757:                i|=WIN_INS|WIN_INSACT|WIN_XTR;
        !           758:        if(savxtrn.name[0])
        !           759:                i|=WIN_PUT;
        !           760:        SETHELP(WHERE);
        !           761: /*
        !           762: &Online External Programs:&
        !           763: 
        !           764: This is a list of the configured online external programs (doors).
        !           765: 
        !           766: To add a program, select the desired location with the arrow keys and
        !           767: hit  INS .
        !           768: 
        !           769: To delete a program, select it with the arrow keys and hit  DEL .
        !           770: 
        !           771: To configure a program, select it with the arrow keys and hit  ENTER .
        !           772: */
        !           773:        sprintf(str,"%s Online Programs",cfg.xtrnsec[section]->name);
        !           774:        i=uifc.list(i,0,0,45,&ext_dflt,&ext_bar,str,opt);
        !           775:        if((signed)i==-1)
        !           776:                return;
        !           777:        if((i&MSK_ON)==MSK_INS) {
        !           778:                i&=MSK_OFF;
        !           779:                SETHELP(WHERE);
        !           780: /*
        !           781: &Online Program Name:&
        !           782: 
        !           783: This is the name or description of the online program (door).
        !           784: */
        !           785:                if(uifc.input(WIN_MID|WIN_SAV,0,0,"Online Program Name",str,25
        !           786:                        ,0)<1)
        !           787:             continue;
        !           788:                sprintf(code,"%.8s",str);
        !           789:                p=strchr(code,' ');
        !           790:                if(p) *p=0;
        !           791:         strupr(code);
        !           792:                SETHELP(WHERE);
        !           793: /*
        !           794: &Online Program Internal Code:&
        !           795: 
        !           796: Every online program must have its own unique code for Synchronet to
        !           797: refer to it internally. This code is usually an abreviation of the
        !           798: online program name.
        !           799: */
        !           800:                if(uifc.input(WIN_MID|WIN_SAV,0,0,"Internal Code"
        !           801:                        ,code,LEN_CODE,K_EDIT|K_UPPER)<1)
        !           802:                        continue;
        !           803:                if(!code_ok(code)) {
        !           804:                        uifc.helpbuf=invalid_code;
        !           805:                        uifc.msg("Invalid Code");
        !           806:                        uifc.helpbuf=0;
        !           807:             continue; }
        !           808:                if((cfg.xtrn=(xtrn_t **)realloc(cfg.xtrn,sizeof(xtrn_t *)*(cfg.total_xtrns+1)))
        !           809:             ==NULL) {
        !           810:             errormsg(WHERE,ERR_ALLOC,nulstr,cfg.total_xtrns+1);
        !           811:                        cfg.total_xtrns=0;
        !           812:                        bail(1);
        !           813:             continue; }
        !           814:                if(j)
        !           815:                        for(n=cfg.total_xtrns;n>xtrnnum[i];n--)
        !           816:                                cfg.xtrn[n]=cfg.xtrn[n-1];
        !           817:                if((cfg.xtrn[xtrnnum[i]]=(xtrn_t *)malloc(sizeof(xtrn_t)))==NULL) {
        !           818:                        errormsg(WHERE,ERR_ALLOC,nulstr,sizeof(xtrn_t));
        !           819:                        continue; }
        !           820:                memset((xtrn_t *)cfg.xtrn[xtrnnum[i]],0,sizeof(xtrn_t));
        !           821:                strcpy(cfg.xtrn[xtrnnum[i]]->name,str);
        !           822:                strcpy(cfg.xtrn[xtrnnum[i]]->code,code);
        !           823:                cfg.xtrn[xtrnnum[i]]->sec=section;
        !           824:                cfg.total_xtrns++;
        !           825:                uifc.changes=TRUE;
        !           826:                continue; }
        !           827:        if((i&MSK_ON)==MSK_DEL) {
        !           828:                i&=MSK_OFF;
        !           829:                free(cfg.xtrn[xtrnnum[i]]);
        !           830:                cfg.total_xtrns--;
        !           831:                for(j=xtrnnum[i];j<cfg.total_xtrns;j++)
        !           832:                        cfg.xtrn[j]=cfg.xtrn[j+1];
        !           833:                uifc.changes=TRUE;
        !           834:                continue; }
        !           835:        if((i&MSK_ON)==MSK_GET) {
        !           836:                i&=MSK_OFF;
        !           837:                savxtrn=*cfg.xtrn[xtrnnum[i]];
        !           838:                continue; }
        !           839:        if((i&MSK_ON)==MSK_PUT) {
        !           840:                i&=MSK_OFF;
        !           841:                *cfg.xtrn[xtrnnum[i]]=savxtrn;
        !           842:                cfg.xtrn[xtrnnum[i]]->sec=section;
        !           843:                uifc.changes=TRUE;
        !           844:         continue; }
        !           845:        done=0;
        !           846:        i=xtrnnum[i];
        !           847:        while(!done) {
        !           848:                k=0;
        !           849:                sprintf(opt[k++],"%-27.27s%s","Name",cfg.xtrn[i]->name);
        !           850:                sprintf(opt[k++],"%-27.27s%s","Internal Code",cfg.xtrn[i]->code);
        !           851:                sprintf(opt[k++],"%-27.27s%.40s","Start-up Directory",cfg.xtrn[i]->path);
        !           852:                sprintf(opt[k++],"%-27.27s%.40s","Command Line",cfg.xtrn[i]->cmd);
        !           853:                sprintf(opt[k++],"%-27.27s%.40s","Clean-up Command Line",cfg.xtrn[i]->clean);
        !           854:                if(cfg.xtrn[i]->cost)
        !           855:                        sprintf(str,"%lu credits",cfg.xtrn[i]->cost);
        !           856:                else
        !           857:                        strcpy(str,"None");
        !           858:                sprintf(opt[k++],"%-27.27s%s","Execution Cost",str);
        !           859:                sprintf(opt[k++],"%-27.27s%.40s","Access Requirements",cfg.xtrn[i]->arstr);
        !           860:                sprintf(opt[k++],"%-27.27s%.40s","Execution Requirements"
        !           861:                        ,cfg.xtrn[i]->run_arstr);
        !           862:                sprintf(opt[k++],"%-27.27s%s","Multiple Concurrent Users"
        !           863:                        ,cfg.xtrn[i]->misc&MULTIUSER ? "Yes" : "No");
        !           864:                sprintf(opt[k++],"%-27.27s%s%s%s","Intercept Standard I/O"
        !           865:                        ,cfg.xtrn[i]->misc&IO_INTS ? "Yes" : "No"
        !           866:                        ,(cfg.xtrn[i]->misc&(IO_INTS|WWIVCOLOR))
        !           867:                                ==(IO_INTS|WWIVCOLOR) ? ", WWIV Color" : nulstr
        !           868:                        ,(cfg.xtrn[i]->misc&(IO_INTS|XTRN_NOECHO))
        !           869:                                ==(IO_INTS|XTRN_NOECHO) ? ", No Echo" : nulstr);
        !           870:                sprintf(opt[k++],"%-27.27s%s","Native (32-bit) Executable"
        !           871:                        ,cfg.xtrn[i]->misc&XTRN_NATIVE ? "Yes" : "No");
        !           872:                sprintf(opt[k++],"%-27.27s%s","Use Shell to Execute"
        !           873:                        ,cfg.xtrn[i]->misc&XTRN_SH ? "Yes" : "No");
        !           874:                sprintf(opt[k++],"%-27.27s%s","Modify User Data"
        !           875:             ,cfg.xtrn[i]->misc&MODUSERDAT ? "Yes" : "No");
        !           876:                switch(cfg.xtrn[i]->event) {
        !           877:                        case EVENT_LOGON:
        !           878:                                strcpy(str,"Logon");
        !           879:                                break;
        !           880:                        case EVENT_LOGOFF:
        !           881:                                strcpy(str,"Logoff");
        !           882:                                break;
        !           883:                        case EVENT_NEWUSER:
        !           884:                                strcpy(str,"New User");
        !           885:                                break;
        !           886:                        case EVENT_BIRTHDAY:
        !           887:                                strcpy(str,"Birthday");
        !           888:                                break;
        !           889:                        case EVENT_POST:
        !           890:                                strcpy(str,"Message Posted");
        !           891:                                break;
        !           892:                        case EVENT_UPLOAD:
        !           893:                                strcpy(str,"File Uploaded");
        !           894:                                break;
        !           895:                        case EVENT_DOWNLOAD:
        !           896:                                strcpy(str,"File Downloaded");
        !           897:                                break;
        !           898:                        default:
        !           899:                                strcpy(str,"No");
        !           900:                                break; 
        !           901:                }
        !           902:                if(cfg.xtrn[i]->misc&EVENTONLY && cfg.xtrn[i]->event)
        !           903:                        strcat(str,", Only");
        !           904:                sprintf(opt[k++],"%-27.27s%s","Execute on Event",str);
        !           905:                sprintf(opt[k++],"%-27.27s%s","Pause After Execution"
        !           906:                        ,cfg.xtrn[i]->misc&XTRN_PAUSE ? "Yes" : "No");
        !           907:                sprintf(opt[k++],"%-23.23s%-4s%s","BBS Drop File Type"
        !           908:                        ,cfg.xtrn[i]->misc&REALNAME ? "(R)":nulstr
        !           909:                        ,dropfile(cfg.xtrn[i]->type,cfg.xtrn[i]->misc));
        !           910:                sprintf(opt[k++],"%-27.27s%s","Place Drop File In"
        !           911:                        ,cfg.xtrn[i]->misc&STARTUPDIR ? "Start-Up Directory":"Node Directory");
        !           912:                sprintf(opt[k++],"Time Options...");
        !           913:                opt[k][0]=0;
        !           914:                SETHELP(WHERE);
        !           915: /*
        !           916: &Online Program Configuration:&
        !           917: 
        !           918: This menu is for configuring the selected online program.
        !           919: */
        !           920:                switch(uifc.list(WIN_SAV|WIN_ACT|WIN_MID,0,0,60,&opt_dflt,0,cfg.xtrn[i]->name
        !           921:                        ,opt)) {
        !           922:                        case -1:
        !           923:                                done=1;
        !           924:                                break;
        !           925:                        case 0:
        !           926:                                SETHELP(WHERE);
        !           927: /*
        !           928: &Online Program Name:&
        !           929: 
        !           930: This is the name or description of the online program (door).
        !           931: */
        !           932:                                strcpy(str,cfg.xtrn[i]->name);
        !           933:                                if(!uifc.input(WIN_MID|WIN_SAV,0,10,"Online Program Name"
        !           934:                                        ,cfg.xtrn[i]->name,sizeof(cfg.xtrn[i]->name)-1,K_EDIT))
        !           935:                                        strcpy(cfg.xtrn[i]->name,str);
        !           936:                                break;
        !           937:                        case 1:
        !           938:                                SETHELP(WHERE);
        !           939: /*
        !           940: &Online Program Internal Code:&
        !           941: 
        !           942: Every online program must have its own unique code for Synchronet to
        !           943: refer to it internally. This code is usually an abreviation of the
        !           944: online program name.
        !           945: */
        !           946:                                strcpy(str,cfg.xtrn[i]->code);
        !           947:                                uifc.input(WIN_MID|WIN_SAV,0,10,"Internal Code"
        !           948:                                        ,str,LEN_CODE,K_UPPER|K_EDIT);
        !           949:                                if(code_ok(str))
        !           950:                                        strcpy(cfg.xtrn[i]->code,str);
        !           951:                                else {
        !           952:                                        uifc.helpbuf=invalid_code;
        !           953:                                        uifc.msg("Invalid Code");
        !           954:                     uifc.helpbuf=0; 
        !           955:                                }
        !           956:                 break;
        !           957:                        case 2:
        !           958:                 SETHELP(WHERE);
        !           959: /*
        !           960: &Online Program Start-up Directory:&
        !           961: 
        !           962: This is the DOS drive/directory where the online program is located.
        !           963: If a path is specified here, it will be made the current directory
        !           964: before the program's command line is executed. This eliminates the need
        !           965: for batch files that just change the current drive and directory before
        !           966: executing the program.
        !           967: 
        !           968: If this option is not used, the current NODE's directory will be the
        !           969: current DOS drive/directory before the command line is executed.
        !           970: */
        !           971:                                uifc.input(WIN_MID|WIN_SAV,0,10,""
        !           972:                                        ,cfg.xtrn[i]->path,sizeof(cfg.xtrn[i]->path)-1,K_EDIT);
        !           973:                 break;
        !           974:                        case 3:
        !           975:                                SETHELP(WHERE);
        !           976: /*
        !           977: &Online Program Command Line:&
        !           978: 
        !           979: This is the command line to execute to run the online program.
        !           980: */
        !           981:                                uifc.input(WIN_MID|WIN_SAV,0,10,"Command"
        !           982:                                        ,cfg.xtrn[i]->cmd,sizeof(cfg.xtrn[i]->cmd)-1,K_EDIT);
        !           983:                                break;
        !           984:                        case 4:
        !           985:                                SETHELP(WHERE);
        !           986: /*
        !           987: &Online Program Clean-up Command:&
        !           988: 
        !           989: This is the command line to execute after the main command line. This
        !           990: option is usually only used for multiuser online programs.
        !           991: */
        !           992:                                uifc.input(WIN_MID|WIN_SAV,0,10,"Clean-up"
        !           993:                                        ,cfg.xtrn[i]->clean,sizeof(cfg.xtrn[i]->clean)-1,K_EDIT);
        !           994:                 break;
        !           995:                        case 5:
        !           996:                 ultoa(cfg.xtrn[i]->cost,str,10);
        !           997:                 SETHELP(WHERE);
        !           998: /*
        !           999: &Online Program Cost to Run:&
        !          1000: 
        !          1001: If you want users to be charged credits to run this online program,
        !          1002: set this value to the number of credits to charge. If you want this
        !          1003: online program to be free, set this value to &0&.
        !          1004: */
        !          1005:                 uifc.input(WIN_MID|WIN_SAV,0,0,"Cost to Run (in Credits)"
        !          1006:                     ,str,10,K_EDIT|K_NUMBER);
        !          1007:                 cfg.xtrn[i]->cost=atol(str);
        !          1008:                 break;
        !          1009:                        case 6:
        !          1010:                                sprintf(str,"%s Access",cfg.xtrn[i]->name);
        !          1011:                                getar(str,cfg.xtrn[i]->arstr);
        !          1012:                 break;
        !          1013:                        case 7:
        !          1014:                                sprintf(str,"%s Execution",cfg.xtrn[i]->name);
        !          1015:                                getar(str,cfg.xtrn[i]->run_arstr);
        !          1016:                 break;
        !          1017:                        case 8:
        !          1018:                                k=cfg.xtrn[i]->misc&MULTIUSER ? 0:1;
        !          1019:                                strcpy(opt[0],"Yes");
        !          1020:                                strcpy(opt[1],"No");
        !          1021:                                opt[2][0]=0;
        !          1022:                                SETHELP(WHERE);
        !          1023: /*
        !          1024: &Supports Multiple Users:&
        !          1025: 
        !          1026: If this online program supports multiple simultaneous users (nodes),
        !          1027: set this option to &Yes&.
        !          1028: */
        !          1029:                                k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0,"Supports Multiple Users"
        !          1030:                                        ,opt);
        !          1031:                                if(!k && !(cfg.xtrn[i]->misc&MULTIUSER)) {
        !          1032:                                        cfg.xtrn[i]->misc|=MULTIUSER;
        !          1033:                                        uifc.changes=TRUE; }
        !          1034:                                else if(k==1 && cfg.xtrn[i]->misc&MULTIUSER) {
        !          1035:                                        cfg.xtrn[i]->misc&=~MULTIUSER;
        !          1036:                                        uifc.changes=TRUE; }
        !          1037:                 break;
        !          1038:                        case 9:
        !          1039:                                k=cfg.xtrn[i]->misc&IO_INTS ? 0:1;
        !          1040:                                strcpy(opt[0],"Yes");
        !          1041:                                strcpy(opt[1],"No");
        !          1042:                                opt[2][0]=0;
        !          1043:                                SETHELP(WHERE);
        !          1044: /*
        !          1045: &Intercept Standard I/O:&
        !          1046: 
        !          1047: If this online program uses a FOSSIL driver or SOCKET communications,
        !          1048: set this option to &No&.
        !          1049: */
        !          1050:                                k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0,"Intercept Standard I/O"
        !          1051:                                        ,opt);
        !          1052:                                if(!k && !(cfg.xtrn[i]->misc&IO_INTS)) {
        !          1053:                                        cfg.xtrn[i]->misc|=IO_INTS;
        !          1054:                                        uifc.changes=TRUE; }
        !          1055:                                else if(k==1 && cfg.xtrn[i]->misc&IO_INTS) {
        !          1056:                                        cfg.xtrn[i]->misc&=~(IO_INTS|WWIVCOLOR);
        !          1057:                                        uifc.changes=TRUE; }
        !          1058:                 else if(k==-1)
        !          1059:                     break;
        !          1060:                                if(!(cfg.xtrn[i]->misc&IO_INTS))
        !          1061:                                        break;
        !          1062:                                k=cfg.xtrn[i]->misc&WWIVCOLOR ? 0:1;
        !          1063:                                SETHELP(WHERE);
        !          1064: /*
        !          1065: &Program Uses WWIV Color Codes:&
        !          1066: 
        !          1067: If this program was written for use exclusively under WWIV, set this
        !          1068: option to &Yes&.
        !          1069: */
        !          1070:                                k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0
        !          1071:                                        ,"Program Uses WWIV Color Codes"
        !          1072:                                        ,opt);
        !          1073:                                if(!k && !(cfg.xtrn[i]->misc&WWIVCOLOR)) {
        !          1074:                                        cfg.xtrn[i]->misc|=WWIVCOLOR;
        !          1075:                                        uifc.changes=TRUE; }
        !          1076:                                else if(k==1 && cfg.xtrn[i]->misc&WWIVCOLOR) {
        !          1077:                                        cfg.xtrn[i]->misc&=~WWIVCOLOR;
        !          1078:                     uifc.changes=TRUE; }
        !          1079:                                k=cfg.xtrn[i]->misc&XTRN_NOECHO ? 1:0;
        !          1080:                                SETHELP(WHERE);
        !          1081: /*
        !          1082: `Echo Input:`
        !          1083: 
        !          1084: If you want the BBS to copy ("echo") all keyboard input to the screen
        !          1085: output, set this option to ~Yes~ (for native Win32 programs only).
        !          1086: */
        !          1087:                                k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0
        !          1088:                                        ,"Echo Keyboard Input"
        !          1089:                                        ,opt);
        !          1090:                                if(!k && cfg.xtrn[i]->misc&XTRN_NOECHO) {
        !          1091:                                        cfg.xtrn[i]->misc&=~XTRN_NOECHO;
        !          1092:                                        uifc.changes=TRUE; 
        !          1093:                                } else if(k==1 && !(cfg.xtrn[i]->misc&XTRN_NOECHO)) {
        !          1094:                                        cfg.xtrn[i]->misc|=XTRN_NOECHO;
        !          1095:                                        uifc.changes=TRUE; 
        !          1096:                                }
        !          1097:                 break;
        !          1098:                        case 10:
        !          1099:                                k=cfg.xtrn[i]->misc&XTRN_NATIVE ? 0:1;
        !          1100:                                strcpy(opt[0],"Yes");
        !          1101:                                strcpy(opt[1],"No");
        !          1102:                                opt[2][0]=0;
        !          1103:                                SETHELP(WHERE);
        !          1104: /*
        !          1105: &Native (32-bit) Executable:&
        !          1106: 
        !          1107: If this online program is a native 32-bit executable,
        !          1108: set this option to &Yes&.
        !          1109: */
        !          1110:                                k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0
        !          1111:                                        ,"Native (32-bit)",opt);
        !          1112:                                if(!k && !(cfg.xtrn[i]->misc&XTRN_NATIVE)) {
        !          1113:                                        cfg.xtrn[i]->misc|=XTRN_NATIVE;
        !          1114:                                        uifc.changes=TRUE; }
        !          1115:                                else if(k==1 && cfg.xtrn[i]->misc&XTRN_NATIVE) {
        !          1116:                                        cfg.xtrn[i]->misc&=~XTRN_NATIVE;
        !          1117:                                        uifc.changes=TRUE; }
        !          1118:                                break;
        !          1119:                        case 11:
        !          1120:                                k=cfg.xtrn[i]->misc&XTRN_SH ? 0:1;
        !          1121:                                strcpy(opt[0],"Yes");
        !          1122:                                strcpy(opt[1],"No");
        !          1123:                                opt[2][0]=0;
        !          1124:                                SETHELP(WHERE);
        !          1125: /*
        !          1126: `Use Shell to Execute Command:`
        !          1127: 
        !          1128: If this command-line requires the system command shell to execute, (Unix 
        !          1129: shell script or DOS batch file), set this option to ~Yes~.
        !          1130: */
        !          1131:                                k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0
        !          1132:                                        ,"Use Shell",opt);
        !          1133:                                if(!k && !(cfg.xtrn[i]->misc&XTRN_SH)) {
        !          1134:                                        cfg.xtrn[i]->misc|=XTRN_SH;
        !          1135:                                        uifc.changes=TRUE; 
        !          1136:                                }
        !          1137:                                else if(k==1 && cfg.xtrn[i]->misc&XTRN_SH) {
        !          1138:                                        cfg.xtrn[i]->misc&=~XTRN_SH;
        !          1139:                                        uifc.changes=TRUE; 
        !          1140:                                }
        !          1141:                                break;
        !          1142:                        case 12:
        !          1143:                                k=cfg.xtrn[i]->misc&MODUSERDAT ? 0:1;
        !          1144:                                strcpy(opt[0],"Yes");
        !          1145:                                strcpy(opt[1],"No");
        !          1146:                                opt[2][0]=0;
        !          1147:                                SETHELP(WHERE);
        !          1148: /*
        !          1149: &Program Can Modify User Data:&
        !          1150: 
        !          1151: If this online programs recognizes the Synchronet MODUSER.DAT format
        !          1152: or the RBBS/QuickBBS EXITINFO.BBS format and you want it to be able to
        !          1153: modify the data of users who run the program, set this option to &Yes&.
        !          1154: */
        !          1155:                                k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0
        !          1156:                                        ,"Program Can Modify User Data",opt);
        !          1157:                                if(!k && !(cfg.xtrn[i]->misc&MODUSERDAT)) {
        !          1158:                                        cfg.xtrn[i]->misc|=MODUSERDAT;
        !          1159:                                        uifc.changes=TRUE; }
        !          1160:                                else if(k==1 && cfg.xtrn[i]->misc&MODUSERDAT) {
        !          1161:                                        cfg.xtrn[i]->misc&=~MODUSERDAT;
        !          1162:                                        uifc.changes=TRUE; }
        !          1163:                 break;
        !          1164:                        case 13:
        !          1165:                                k=0;
        !          1166:                                strcpy(opt[k++],"No");
        !          1167:                                strcpy(opt[k++],"Logon");
        !          1168:                                strcpy(opt[k++],"Logoff");
        !          1169:                                strcpy(opt[k++],"New User");
        !          1170:                                strcpy(opt[k++],"Birthday");
        !          1171:                                strcpy(opt[k++],"Message Posted");
        !          1172:                                strcpy(opt[k++],"File Uploaded");
        !          1173:                                strcpy(opt[k++],"File Downloaded");
        !          1174:                                opt[k][0]=0;
        !          1175:                                k=cfg.xtrn[i]->event;
        !          1176:                                SETHELP(WHERE);
        !          1177: /*
        !          1178: &Execute Online Program on Event:&
        !          1179: 
        !          1180: If you would like this online program to automatically execute on a
        !          1181: specific user event, select the event. Otherwise, select &No&.
        !          1182: */
        !          1183:                                k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0
        !          1184:                                        ,"Execute on Event",opt);
        !          1185:                                if(k==-1)
        !          1186:                                        break;
        !          1187:                                if(cfg.xtrn[i]->event!=k) {
        !          1188:                                        cfg.xtrn[i]->event=k;
        !          1189:                                        uifc.changes=TRUE; }
        !          1190:                                if(!cfg.xtrn[i]->event) {
        !          1191:                                        if(cfg.xtrn[i]->misc&EVENTONLY) {
        !          1192:                                                cfg.xtrn[i]->misc&=~EVENTONLY;
        !          1193:                                                uifc.changes=TRUE; 
        !          1194:                                        }
        !          1195:                                        break;
        !          1196:                                }
        !          1197:                                k=cfg.xtrn[i]->misc&EVENTONLY ? 0:1;
        !          1198:                 strcpy(opt[0],"Yes");
        !          1199:                 strcpy(opt[1],"No");
        !          1200:                                opt[2][0]=0;
        !          1201:                                SETHELP(WHERE);
        !          1202: /*
        !          1203: &Execute Online Program as Event Only:&
        !          1204: 
        !          1205: If you would like this online program to execute as an event only
        !          1206: (not available to users on the online program menu), set this option
        !          1207: to &Yes&.
        !          1208: */
        !          1209:                                k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k
        !          1210:                                        ,0,"Execute as Event Only"
        !          1211:                     ,opt);
        !          1212:                 if(!k && !(cfg.xtrn[i]->misc&EVENTONLY)) {
        !          1213:                     cfg.xtrn[i]->misc|=EVENTONLY;
        !          1214:                     uifc.changes=TRUE; }
        !          1215:                 else if(k==1 && cfg.xtrn[i]->misc&EVENTONLY) {
        !          1216:                     cfg.xtrn[i]->misc&=~EVENTONLY;
        !          1217:                     uifc.changes=TRUE; }
        !          1218:                 break;
        !          1219:                        case 14:
        !          1220:                                k=cfg.xtrn[i]->misc&XTRN_PAUSE ? 0:1;
        !          1221:                                strcpy(opt[0],"Yes");
        !          1222:                                strcpy(opt[1],"No");
        !          1223:                                opt[2][0]=0;
        !          1224:                                SETHELP(WHERE);
        !          1225: /*
        !          1226: `Pause Screen After Execution:`
        !          1227: 
        !          1228: Set this option to ~Yes~ if you would like an automatic screen pause
        !          1229: (`[Hit a key]` prompt) to appear after the program executes.
        !          1230: 
        !          1231: This can be useful if the program displays information just before exiting
        !          1232: or you want to debug a program with a program not running correctly.
        !          1233: */
        !          1234:                                k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0
        !          1235:                                        ,"Pause After Execution",opt);
        !          1236:                                if((!k && !(cfg.xtrn[i]->misc&XTRN_PAUSE))
        !          1237:                                        || (k && cfg.xtrn[i]->misc&XTRN_PAUSE)) {
        !          1238:                                        cfg.xtrn[i]->misc^=XTRN_PAUSE;
        !          1239:                                        uifc.changes=TRUE; 
        !          1240:                                }
        !          1241:                                break;
        !          1242:                        case 15:
        !          1243:                                k=0;
        !          1244:                                strcpy(opt[k++],"None");
        !          1245:                                sprintf(opt[k++],"%-15s %s","Synchronet","XTRN.DAT");
        !          1246:                                sprintf(opt[k++],"%-15s %s","WWIV","CHAIN.TXT");
        !          1247:                                sprintf(opt[k++],"%-15s %s","GAP","DOOR.SYS");
        !          1248:                                sprintf(opt[k++],"%-15s %s","RBBS/QuickBBS","DORINFO#.DEF");
        !          1249:                                sprintf(opt[k++],"%-15s %s","Wildcat","CALLINFO.BBS");
        !          1250:                                sprintf(opt[k++],"%-15s %s","PCBoard","PCBOARD.SYS");
        !          1251:                                sprintf(opt[k++],"%-15s %s","SpitFire","SFDOORS.DAT");
        !          1252:                                sprintf(opt[k++],"%-15s %s","MegaMail","UTIDOOR.TXT");
        !          1253:                                sprintf(opt[k++],"%-15s %s","Solar Realms","DOORFILE.SR");
        !          1254:                                sprintf(opt[k++],"%-15s %s","RBBS/QuickBBS","DORINFO1.DEF");
        !          1255:                                sprintf(opt[k++],"%-15s %s","TriBBS","TRIBBS.SYS");
        !          1256:                                sprintf(opt[k++],"%-15s %s","Mystic","DOOR32.SYS");
        !          1257:                                opt[k][0]=0;
        !          1258:                                k=cfg.xtrn[i]->type;
        !          1259:                                SETHELP(WHERE);
        !          1260: /*
        !          1261: &Online Program BBS Drop File Type:&
        !          1262: 
        !          1263: If this online program requires a specific BBS data (drop) file
        !          1264: format, select the file format from the list.
        !          1265: */
        !          1266:                                k=uifc.list(WIN_MID|WIN_ACT,0,0,0,&k,0
        !          1267:                                        ,"BBS Drop File Type",opt);
        !          1268:                                if(k==-1)
        !          1269:                                        break;
        !          1270:                                if(cfg.xtrn[i]->type!=k) {
        !          1271:                                        cfg.xtrn[i]->type=k;
        !          1272:                     if(cfg.xtrn[i]->type==XTRN_DOOR32)
        !          1273:                         cfg.xtrn[i]->misc|=XTRN_NATIVE;
        !          1274:                                        uifc.changes=TRUE; }
        !          1275:                                if(cfg.xtrn[i]->type && cfg.uq&UQ_ALIASES) {
        !          1276:                                        strcpy(opt[0],"Yes");
        !          1277:                                        strcpy(opt[1],"No");
        !          1278:                                        opt[2][0]=0;
        !          1279:                                        k=cfg.xtrn[i]->misc&REALNAME ? 0:1;
        !          1280:                                        k=uifc.list(WIN_MID,0,0,0,&k,0,"Use Real Names",opt);
        !          1281:                                        if(k==0 && !(cfg.xtrn[i]->misc&REALNAME)) {
        !          1282:                                                cfg.xtrn[i]->misc|=REALNAME;
        !          1283:                                                uifc.changes=TRUE; }
        !          1284:                                        else if(k==1 && cfg.xtrn[i]->misc&REALNAME) {
        !          1285:                                                cfg.xtrn[i]->misc&=~REALNAME;
        !          1286:                                                uifc.changes=TRUE; 
        !          1287:                                        } 
        !          1288:                                }
        !          1289:                                if(cfg.xtrn[i]->type) {
        !          1290:                                        strcpy(opt[0],"Yes");
        !          1291:                                        strcpy(opt[1],"No");
        !          1292:                                        opt[2][0]=0;
        !          1293:                                        k=cfg.xtrn[i]->misc&XTRN_LWRCASE ? 0:1;
        !          1294:                                        k=uifc.list(WIN_MID,0,0,0,&k,0,"Lowercase Filename",opt);
        !          1295:                                        if(k==0 && !(cfg.xtrn[i]->misc&XTRN_LWRCASE)) {
        !          1296:                                                cfg.xtrn[i]->misc|=XTRN_LWRCASE;
        !          1297:                                                uifc.changes=TRUE; 
        !          1298:                                        }
        !          1299:                                        else if(k==1 && cfg.xtrn[i]->misc&XTRN_LWRCASE) {
        !          1300:                                                cfg.xtrn[i]->misc&=~XTRN_LWRCASE;
        !          1301:                                                uifc.changes=TRUE; 
        !          1302:                                        } 
        !          1303:                                }
        !          1304:                                break;
        !          1305:                        case 16:
        !          1306:                                k=0;
        !          1307:                                strcpy(opt[0],"Node Directory");
        !          1308:                                strcpy(opt[1],"Start-up Directory");
        !          1309:                                opt[2][0]=0;
        !          1310:                                SETHELP(WHERE);
        !          1311: /*
        !          1312: &Directory for Drop File:&
        !          1313: 
        !          1314: You can have the data file created in the current &Node Directory& or the
        !          1315: &Start-up Directory& (if one is specified).
        !          1316: */
        !          1317:                                k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0,"Create Drop File In"
        !          1318:                     ,opt);
        !          1319:                                if(!k && cfg.xtrn[i]->misc&STARTUPDIR) {
        !          1320:                                        cfg.xtrn[i]->misc&=~STARTUPDIR;
        !          1321:                     uifc.changes=TRUE; }
        !          1322:                                else if(k==1 && !(cfg.xtrn[i]->misc&STARTUPDIR)) {
        !          1323:                                        cfg.xtrn[i]->misc|=STARTUPDIR;
        !          1324:                     uifc.changes=TRUE; }
        !          1325:                                break;
        !          1326:                        case 17:
        !          1327:                                while(1) {
        !          1328:                                        k=0;
        !          1329:                                        if(cfg.xtrn[i]->textra)
        !          1330:                                                sprintf(str,"%u minutes",cfg.xtrn[i]->textra);
        !          1331:                                        else
        !          1332:                                                strcpy(str,"None");
        !          1333:                                        sprintf(opt[k++],"%-25.25s%s","Extra Time",str);
        !          1334:                                        if(cfg.xtrn[i]->maxtime)
        !          1335:                                                sprintf(str,"%u minutes",cfg.xtrn[i]->maxtime);
        !          1336:                                        else
        !          1337:                                                strcpy(str,"None");
        !          1338:                                        sprintf(opt[k++],"%-25.25s%s","Maximum Time",str);
        !          1339:                                        sprintf(opt[k++],"%-25.25s%s","Suspended (Free) Time"
        !          1340:                                                ,cfg.xtrn[i]->misc&FREETIME ? "Yes" : "No");
        !          1341:                                        sprintf(opt[k++],"%-25.25s%s","Monitor Time Left"
        !          1342:                                                ,cfg.xtrn[i]->misc&XTRN_CHKTIME ? "Yes" : "No");
        !          1343:                                        opt[k][0]=0;
        !          1344:                                        SETHELP(WHERE);
        !          1345: /*
        !          1346: &Online Program Time Options:&
        !          1347: 
        !          1348: This sub-menu allows you to define specific preferences regarding the
        !          1349: time users spend running this program.
        !          1350: */
        !          1351:                                        k=uifc.list(WIN_SAV|WIN_ACT|WIN_RHT|WIN_BOT,0,0,40
        !          1352:                                                ,&time_dflt,0
        !          1353:                                                ,"Online Program Time Options",opt);
        !          1354:                                        if(k==-1)
        !          1355:                                                break;
        !          1356:                                        switch(k) {
        !          1357:                                                case 0:
        !          1358:                                                        ultoa(cfg.xtrn[i]->textra,str,10);
        !          1359:                                                        SETHELP(WHERE);
        !          1360: /*
        !          1361: &Extra Time to Give User in Program:&
        !          1362: 
        !          1363: If you want to give users extra time while in this online program,
        !          1364: set this value to the number of minutes to add to their current time
        !          1365: left online.
        !          1366: */
        !          1367:                                                        uifc.input(WIN_MID|WIN_SAV,0,0
        !          1368:                                                                ,"Extra Time to Give User (in minutes)"
        !          1369:                                                                ,str,2,K_EDIT|K_NUMBER);
        !          1370:                                                        cfg.xtrn[i]->textra=atoi(str);
        !          1371:                                                        break;
        !          1372:                                                case 1:
        !          1373:                                                        ultoa(cfg.xtrn[i]->maxtime,str,10);
        !          1374:                                                        SETHELP(WHERE);
        !          1375: /*
        !          1376: &Maximum Time Allowed in Program:&
        !          1377: 
        !          1378: If this program supports a drop file that contains the number of minutes
        !          1379: left online for the current user, this option allows the sysop to set
        !          1380: the maximum number of minutes that will be allowed in the drop file.
        !          1381: 
        !          1382: Setting this option to &0&, disables this feature.
        !          1383: */
        !          1384:                                                        uifc.input(WIN_MID|WIN_SAV,0,0
        !          1385:                                                                ,"Maximum Time (in minutes, 0=disabled)"
        !          1386:                                                                ,str,2,K_EDIT|K_NUMBER);
        !          1387:                                                        cfg.xtrn[i]->maxtime=atoi(str);
        !          1388:                                                        break;
        !          1389:                                                case 2:
        !          1390:                                                        k=cfg.xtrn[i]->misc&FREETIME ? 0:1;
        !          1391:                                                        strcpy(opt[0],"Yes");
        !          1392:                                                        strcpy(opt[1],"No");
        !          1393:                                                        opt[2][0]=0;
        !          1394:                                                        SETHELP(WHERE);
        !          1395: /*
        !          1396: &Suspended (Free) Time:&
        !          1397: 
        !          1398: If you want the user's time online to be suspended while running this
        !          1399: online program (e.g. Free Time), set this option to &Yes&.
        !          1400: */
        !          1401:                                                        k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0
        !          1402:                                                                ,"Suspended (Free) Time",opt);
        !          1403:                                                        if(!k && !(cfg.xtrn[i]->misc&FREETIME)) {
        !          1404:                                                                cfg.xtrn[i]->misc|=FREETIME;
        !          1405:                                                                uifc.changes=TRUE; }
        !          1406:                                                        else if(k==1 && cfg.xtrn[i]->misc&FREETIME) {
        !          1407:                                                                cfg.xtrn[i]->misc&=~FREETIME;
        !          1408:                                                                uifc.changes=TRUE; }
        !          1409:                                                        break; 
        !          1410:                                                case 3:
        !          1411:                                                        k=cfg.xtrn[i]->misc&XTRN_CHKTIME ? 0:1;
        !          1412:                                                        strcpy(opt[0],"Yes");
        !          1413:                                                        strcpy(opt[1],"No");
        !          1414:                                                        opt[2][0]=0;
        !          1415:                                                        SETHELP(WHERE);
        !          1416: /*
        !          1417: &Monitor Time Left:&
        !          1418: 
        !          1419: If you want Synchronet to monitor the user's time left onlnie while this
        !          1420: program runs (and disconnect the user if their time runs out), set this
        !          1421: option to &Yes&.
        !          1422: */
        !          1423:                                                        k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0
        !          1424:                                                                ,"Monitor Time Left",opt);
        !          1425:                                                        if(!k && !(cfg.xtrn[i]->misc&XTRN_CHKTIME)) {
        !          1426:                                                                cfg.xtrn[i]->misc|=XTRN_CHKTIME;
        !          1427:                                                                uifc.changes=TRUE; }
        !          1428:                                                        else if(k==1 && cfg.xtrn[i]->misc&XTRN_CHKTIME) {
        !          1429:                                                                cfg.xtrn[i]->misc&=~XTRN_CHKTIME;
        !          1430:                                                                uifc.changes=TRUE; }
        !          1431:                                                        break;
        !          1432:                                                } 
        !          1433:                                        }
        !          1434:                                        break;
        !          1435: 
        !          1436:                                } } }
        !          1437: }
        !          1438: 
        !          1439: void xedit_cfg()
        !          1440: {
        !          1441:        static int dflt,dfltopt,bar;
        !          1442:        char str[81],code[81],done=0,*p;
        !          1443:        int j,k;
        !          1444:        uint i;
        !          1445:        static xedit_t savxedit;
        !          1446: 
        !          1447: while(1) {
        !          1448:        for(i=0;i<cfg.total_xedits && i<MAX_OPTS;i++)
        !          1449:                sprintf(opt[i],"%-8.8s    %.40s",cfg.xedit[i]->code,cfg.xedit[i]->rcmd);
        !          1450:        opt[i][0]=0;
        !          1451:        j=WIN_SAV|WIN_ACT|WIN_CHE|WIN_RHT;
        !          1452:        if(cfg.total_xedits)
        !          1453:                j|=WIN_DEL|WIN_GET;
        !          1454:        if(cfg.total_xedits<MAX_OPTS)
        !          1455:                j|=WIN_INS|WIN_INSACT|WIN_XTR;
        !          1456:        if(savxedit.name[0])
        !          1457:                j|=WIN_PUT;
        !          1458:        SETHELP(WHERE);
        !          1459: /*
        !          1460: &External Editors:&
        !          1461: 
        !          1462: This is a list of the configured external editors.
        !          1463: 
        !          1464: To add an editor, select the desired location and hit  INS .
        !          1465: 
        !          1466: To delete an editor, select it and hit  DEL .
        !          1467: 
        !          1468: To configure an editor, select it and hit  ENTER .
        !          1469: */
        !          1470:        i=uifc.list(j,0,0,45,&dflt,&bar,"External Editors",opt);
        !          1471:        if((signed)i==-1)
        !          1472:                return;
        !          1473:        if((i&MSK_ON)==MSK_INS) {
        !          1474:                i&=MSK_OFF;
        !          1475:                SETHELP(WHERE);
        !          1476: /*
        !          1477: &External Editor Name:&
        !          1478: 
        !          1479: This is the name or description of the external editor.
        !          1480: */
        !          1481:                if(uifc.input(WIN_MID|WIN_SAV,0,0,"External Editor Name",str,40
        !          1482:                        ,0)<1)
        !          1483:             continue;
        !          1484:                sprintf(code,"%.8s",str);
        !          1485:                p=strchr(code,' ');
        !          1486:                if(p) *p=0;
        !          1487:         strupr(code);
        !          1488:                SETHELP(WHERE);
        !          1489: /*
        !          1490: &External Editor Internal Code:&
        !          1491: 
        !          1492: This is the internal code for the external editor.
        !          1493: */
        !          1494:                if(uifc.input(WIN_MID|WIN_SAV,0,0,"External Editor Internal Code",code,8
        !          1495:                        ,K_UPPER|K_EDIT)<1)
        !          1496:             continue;
        !          1497:                if(!code_ok(code)) {
        !          1498:                        uifc.helpbuf=invalid_code;
        !          1499:                        uifc.msg("Invalid Code");
        !          1500:                        uifc.helpbuf=0;
        !          1501:             continue; }
        !          1502: 
        !          1503:                if((cfg.xedit=(xedit_t **)realloc(cfg.xedit
        !          1504:             ,sizeof(xedit_t *)*(cfg.total_xedits+1)))==NULL) {
        !          1505:             errormsg(WHERE,ERR_ALLOC,nulstr,cfg.total_xedits+1);
        !          1506:                        cfg.total_xedits=0;
        !          1507:                        bail(1);
        !          1508:             continue; }
        !          1509:                if(cfg.total_xedits)
        !          1510:                        for(j=cfg.total_xedits;j>i;j--)
        !          1511:                                cfg.xedit[j]=cfg.xedit[j-1];
        !          1512:                if((cfg.xedit[i]=(xedit_t *)malloc(sizeof(xedit_t)))==NULL) {
        !          1513:                        errormsg(WHERE,ERR_ALLOC,nulstr,sizeof(xedit_t));
        !          1514:                        continue; }
        !          1515:                memset((xedit_t *)cfg.xedit[i],0,sizeof(xedit_t));
        !          1516:                strcpy(cfg.xedit[i]->name,str);
        !          1517:                strcpy(cfg.xedit[i]->code,code);
        !          1518:                cfg.total_xedits++;
        !          1519:                uifc.changes=TRUE;
        !          1520:                continue; }
        !          1521:        if((i&MSK_ON)==MSK_DEL) {
        !          1522:                i&=MSK_OFF;
        !          1523:                free(cfg.xedit[i]);
        !          1524:                cfg.total_xedits--;
        !          1525:                for(j=i;j<cfg.total_xedits;j++)
        !          1526:                        cfg.xedit[j]=cfg.xedit[j+1];
        !          1527:                uifc.changes=TRUE;
        !          1528:                continue; }
        !          1529:        if((i&MSK_ON)==MSK_GET) {
        !          1530:                i&=MSK_OFF;
        !          1531:                savxedit=*cfg.xedit[i];
        !          1532:                continue; }
        !          1533:        if((i&MSK_ON)==MSK_PUT) {
        !          1534:                i&=MSK_OFF;
        !          1535:                *cfg.xedit[i]=savxedit;
        !          1536:                uifc.changes=TRUE;
        !          1537:         continue; }
        !          1538:        done=0;
        !          1539:        while(!done) {
        !          1540:                k=0;
        !          1541:                sprintf(opt[k++],"%-32.32s%s","Name",cfg.xedit[i]->name);
        !          1542:                sprintf(opt[k++],"%-32.32s%s","Internal Code",cfg.xedit[i]->code);
        !          1543:                sprintf(opt[k++],"%-32.32s%.40s","Remote Command Line",cfg.xedit[i]->rcmd);
        !          1544:                sprintf(opt[k++],"%-32.32s%.40s","Access Requirements",cfg.xedit[i]->arstr);
        !          1545:                sprintf(opt[k++],"%-32.32s%s%s","Intercept Standard I/O"
        !          1546:                        ,cfg.xedit[i]->misc&IO_INTS ? "Yes":"No"
        !          1547:                        ,cfg.xedit[i]->misc&WWIVCOLOR ? ", WWIV" : nulstr);
        !          1548:         sprintf(opt[k++],"%-32.32s%s","Native (32-bit) Executable"
        !          1549:                        ,cfg.xedit[i]->misc&XTRN_NATIVE ? "Yes" : "No");
        !          1550:                sprintf(opt[k++],"%-32.32s%s","Use Shell to Execute"
        !          1551:                        ,cfg.xedit[i]->misc&XTRN_SH ? "Yes" : "No");
        !          1552:                sprintf(opt[k++],"%-32.32s%s","Quoted Text"
        !          1553:                        ,cfg.xedit[i]->misc&QUOTEALL ? "All":cfg.xedit[i]->misc&QUOTENONE
        !          1554:                                ? "None" : "Prompt User");
        !          1555:                sprintf(opt[k++],"%-32.32s%s","QuickBBS Style (MSGTMP)"
        !          1556:                        ,cfg.xedit[i]->misc&QUICKBBS ? "Yes":"No");
        !          1557:                sprintf(opt[k++],"%-32.32s%s","Expand Line Feeds to CRLF"
        !          1558:                        ,cfg.xedit[i]->misc&EXPANDLF ? "Yes":"No");
        !          1559:                sprintf(opt[k++],"%-32.32s%s","Strip FidoNet Kludge Lines"
        !          1560:                        ,cfg.xedit[i]->misc&STRIPKLUDGE ? "Yes":"No");
        !          1561:                sprintf(opt[k++],"%-32.32s%s","BBS Drop File Type"
        !          1562:                        ,dropfile(cfg.xedit[i]->type,cfg.xedit[i]->misc));
        !          1563:         opt[k][0]=0;
        !          1564:                SETHELP(WHERE);
        !          1565: /*
        !          1566: &External Editor Configuration:&
        !          1567: 
        !          1568: This menu allows you to change the settings for the selected external
        !          1569: message editor. External message editors are very common on BBSs. Some
        !          1570: popular editors include &SyncEdit&, &WWIVedit&, &FEdit&, &GEdit&, &IceEdit&,
        !          1571: and many others.
        !          1572: */
        !          1573: 
        !          1574:                sprintf(str,"%s Editor",cfg.xedit[i]->name);
        !          1575:                switch(uifc.list(WIN_SAV|WIN_ACT|WIN_L2R|WIN_BOT,0,0,70,&dfltopt,0
        !          1576:                        ,str,opt)) {
        !          1577:                        case -1:
        !          1578:                                done=1;
        !          1579:                                break;
        !          1580:                        case 0:
        !          1581:                                SETHELP(WHERE);
        !          1582: /*
        !          1583: &External Editor Name:&
        !          1584: 
        !          1585: This is the name or description of the external editor.
        !          1586: */
        !          1587:                                strcpy(str,cfg.xedit[i]->name);
        !          1588:                                if(!uifc.input(WIN_MID|WIN_SAV,0,10,"External Editor Name"
        !          1589:                                        ,cfg.xedit[i]->name,sizeof(cfg.xedit[i]->name)-1,K_EDIT))
        !          1590:                                        strcpy(cfg.xedit[i]->name,str);
        !          1591:                                break;
        !          1592:                        case 1:
        !          1593:                                strcpy(str,cfg.xedit[i]->code);
        !          1594:                                SETHELP(WHERE);
        !          1595: /*
        !          1596: &External Editor Internal Code:&
        !          1597: 
        !          1598: Every external editor must have its own unique internal code for
        !          1599: Synchronet to reference it by. It is helpful if this code is an
        !          1600: abreviation of the name.
        !          1601: */
        !          1602:                                uifc.input(WIN_MID|WIN_SAV,0,17,"Internal Code (unique)"
        !          1603:                                        ,str,LEN_CODE,K_EDIT|K_UPPER);
        !          1604:                                if(code_ok(str))
        !          1605:                                        strcpy(cfg.xedit[i]->code,str);
        !          1606:                                else {
        !          1607:                                        uifc.helpbuf=invalid_code;
        !          1608:                                        uifc.msg("Invalid Code");
        !          1609:                                        uifc.helpbuf=0; }
        !          1610:                 break;
        !          1611:                   case 2:
        !          1612:                                SETHELP(WHERE);
        !          1613: /*
        !          1614: &External Editor Remote Command Line:&
        !          1615: 
        !          1616: This is the command line to execute when using this editor remotely.
        !          1617: */
        !          1618:                                uifc.input(WIN_MID|WIN_SAV,0,10,"Remote"
        !          1619:                                        ,cfg.xedit[i]->rcmd,sizeof(cfg.xedit[i]->rcmd)-1,K_EDIT);
        !          1620:                                break;
        !          1621:                        case 3:
        !          1622:                                sprintf(str,"%s External Editor",cfg.xedit[i]->name);
        !          1623:                                getar(str,cfg.xedit[i]->arstr);
        !          1624:                                break;
        !          1625:                        case 4:
        !          1626:                                k=cfg.xedit[i]->misc&IO_INTS ? 0:1;
        !          1627:                                strcpy(opt[0],"Yes");
        !          1628:                                strcpy(opt[1],"No");
        !          1629:                                opt[2][0]=0;
        !          1630:                                SETHELP(WHERE);
        !          1631: /*
        !          1632: &Intercept Standard I/O:&
        !          1633: 
        !          1634: If this external editor uses a FOSSIL driver or SOCKET communications,
        !          1635: set this option to &No&.
        !          1636: */
        !          1637:                                k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0,"Intercept Standard I/O"
        !          1638:                                        ,opt);
        !          1639:                                if(!k && !(cfg.xedit[i]->misc&IO_INTS)) {
        !          1640:                                        cfg.xedit[i]->misc|=IO_INTS;
        !          1641:                                        uifc.changes=TRUE; }
        !          1642:                                else if(k==1 && cfg.xedit[i]->misc&IO_INTS) {
        !          1643:                                        cfg.xedit[i]->misc&=~(IO_INTS|WWIVCOLOR);
        !          1644:                                        uifc.changes=TRUE; }
        !          1645:                                if(!(cfg.xedit[i]->misc&IO_INTS))
        !          1646:                                        break;
        !          1647:                                k=cfg.xedit[i]->misc&WWIVCOLOR ? 0:1;
        !          1648:                                strcpy(opt[0],"Yes");
        !          1649:                                strcpy(opt[1],"No");
        !          1650:                                opt[2][0]=0;
        !          1651:                                SETHELP(WHERE);
        !          1652: /*
        !          1653: &Editor Uses WWIV Color Codes:&
        !          1654: 
        !          1655: If this editor was written for use exclusively under WWIV, set this
        !          1656: option to &Yes&.
        !          1657: */
        !          1658:                                k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0
        !          1659:                                        ,"Editor Uses WWIV Color Codes",opt);
        !          1660:                                if(!k && !(cfg.xedit[i]->misc&WWIVCOLOR)) {
        !          1661:                                        cfg.xedit[i]->misc|=WWIVCOLOR;
        !          1662:                                        uifc.changes=TRUE; }
        !          1663:                                else if(k==1 && cfg.xedit[i]->misc&WWIVCOLOR) {
        !          1664:                                        cfg.xedit[i]->misc&=~WWIVCOLOR;
        !          1665:                     uifc.changes=TRUE; }
        !          1666:                 break;
        !          1667:                        case 5:
        !          1668:                                k=cfg.xedit[i]->misc&XTRN_NATIVE ? 0:1;
        !          1669:                                strcpy(opt[0],"Yes");
        !          1670:                                strcpy(opt[1],"No");
        !          1671:                                opt[2][0]=0;
        !          1672:                                SETHELP(WHERE);
        !          1673: /*
        !          1674: &Native (32-bit) Executable:&
        !          1675: 
        !          1676: If this editor is a native 32-bit executable, set this option to &Yes&.
        !          1677: */
        !          1678:                                k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0
        !          1679:                                        ,"Native (32-bit)",opt);
        !          1680:                                if(!k && !(cfg.xedit[i]->misc&XTRN_NATIVE)) {
        !          1681:                                        cfg.xedit[i]->misc|=XTRN_NATIVE;
        !          1682:                                        uifc.changes=TRUE; }
        !          1683:                                else if(k==1 && cfg.xedit[i]->misc&XTRN_NATIVE) {
        !          1684:                                        cfg.xedit[i]->misc&=~XTRN_NATIVE;
        !          1685:                                        uifc.changes=TRUE; }
        !          1686:                                break;
        !          1687:                        case 6:
        !          1688:                                k=cfg.xedit[i]->misc&XTRN_SH ? 0:1;
        !          1689:                                strcpy(opt[0],"Yes");
        !          1690:                                strcpy(opt[1],"No");
        !          1691:                                opt[2][0]=0;
        !          1692:                                SETHELP(WHERE);
        !          1693: /*
        !          1694: `Use Shell to Execute Command:`
        !          1695: 
        !          1696: If this command-line requires the system command shell to execute, (Unix 
        !          1697: shell script or DOS batch file), set this option to ~Yes~.
        !          1698: */
        !          1699:                                k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0
        !          1700:                                        ,"Use Shell",opt);
        !          1701:                                if(!k && !(cfg.xedit[i]->misc&XTRN_SH)) {
        !          1702:                                        cfg.xedit[i]->misc|=XTRN_SH;
        !          1703:                                        uifc.changes=TRUE; 
        !          1704:                                } else if(k==1 && cfg.xedit[i]->misc&XTRN_SH) {
        !          1705:                                        cfg.xedit[i]->misc&=~XTRN_SH;
        !          1706:                                        uifc.changes=TRUE; 
        !          1707:                                }
        !          1708:                                break;
        !          1709:                        case 7:
        !          1710:                                k=3;
        !          1711:                                strcpy(opt[0],"All");
        !          1712:                                strcpy(opt[1],"None");
        !          1713:                                strcpy(opt[2],"Prompt User");
        !          1714:                                opt[3][0]=0;
        !          1715:                                SETHELP(WHERE);
        !          1716: /*
        !          1717: &Quoted Text:&
        !          1718: 
        !          1719: If you want all the message text to be automatically entered into the
        !          1720: message edit/quote file (&INPUT.MSG& or &MSGTMP&), select &All&.
        !          1721: 
        !          1722: If you want the user to be prompted for which lines to quote before
        !          1723: running the editor, select &Prompt User&.
        !          1724: 
        !          1725: If you want none of the lines to be automatically quoted, select &None&.
        !          1726: This option is mainly for use with editors that support the "ES.TXT&
        !          1727: drop file (like &SyncEdit v2.x&).
        !          1728: */
        !          1729:                                k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0,"Quoted Text"
        !          1730:                                        ,opt);
        !          1731:                                if(!k && !(cfg.xedit[i]->misc&QUOTEALL)) {
        !          1732:                                        cfg.xedit[i]->misc|=QUOTEALL;
        !          1733:                                        cfg.xedit[i]->misc&=~QUOTENONE;
        !          1734:                                        uifc.changes=TRUE; }
        !          1735:                                else if(k==1 && !(cfg.xedit[i]->misc&QUOTENONE)) {
        !          1736:                                        cfg.xedit[i]->misc|=QUOTENONE;
        !          1737:                                        cfg.xedit[i]->misc&=~QUOTEALL;
        !          1738:                     uifc.changes=TRUE; }
        !          1739:                                else if(k==2 && cfg.xedit[i]->misc&(QUOTENONE|QUOTEALL)) {
        !          1740:                                        cfg.xedit[i]->misc&=~(QUOTENONE|QUOTEALL);
        !          1741:                                        uifc.changes=TRUE; }
        !          1742:                 break;
        !          1743:                        case 8:
        !          1744:                                k=cfg.xedit[i]->misc&QUICKBBS ? 0:1;
        !          1745:                                strcpy(opt[0],"Yes");
        !          1746:                                strcpy(opt[1],"No");
        !          1747:                                opt[2][0]=0;
        !          1748:                                SETHELP(WHERE);
        !          1749: /*
        !          1750: &QuickBBS Style (MSGTMP):&
        !          1751: 
        !          1752: If this external editor uses the QuickBBS style MSGTMP interface, set
        !          1753: this option to &Yes&.
        !          1754: */
        !          1755:                                k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0,"QuickBBS Style (MSGTMP)"
        !          1756:                                        ,opt);
        !          1757:                                if(!k && !(cfg.xedit[i]->misc&QUICKBBS)) {
        !          1758:                                        cfg.xedit[i]->misc|=QUICKBBS;
        !          1759:                                        uifc.changes=TRUE; }
        !          1760:                                else if(k==1 && cfg.xedit[i]->misc&QUICKBBS) {
        !          1761:                                        cfg.xedit[i]->misc&=~QUICKBBS;
        !          1762:                     uifc.changes=TRUE; }
        !          1763:                                break;
        !          1764:                        case 9:
        !          1765:                                k=cfg.xedit[i]->misc&EXPANDLF ? 0:1;
        !          1766:                                strcpy(opt[0],"Yes");
        !          1767:                                strcpy(opt[1],"No");
        !          1768:                                opt[2][0]=0;
        !          1769:                                SETHELP(WHERE);
        !          1770: /*
        !          1771: &Expand Line Feeds to Carriage Return/Line Feed Pairs:&
        !          1772: 
        !          1773: If this external editor saves new lines as a single line feed character
        !          1774: instead of a carriage return/line feed pair, set this option to &Yes&.
        !          1775: */
        !          1776:                                k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0,"Expand LF to CRLF"
        !          1777:                                        ,opt);
        !          1778:                                if(!k && !(cfg.xedit[i]->misc&EXPANDLF)) {
        !          1779:                                        cfg.xedit[i]->misc|=EXPANDLF;
        !          1780:                                        uifc.changes=TRUE; }
        !          1781:                                else if(k==1 && cfg.xedit[i]->misc&EXPANDLF) {
        !          1782:                                        cfg.xedit[i]->misc&=~EXPANDLF;
        !          1783:                     uifc.changes=TRUE; }
        !          1784:                                break;
        !          1785:                        case 10:
        !          1786:                                k=cfg.xedit[i]->misc&STRIPKLUDGE ? 0:1;
        !          1787:                                strcpy(opt[0],"Yes");
        !          1788:                                strcpy(opt[1],"No");
        !          1789:                                opt[2][0]=0;
        !          1790:                                SETHELP(WHERE);
        !          1791: /*
        !          1792: &Strip FidoNet Kludge Lines From Messages:&
        !          1793: 
        !          1794: If this external editor adds FidoNet Kludge lines to the message text,
        !          1795: set this option to &Yes& to strip those lines from the message.
        !          1796: */
        !          1797:                                k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0
        !          1798:                        ,"Strip FidoNet Kludge Lines"
        !          1799:                                        ,opt);
        !          1800:                                if(!k && !(cfg.xedit[i]->misc&STRIPKLUDGE)) {
        !          1801:                                        cfg.xedit[i]->misc|=STRIPKLUDGE;
        !          1802:                                        uifc.changes=TRUE; }
        !          1803:                                else if(k==1 && cfg.xedit[i]->misc&STRIPKLUDGE) {
        !          1804:                                        cfg.xedit[i]->misc&=~STRIPKLUDGE;
        !          1805:                     uifc.changes=TRUE; }
        !          1806:                                break;
        !          1807:                        case 11:
        !          1808:                                k=0;
        !          1809:                                strcpy(opt[k++],"None");
        !          1810:                                sprintf(opt[k++],"%-15s %s","Synchronet","XTRN.DAT");
        !          1811:                                sprintf(opt[k++],"%-15s %s","WWIV","CHAIN.TXT");
        !          1812:                                sprintf(opt[k++],"%-15s %s","GAP","DOOR.SYS");
        !          1813:                                sprintf(opt[k++],"%-15s %s","RBBS/QuickBBS","DORINFO#.DEF");
        !          1814:                                sprintf(opt[k++],"%-15s %s","Wildcat","CALLINFO.BBS");
        !          1815:                                sprintf(opt[k++],"%-15s %s","PCBoard","PCBOARD.SYS");
        !          1816:                                sprintf(opt[k++],"%-15s %s","SpitFire","SFDOORS.DAT");
        !          1817:                                sprintf(opt[k++],"%-15s %s","MegaMail","UTIDOOR.TXT");
        !          1818:                                sprintf(opt[k++],"%-15s %s","Solar Realms","DOORFILE.SR");
        !          1819:                                sprintf(opt[k++],"%-15s %s","RBBS/QuickBBS","DORINFO1.DEF");
        !          1820:                                sprintf(opt[k++],"%-15s %s","TriBBS","TRIBBS.SYS");
        !          1821:                                sprintf(opt[k++],"%-15s %s","Mystic","DOOR32.SYS");
        !          1822:                                opt[k][0]=0;
        !          1823:                                k=cfg.xedit[i]->type;
        !          1824:                                SETHELP(WHERE);
        !          1825: /*
        !          1826: &External Program BBS Drop File Type:&
        !          1827: 
        !          1828: If this external editor requires a specific BBS data (drop) file
        !          1829: format, select the file format from the list.
        !          1830: */
        !          1831:                                k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0
        !          1832:                                        ,"BBS Drop File Type",opt);
        !          1833:                                if(k==-1)
        !          1834:                                        break;
        !          1835:                                if(cfg.xedit[i]->type!=k) {
        !          1836:                                        cfg.xedit[i]->type=k;
        !          1837:                     if(cfg.xedit[i]->type==XTRN_DOOR32)
        !          1838:                         cfg.xedit[i]->misc|=XTRN_NATIVE;
        !          1839:                                        uifc.changes=TRUE; 
        !          1840:                                }
        !          1841:                                if(cfg.xedit[i]->type) {
        !          1842:                                        strcpy(opt[0],"Yes");
        !          1843:                                        strcpy(opt[1],"No");
        !          1844:                                        opt[2][0]=0;
        !          1845:                                        k=cfg.xedit[i]->misc&XTRN_LWRCASE ? 0:1;
        !          1846:                                        k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0,"Lowercase Filename",opt);
        !          1847:                                        if(k==0 && !(cfg.xedit[i]->misc&XTRN_LWRCASE)) {
        !          1848:                                                cfg.xedit[i]->misc|=XTRN_LWRCASE;
        !          1849:                                                uifc.changes=TRUE; 
        !          1850:                                        }
        !          1851:                                        else if(k==1 && cfg.xedit[i]->misc&XTRN_LWRCASE) {
        !          1852:                                                cfg.xedit[i]->misc&=~XTRN_LWRCASE;
        !          1853:                                                uifc.changes=TRUE; 
        !          1854:                                        } 
        !          1855:                                }
        !          1856:                                break;
        !          1857: 
        !          1858:                                } } }
        !          1859: }
        !          1860: 
        !          1861: int natvpgm_cfg()
        !          1862: {
        !          1863:        static int dflt,bar;
        !          1864:        char str[81];
        !          1865:        int j;
        !          1866:        uint i;
        !          1867: 
        !          1868: while(1) {
        !          1869:        for(i=0;i<MAX_OPTS && i<cfg.total_natvpgms;i++)
        !          1870:                sprintf(opt[i],"%-12s",cfg.natvpgm[i]->name);
        !          1871:        opt[i][0]=0;
        !          1872:        j=WIN_ACT|WIN_CHE|WIN_L2R|WIN_SAV;
        !          1873:        if(cfg.total_natvpgms)
        !          1874:                j|=WIN_DEL;
        !          1875:        if(cfg.total_natvpgms<MAX_OPTS)
        !          1876:                j|=WIN_INS|WIN_INSACT|WIN_XTR;
        !          1877:        SETHELP(WHERE);
        !          1878: /*
        !          1879: &Native (32-bit) Program List:&
        !          1880: 
        !          1881: This is a list of all native (32-bit) external program (executable file)
        !          1882: names that you may execute under &Synchronet&. This list is not
        !          1883: used in Synchronet for DOS. Any programs not listed here will be assumed
        !          1884: to be DOS programs and executed accordingly.
        !          1885: 
        !          1886: Use  INS  and  DELETE  to add and remove native program names.
        !          1887: 
        !          1888: To change the filename of a program, hit  ENTER .
        !          1889: */
        !          1890:        i=uifc.list(j,0,0,30,&dflt,&bar,"Native (32-bit) Program List",opt);
        !          1891:        if((signed)i==-1)
        !          1892:                break;
        !          1893:        if((i&MSK_ON)==MSK_INS) {
        !          1894:                i&=MSK_OFF;
        !          1895:                SETHELP(WHERE);
        !          1896: /*
        !          1897: &Native (32-bit) Program Name:&
        !          1898: 
        !          1899: This is the executable filename of the native external program.
        !          1900: */
        !          1901:                if(uifc.input(WIN_MID|WIN_SAV,0,0,"Native Program Name",str,12
        !          1902:                        ,0)<1)
        !          1903:             continue;
        !          1904:                if((cfg.natvpgm=(natvpgm_t **)realloc(cfg.natvpgm
        !          1905:                        ,sizeof(natvpgm_t *)*(cfg.total_natvpgms+1)))==NULL) {
        !          1906:                        errormsg(WHERE,ERR_ALLOC,nulstr,cfg.total_natvpgms+1);
        !          1907:                        cfg.total_natvpgms=0;
        !          1908:                        bail(1);
        !          1909:             continue; }
        !          1910:                if(cfg.total_natvpgms)
        !          1911:                        for(j=cfg.total_natvpgms;j>i;j--)
        !          1912:                                cfg.natvpgm[j]=cfg.natvpgm[j-1];
        !          1913:                if((cfg.natvpgm[i]=(natvpgm_t *)malloc(sizeof(natvpgm_t)))==NULL) {
        !          1914:                        errormsg(WHERE,ERR_ALLOC,nulstr,sizeof(natvpgm_t));
        !          1915:                        continue; }
        !          1916:                memset((natvpgm_t *)cfg.natvpgm[i],0,sizeof(natvpgm_t));
        !          1917:                strcpy(cfg.natvpgm[i]->name,str);
        !          1918:                cfg.total_natvpgms++;
        !          1919:                uifc.changes=TRUE;
        !          1920:                continue; }
        !          1921:        if((i&MSK_ON)==MSK_DEL) {
        !          1922:                i&=MSK_OFF;
        !          1923:                free(cfg.natvpgm[i]);
        !          1924:                cfg.total_natvpgms--;
        !          1925:                for(j=i;j<cfg.total_natvpgms;j++)
        !          1926:                        cfg.natvpgm[j]=cfg.natvpgm[j+1];
        !          1927:                uifc.changes=TRUE;
        !          1928:                continue; }
        !          1929:        SETHELP(WHERE);
        !          1930: /*
        !          1931: &Native Program Name:&
        !          1932: 
        !          1933: This is the executable filename of the Native external program.
        !          1934: */
        !          1935:        strcpy(str,cfg.natvpgm[i]->name);
        !          1936:        if(uifc.input(WIN_MID|WIN_SAV,0,5,"Native (32-bit) Program Name",str,12
        !          1937:                ,K_EDIT)>0)
        !          1938:                strcpy(cfg.natvpgm[i]->name,str);
        !          1939:        }
        !          1940: return(0);
        !          1941: }
        !          1942: 
        !          1943: 
        !          1944: void xtrnsec_cfg()
        !          1945: {
        !          1946:        static int xtrnsec_dflt,xtrnsec_opt;
        !          1947:        char str[81],code[9],done=0,*p;
        !          1948:        int j,k;
        !          1949:        uint i;
        !          1950:        static xtrnsec_t savxtrnsec;
        !          1951: 
        !          1952: while(1) {
        !          1953:        for(i=0;i<cfg.total_xtrnsecs && i<MAX_OPTS;i++)
        !          1954:                sprintf(opt[i],"%-25s",cfg.xtrnsec[i]->name);
        !          1955:        opt[i][0]=0;
        !          1956:        j=WIN_SAV|WIN_ACT|WIN_CHE|WIN_BOT;
        !          1957:        if(cfg.total_xtrnsecs)
        !          1958:                j|=WIN_DEL|WIN_GET;
        !          1959:        if(cfg.total_xtrnsecs<MAX_OPTS)
        !          1960:                j|=WIN_INS|WIN_INSACT|WIN_XTR;
        !          1961:        if(savxtrnsec.name[0])
        !          1962:                j|=WIN_PUT;
        !          1963:        SETHELP(WHERE);
        !          1964: /*
        !          1965: &Online Program Sections:&
        !          1966: 
        !          1967: This is a list of &Online Program Sections& configured for your system.
        !          1968: 
        !          1969: To add an online program section, select the desired location with the
        !          1970: arrow keys and hit  INS .
        !          1971: 
        !          1972: To delete an online program section, select it and hit  DEL .
        !          1973: 
        !          1974: To configure an online program section, select it and hit  ENTER .
        !          1975: */
        !          1976:        i=uifc.list(j,0,0,45,&xtrnsec_dflt,0,"Online Program Sections",opt);
        !          1977:        if((signed)i==-1)
        !          1978:                return;
        !          1979:        if((i&MSK_ON)==MSK_INS) {
        !          1980:                i&=MSK_OFF;
        !          1981:                SETHELP(WHERE);
        !          1982: /*
        !          1983: &Online Program Section Name:&
        !          1984: 
        !          1985: This is the name of this section.
        !          1986: */
        !          1987:                if(uifc.input(WIN_MID|WIN_SAV,0,0,"Online Program Section Name",str,40
        !          1988:                        ,0)<1)
        !          1989:             continue;
        !          1990:                sprintf(code,"%.8s",str);
        !          1991:                p=strchr(code,' ');
        !          1992:                if(p) *p=0;
        !          1993:         strupr(code);
        !          1994:                SETHELP(WHERE);
        !          1995: /*
        !          1996: &Online Program Section Internal Code:&
        !          1997: 
        !          1998: Every online program section must have its own unique internal code
        !          1999: for Synchronet to reference it by. It is helpful if this code is an
        !          2000: abreviation of the name.
        !          2001: */
        !          2002:                if(uifc.input(WIN_MID|WIN_SAV,0,0,"Online Program Section Internal Code"
        !          2003:                        ,code,LEN_CODE,K_EDIT|K_UPPER)<1)
        !          2004:                        continue;
        !          2005:                if(!code_ok(code)) {
        !          2006:                        uifc.helpbuf=invalid_code;
        !          2007:                        uifc.msg("Invalid Code");
        !          2008:                        uifc.helpbuf=0;
        !          2009:             continue; }
        !          2010:                if((cfg.xtrnsec=(xtrnsec_t **)realloc(cfg.xtrnsec
        !          2011:                        ,sizeof(xtrnsec_t *)*(cfg.total_xtrnsecs+1)))==NULL) {
        !          2012:                        errormsg(WHERE,ERR_ALLOC,nulstr,cfg.total_xtrnsecs+1);
        !          2013:                        cfg.total_xtrnsecs=0;
        !          2014:                        bail(1);
        !          2015:                        continue; }
        !          2016:                if(cfg.total_xtrnsecs) {
        !          2017:                        for(j=cfg.total_xtrnsecs;j>i;j--)
        !          2018:                                cfg.xtrnsec[j]=cfg.xtrnsec[j-1];
        !          2019:                        for(j=0;j<cfg.total_xtrns;j++)
        !          2020:                                if(cfg.xtrn[j]->sec>=i)
        !          2021:                                        cfg.xtrn[j]->sec++; }
        !          2022: 
        !          2023: 
        !          2024:                if((cfg.xtrnsec[i]=(xtrnsec_t *)malloc(sizeof(xtrnsec_t)))==NULL) {
        !          2025:                        errormsg(WHERE,ERR_ALLOC,nulstr,sizeof(xtrnsec_t));
        !          2026:                        continue; }
        !          2027:                memset((xtrnsec_t *)cfg.xtrnsec[i],0,sizeof(xtrnsec_t));
        !          2028:                strcpy(cfg.xtrnsec[i]->name,str);
        !          2029:                strcpy(cfg.xtrnsec[i]->code,code);
        !          2030:                cfg.total_xtrnsecs++;
        !          2031:                uifc.changes=TRUE;
        !          2032:                continue; }
        !          2033:        if((i&MSK_ON)==MSK_DEL) {
        !          2034:                i&=MSK_OFF;
        !          2035:                free(cfg.xtrnsec[i]);
        !          2036:                for(j=0;j<cfg.total_xtrns;) {
        !          2037:                        if(cfg.xtrn[j]->sec==i) {        /* delete xtrns of this group */
        !          2038:                                free(cfg.xtrn[j]);
        !          2039:                                cfg.total_xtrns--;
        !          2040:                                k=j;
        !          2041:                                while(k<cfg.total_xtrns) {       /* move all xtrns down */
        !          2042:                                        cfg.xtrn[k]=cfg.xtrn[k+1];
        !          2043:                                        k++; } }
        !          2044:                        else j++; }
        !          2045:                for(j=0;j<cfg.total_xtrns;j++)   /* move xtrn group numbers down */
        !          2046:                        if(cfg.xtrn[j]->sec>i)
        !          2047:                                cfg.xtrn[j]->sec--;
        !          2048:                cfg.total_xtrnsecs--;
        !          2049:                while(i<cfg.total_xtrnsecs) {
        !          2050:                        cfg.xtrnsec[i]=cfg.xtrnsec[i+1];
        !          2051:             i++; }
        !          2052:                uifc.changes=TRUE;
        !          2053:                continue; }
        !          2054:        if((i&MSK_ON)==MSK_GET) {
        !          2055:                i&=MSK_OFF;
        !          2056:                savxtrnsec=*cfg.xtrnsec[i];
        !          2057:                continue; }
        !          2058:        if((i&MSK_ON)==MSK_PUT) {
        !          2059:                i&=MSK_OFF;
        !          2060:                *cfg.xtrnsec[i]=savxtrnsec;
        !          2061:                uifc.changes=TRUE;
        !          2062:         continue; }
        !          2063:        done=0;
        !          2064:        while(!done) {
        !          2065:                k=0;
        !          2066:                sprintf(opt[k++],"%-27.27s%s","Name",cfg.xtrnsec[i]->name);
        !          2067:                sprintf(opt[k++],"%-27.27s%s","Internal Code",cfg.xtrnsec[i]->code);
        !          2068:                sprintf(opt[k++],"%-27.27s%.40s","Access Requirements"
        !          2069:                        ,cfg.xtrnsec[i]->arstr);
        !          2070:                sprintf(opt[k++],"%s","Available Online Programs...");
        !          2071:                opt[k][0]=0;
        !          2072:                sprintf(str,"%s Program Section",cfg.xtrnsec[i]->name);
        !          2073:                switch(uifc.list(WIN_SAV|WIN_ACT|WIN_MID,0,0,60,&xtrnsec_opt,0,str
        !          2074:                        ,opt)) {
        !          2075:                        case -1:
        !          2076:                                done=1;
        !          2077:                                break;
        !          2078:                        case 0:
        !          2079:                                SETHELP(WHERE);
        !          2080: /*
        !          2081: &Online Program Section Name:&
        !          2082: 
        !          2083: This is the name of this section.
        !          2084: */
        !          2085:                                strcpy(str,cfg.xtrnsec[i]->name);        /* save */
        !          2086:                                if(!uifc.input(WIN_MID|WIN_SAV,0,10
        !          2087:                                        ,"Program Section Name"
        !          2088:                                        ,cfg.xtrnsec[i]->name,sizeof(cfg.xtrnsec[i]->name)-1,K_EDIT))
        !          2089:                                        strcpy(cfg.xtrnsec[i]->name,str);
        !          2090:                                break;
        !          2091:                        case 1:
        !          2092:                                strcpy(str,cfg.xtrnsec[i]->code);
        !          2093:                                SETHELP(WHERE);
        !          2094: /*
        !          2095: &Online Program Section Internal Code:&
        !          2096: 
        !          2097: Every online program section must have its own unique internal code
        !          2098: for Synchronet to reference it by. It is helpful if this code is an
        !          2099: abreviation of the name.
        !          2100: */
        !          2101:                                uifc.input(WIN_MID|WIN_SAV,0,17,"Internal Code (unique)"
        !          2102:                                        ,str,LEN_CODE,K_EDIT|K_UPPER);
        !          2103:                                if(code_ok(str))
        !          2104:                                        strcpy(cfg.xtrnsec[i]->code,str);
        !          2105:                                else {
        !          2106:                                        uifc.helpbuf=invalid_code;
        !          2107:                                        uifc.msg("Invalid Code");
        !          2108:                                        uifc.helpbuf=0; 
        !          2109:                                }
        !          2110:                                break;
        !          2111:                        case 2:
        !          2112:                                getar(cfg.xtrnsec[i]->name,cfg.xtrnsec[i]->arstr);
        !          2113:                 break;
        !          2114:                        case 3:
        !          2115:                                xtrn_cfg(i);
        !          2116:                                break; 
        !          2117:                        } 
        !          2118:                } 
        !          2119:        }
        !          2120: }
        !          2121: 
        !          2122: void hotkey_cfg(void)
        !          2123: {
        !          2124:        static int dflt,dfltopt,bar;
        !          2125:        char str[81],done=0;
        !          2126:        int j,k;
        !          2127:        uint i;
        !          2128:        static hotkey_t savhotkey;
        !          2129: 
        !          2130: while(1) {
        !          2131:        for(i=0;i<cfg.total_hotkeys && i<MAX_OPTS;i++)
        !          2132:                sprintf(opt[i],"Ctrl-%c    %.40s"
        !          2133:             ,cfg.hotkey[i]->key+'@'
        !          2134:             ,cfg.hotkey[i]->cmd);
        !          2135:        opt[i][0]=0;
        !          2136:        j=WIN_SAV|WIN_ACT|WIN_CHE|WIN_RHT;
        !          2137:        if(cfg.total_hotkeys)
        !          2138:                j|=WIN_DEL|WIN_GET;
        !          2139:        if(cfg.total_hotkeys<MAX_OPTS)
        !          2140:                j|=WIN_INS|WIN_INSACT|WIN_XTR;
        !          2141:        if(savhotkey.cmd[0])
        !          2142:                j|=WIN_PUT;
        !          2143:        SETHELP(WHERE);
        !          2144: /*
        !          2145: &Global Hot Key Events:&
        !          2146: 
        !          2147: This is a list of programs or loadable modules that can be executed by
        !          2148: anyone on the BBS at any time (while the BBS has control of user input).
        !          2149: 
        !          2150: To add a hot key event, select the desired location and hit  INS .
        !          2151: 
        !          2152: To delete a hot key event, select it and hit  DEL .
        !          2153: 
        !          2154: To configure a hot key event, select it and hit  ENTER .
        !          2155: */
        !          2156:        i=uifc.list(j,0,0,45,&dflt,&bar,"Global Hot Key Events",opt);
        !          2157:        if((signed)i==-1)
        !          2158:                return;
        !          2159:        if((i&MSK_ON)==MSK_INS) {
        !          2160:                i&=MSK_OFF;
        !          2161:                SETHELP(WHERE);
        !          2162: /*
        !          2163: &Global Hot Key:&
        !          2164: 
        !          2165: This is the control key used to trigger the hot key event. Example, A
        !          2166: indicates a Ctrl-A hot key event.
        !          2167: */
        !          2168:                if(uifc.input(WIN_MID|WIN_SAV,0,0,"Control Key",str,1
        !          2169:                        ,K_UPPER)<1)
        !          2170:             continue;
        !          2171: 
        !          2172:                if((cfg.hotkey=(hotkey_t **)realloc(cfg.hotkey
        !          2173:             ,sizeof(hotkey_t *)*(cfg.total_hotkeys+1)))==NULL) {
        !          2174:             errormsg(WHERE,ERR_ALLOC,nulstr,cfg.total_hotkeys+1);
        !          2175:                        cfg.total_hotkeys=0;
        !          2176:                        bail(1);
        !          2177:             continue; }
        !          2178:                if(cfg.total_hotkeys)
        !          2179:                        for(j=cfg.total_hotkeys;j>i;j--)
        !          2180:                                cfg.hotkey[j]=cfg.hotkey[j-1];
        !          2181:                if((cfg.hotkey[i]=(hotkey_t *)malloc(sizeof(hotkey_t)))==NULL) {
        !          2182:                        errormsg(WHERE,ERR_ALLOC,nulstr,sizeof(hotkey_t));
        !          2183:                        continue; }
        !          2184:                memset((hotkey_t *)cfg.hotkey[i],0,sizeof(hotkey_t));
        !          2185:                cfg.hotkey[i]->key=str[0]-'@';
        !          2186:                cfg.total_hotkeys++;
        !          2187:                uifc.changes=TRUE;
        !          2188:                continue; }
        !          2189:        if((i&MSK_ON)==MSK_DEL) {
        !          2190:                i&=MSK_OFF;
        !          2191:                free(cfg.hotkey[i]);
        !          2192:                cfg.total_hotkeys--;
        !          2193:                for(j=i;j<cfg.total_hotkeys;j++)
        !          2194:                        cfg.hotkey[j]=cfg.hotkey[j+1];
        !          2195:                uifc.changes=TRUE;
        !          2196:                continue; }
        !          2197:        if((i&MSK_ON)==MSK_GET) {
        !          2198:                i&=MSK_OFF;
        !          2199:                savhotkey=*cfg.hotkey[i];
        !          2200:                continue; }
        !          2201:        if((i&MSK_ON)==MSK_PUT) {
        !          2202:                i&=MSK_OFF;
        !          2203:                *cfg.hotkey[i]=savhotkey;
        !          2204:                uifc.changes=TRUE;
        !          2205:         continue; }
        !          2206:        done=0;
        !          2207:        while(!done) {
        !          2208:                k=0;
        !          2209:                sprintf(opt[k++],"%-27.27sCtrl-%c","Global Hot Key"
        !          2210:             ,cfg.hotkey[i]->key+'@');
        !          2211:                sprintf(opt[k++],"%-27.27s%.40s","Command Line",cfg.hotkey[i]->cmd);
        !          2212:         opt[k][0]=0;
        !          2213:                SETHELP(WHERE);
        !          2214: /*
        !          2215: &Global Hot Key Event:&
        !          2216: 
        !          2217: This menu allows you to change the settings for the selected global
        !          2218: hot key event. Hot key events are control characters that are used to
        !          2219: execute an external program or module anywhere in the BBS.
        !          2220: */
        !          2221:                sprintf(str,"Ctrl-%c Hot Key Event",cfg.hotkey[i]->key+'@');
        !          2222:                switch(uifc.list(WIN_SAV|WIN_ACT|WIN_L2R|WIN_BOT,0,0,60,&dfltopt,0
        !          2223:                        ,str,opt)) {
        !          2224:                        case -1:
        !          2225:                                done=1;
        !          2226:                                break;
        !          2227:                        case 0:
        !          2228:                                SETHELP(WHERE);
        !          2229: /*
        !          2230: &Global Hot-Ctrl Key:&
        !          2231: 
        !          2232: This is the global control key used to execute this event.
        !          2233: */
        !          2234:                                sprintf(str,"%c",cfg.hotkey[i]->key+'@');
        !          2235:                                if(uifc.input(WIN_MID|WIN_SAV,0,10,"Global Hot Ctrl-Key"
        !          2236:                                        ,str,1,K_EDIT|K_UPPER)>0)
        !          2237:                                        cfg.hotkey[i]->key=str[0]-'@';
        !          2238:                                break;
        !          2239:                   case 1:
        !          2240:                                SETHELP(WHERE);
        !          2241: /*
        !          2242: &Hot Key Event Command Line:&
        !          2243: 
        !          2244: This is the command line to execute when this hot key is pressed.
        !          2245: */
        !          2246:                                uifc.input(WIN_MID|WIN_SAV,0,10,"Command Line"
        !          2247:                                        ,cfg.hotkey[i]->cmd,sizeof(cfg.hotkey[i]->cmd)-1,K_EDIT);
        !          2248:                                break;
        !          2249:                                } } }
        !          2250: 
        !          2251: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.