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

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

unix.superglobalmegacorp.com

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