--- sbbs/src/sbbs3/scfg/scfgxtrn.c 2018/04/24 16:41:24 1.1.1.1 +++ sbbs/src/sbbs3/scfg/scfgxtrn.c 2018/04/24 16:44:51 1.1.1.2 @@ -1,2251 +1,2394 @@ -/* scfgxtrn.c */ - -/* $Id: scfgxtrn.c,v 1.1.1.1 2018/04/24 16:41:24 root Exp $ */ - -/**************************************************************************** - * @format.tab-size 4 (Plain Text/Source Code File Header) * - * @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) * - * * - * Copyright 2006 Rob Swindell - http://www.synchro.net/copyright.html * - * * - * This program is free software; you can redistribute it and/or * - * modify it under the terms of the GNU General Public License * - * as published by the Free Software Foundation; either version 2 * - * of the License, or (at your option) any later version. * - * See the GNU General Public License for more details: gpl.txt or * - * http://www.fsf.org/copyleft/gpl.html * - * * - * Anonymous FTP access to the most recent released source is available at * - * ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net * - * * - * Anonymous CVS access to the development source and modification history * - * is available at cvs.synchro.net:/cvsroot/sbbs, example: * - * cvs -d :pserver:anonymous@cvs.synchro.net:/cvsroot/sbbs login * - * (just hit return, no password is necessary) * - * cvs -d :pserver:anonymous@cvs.synchro.net:/cvsroot/sbbs checkout src * - * * - * For Synchronet coding style and modification guidelines, see * - * http://www.synchro.net/source.html * - * * - * You are encouraged to submit any modifications (preferably in Unix diff * - * format) via e-mail to mods@synchro.net * - * * - * Note: If this box doesn't appear square, then you need to fix your tabs. * - ****************************************************************************/ -/****************************************************************************/ -/* Synchronet configuration utility */ -/****************************************************************************/ - -#include "scfg.h" - -char *daystr(char days); -static void hotkey_cfg(void); - -static char* mdaystr(long mdays) -{ - int i; - char tmp[16]; - static char str[256]; - - if(mdays==0 || mdays==1) - return("Any"); - - str[0]=0; - for(i=1;i<32;i++) { - if((mdays&(1<code,cfg.event[i]->cmd); - opt[i][0]=0; - j=WIN_SAV|WIN_ACT|WIN_CHE|WIN_RHT; - if(cfg.total_events) - j|=WIN_DEL|WIN_GET; - if(cfg.total_eventscode,str); - cfg.event[i]->node=1; - cfg.event[i]->days=0xff; - cfg.total_events++; - uifc.changes=1; - continue; } - if((i&MSK_ON)==MSK_DEL) { - i&=MSK_OFF; - free(cfg.event[i]); - cfg.total_events--; - for(j=i;jcode); - sprintf(opt[k++],"%-32.32s%.40s","Start-up Directory",cfg.event[i]->dir); - sprintf(opt[k++],"%-32.32s%.40s","Command Line",cfg.event[i]->cmd); - sprintf(opt[k++],"%-32.32s%s","Enabled" - ,cfg.event[i]->misc&EVENT_DISABLED ? "No":"Yes"); - sprintf(opt[k++],"%-32.32s%u","Execution Node",cfg.event[i]->node); - sprintf(opt[k++],"%-32.32s%s","Execution Days of Month" - ,mdaystr(cfg.event[i]->mdays)); - sprintf(opt[k++],"%-32.32s%s","Execution Days of Week",daystr(cfg.event[i]->days)); - if(cfg.event[i]->freq) { - sprintf(str,"%u times a day",1440/cfg.event[i]->freq); - sprintf(opt[k++],"%-32.32s%s","Execution Frequency",str); - } else { - sprintf(str,"%2.2u:%2.2u" - ,cfg.event[i]->time/60,cfg.event[i]->time%60); - sprintf(opt[k++],"%-32.32s%s","Execution Time",str); - } - sprintf(opt[k++],"%-32.32s%s","Requires Exclusive Execution" - ,cfg.event[i]->misc&EVENT_EXCL ? "Yes":"No"); - sprintf(opt[k++],"%-32.32s%s","Force Users Off-line For Event" - ,cfg.event[i]->misc&EVENT_FORCE ? "Yes":"No"); - sprintf(opt[k++],"%-32.32s%s","Native (32-bit) Executable" - ,cfg.event[i]->misc&EX_NATIVE ? "Yes" : "No"); - sprintf(opt[k++],"%-32.32s%s","Use Shell to Execute" - ,cfg.event[i]->misc&XTRN_SH ? "Yes" : "No"); - sprintf(opt[k++],"%-32.32s%s","Background Execution" - ,cfg.event[i]->misc&EX_BG ? "Yes" : "No"); - sprintf(opt[k++],"%-32.32s%s","Always Run After Init/Re-init" - ,cfg.event[i]->misc&EVENT_INIT ? "Yes":"No"); - - opt[k][0]=0; - SETHELP(WHERE); -/* -Timed Event: - -This is the configuration menu for a timed event. An event is an -external program that performs some type of automated function on the -system. Use this menu to configure how and when this event will be -executed. - -If you need the BBS to swap out of memory for this event (to make more -available memory), add the program name (first word of the command line) -to Global Swap List from the External Programs menu. -*/ - sprintf(str,"%s Timed Event",cfg.event[i]->code); - switch(uifc.list(WIN_SAV|WIN_ACT|WIN_L2R|WIN_BOT,0,0,70,&dfltopt,0 - ,str,opt)) { - case -1: - done=1; - break; - case 0: - strcpy(str,cfg.event[i]->code); - SETHELP(WHERE); -/* -Timed Event Internal Code: - -Every timed event must have its own unique internal code for Synchronet -to reference it by. It is helpful if this code is an abreviation of the -command line. -*/ - uifc.input(WIN_MID|WIN_SAV,0,17,"Internal Code (unique)" - ,str,LEN_CODE,K_EDIT|K_UPPER); - if(code_ok(str)) - strcpy(cfg.event[i]->code,str); - else { - uifc.helpbuf=invalid_code; - uifc.msg("Invalid Code"); - uifc.helpbuf=0; } - break; - case 1: - SETHELP(WHERE); -/* -Timed Event Start-up Directory: - -This is the DOS drive/directory where the event program is located. -If a path is specified here, it will be made the current directory -before the event's command line is executed. This eliminates the need -for batch files that just change the current drive and directory before -executing the event. - -If this option is not used, the current NODE's directory will be the -current DOS drive/directory before the command line is executed. -*/ - uifc.input(WIN_MID|WIN_SAV,0,10,"Directory" - ,cfg.event[i]->dir,sizeof(cfg.event[i]->dir)-1,K_EDIT); - break; - case 2: - SETHELP(WHERE); -/* -Timed Event Command Line: - -This is the command line to execute upon this timed event. -*/ - uifc.input(WIN_MID|WIN_SAV,0,10,"Command" - ,cfg.event[i]->cmd,sizeof(cfg.event[i]->cmd)-1,K_EDIT); - break; - - case 3: - k=cfg.event[i]->misc&EVENT_DISABLED ? 1:0; - strcpy(opt[0],"Yes"); - strcpy(opt[1],"No"); - opt[2][0]=0; - SETHELP(WHERE); -/* -`Event Enabled:` - -If you want disable this event from executing, set this option to ~No~. -*/ - k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0 - ,"Enabled",opt); - if((k==0 && cfg.event[i]->misc&EVENT_DISABLED) - || (k==1 && !(cfg.event[i]->misc&EVENT_DISABLED))) { - cfg.event[i]->misc^=EVENT_DISABLED; - uifc.changes=1; - } - break; - - case 4: - SETHELP(WHERE); -/* -Timed Event Node: - -This is the node number to execute the timed event. -*/ - sprintf(str,"%u",cfg.event[i]->node); - uifc.input(WIN_MID|WIN_SAV,0,0,"Node Number" - ,str,3,K_EDIT|K_NUMBER); - cfg.event[i]->node=atoi(str); - break; - case 5: - SETHELP(WHERE); -/* -`Days of Month to Execute Event:` - -Specifies the days of the month (`1-31`, separated by spaces) on which -to execute this event, or `Any` to execute event on any and all days of -the month. -*/ - SAFECOPY(str,mdaystr(cfg.event[i]->mdays)); - uifc.input(WIN_MID|WIN_SAV,0,0,"Days of Month to Execute Event (or Any)" - ,str,16,K_EDIT); - cfg.event[i]->mdays=0; - for(p=str;*p;p++) { - if(!isdigit(*p)) - continue; - cfg.event[i]->mdays|=(1<days&(1<days=0xff; - else if(k==8) - cfg.event[i]->days=0; - else - cfg.event[i]->days^=(1<freq==0) - k=0; - else - k=1; - strcpy(opt[0],"Yes"); - strcpy(opt[1],"No"); - opt[2][0]=0; - SETHELP(WHERE); -/* -Execute Event at a Specific Time: - -If you want the system execute this event at a specific time, set -this option to Yes. If you want the system to execute this event more -than once a day at predetermined intervals, set this option to No. -*/ - k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0 - ,"Execute Event at a Specific Time",opt); - if(k==0) { - sprintf(str,"%2.2u:%2.2u",cfg.event[i]->time/60 - ,cfg.event[i]->time%60); - SETHELP(WHERE); -/* -Time to Execute Event: - -This is the time (in 24 hour HH:MM format) to execute the event. -*/ - if(uifc.input(WIN_MID|WIN_SAV,0,0 - ,"Time to Execute Event (HH:MM)" - ,str,5,K_UPPER|K_EDIT)>0) { - cfg.event[i]->freq=0; - cfg.event[i]->time=atoi(str)*60; - if((p=strchr(str,':'))!=NULL) - cfg.event[i]->time+=atoi(p+1); } } - else if(k==1) { - sprintf(str,"%u" - ,cfg.event[i]->freq && cfg.event[i]->freq<=1440 - ? 1440/cfg.event[i]->freq : 0); - SETHELP(WHERE); -/* -Number of Executions Per Day: - -This is the maximum number of times the system will execute this event -per day. -*/ - if(uifc.input(WIN_MID|WIN_SAV,0,0 - ,"Number of Executions Per Day" - ,str,4,K_NUMBER|K_EDIT)>0) { - cfg.event[i]->time=0; - k=atoi(str); - if(k && k<=1440) - cfg.event[i]->freq=1440/k; - else - cfg.event[i]->freq=0; - } - } - break; - case 8: - k=cfg.event[i]->misc&EVENT_EXCL ? 0:1; - strcpy(opt[0],"Yes"); - strcpy(opt[1],"No"); - opt[2][0]=0; - SETHELP(WHERE); -/* -Exclusive Event Execution: - -If this event must be run exclusively (all nodes inactive), set this -option to Yes. -*/ - k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0,"Exclusive Execution" - ,opt); - if(!k && !(cfg.event[i]->misc&EVENT_EXCL)) { - cfg.event[i]->misc|=EVENT_EXCL; - uifc.changes=1; } - else if(k==1 && cfg.event[i]->misc&EVENT_EXCL) { - cfg.event[i]->misc&=~EVENT_EXCL; - uifc.changes=1; } - break; - case 9: - k=cfg.event[i]->misc&EVENT_FORCE ? 0:1; - strcpy(opt[0],"Yes"); - strcpy(opt[1],"No"); - opt[2][0]=0; - SETHELP(WHERE); -/* -Force Users Off-line for Event: - -If you want to have your users' on-line time reduced so the event can -execute precisely on time, set this option to Yes. -*/ - k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0 - ,"Force Users Off-line for Event",opt); - if(!k && !(cfg.event[i]->misc&EVENT_FORCE)) { - cfg.event[i]->misc|=EVENT_FORCE; - uifc.changes=1; } - else if(k==1 && cfg.event[i]->misc&EVENT_FORCE) { - cfg.event[i]->misc&=~EVENT_FORCE; - uifc.changes=1; } - break; - - case 10: - k=cfg.event[i]->misc&EX_NATIVE ? 0:1; - strcpy(opt[0],"Yes"); - strcpy(opt[1],"No"); - opt[2][0]=0; - SETHELP(WHERE); -/* -Native (32-bit) Executable: - -If this event program is a native 32-bit executable, -set this option to Yes. -*/ - k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0 - ,"Native (32-bit)",opt); - if(!k && !(cfg.event[i]->misc&EX_NATIVE)) { - cfg.event[i]->misc|=EX_NATIVE; - uifc.changes=TRUE; - } - else if(k==1 && cfg.event[i]->misc&EX_NATIVE) { - cfg.event[i]->misc&=~EX_NATIVE; - uifc.changes=TRUE; - } - break; - - case 11: - k=cfg.event[i]->misc&XTRN_SH ? 0:1; - strcpy(opt[0],"Yes"); - strcpy(opt[1],"No"); - opt[2][0]=0; - SETHELP(WHERE); -/* -`Use Shell to Execute Command:` - -If this command-line requires the system command shell to execute, (Unix -shell script or DOS batch file), set this option to ~Yes~. -*/ - k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0 - ,"Use Shell",opt); - if(!k && !(cfg.event[i]->misc&XTRN_SH)) { - cfg.event[i]->misc|=XTRN_SH; - uifc.changes=TRUE; - } - else if(k==1 && cfg.event[i]->misc&XTRN_SH) { - cfg.event[i]->misc&=~XTRN_SH; - uifc.changes=TRUE; - } - break; - - case 12: - k=cfg.event[i]->misc&EX_BG ? 0:1; - strcpy(opt[0],"Yes"); - strcpy(opt[1],"No"); - opt[2][0]=0; - SETHELP(WHERE); -/* -Execute Event in Background (Asynchronously): - -If you would like this event to run simultaneously with other events, -set this option to Yes. Exclusive events will not run in the background. -*/ - k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0 - ,"Background (Asynchronous) Execution",opt); - if(!k && !(cfg.event[i]->misc&EX_BG)) { - cfg.event[i]->misc|=EX_BG; - uifc.changes=TRUE; - } - else if(k==1 && cfg.event[i]->misc&EX_BG) { - cfg.event[i]->misc&=~EX_BG; - uifc.changes=TRUE; - } - break; - - case 13: - k=cfg.event[i]->misc&EVENT_INIT ? 0:1; - strcpy(opt[0],"Yes"); - strcpy(opt[1],"No"); - opt[2][0]=0; - SETHELP(WHERE); -/* -`Always Run After Initialization or Re-initialization:` - -If you want this event to always run after the BBS is initialized or -re-initialized, set this option to ~Yes~. -*/ - k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0 - ,"Always Run After Initialization or Re-initialization",opt); - if(!k && !(cfg.event[i]->misc&EVENT_INIT)) { - cfg.event[i]->misc|=EVENT_INIT; - uifc.changes=1; - } - else if(k==1 && cfg.event[i]->misc&EVENT_INIT) { - cfg.event[i]->misc&=~EVENT_INIT; - uifc.changes=1; - } - break; - } - } - } -} - - -void xtrn_cfg(uint section) -{ - static int ext_dflt,ext_bar,opt_dflt,time_dflt; - char str[128],code[9],done=0,*p; - int j,k; - uint i,n,xtrnnum[MAX_OPTS+1]; - static xtrn_t savxtrn; - -while(1) { - for(i=0,j=0;isec==section) { - sprintf(opt[j],"%-25s",cfg.xtrn[i]->name); - xtrnnum[j++]=i; } - xtrnnum[j]=cfg.total_xtrns; - opt[j][0]=0; - i=WIN_ACT|WIN_CHE|WIN_SAV|WIN_RHT; - if(j) - i|=WIN_DEL|WIN_GET; - if(cfg.total_xtrnsname); - i=uifc.list(i,0,0,45,&ext_dflt,&ext_bar,str,opt); - if((signed)i==-1) - return; - if((i&MSK_ON)==MSK_INS) { - i&=MSK_OFF; - SETHELP(WHERE); -/* -Online Program Name: - -This is the name or description of the online program (door). -*/ - if(uifc.input(WIN_MID|WIN_SAV,0,0,"Online Program Name",str,25 - ,0)<1) - continue; - sprintf(code,"%.8s",str); - p=strchr(code,' '); - if(p) *p=0; - strupr(code); - SETHELP(WHERE); -/* -Online Program Internal Code: - -Every online program must have its own unique code for Synchronet to -refer to it internally. This code is usually an abreviation of the -online program name. -*/ - if(uifc.input(WIN_MID|WIN_SAV,0,0,"Internal Code" - ,code,LEN_CODE,K_EDIT|K_UPPER)<1) - continue; - if(!code_ok(code)) { - uifc.helpbuf=invalid_code; - uifc.msg("Invalid Code"); - uifc.helpbuf=0; - continue; } - if((cfg.xtrn=(xtrn_t **)realloc(cfg.xtrn,sizeof(xtrn_t *)*(cfg.total_xtrns+1))) - ==NULL) { - errormsg(WHERE,ERR_ALLOC,nulstr,cfg.total_xtrns+1); - cfg.total_xtrns=0; - bail(1); - continue; } - if(j) - for(n=cfg.total_xtrns;n>xtrnnum[i];n--) - cfg.xtrn[n]=cfg.xtrn[n-1]; - if((cfg.xtrn[xtrnnum[i]]=(xtrn_t *)malloc(sizeof(xtrn_t)))==NULL) { - errormsg(WHERE,ERR_ALLOC,nulstr,sizeof(xtrn_t)); - continue; } - memset((xtrn_t *)cfg.xtrn[xtrnnum[i]],0,sizeof(xtrn_t)); - strcpy(cfg.xtrn[xtrnnum[i]]->name,str); - strcpy(cfg.xtrn[xtrnnum[i]]->code,code); - cfg.xtrn[xtrnnum[i]]->sec=section; - cfg.total_xtrns++; - uifc.changes=TRUE; - continue; } - if((i&MSK_ON)==MSK_DEL) { - i&=MSK_OFF; - free(cfg.xtrn[xtrnnum[i]]); - cfg.total_xtrns--; - for(j=xtrnnum[i];jsec=section; - uifc.changes=TRUE; - continue; } - done=0; - i=xtrnnum[i]; - while(!done) { - k=0; - sprintf(opt[k++],"%-27.27s%s","Name",cfg.xtrn[i]->name); - sprintf(opt[k++],"%-27.27s%s","Internal Code",cfg.xtrn[i]->code); - sprintf(opt[k++],"%-27.27s%.40s","Start-up Directory",cfg.xtrn[i]->path); - sprintf(opt[k++],"%-27.27s%.40s","Command Line",cfg.xtrn[i]->cmd); - sprintf(opt[k++],"%-27.27s%.40s","Clean-up Command Line",cfg.xtrn[i]->clean); - if(cfg.xtrn[i]->cost) - sprintf(str,"%lu credits",cfg.xtrn[i]->cost); - else - strcpy(str,"None"); - sprintf(opt[k++],"%-27.27s%s","Execution Cost",str); - sprintf(opt[k++],"%-27.27s%.40s","Access Requirements",cfg.xtrn[i]->arstr); - sprintf(opt[k++],"%-27.27s%.40s","Execution Requirements" - ,cfg.xtrn[i]->run_arstr); - sprintf(opt[k++],"%-27.27s%s","Multiple Concurrent Users" - ,cfg.xtrn[i]->misc&MULTIUSER ? "Yes" : "No"); - sprintf(opt[k++],"%-27.27s%s%s%s","Intercept Standard I/O" - ,cfg.xtrn[i]->misc&IO_INTS ? "Yes" : "No" - ,(cfg.xtrn[i]->misc&(IO_INTS|WWIVCOLOR)) - ==(IO_INTS|WWIVCOLOR) ? ", WWIV Color" : nulstr - ,(cfg.xtrn[i]->misc&(IO_INTS|XTRN_NOECHO)) - ==(IO_INTS|XTRN_NOECHO) ? ", No Echo" : nulstr); - sprintf(opt[k++],"%-27.27s%s","Native (32-bit) Executable" - ,cfg.xtrn[i]->misc&XTRN_NATIVE ? "Yes" : "No"); - sprintf(opt[k++],"%-27.27s%s","Use Shell to Execute" - ,cfg.xtrn[i]->misc&XTRN_SH ? "Yes" : "No"); - sprintf(opt[k++],"%-27.27s%s","Modify User Data" - ,cfg.xtrn[i]->misc&MODUSERDAT ? "Yes" : "No"); - switch(cfg.xtrn[i]->event) { - case EVENT_LOGON: - strcpy(str,"Logon"); - break; - case EVENT_LOGOFF: - strcpy(str,"Logoff"); - break; - case EVENT_NEWUSER: - strcpy(str,"New User"); - break; - case EVENT_BIRTHDAY: - strcpy(str,"Birthday"); - break; - case EVENT_POST: - strcpy(str,"Message Posted"); - break; - case EVENT_UPLOAD: - strcpy(str,"File Uploaded"); - break; - case EVENT_DOWNLOAD: - strcpy(str,"File Downloaded"); - break; - default: - strcpy(str,"No"); - break; - } - if(cfg.xtrn[i]->misc&EVENTONLY && cfg.xtrn[i]->event) - strcat(str,", Only"); - sprintf(opt[k++],"%-27.27s%s","Execute on Event",str); - sprintf(opt[k++],"%-27.27s%s","Pause After Execution" - ,cfg.xtrn[i]->misc&XTRN_PAUSE ? "Yes" : "No"); - sprintf(opt[k++],"%-23.23s%-4s%s","BBS Drop File Type" - ,cfg.xtrn[i]->misc&REALNAME ? "(R)":nulstr - ,dropfile(cfg.xtrn[i]->type,cfg.xtrn[i]->misc)); - sprintf(opt[k++],"%-27.27s%s","Place Drop File In" - ,cfg.xtrn[i]->misc&STARTUPDIR ? "Start-Up Directory":"Node Directory"); - sprintf(opt[k++],"Time Options..."); - opt[k][0]=0; - SETHELP(WHERE); -/* -Online Program Configuration: - -This menu is for configuring the selected online program. -*/ - switch(uifc.list(WIN_SAV|WIN_ACT|WIN_MID,0,0,60,&opt_dflt,0,cfg.xtrn[i]->name - ,opt)) { - case -1: - done=1; - break; - case 0: - SETHELP(WHERE); -/* -Online Program Name: - -This is the name or description of the online program (door). -*/ - strcpy(str,cfg.xtrn[i]->name); - if(!uifc.input(WIN_MID|WIN_SAV,0,10,"Online Program Name" - ,cfg.xtrn[i]->name,sizeof(cfg.xtrn[i]->name)-1,K_EDIT)) - strcpy(cfg.xtrn[i]->name,str); - break; - case 1: - SETHELP(WHERE); -/* -Online Program Internal Code: - -Every online program must have its own unique code for Synchronet to -refer to it internally. This code is usually an abreviation of the -online program name. -*/ - strcpy(str,cfg.xtrn[i]->code); - uifc.input(WIN_MID|WIN_SAV,0,10,"Internal Code" - ,str,LEN_CODE,K_UPPER|K_EDIT); - if(code_ok(str)) - strcpy(cfg.xtrn[i]->code,str); - else { - uifc.helpbuf=invalid_code; - uifc.msg("Invalid Code"); - uifc.helpbuf=0; - } - break; - case 2: - SETHELP(WHERE); -/* -Online Program Start-up Directory: - -This is the DOS drive/directory where the online program is located. -If a path is specified here, it will be made the current directory -before the program's command line is executed. This eliminates the need -for batch files that just change the current drive and directory before -executing the program. - -If this option is not used, the current NODE's directory will be the -current DOS drive/directory before the command line is executed. -*/ - uifc.input(WIN_MID|WIN_SAV,0,10,"" - ,cfg.xtrn[i]->path,sizeof(cfg.xtrn[i]->path)-1,K_EDIT); - break; - case 3: - SETHELP(WHERE); -/* -Online Program Command Line: - -This is the command line to execute to run the online program. -*/ - uifc.input(WIN_MID|WIN_SAV,0,10,"Command" - ,cfg.xtrn[i]->cmd,sizeof(cfg.xtrn[i]->cmd)-1,K_EDIT); - break; - case 4: - SETHELP(WHERE); -/* -Online Program Clean-up Command: - -This is the command line to execute after the main command line. This -option is usually only used for multiuser online programs. -*/ - uifc.input(WIN_MID|WIN_SAV,0,10,"Clean-up" - ,cfg.xtrn[i]->clean,sizeof(cfg.xtrn[i]->clean)-1,K_EDIT); - break; - case 5: - ultoa(cfg.xtrn[i]->cost,str,10); - SETHELP(WHERE); -/* -Online Program Cost to Run: - -If you want users to be charged credits to run this online program, -set this value to the number of credits to charge. If you want this -online program to be free, set this value to 0. -*/ - uifc.input(WIN_MID|WIN_SAV,0,0,"Cost to Run (in Credits)" - ,str,10,K_EDIT|K_NUMBER); - cfg.xtrn[i]->cost=atol(str); - break; - case 6: - sprintf(str,"%s Access",cfg.xtrn[i]->name); - getar(str,cfg.xtrn[i]->arstr); - break; - case 7: - sprintf(str,"%s Execution",cfg.xtrn[i]->name); - getar(str,cfg.xtrn[i]->run_arstr); - break; - case 8: - k=cfg.xtrn[i]->misc&MULTIUSER ? 0:1; - strcpy(opt[0],"Yes"); - strcpy(opt[1],"No"); - opt[2][0]=0; - SETHELP(WHERE); -/* -Supports Multiple Users: - -If this online program supports multiple simultaneous users (nodes), -set this option to Yes. -*/ - k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0,"Supports Multiple Users" - ,opt); - if(!k && !(cfg.xtrn[i]->misc&MULTIUSER)) { - cfg.xtrn[i]->misc|=MULTIUSER; - uifc.changes=TRUE; } - else if(k==1 && cfg.xtrn[i]->misc&MULTIUSER) { - cfg.xtrn[i]->misc&=~MULTIUSER; - uifc.changes=TRUE; } - break; - case 9: - k=cfg.xtrn[i]->misc&IO_INTS ? 0:1; - strcpy(opt[0],"Yes"); - strcpy(opt[1],"No"); - opt[2][0]=0; - SETHELP(WHERE); -/* -Intercept Standard I/O: - -If this online program uses a FOSSIL driver or SOCKET communications, -set this option to No. -*/ - k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0,"Intercept Standard I/O" - ,opt); - if(!k && !(cfg.xtrn[i]->misc&IO_INTS)) { - cfg.xtrn[i]->misc|=IO_INTS; - uifc.changes=TRUE; } - else if(k==1 && cfg.xtrn[i]->misc&IO_INTS) { - cfg.xtrn[i]->misc&=~(IO_INTS|WWIVCOLOR); - uifc.changes=TRUE; } - else if(k==-1) - break; - if(!(cfg.xtrn[i]->misc&IO_INTS)) - break; - k=cfg.xtrn[i]->misc&WWIVCOLOR ? 0:1; - SETHELP(WHERE); -/* -Program Uses WWIV Color Codes: - -If this program was written for use exclusively under WWIV, set this -option to Yes. -*/ - k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0 - ,"Program Uses WWIV Color Codes" - ,opt); - if(!k && !(cfg.xtrn[i]->misc&WWIVCOLOR)) { - cfg.xtrn[i]->misc|=WWIVCOLOR; - uifc.changes=TRUE; } - else if(k==1 && cfg.xtrn[i]->misc&WWIVCOLOR) { - cfg.xtrn[i]->misc&=~WWIVCOLOR; - uifc.changes=TRUE; } - k=cfg.xtrn[i]->misc&XTRN_NOECHO ? 1:0; - SETHELP(WHERE); -/* -`Echo Input:` - -If you want the BBS to copy ("echo") all keyboard input to the screen -output, set this option to ~Yes~ (for native Win32 programs only). -*/ - k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0 - ,"Echo Keyboard Input" - ,opt); - if(!k && cfg.xtrn[i]->misc&XTRN_NOECHO) { - cfg.xtrn[i]->misc&=~XTRN_NOECHO; - uifc.changes=TRUE; - } else if(k==1 && !(cfg.xtrn[i]->misc&XTRN_NOECHO)) { - cfg.xtrn[i]->misc|=XTRN_NOECHO; - uifc.changes=TRUE; - } - break; - case 10: - k=cfg.xtrn[i]->misc&XTRN_NATIVE ? 0:1; - strcpy(opt[0],"Yes"); - strcpy(opt[1],"No"); - opt[2][0]=0; - SETHELP(WHERE); -/* -Native (32-bit) Executable: - -If this online program is a native 32-bit executable, -set this option to Yes. -*/ - k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0 - ,"Native (32-bit)",opt); - if(!k && !(cfg.xtrn[i]->misc&XTRN_NATIVE)) { - cfg.xtrn[i]->misc|=XTRN_NATIVE; - uifc.changes=TRUE; } - else if(k==1 && cfg.xtrn[i]->misc&XTRN_NATIVE) { - cfg.xtrn[i]->misc&=~XTRN_NATIVE; - uifc.changes=TRUE; } - break; - case 11: - k=cfg.xtrn[i]->misc&XTRN_SH ? 0:1; - strcpy(opt[0],"Yes"); - strcpy(opt[1],"No"); - opt[2][0]=0; - SETHELP(WHERE); -/* -`Use Shell to Execute Command:` - -If this command-line requires the system command shell to execute, (Unix -shell script or DOS batch file), set this option to ~Yes~. -*/ - k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0 - ,"Use Shell",opt); - if(!k && !(cfg.xtrn[i]->misc&XTRN_SH)) { - cfg.xtrn[i]->misc|=XTRN_SH; - uifc.changes=TRUE; - } - else if(k==1 && cfg.xtrn[i]->misc&XTRN_SH) { - cfg.xtrn[i]->misc&=~XTRN_SH; - uifc.changes=TRUE; - } - break; - case 12: - k=cfg.xtrn[i]->misc&MODUSERDAT ? 0:1; - strcpy(opt[0],"Yes"); - strcpy(opt[1],"No"); - opt[2][0]=0; - SETHELP(WHERE); -/* -Program Can Modify User Data: - -If this online programs recognizes the Synchronet MODUSER.DAT format -or the RBBS/QuickBBS EXITINFO.BBS format and you want it to be able to -modify the data of users who run the program, set this option to Yes. -*/ - k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0 - ,"Program Can Modify User Data",opt); - if(!k && !(cfg.xtrn[i]->misc&MODUSERDAT)) { - cfg.xtrn[i]->misc|=MODUSERDAT; - uifc.changes=TRUE; } - else if(k==1 && cfg.xtrn[i]->misc&MODUSERDAT) { - cfg.xtrn[i]->misc&=~MODUSERDAT; - uifc.changes=TRUE; } - break; - case 13: - k=0; - strcpy(opt[k++],"No"); - strcpy(opt[k++],"Logon"); - strcpy(opt[k++],"Logoff"); - strcpy(opt[k++],"New User"); - strcpy(opt[k++],"Birthday"); - strcpy(opt[k++],"Message Posted"); - strcpy(opt[k++],"File Uploaded"); - strcpy(opt[k++],"File Downloaded"); - opt[k][0]=0; - k=cfg.xtrn[i]->event; - SETHELP(WHERE); -/* -Execute Online Program on Event: - -If you would like this online program to automatically execute on a -specific user event, select the event. Otherwise, select No. -*/ - k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0 - ,"Execute on Event",opt); - if(k==-1) - break; - if(cfg.xtrn[i]->event!=k) { - cfg.xtrn[i]->event=k; - uifc.changes=TRUE; } - if(!cfg.xtrn[i]->event) { - if(cfg.xtrn[i]->misc&EVENTONLY) { - cfg.xtrn[i]->misc&=~EVENTONLY; - uifc.changes=TRUE; - } - break; - } - k=cfg.xtrn[i]->misc&EVENTONLY ? 0:1; - strcpy(opt[0],"Yes"); - strcpy(opt[1],"No"); - opt[2][0]=0; - SETHELP(WHERE); -/* -Execute Online Program as Event Only: - -If you would like this online program to execute as an event only -(not available to users on the online program menu), set this option -to Yes. -*/ - k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k - ,0,"Execute as Event Only" - ,opt); - if(!k && !(cfg.xtrn[i]->misc&EVENTONLY)) { - cfg.xtrn[i]->misc|=EVENTONLY; - uifc.changes=TRUE; } - else if(k==1 && cfg.xtrn[i]->misc&EVENTONLY) { - cfg.xtrn[i]->misc&=~EVENTONLY; - uifc.changes=TRUE; } - break; - case 14: - k=cfg.xtrn[i]->misc&XTRN_PAUSE ? 0:1; - strcpy(opt[0],"Yes"); - strcpy(opt[1],"No"); - opt[2][0]=0; - SETHELP(WHERE); -/* -`Pause Screen After Execution:` - -Set this option to ~Yes~ if you would like an automatic screen pause -(`[Hit a key]` prompt) to appear after the program executes. - -This can be useful if the program displays information just before exiting -or you want to debug a program with a program not running correctly. -*/ - k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0 - ,"Pause After Execution",opt); - if((!k && !(cfg.xtrn[i]->misc&XTRN_PAUSE)) - || (k && cfg.xtrn[i]->misc&XTRN_PAUSE)) { - cfg.xtrn[i]->misc^=XTRN_PAUSE; - uifc.changes=TRUE; - } - break; - case 15: - k=0; - strcpy(opt[k++],"None"); - sprintf(opt[k++],"%-15s %s","Synchronet","XTRN.DAT"); - sprintf(opt[k++],"%-15s %s","WWIV","CHAIN.TXT"); - sprintf(opt[k++],"%-15s %s","GAP","DOOR.SYS"); - sprintf(opt[k++],"%-15s %s","RBBS/QuickBBS","DORINFO#.DEF"); - sprintf(opt[k++],"%-15s %s","Wildcat","CALLINFO.BBS"); - sprintf(opt[k++],"%-15s %s","PCBoard","PCBOARD.SYS"); - sprintf(opt[k++],"%-15s %s","SpitFire","SFDOORS.DAT"); - sprintf(opt[k++],"%-15s %s","MegaMail","UTIDOOR.TXT"); - sprintf(opt[k++],"%-15s %s","Solar Realms","DOORFILE.SR"); - sprintf(opt[k++],"%-15s %s","RBBS/QuickBBS","DORINFO1.DEF"); - sprintf(opt[k++],"%-15s %s","TriBBS","TRIBBS.SYS"); - sprintf(opt[k++],"%-15s %s","Mystic","DOOR32.SYS"); - opt[k][0]=0; - k=cfg.xtrn[i]->type; - SETHELP(WHERE); -/* -Online Program BBS Drop File Type: - -If this online program requires a specific BBS data (drop) file -format, select the file format from the list. -*/ - k=uifc.list(WIN_MID|WIN_ACT,0,0,0,&k,0 - ,"BBS Drop File Type",opt); - if(k==-1) - break; - if(cfg.xtrn[i]->type!=k) { - cfg.xtrn[i]->type=k; - if(cfg.xtrn[i]->type==XTRN_DOOR32) - cfg.xtrn[i]->misc|=XTRN_NATIVE; - uifc.changes=TRUE; } - if(cfg.xtrn[i]->type && cfg.uq&UQ_ALIASES) { - strcpy(opt[0],"Yes"); - strcpy(opt[1],"No"); - opt[2][0]=0; - k=cfg.xtrn[i]->misc&REALNAME ? 0:1; - k=uifc.list(WIN_MID,0,0,0,&k,0,"Use Real Names",opt); - if(k==0 && !(cfg.xtrn[i]->misc&REALNAME)) { - cfg.xtrn[i]->misc|=REALNAME; - uifc.changes=TRUE; } - else if(k==1 && cfg.xtrn[i]->misc&REALNAME) { - cfg.xtrn[i]->misc&=~REALNAME; - uifc.changes=TRUE; - } - } - if(cfg.xtrn[i]->type) { - strcpy(opt[0],"Yes"); - strcpy(opt[1],"No"); - opt[2][0]=0; - k=cfg.xtrn[i]->misc&XTRN_LWRCASE ? 0:1; - k=uifc.list(WIN_MID,0,0,0,&k,0,"Lowercase Filename",opt); - if(k==0 && !(cfg.xtrn[i]->misc&XTRN_LWRCASE)) { - cfg.xtrn[i]->misc|=XTRN_LWRCASE; - uifc.changes=TRUE; - } - else if(k==1 && cfg.xtrn[i]->misc&XTRN_LWRCASE) { - cfg.xtrn[i]->misc&=~XTRN_LWRCASE; - uifc.changes=TRUE; - } - } - break; - case 16: - k=0; - strcpy(opt[0],"Node Directory"); - strcpy(opt[1],"Start-up Directory"); - opt[2][0]=0; - SETHELP(WHERE); -/* -Directory for Drop File: - -You can have the data file created in the current Node Directory or the -Start-up Directory (if one is specified). -*/ - k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0,"Create Drop File In" - ,opt); - if(!k && cfg.xtrn[i]->misc&STARTUPDIR) { - cfg.xtrn[i]->misc&=~STARTUPDIR; - uifc.changes=TRUE; } - else if(k==1 && !(cfg.xtrn[i]->misc&STARTUPDIR)) { - cfg.xtrn[i]->misc|=STARTUPDIR; - uifc.changes=TRUE; } - break; - case 17: - while(1) { - k=0; - if(cfg.xtrn[i]->textra) - sprintf(str,"%u minutes",cfg.xtrn[i]->textra); - else - strcpy(str,"None"); - sprintf(opt[k++],"%-25.25s%s","Extra Time",str); - if(cfg.xtrn[i]->maxtime) - sprintf(str,"%u minutes",cfg.xtrn[i]->maxtime); - else - strcpy(str,"None"); - sprintf(opt[k++],"%-25.25s%s","Maximum Time",str); - sprintf(opt[k++],"%-25.25s%s","Suspended (Free) Time" - ,cfg.xtrn[i]->misc&FREETIME ? "Yes" : "No"); - sprintf(opt[k++],"%-25.25s%s","Monitor Time Left" - ,cfg.xtrn[i]->misc&XTRN_CHKTIME ? "Yes" : "No"); - opt[k][0]=0; - SETHELP(WHERE); -/* -Online Program Time Options: - -This sub-menu allows you to define specific preferences regarding the -time users spend running this program. -*/ - k=uifc.list(WIN_SAV|WIN_ACT|WIN_RHT|WIN_BOT,0,0,40 - ,&time_dflt,0 - ,"Online Program Time Options",opt); - if(k==-1) - break; - switch(k) { - case 0: - ultoa(cfg.xtrn[i]->textra,str,10); - SETHELP(WHERE); -/* -Extra Time to Give User in Program: - -If you want to give users extra time while in this online program, -set this value to the number of minutes to add to their current time -left online. -*/ - uifc.input(WIN_MID|WIN_SAV,0,0 - ,"Extra Time to Give User (in minutes)" - ,str,2,K_EDIT|K_NUMBER); - cfg.xtrn[i]->textra=atoi(str); - break; - case 1: - ultoa(cfg.xtrn[i]->maxtime,str,10); - SETHELP(WHERE); -/* -Maximum Time Allowed in Program: - -If this program supports a drop file that contains the number of minutes -left online for the current user, this option allows the sysop to set -the maximum number of minutes that will be allowed in the drop file. - -Setting this option to 0, disables this feature. -*/ - uifc.input(WIN_MID|WIN_SAV,0,0 - ,"Maximum Time (in minutes, 0=disabled)" - ,str,2,K_EDIT|K_NUMBER); - cfg.xtrn[i]->maxtime=atoi(str); - break; - case 2: - k=cfg.xtrn[i]->misc&FREETIME ? 0:1; - strcpy(opt[0],"Yes"); - strcpy(opt[1],"No"); - opt[2][0]=0; - SETHELP(WHERE); -/* -Suspended (Free) Time: - -If you want the user's time online to be suspended while running this -online program (e.g. Free Time), set this option to Yes. -*/ - k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0 - ,"Suspended (Free) Time",opt); - if(!k && !(cfg.xtrn[i]->misc&FREETIME)) { - cfg.xtrn[i]->misc|=FREETIME; - uifc.changes=TRUE; } - else if(k==1 && cfg.xtrn[i]->misc&FREETIME) { - cfg.xtrn[i]->misc&=~FREETIME; - uifc.changes=TRUE; } - break; - case 3: - k=cfg.xtrn[i]->misc&XTRN_CHKTIME ? 0:1; - strcpy(opt[0],"Yes"); - strcpy(opt[1],"No"); - opt[2][0]=0; - SETHELP(WHERE); -/* -Monitor Time Left: - -If you want Synchronet to monitor the user's time left onlnie while this -program runs (and disconnect the user if their time runs out), set this -option to Yes. -*/ - k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0 - ,"Monitor Time Left",opt); - if(!k && !(cfg.xtrn[i]->misc&XTRN_CHKTIME)) { - cfg.xtrn[i]->misc|=XTRN_CHKTIME; - uifc.changes=TRUE; } - else if(k==1 && cfg.xtrn[i]->misc&XTRN_CHKTIME) { - cfg.xtrn[i]->misc&=~XTRN_CHKTIME; - uifc.changes=TRUE; } - break; - } - } - break; - - } } } -} - -void xedit_cfg() -{ - static int dflt,dfltopt,bar; - char str[81],code[81],done=0,*p; - int j,k; - uint i; - static xedit_t savxedit; - -while(1) { - for(i=0;icode,cfg.xedit[i]->rcmd); - opt[i][0]=0; - j=WIN_SAV|WIN_ACT|WIN_CHE|WIN_RHT; - if(cfg.total_xedits) - j|=WIN_DEL|WIN_GET; - if(cfg.total_xeditsi;j--) - cfg.xedit[j]=cfg.xedit[j-1]; - if((cfg.xedit[i]=(xedit_t *)malloc(sizeof(xedit_t)))==NULL) { - errormsg(WHERE,ERR_ALLOC,nulstr,sizeof(xedit_t)); - continue; } - memset((xedit_t *)cfg.xedit[i],0,sizeof(xedit_t)); - strcpy(cfg.xedit[i]->name,str); - strcpy(cfg.xedit[i]->code,code); - cfg.total_xedits++; - uifc.changes=TRUE; - continue; } - if((i&MSK_ON)==MSK_DEL) { - i&=MSK_OFF; - free(cfg.xedit[i]); - cfg.total_xedits--; - for(j=i;jname); - sprintf(opt[k++],"%-32.32s%s","Internal Code",cfg.xedit[i]->code); - sprintf(opt[k++],"%-32.32s%.40s","Remote Command Line",cfg.xedit[i]->rcmd); - sprintf(opt[k++],"%-32.32s%.40s","Access Requirements",cfg.xedit[i]->arstr); - sprintf(opt[k++],"%-32.32s%s%s","Intercept Standard I/O" - ,cfg.xedit[i]->misc&IO_INTS ? "Yes":"No" - ,cfg.xedit[i]->misc&WWIVCOLOR ? ", WWIV" : nulstr); - sprintf(opt[k++],"%-32.32s%s","Native (32-bit) Executable" - ,cfg.xedit[i]->misc&XTRN_NATIVE ? "Yes" : "No"); - sprintf(opt[k++],"%-32.32s%s","Use Shell to Execute" - ,cfg.xedit[i]->misc&XTRN_SH ? "Yes" : "No"); - sprintf(opt[k++],"%-32.32s%s","Quoted Text" - ,cfg.xedit[i]->misc"EALL ? "All":cfg.xedit[i]->misc"ENONE - ? "None" : "Prompt User"); - sprintf(opt[k++],"%-32.32s%s","QuickBBS Style (MSGTMP)" - ,cfg.xedit[i]->misc&QUICKBBS ? "Yes":"No"); - sprintf(opt[k++],"%-32.32s%s","Expand Line Feeds to CRLF" - ,cfg.xedit[i]->misc&EXPANDLF ? "Yes":"No"); - sprintf(opt[k++],"%-32.32s%s","Strip FidoNet Kludge Lines" - ,cfg.xedit[i]->misc&STRIPKLUDGE ? "Yes":"No"); - sprintf(opt[k++],"%-32.32s%s","BBS Drop File Type" - ,dropfile(cfg.xedit[i]->type,cfg.xedit[i]->misc)); - opt[k][0]=0; - SETHELP(WHERE); -/* -External Editor Configuration: - -This menu allows you to change the settings for the selected external -message editor. External message editors are very common on BBSs. Some -popular editors include SyncEdit, WWIVedit, FEdit, GEdit, IceEdit, -and many others. -*/ - - sprintf(str,"%s Editor",cfg.xedit[i]->name); - switch(uifc.list(WIN_SAV|WIN_ACT|WIN_L2R|WIN_BOT,0,0,70,&dfltopt,0 - ,str,opt)) { - case -1: - done=1; - break; - case 0: - SETHELP(WHERE); -/* -External Editor Name: - -This is the name or description of the external editor. -*/ - strcpy(str,cfg.xedit[i]->name); - if(!uifc.input(WIN_MID|WIN_SAV,0,10,"External Editor Name" - ,cfg.xedit[i]->name,sizeof(cfg.xedit[i]->name)-1,K_EDIT)) - strcpy(cfg.xedit[i]->name,str); - break; - case 1: - strcpy(str,cfg.xedit[i]->code); - SETHELP(WHERE); -/* -External Editor Internal Code: - -Every external editor must have its own unique internal code for -Synchronet to reference it by. It is helpful if this code is an -abreviation of the name. -*/ - uifc.input(WIN_MID|WIN_SAV,0,17,"Internal Code (unique)" - ,str,LEN_CODE,K_EDIT|K_UPPER); - if(code_ok(str)) - strcpy(cfg.xedit[i]->code,str); - else { - uifc.helpbuf=invalid_code; - uifc.msg("Invalid Code"); - uifc.helpbuf=0; } - break; - case 2: - SETHELP(WHERE); -/* -External Editor Remote Command Line: - -This is the command line to execute when using this editor remotely. -*/ - uifc.input(WIN_MID|WIN_SAV,0,10,"Remote" - ,cfg.xedit[i]->rcmd,sizeof(cfg.xedit[i]->rcmd)-1,K_EDIT); - break; - case 3: - sprintf(str,"%s External Editor",cfg.xedit[i]->name); - getar(str,cfg.xedit[i]->arstr); - break; - case 4: - k=cfg.xedit[i]->misc&IO_INTS ? 0:1; - strcpy(opt[0],"Yes"); - strcpy(opt[1],"No"); - opt[2][0]=0; - SETHELP(WHERE); -/* -Intercept Standard I/O: - -If this external editor uses a FOSSIL driver or SOCKET communications, -set this option to No. -*/ - k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0,"Intercept Standard I/O" - ,opt); - if(!k && !(cfg.xedit[i]->misc&IO_INTS)) { - cfg.xedit[i]->misc|=IO_INTS; - uifc.changes=TRUE; } - else if(k==1 && cfg.xedit[i]->misc&IO_INTS) { - cfg.xedit[i]->misc&=~(IO_INTS|WWIVCOLOR); - uifc.changes=TRUE; } - if(!(cfg.xedit[i]->misc&IO_INTS)) - break; - k=cfg.xedit[i]->misc&WWIVCOLOR ? 0:1; - strcpy(opt[0],"Yes"); - strcpy(opt[1],"No"); - opt[2][0]=0; - SETHELP(WHERE); -/* -Editor Uses WWIV Color Codes: - -If this editor was written for use exclusively under WWIV, set this -option to Yes. -*/ - k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0 - ,"Editor Uses WWIV Color Codes",opt); - if(!k && !(cfg.xedit[i]->misc&WWIVCOLOR)) { - cfg.xedit[i]->misc|=WWIVCOLOR; - uifc.changes=TRUE; } - else if(k==1 && cfg.xedit[i]->misc&WWIVCOLOR) { - cfg.xedit[i]->misc&=~WWIVCOLOR; - uifc.changes=TRUE; } - break; - case 5: - k=cfg.xedit[i]->misc&XTRN_NATIVE ? 0:1; - strcpy(opt[0],"Yes"); - strcpy(opt[1],"No"); - opt[2][0]=0; - SETHELP(WHERE); -/* -Native (32-bit) Executable: - -If this editor is a native 32-bit executable, set this option to Yes. -*/ - k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0 - ,"Native (32-bit)",opt); - if(!k && !(cfg.xedit[i]->misc&XTRN_NATIVE)) { - cfg.xedit[i]->misc|=XTRN_NATIVE; - uifc.changes=TRUE; } - else if(k==1 && cfg.xedit[i]->misc&XTRN_NATIVE) { - cfg.xedit[i]->misc&=~XTRN_NATIVE; - uifc.changes=TRUE; } - break; - case 6: - k=cfg.xedit[i]->misc&XTRN_SH ? 0:1; - strcpy(opt[0],"Yes"); - strcpy(opt[1],"No"); - opt[2][0]=0; - SETHELP(WHERE); -/* -`Use Shell to Execute Command:` - -If this command-line requires the system command shell to execute, (Unix -shell script or DOS batch file), set this option to ~Yes~. -*/ - k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0 - ,"Use Shell",opt); - if(!k && !(cfg.xedit[i]->misc&XTRN_SH)) { - cfg.xedit[i]->misc|=XTRN_SH; - uifc.changes=TRUE; - } else if(k==1 && cfg.xedit[i]->misc&XTRN_SH) { - cfg.xedit[i]->misc&=~XTRN_SH; - uifc.changes=TRUE; - } - break; - case 7: - k=3; - strcpy(opt[0],"All"); - strcpy(opt[1],"None"); - strcpy(opt[2],"Prompt User"); - opt[3][0]=0; - SETHELP(WHERE); -/* -Quoted Text: - -If you want all the message text to be automatically entered into the -message edit/quote file (INPUT.MSG or MSGTMP), select All. - -If you want the user to be prompted for which lines to quote before -running the editor, select Prompt User. - -If you want none of the lines to be automatically quoted, select None. -This option is mainly for use with editors that support the QUOTES.TXT -drop file (like SyncEdit v2.x). -*/ - k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0,"Quoted Text" - ,opt); - if(!k && !(cfg.xedit[i]->misc"EALL)) { - cfg.xedit[i]->misc|=QUOTEALL; - cfg.xedit[i]->misc&=~QUOTENONE; - uifc.changes=TRUE; } - else if(k==1 && !(cfg.xedit[i]->misc"ENONE)) { - cfg.xedit[i]->misc|=QUOTENONE; - cfg.xedit[i]->misc&=~QUOTEALL; - uifc.changes=TRUE; } - else if(k==2 && cfg.xedit[i]->misc&(QUOTENONE|QUOTEALL)) { - cfg.xedit[i]->misc&=~(QUOTENONE|QUOTEALL); - uifc.changes=TRUE; } - break; - case 8: - k=cfg.xedit[i]->misc&QUICKBBS ? 0:1; - strcpy(opt[0],"Yes"); - strcpy(opt[1],"No"); - opt[2][0]=0; - SETHELP(WHERE); -/* -QuickBBS Style (MSGTMP): - -If this external editor uses the QuickBBS style MSGTMP interface, set -this option to Yes. -*/ - k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0,"QuickBBS Style (MSGTMP)" - ,opt); - if(!k && !(cfg.xedit[i]->misc&QUICKBBS)) { - cfg.xedit[i]->misc|=QUICKBBS; - uifc.changes=TRUE; } - else if(k==1 && cfg.xedit[i]->misc&QUICKBBS) { - cfg.xedit[i]->misc&=~QUICKBBS; - uifc.changes=TRUE; } - break; - case 9: - k=cfg.xedit[i]->misc&EXPANDLF ? 0:1; - strcpy(opt[0],"Yes"); - strcpy(opt[1],"No"); - opt[2][0]=0; - SETHELP(WHERE); -/* -Expand Line Feeds to Carriage Return/Line Feed Pairs: - -If this external editor saves new lines as a single line feed character -instead of a carriage return/line feed pair, set this option to Yes. -*/ - k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0,"Expand LF to CRLF" - ,opt); - if(!k && !(cfg.xedit[i]->misc&EXPANDLF)) { - cfg.xedit[i]->misc|=EXPANDLF; - uifc.changes=TRUE; } - else if(k==1 && cfg.xedit[i]->misc&EXPANDLF) { - cfg.xedit[i]->misc&=~EXPANDLF; - uifc.changes=TRUE; } - break; - case 10: - k=cfg.xedit[i]->misc&STRIPKLUDGE ? 0:1; - strcpy(opt[0],"Yes"); - strcpy(opt[1],"No"); - opt[2][0]=0; - SETHELP(WHERE); -/* -Strip FidoNet Kludge Lines From Messages: - -If this external editor adds FidoNet Kludge lines to the message text, -set this option to Yes to strip those lines from the message. -*/ - k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0 - ,"Strip FidoNet Kludge Lines" - ,opt); - if(!k && !(cfg.xedit[i]->misc&STRIPKLUDGE)) { - cfg.xedit[i]->misc|=STRIPKLUDGE; - uifc.changes=TRUE; } - else if(k==1 && cfg.xedit[i]->misc&STRIPKLUDGE) { - cfg.xedit[i]->misc&=~STRIPKLUDGE; - uifc.changes=TRUE; } - break; - case 11: - k=0; - strcpy(opt[k++],"None"); - sprintf(opt[k++],"%-15s %s","Synchronet","XTRN.DAT"); - sprintf(opt[k++],"%-15s %s","WWIV","CHAIN.TXT"); - sprintf(opt[k++],"%-15s %s","GAP","DOOR.SYS"); - sprintf(opt[k++],"%-15s %s","RBBS/QuickBBS","DORINFO#.DEF"); - sprintf(opt[k++],"%-15s %s","Wildcat","CALLINFO.BBS"); - sprintf(opt[k++],"%-15s %s","PCBoard","PCBOARD.SYS"); - sprintf(opt[k++],"%-15s %s","SpitFire","SFDOORS.DAT"); - sprintf(opt[k++],"%-15s %s","MegaMail","UTIDOOR.TXT"); - sprintf(opt[k++],"%-15s %s","Solar Realms","DOORFILE.SR"); - sprintf(opt[k++],"%-15s %s","RBBS/QuickBBS","DORINFO1.DEF"); - sprintf(opt[k++],"%-15s %s","TriBBS","TRIBBS.SYS"); - sprintf(opt[k++],"%-15s %s","Mystic","DOOR32.SYS"); - opt[k][0]=0; - k=cfg.xedit[i]->type; - SETHELP(WHERE); -/* -External Program BBS Drop File Type: - -If this external editor requires a specific BBS data (drop) file -format, select the file format from the list. -*/ - k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0 - ,"BBS Drop File Type",opt); - if(k==-1) - break; - if(cfg.xedit[i]->type!=k) { - cfg.xedit[i]->type=k; - if(cfg.xedit[i]->type==XTRN_DOOR32) - cfg.xedit[i]->misc|=XTRN_NATIVE; - uifc.changes=TRUE; - } - if(cfg.xedit[i]->type) { - strcpy(opt[0],"Yes"); - strcpy(opt[1],"No"); - opt[2][0]=0; - k=cfg.xedit[i]->misc&XTRN_LWRCASE ? 0:1; - k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0,"Lowercase Filename",opt); - if(k==0 && !(cfg.xedit[i]->misc&XTRN_LWRCASE)) { - cfg.xedit[i]->misc|=XTRN_LWRCASE; - uifc.changes=TRUE; - } - else if(k==1 && cfg.xedit[i]->misc&XTRN_LWRCASE) { - cfg.xedit[i]->misc&=~XTRN_LWRCASE; - uifc.changes=TRUE; - } - } - break; - - } } } -} - -int natvpgm_cfg() -{ - static int dflt,bar; - char str[81]; - int j; - uint i; - -while(1) { - for(i=0;iname); - opt[i][0]=0; - j=WIN_ACT|WIN_CHE|WIN_L2R|WIN_SAV; - if(cfg.total_natvpgms) - j|=WIN_DEL; - if(cfg.total_natvpgmsi;j--) - cfg.natvpgm[j]=cfg.natvpgm[j-1]; - if((cfg.natvpgm[i]=(natvpgm_t *)malloc(sizeof(natvpgm_t)))==NULL) { - errormsg(WHERE,ERR_ALLOC,nulstr,sizeof(natvpgm_t)); - continue; } - memset((natvpgm_t *)cfg.natvpgm[i],0,sizeof(natvpgm_t)); - strcpy(cfg.natvpgm[i]->name,str); - cfg.total_natvpgms++; - uifc.changes=TRUE; - continue; } - if((i&MSK_ON)==MSK_DEL) { - i&=MSK_OFF; - free(cfg.natvpgm[i]); - cfg.total_natvpgms--; - for(j=i;jname); - if(uifc.input(WIN_MID|WIN_SAV,0,5,"Native (32-bit) Program Name",str,12 - ,K_EDIT)>0) - strcpy(cfg.natvpgm[i]->name,str); - } -return(0); -} - - -void xtrnsec_cfg() -{ - static int xtrnsec_dflt,xtrnsec_opt; - char str[81],code[9],done=0,*p; - int j,k; - uint i; - static xtrnsec_t savxtrnsec; - -while(1) { - for(i=0;iname); - opt[i][0]=0; - j=WIN_SAV|WIN_ACT|WIN_CHE|WIN_BOT; - if(cfg.total_xtrnsecs) - j|=WIN_DEL|WIN_GET; - if(cfg.total_xtrnsecsi;j--) - cfg.xtrnsec[j]=cfg.xtrnsec[j-1]; - for(j=0;jsec>=i) - cfg.xtrn[j]->sec++; } - - - if((cfg.xtrnsec[i]=(xtrnsec_t *)malloc(sizeof(xtrnsec_t)))==NULL) { - errormsg(WHERE,ERR_ALLOC,nulstr,sizeof(xtrnsec_t)); - continue; } - memset((xtrnsec_t *)cfg.xtrnsec[i],0,sizeof(xtrnsec_t)); - strcpy(cfg.xtrnsec[i]->name,str); - strcpy(cfg.xtrnsec[i]->code,code); - cfg.total_xtrnsecs++; - uifc.changes=TRUE; - continue; } - if((i&MSK_ON)==MSK_DEL) { - i&=MSK_OFF; - free(cfg.xtrnsec[i]); - for(j=0;jsec==i) { /* delete xtrns of this group */ - free(cfg.xtrn[j]); - cfg.total_xtrns--; - k=j; - while(ksec>i) - cfg.xtrn[j]->sec--; - cfg.total_xtrnsecs--; - while(iname); - sprintf(opt[k++],"%-27.27s%s","Internal Code",cfg.xtrnsec[i]->code); - sprintf(opt[k++],"%-27.27s%.40s","Access Requirements" - ,cfg.xtrnsec[i]->arstr); - sprintf(opt[k++],"%s","Available Online Programs..."); - opt[k][0]=0; - sprintf(str,"%s Program Section",cfg.xtrnsec[i]->name); - switch(uifc.list(WIN_SAV|WIN_ACT|WIN_MID,0,0,60,&xtrnsec_opt,0,str - ,opt)) { - case -1: - done=1; - break; - case 0: - SETHELP(WHERE); -/* -Online Program Section Name: - -This is the name of this section. -*/ - strcpy(str,cfg.xtrnsec[i]->name); /* save */ - if(!uifc.input(WIN_MID|WIN_SAV,0,10 - ,"Program Section Name" - ,cfg.xtrnsec[i]->name,sizeof(cfg.xtrnsec[i]->name)-1,K_EDIT)) - strcpy(cfg.xtrnsec[i]->name,str); - break; - case 1: - strcpy(str,cfg.xtrnsec[i]->code); - SETHELP(WHERE); -/* -Online Program Section Internal Code: - -Every online program section must have its own unique internal code -for Synchronet to reference it by. It is helpful if this code is an -abreviation of the name. -*/ - uifc.input(WIN_MID|WIN_SAV,0,17,"Internal Code (unique)" - ,str,LEN_CODE,K_EDIT|K_UPPER); - if(code_ok(str)) - strcpy(cfg.xtrnsec[i]->code,str); - else { - uifc.helpbuf=invalid_code; - uifc.msg("Invalid Code"); - uifc.helpbuf=0; - } - break; - case 2: - getar(cfg.xtrnsec[i]->name,cfg.xtrnsec[i]->arstr); - break; - case 3: - xtrn_cfg(i); - break; - } - } - } -} - -void hotkey_cfg(void) -{ - static int dflt,dfltopt,bar; - char str[81],done=0; - int j,k; - uint i; - static hotkey_t savhotkey; - -while(1) { - for(i=0;ikey+'@' - ,cfg.hotkey[i]->cmd); - opt[i][0]=0; - j=WIN_SAV|WIN_ACT|WIN_CHE|WIN_RHT; - if(cfg.total_hotkeys) - j|=WIN_DEL|WIN_GET; - if(cfg.total_hotkeysi;j--) - cfg.hotkey[j]=cfg.hotkey[j-1]; - if((cfg.hotkey[i]=(hotkey_t *)malloc(sizeof(hotkey_t)))==NULL) { - errormsg(WHERE,ERR_ALLOC,nulstr,sizeof(hotkey_t)); - continue; } - memset((hotkey_t *)cfg.hotkey[i],0,sizeof(hotkey_t)); - cfg.hotkey[i]->key=str[0]-'@'; - cfg.total_hotkeys++; - uifc.changes=TRUE; - continue; } - if((i&MSK_ON)==MSK_DEL) { - i&=MSK_OFF; - free(cfg.hotkey[i]); - cfg.total_hotkeys--; - for(j=i;jkey+'@'); - sprintf(opt[k++],"%-27.27s%.40s","Command Line",cfg.hotkey[i]->cmd); - opt[k][0]=0; - SETHELP(WHERE); -/* -Global Hot Key Event: - -This menu allows you to change the settings for the selected global -hot key event. Hot key events are control characters that are used to -execute an external program or module anywhere in the BBS. -*/ - sprintf(str,"Ctrl-%c Hot Key Event",cfg.hotkey[i]->key+'@'); - switch(uifc.list(WIN_SAV|WIN_ACT|WIN_L2R|WIN_BOT,0,0,60,&dfltopt,0 - ,str,opt)) { - case -1: - done=1; - break; - case 0: - SETHELP(WHERE); -/* -Global Hot-Ctrl Key: - -This is the global control key used to execute this event. -*/ - sprintf(str,"%c",cfg.hotkey[i]->key+'@'); - if(uifc.input(WIN_MID|WIN_SAV,0,10,"Global Hot Ctrl-Key" - ,str,1,K_EDIT|K_UPPER)>0) - cfg.hotkey[i]->key=str[0]-'@'; - break; - case 1: - SETHELP(WHERE); -/* -Hot Key Event Command Line: - -This is the command line to execute when this hot key is pressed. -*/ - uifc.input(WIN_MID|WIN_SAV,0,10,"Command Line" - ,cfg.hotkey[i]->cmd,sizeof(cfg.hotkey[i]->cmd)-1,K_EDIT); - break; - } } } - -} +/* scfgxtrn.c */ + +/* $Id: scfgxtrn.c,v 1.1.1.2 2018/04/24 16:44:51 root Exp $ */ + +/**************************************************************************** + * @format.tab-size 4 (Plain Text/Source Code File Header) * + * @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) * + * * + * Copyright 2011 Rob Swindell - http://www.synchro.net/copyright.html * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * See the GNU General Public License for more details: gpl.txt or * + * http://www.fsf.org/copyleft/gpl.html * + * * + * Anonymous FTP access to the most recent released source is available at * + * ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net * + * * + * Anonymous CVS access to the development source and modification history * + * is available at cvs.synchro.net:/cvsroot/sbbs, example: * + * cvs -d :pserver:anonymous@cvs.synchro.net:/cvsroot/sbbs login * + * (just hit return, no password is necessary) * + * cvs -d :pserver:anonymous@cvs.synchro.net:/cvsroot/sbbs checkout src * + * * + * For Synchronet coding style and modification guidelines, see * + * http://www.synchro.net/source.html * + * * + * You are encouraged to submit any modifications (preferably in Unix diff * + * format) via e-mail to mods@synchro.net * + * * + * Note: If this box doesn't appear square, then you need to fix your tabs. * + ****************************************************************************/ +/****************************************************************************/ +/* Synchronet configuration utility */ +/****************************************************************************/ + +#include "scfg.h" + +char *daystr(char days); +static void hotkey_cfg(void); + +static char* monthstr(uint16_t months) +{ + int i; + static char str[256]; + + if(months==0) + return("Any"); + + str[0]=0; + for(i=0;i<12;i++) { + if((months&(1<code,cfg.event[i]->cmd); + opt[i][0]=0; + j=WIN_SAV|WIN_ACT|WIN_CHE|WIN_RHT; + if(cfg.total_events) + j|=WIN_DEL|WIN_GET; + if(cfg.total_eventscode,str); + cfg.event[i]->node=1; + cfg.event[i]->days=(uchar)0xff; + cfg.total_events++; + uifc.changes=1; + continue; + } + if((i&MSK_ON)==MSK_DEL) { + i&=MSK_OFF; + free(cfg.event[i]); + cfg.total_events--; + for(j=i;jcode); + sprintf(opt[k++],"%-32.32s%.40s","Start-up Directory",cfg.event[i]->dir); + sprintf(opt[k++],"%-32.32s%.40s","Command Line",cfg.event[i]->cmd); + sprintf(opt[k++],"%-32.32s%s","Enabled" + ,cfg.event[i]->misc&EVENT_DISABLED ? "No":"Yes"); + sprintf(opt[k++],"%-32.32s%u","Execution Node",cfg.event[i]->node); + sprintf(opt[k++],"%-32.32s%s","Execution Months" + ,monthstr(cfg.event[i]->months)); + sprintf(opt[k++],"%-32.32s%s","Execution Days of Month" + ,mdaystr(cfg.event[i]->mdays)); + sprintf(opt[k++],"%-32.32s%s","Execution Days of Week",daystr(cfg.event[i]->days)); + if(cfg.event[i]->freq) { + sprintf(str,"%u times a day",1440/cfg.event[i]->freq); + sprintf(opt[k++],"%-32.32s%s","Execution Frequency",str); + } else { + sprintf(str,"%2.2u:%2.2u" + ,cfg.event[i]->time/60,cfg.event[i]->time%60); + sprintf(opt[k++],"%-32.32s%s","Execution Time",str); + } + sprintf(opt[k++],"%-32.32s%s","Requires Exclusive Execution" + ,cfg.event[i]->misc&EVENT_EXCL ? "Yes":"No"); + sprintf(opt[k++],"%-32.32s%s","Force Users Off-line For Event" + ,cfg.event[i]->misc&EVENT_FORCE ? "Yes":"No"); + sprintf(opt[k++],"%-32.32s%s","Native Executable" + ,cfg.event[i]->misc&EX_NATIVE ? "Yes" : "No"); + sprintf(opt[k++],"%-32.32s%s","Use Shell to Execute" + ,cfg.event[i]->misc&XTRN_SH ? "Yes" : "No"); + sprintf(opt[k++],"%-32.32s%s","Background Execution" + ,cfg.event[i]->misc&EX_BG ? "Yes" : "No"); + sprintf(opt[k++],"%-32.32s%s","Always Run After Init/Re-init" + ,cfg.event[i]->misc&EVENT_INIT ? "Yes":"No"); + + opt[k][0]=0; + SETHELP(WHERE); +/* +`Timed Event:` + +This is the configuration menu for a timed event. An event is an +external program that performs some type of automated function on the +system. Use this menu to configure how and when this event will be +executed. + +If you need the BBS to swap out of memory for this event (to make more +available memory), add the program name (first word of the command line) +to `Global Swap List` from the `External Programs` menu. +*/ + sprintf(str,"%s Timed Event",cfg.event[i]->code); + switch(uifc.list(WIN_SAV|WIN_ACT|WIN_L2R|WIN_BOT,0,0,70,&dfltopt,0 + ,str,opt)) { + case -1: + done=1; + break; + case 0: + strcpy(str,cfg.event[i]->code); + SETHELP(WHERE); +/* +`Timed Event Internal Code:` + +Every timed event must have its own unique internal code for Synchronet +to reference it by. It is helpful if this code is an abreviation of the +command line. +*/ + uifc.input(WIN_MID|WIN_SAV,0,17,"Internal Code (unique)" + ,str,LEN_CODE,K_EDIT|K_UPPER); + if(code_ok(str)) + strcpy(cfg.event[i]->code,str); + else { + uifc.helpbuf=invalid_code; + uifc.msg("Invalid Code"); + uifc.helpbuf=0; + } + break; + case 1: + SETHELP(WHERE); +/* +`Timed Event Start-up Directory:` + +This is the DOS drive/directory where the event program is located. +If a path is specified here, it will be made the current directory +before the event's command line is executed. This eliminates the need +for batch files that just change the current drive and directory before +executing the event. + +If this option is not used, the current NODE's directory will be the +current DOS drive/directory before the command line is executed. +*/ + uifc.input(WIN_MID|WIN_SAV,0,10,"Directory" + ,cfg.event[i]->dir,sizeof(cfg.event[i]->dir)-1,K_EDIT); + break; + case 2: + SETHELP(WHERE); +/* +`Timed Event Command Line:` + +This is the command line to execute upon this timed event. +*/ + uifc.input(WIN_MID|WIN_SAV,0,10,"Command" + ,cfg.event[i]->cmd,sizeof(cfg.event[i]->cmd)-1,K_EDIT); + break; + + case 3: + k=(cfg.event[i]->misc&EVENT_DISABLED) ? 1:0; + SETHELP(WHERE); +/* +`Event Enabled:` + +If you want disable this event from executing, set this option to ~No~. +*/ + k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0 + ,"Enabled",uifcYesNoOpts); + if((k==0 && cfg.event[i]->misc&EVENT_DISABLED) + || (k==1 && !(cfg.event[i]->misc&EVENT_DISABLED))) { + cfg.event[i]->misc^=EVENT_DISABLED; + uifc.changes=1; + } + break; + + case 4: + SETHELP(WHERE); +/* +`Timed Event Node:` + +This is the node number to execute the timed event. +*/ + sprintf(str,"%u",cfg.event[i]->node); + uifc.input(WIN_MID|WIN_SAV,0,0,"Node Number" + ,str,3,K_EDIT|K_NUMBER); + cfg.event[i]->node=atoi(str); + break; + case 5: + SETHELP(WHERE); +/* +`Months to Execute Event:` + +Specifies the months (`Jan`-`Dec`, separated by spaces) on which +to execute this event, or `Any` to execute event for any/all months. +*/ + SAFECOPY(str,monthstr(cfg.event[i]->months)); + uifc.input(WIN_MID|WIN_SAV,0,0,"Months to Execute Event (or Any)" + ,str,50,K_EDIT); + cfg.event[i]->months=0; + for(p=str;*p;p++) { + if(atoi(p)) { + cfg.event[i]->months|=(1<<(atoi(p)-1)); + while(*p && isdigit(*p)) + p++; + } else { + for(j=0;j<12;j++) + if(strnicmp(mon[j],p,3)==0) { + cfg.event[i]->months|=(1<mdays)); + uifc.input(WIN_MID|WIN_SAV,0,0,"Days of Month to Execute Event (or Any)" + ,str,16,K_EDIT); + cfg.event[i]->mdays=0; + for(p=str;*p;p++) { + if(!isdigit(*p)) + continue; + cfg.event[i]->mdays|=(1<days&(1<days=(uchar)0xff; + else if(k==8) + cfg.event[i]->days=0; + else + cfg.event[i]->days^=(1<freq==0) + k=0; + else + k=1; + SETHELP(WHERE); +/* +`Execute Event at a Specific Time:` + +If you want the system execute this event at a specific time, set +this option to `Yes`. If you want the system to execute this event more +than once a day at predetermined intervals, set this option to `No`. +*/ + k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0 + ,"Execute Event at a Specific Time",uifcYesNoOpts); + if(k==0) { + sprintf(str,"%2.2u:%2.2u",cfg.event[i]->time/60 + ,cfg.event[i]->time%60); + SETHELP(WHERE); +/* +`Time to Execute Event:` + +This is the time (in 24 hour HH:MM format) to execute the event. +*/ + if(uifc.input(WIN_MID|WIN_SAV,0,0 + ,"Time to Execute Event (HH:MM)" + ,str,5,K_UPPER|K_EDIT)>0) { + cfg.event[i]->freq=0; + cfg.event[i]->time=atoi(str)*60; + if((p=strchr(str,':'))!=NULL) + cfg.event[i]->time+=atoi(p+1); + } + } + else if(k==1) { + sprintf(str,"%u" + ,cfg.event[i]->freq && cfg.event[i]->freq<=1440 + ? 1440/cfg.event[i]->freq : 0); + SETHELP(WHERE); +/* +`Number of Executions Per Day:` + +This is the maximum number of times the system will execute this event +per day. +*/ + if(uifc.input(WIN_MID|WIN_SAV,0,0 + ,"Number of Executions Per Day" + ,str,4,K_NUMBER|K_EDIT)>0) { + cfg.event[i]->time=0; + k=atoi(str); + if(k && k<=1440) + cfg.event[i]->freq=1440/k; + else + cfg.event[i]->freq=0; + } + } + break; + case 9: + k=(cfg.event[i]->misc&EVENT_EXCL) ? 0:1; + SETHELP(WHERE); +/* +`Exclusive Event Execution:` + +If this event must be run exclusively (all nodes inactive), set this +option to `Yes`. +*/ + k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0,"Exclusive Execution" + ,uifcYesNoOpts); + if(!k && !(cfg.event[i]->misc&EVENT_EXCL)) { + cfg.event[i]->misc|=EVENT_EXCL; + uifc.changes=1; + } + else if(k==1 && cfg.event[i]->misc&EVENT_EXCL) { + cfg.event[i]->misc&=~EVENT_EXCL; + uifc.changes=1; + } + break; + case 10: + k=(cfg.event[i]->misc&EVENT_FORCE) ? 0:1; + SETHELP(WHERE); +/* +`Force Users Off-line for Event:` + +If you want to have your users' on-line time reduced so the event can +execute precisely on time, set this option to `Yes`. +*/ + k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0 + ,"Force Users Off-line for Event",uifcYesNoOpts); + if(!k && !(cfg.event[i]->misc&EVENT_FORCE)) { + cfg.event[i]->misc|=EVENT_FORCE; + uifc.changes=1; + } + else if(k==1 && (cfg.event[i]->misc&EVENT_FORCE)) { + cfg.event[i]->misc&=~EVENT_FORCE; + uifc.changes=1; + } + break; + + case 11: + k=(cfg.event[i]->misc&EX_NATIVE) ? 0:1; + SETHELP(WHERE); +/* +`Native Executable:` + +If this event program is a native (e.g. non-DOS) executable, +set this option to `Yes`. +*/ + k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0 + ,"Native",uifcYesNoOpts); + if(!k && !(cfg.event[i]->misc&EX_NATIVE)) { + cfg.event[i]->misc|=EX_NATIVE; + uifc.changes=TRUE; + } + else if(k==1 && (cfg.event[i]->misc&EX_NATIVE)) { + cfg.event[i]->misc&=~EX_NATIVE; + uifc.changes=TRUE; + } + break; + + case 12: + k=(cfg.event[i]->misc&XTRN_SH) ? 0:1; + SETHELP(WHERE); +/* +`Use Shell to Execute Command:` + +If this command-line requires the system command shell to execute, (Unix +shell script or DOS batch file), set this option to ~Yes~. +*/ + k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0 + ,"Use Shell",uifcYesNoOpts); + if(!k && !(cfg.event[i]->misc&XTRN_SH)) { + cfg.event[i]->misc|=XTRN_SH; + uifc.changes=TRUE; + } + else if(k==1 && (cfg.event[i]->misc&XTRN_SH)) { + cfg.event[i]->misc&=~XTRN_SH; + uifc.changes=TRUE; + } + break; + + case 13: + k=(cfg.event[i]->misc&EX_BG) ? 0:1; + SETHELP(WHERE); +/* +`Execute Event in Background (Asynchronously):` + +If you would like this event to run simultaneously with other events, +set this option to `Yes`. Exclusive events will not run in the background. +*/ + k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0 + ,"Background (Asynchronous) Execution",uifcYesNoOpts); + if(!k && !(cfg.event[i]->misc&EX_BG)) { + cfg.event[i]->misc|=EX_BG; + uifc.changes=TRUE; + } + else if(k==1 && (cfg.event[i]->misc&EX_BG)) { + cfg.event[i]->misc&=~EX_BG; + uifc.changes=TRUE; + } + break; + + case 14: + k=(cfg.event[i]->misc&EVENT_INIT) ? 0:1; + SETHELP(WHERE); +/* +`Always Run After Initialization or Re-initialization:` + +If you want this event to always run after the BBS is initialized or +re-initialized, set this option to ~Yes~. +*/ + k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0 + ,"Always Run After Initialization or Re-initialization",uifcYesNoOpts); + if(!k && !(cfg.event[i]->misc&EVENT_INIT)) { + cfg.event[i]->misc|=EVENT_INIT; + uifc.changes=1; + } + else if(k==1 && (cfg.event[i]->misc&EVENT_INIT)) { + cfg.event[i]->misc&=~EVENT_INIT; + uifc.changes=1; + } + break; + } + } + } +} + + +void xtrn_cfg(uint section) +{ + static int ext_dflt,ext_bar,sub_bar,opt_dflt,time_dflt; + char str[128],code[9],done=0,*p; + int j,k; + uint i,n,xtrnnum[MAX_OPTS+1]; + static xtrn_t savxtrn; + + sub_bar=0; + opt_dflt=0; + +while(1) { + for(i=0,j=0;isec==section) { + sprintf(opt[j],"%-25s",cfg.xtrn[i]->name); + xtrnnum[j++]=i; + } + xtrnnum[j]=cfg.total_xtrns; + opt[j][0]=0; + i=WIN_ACT|WIN_CHE|WIN_SAV|WIN_RHT; + if(j) + i|=WIN_DEL|WIN_GET; + if(cfg.total_xtrnsname); + i=uifc.list(i,0,0,45,&ext_dflt,&ext_bar,str,opt); + if((signed)i==-1) + return; + if((i&MSK_ON)==MSK_INS) { + i&=MSK_OFF; + SETHELP(WHERE); +/* +`Online Program Name:` + +This is the name or description of the online program (door). +*/ + if(uifc.input(WIN_MID|WIN_SAV,0,0,"Online Program Name",str,25 + ,0)<1) + continue; + sprintf(code,"%.8s",str); + p=strchr(code,' '); + if(p) *p=0; + strupr(code); + SETHELP(WHERE); +/* +`Online Program Internal Code:` + +Every online program must have its own unique code for Synchronet to +refer to it internally. This code is usually an abreviation of the +online program name. +*/ + if(uifc.input(WIN_MID|WIN_SAV,0,0,"Internal Code" + ,code,LEN_CODE,K_EDIT|K_UPPER)<1) + continue; + if(!code_ok(code)) { + uifc.helpbuf=invalid_code; + uifc.msg("Invalid Code"); + uifc.helpbuf=0; + continue; + } + if((cfg.xtrn=(xtrn_t **)realloc(cfg.xtrn,sizeof(xtrn_t *)*(cfg.total_xtrns+1))) + ==NULL) { + errormsg(WHERE,ERR_ALLOC,nulstr,cfg.total_xtrns+1); + cfg.total_xtrns=0; + bail(1); + continue; + } + if(j) + for(n=cfg.total_xtrns;n>xtrnnum[i];n--) + cfg.xtrn[n]=cfg.xtrn[n-1]; + if((cfg.xtrn[xtrnnum[i]]=(xtrn_t *)malloc(sizeof(xtrn_t)))==NULL) { + errormsg(WHERE,ERR_ALLOC,nulstr,sizeof(xtrn_t)); + continue; + } + memset((xtrn_t *)cfg.xtrn[xtrnnum[i]],0,sizeof(xtrn_t)); + strcpy(cfg.xtrn[xtrnnum[i]]->name,str); + strcpy(cfg.xtrn[xtrnnum[i]]->code,code); + cfg.xtrn[xtrnnum[i]]->sec=section; + cfg.total_xtrns++; + uifc.changes=TRUE; + continue; + } + if((i&MSK_ON)==MSK_DEL) { + i&=MSK_OFF; + free(cfg.xtrn[xtrnnum[i]]); + cfg.total_xtrns--; + for(j=xtrnnum[i];jsec=section; + uifc.changes=TRUE; + continue; + } + done=0; + i=xtrnnum[i]; + while(!done) { + k=0; + sprintf(opt[k++],"%-27.27s%s","Name",cfg.xtrn[i]->name); + sprintf(opt[k++],"%-27.27s%s","Internal Code",cfg.xtrn[i]->code); + sprintf(opt[k++],"%-27.27s%.40s","Start-up Directory",cfg.xtrn[i]->path); + sprintf(opt[k++],"%-27.27s%.40s","Command Line",cfg.xtrn[i]->cmd); + sprintf(opt[k++],"%-27.27s%.40s","Clean-up Command Line",cfg.xtrn[i]->clean); + if(cfg.xtrn[i]->cost) + sprintf(str,"%lu credits",cfg.xtrn[i]->cost); + else + strcpy(str,"None"); + sprintf(opt[k++],"%-27.27s%s","Execution Cost",str); + sprintf(opt[k++],"%-27.27s%.40s","Access Requirements",cfg.xtrn[i]->arstr); + sprintf(opt[k++],"%-27.27s%.40s","Execution Requirements" + ,cfg.xtrn[i]->run_arstr); + sprintf(opt[k++],"%-27.27s%s","Multiple Concurrent Users" + ,cfg.xtrn[i]->misc&MULTIUSER ? "Yes" : "No"); + sprintf(opt[k++],"%-27.27s%s%s%s","Intercept I/O" + ,cfg.xtrn[i]->misc&XTRN_STDIO ? "Standard" + : cfg.xtrn[i]->misc&XTRN_CONIO ? "Console":"No" + ,(cfg.xtrn[i]->misc&(XTRN_STDIO|WWIVCOLOR)) + ==(XTRN_STDIO|WWIVCOLOR) ? ", WWIV Color" : nulstr + ,(cfg.xtrn[i]->misc&(XTRN_STDIO|XTRN_NOECHO)) + ==(XTRN_STDIO|XTRN_NOECHO) ? ", No Echo" : nulstr); + sprintf(opt[k++],"%-27.27s%s","Native Executable" + ,cfg.xtrn[i]->misc&XTRN_NATIVE ? "Yes" : "No"); + sprintf(opt[k++],"%-27.27s%s","Use Shell to Execute" + ,cfg.xtrn[i]->misc&XTRN_SH ? "Yes" : "No"); + sprintf(opt[k++],"%-27.27s%s","Modify User Data" + ,cfg.xtrn[i]->misc&MODUSERDAT ? "Yes" : "No"); + switch(cfg.xtrn[i]->event) { + case EVENT_LOGON: + strcpy(str,"Logon"); + break; + case EVENT_LOGOFF: + strcpy(str,"Logoff"); + break; + case EVENT_NEWUSER: + strcpy(str,"New User"); + break; + case EVENT_BIRTHDAY: + strcpy(str,"Birthday"); + break; + case EVENT_POST: + strcpy(str,"Message Posted"); + break; + case EVENT_UPLOAD: + strcpy(str,"File Uploaded"); + break; + case EVENT_DOWNLOAD: + strcpy(str,"File Downloaded"); + break; + default: + strcpy(str,"No"); + break; + } + if((cfg.xtrn[i]->misc&EVENTONLY) && cfg.xtrn[i]->event) + strcat(str,", Only"); + sprintf(opt[k++],"%-27.27s%s","Execute on Event",str); + sprintf(opt[k++],"%-27.27s%s","Pause After Execution" + ,cfg.xtrn[i]->misc&XTRN_PAUSE ? "Yes" : "No"); + sprintf(opt[k++],"%-23.23s%-4s%s","BBS Drop File Type" + ,cfg.xtrn[i]->misc&REALNAME ? "(R)":nulstr + ,dropfile(cfg.xtrn[i]->type,cfg.xtrn[i]->misc)); + sprintf(opt[k++],"%-27.27s%s","Place Drop File In" + ,cfg.xtrn[i]->misc&STARTUPDIR ? "Start-Up Directory":"Node Directory"); + sprintf(opt[k++],"Time Options..."); + opt[k][0]=0; + SETHELP(WHERE); +/* +`Online Program Configuration:` + +This menu is for configuring the selected online program. +*/ + switch(uifc.list(WIN_SAV|WIN_ACT|WIN_MID,0,0,60,&opt_dflt,&sub_bar,cfg.xtrn[i]->name + ,opt)) { + case -1: + done=1; + break; + case 0: + SETHELP(WHERE); +/* +`Online Program Name:` + +This is the name or description of the online program (door). +*/ + strcpy(str,cfg.xtrn[i]->name); + if(!uifc.input(WIN_MID|WIN_SAV,0,10,"Online Program Name" + ,cfg.xtrn[i]->name,sizeof(cfg.xtrn[i]->name)-1,K_EDIT)) + strcpy(cfg.xtrn[i]->name,str); + break; + case 1: + SETHELP(WHERE); +/* +`Online Program Internal Code:` + +Every online program must have its own unique code for Synchronet to +refer to it internally. This code is usually an abreviation of the +online program name. +*/ + strcpy(str,cfg.xtrn[i]->code); + uifc.input(WIN_MID|WIN_SAV,0,10,"Internal Code" + ,str,LEN_CODE,K_UPPER|K_EDIT); + if(code_ok(str)) + strcpy(cfg.xtrn[i]->code,str); + else { + uifc.helpbuf=invalid_code; + uifc.msg("Invalid Code"); + uifc.helpbuf=0; + } + break; + case 2: + SETHELP(WHERE); +/* +`Online Program Start-up Directory:` + +This is the DOS drive/directory where the online program is located. +If a path is specified here, it will be made the current directory +before the program's command line is executed. This eliminates the need +for batch files that just change the current drive and directory before +executing the program. + +If this option is not used, the current NODE's directory will be the +current DOS drive/directory before the command line is executed. +*/ + uifc.input(WIN_MID|WIN_SAV,0,10,"" + ,cfg.xtrn[i]->path,sizeof(cfg.xtrn[i]->path)-1,K_EDIT); + break; + case 3: + SETHELP(WHERE); +/* +`Online Program Command Line:` + +This is the command line to execute to run the online program. +*/ + uifc.input(WIN_MID|WIN_SAV,0,10,"Command" + ,cfg.xtrn[i]->cmd,sizeof(cfg.xtrn[i]->cmd)-1,K_EDIT); + break; + case 4: + SETHELP(WHERE); +/* +`Online Program Clean-up Command:` + +This is the command line to execute after the main command line. This +option is usually only used for multiuser online programs. +*/ + uifc.input(WIN_MID|WIN_SAV,0,10,"Clean-up" + ,cfg.xtrn[i]->clean,sizeof(cfg.xtrn[i]->clean)-1,K_EDIT); + break; + case 5: + ultoa(cfg.xtrn[i]->cost,str,10); + SETHELP(WHERE); +/* +`Online Program Cost to Run:` + +If you want users to be charged credits to run this online program, +set this value to the number of credits to charge. If you want this +online program to be free, set this value to `0`. +*/ + uifc.input(WIN_MID|WIN_SAV,0,0,"Cost to Run (in Credits)" + ,str,10,K_EDIT|K_NUMBER); + cfg.xtrn[i]->cost=atol(str); + break; + case 6: + sprintf(str,"%s Access",cfg.xtrn[i]->name); + getar(str,cfg.xtrn[i]->arstr); + break; + case 7: + sprintf(str,"%s Execution",cfg.xtrn[i]->name); + getar(str,cfg.xtrn[i]->run_arstr); + break; + case 8: + k=(cfg.xtrn[i]->misc&MULTIUSER) ? 0:1; + SETHELP(WHERE); +/* +`Supports Multiple Users:` + +If this online program supports multiple simultaneous users (nodes), +set this option to `Yes`. +*/ + k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0,"Supports Multiple Users" + ,uifcYesNoOpts); + if(!k && !(cfg.xtrn[i]->misc&MULTIUSER)) { + cfg.xtrn[i]->misc|=MULTIUSER; + uifc.changes=TRUE; + } + else if(k==1 && (cfg.xtrn[i]->misc&MULTIUSER)) { + cfg.xtrn[i]->misc&=~MULTIUSER; + uifc.changes=TRUE; + } + break; + case 9: + switch(cfg.xtrn[i]->misc&(XTRN_STDIO|XTRN_CONIO)) { + case XTRN_STDIO: + k=0; + break; + case XTRN_CONIO: + k=1; + break; + default: + k=2; + } + strcpy(opt[0],"Standard"); + strcpy(opt[1],"Console"); + strcpy(opt[2],"No"); + opt[3][0]=0; + SETHELP(WHERE); +/* +`Intercept I/O:` + +If this online program uses a FOSSIL driver or SOCKET communications, +set this option to `No`. +*/ + switch(uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0,"Intercept I/O" + ,opt)) { + case 0: /* Standard I/O */ + if((cfg.xtrn[i]->misc&(XTRN_STDIO|XTRN_CONIO)) != XTRN_STDIO) { + cfg.xtrn[i]->misc|=XTRN_STDIO; + cfg.xtrn[i]->misc&=~XTRN_CONIO; + uifc.changes=1; + } + k=(cfg.xtrn[i]->misc&WWIVCOLOR) ? 0:1; + SETHELP(WHERE); +/* +.Program Uses WWIV Color Codes:. + +If this program was written for use exclusively under WWIV, set this +option to .Yes.. +*/ + k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0 + ,"Program Uses WWIV Color Codes" + ,uifcYesNoOpts); + if(!k && !(cfg.xtrn[i]->misc&WWIVCOLOR)) { + cfg.xtrn[i]->misc|=WWIVCOLOR; + uifc.changes=TRUE; + } + else if(k==1 && (cfg.xtrn[i]->misc&WWIVCOLOR)) { + cfg.xtrn[i]->misc&=~WWIVCOLOR; + uifc.changes=TRUE; + } + k=(cfg.xtrn[i]->misc&XTRN_NOECHO) ? 1:0; + SETHELP(WHERE); +/* +`Echo Input:` + +If you want the BBS to copy ("echo") all keyboard input to the screen +output, set this option to ~Yes~ (for native Win32 programs only). +*/ + k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0 + ,"Echo Keyboard Input" + ,uifcYesNoOpts); + if(!k && (cfg.xtrn[i]->misc&XTRN_NOECHO)) { + cfg.xtrn[i]->misc&=~XTRN_NOECHO; + uifc.changes=TRUE; + } else if(k==1 && !(cfg.xtrn[i]->misc&XTRN_NOECHO)) { + cfg.xtrn[i]->misc|=XTRN_NOECHO; + uifc.changes=TRUE; + } + break; + case 1: /* Console I/O */ + if((cfg.xtrn[i]->misc&(XTRN_STDIO|XTRN_CONIO)) != XTRN_CONIO) { + cfg.xtrn[i]->misc|=XTRN_CONIO; + cfg.xtrn[i]->misc&=~(XTRN_STDIO|WWIVCOLOR|XTRN_NOECHO); + uifc.changes=TRUE; + } + break; + case 2: /* No */ + if((cfg.xtrn[i]->misc&(XTRN_STDIO|XTRN_CONIO)) != 0) { + cfg.xtrn[i]->misc&=~(XTRN_CONIO|XTRN_STDIO|WWIVCOLOR|XTRN_NOECHO); + uifc.changes=TRUE; + } + break; + } + break; + case 10: + k=(cfg.xtrn[i]->misc&XTRN_NATIVE) ? 0:1; + SETHELP(WHERE); +/* +`Native Executable:` + +If this online program is a native (e.g. non-DOS) executable, +set this option to `Yes`. +*/ + k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0 + ,"Native",uifcYesNoOpts); + if(!k && !(cfg.xtrn[i]->misc&XTRN_NATIVE)) { + cfg.xtrn[i]->misc|=XTRN_NATIVE; + uifc.changes=TRUE; + } + else if(k==1 && (cfg.xtrn[i]->misc&XTRN_NATIVE)) { + cfg.xtrn[i]->misc&=~XTRN_NATIVE; + uifc.changes=TRUE; + } + break; + case 11: + k=(cfg.xtrn[i]->misc&XTRN_SH) ? 0:1; + SETHELP(WHERE); +/* +`Use Shell to Execute Command:` + +If this command-line requires the system command shell to execute, (Unix +shell script or DOS batch file), set this option to ~Yes~. +*/ + k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0 + ,"Use Shell",uifcYesNoOpts); + if(!k && !(cfg.xtrn[i]->misc&XTRN_SH)) { + cfg.xtrn[i]->misc|=XTRN_SH; + uifc.changes=TRUE; + } + else if(k==1 && (cfg.xtrn[i]->misc&XTRN_SH)) { + cfg.xtrn[i]->misc&=~XTRN_SH; + uifc.changes=TRUE; + } + break; + case 12: + k=(cfg.xtrn[i]->misc&MODUSERDAT) ? 0:1; + SETHELP(WHERE); +/* +`Program Can Modify User Data:` + +If this online programs recognizes the Synchronet MODUSER.DAT format +or the RBBS/QuickBBS EXITINFO.BBS format and you want it to be able to +modify the data of users who run the program, set this option to `Yes`. +*/ + k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0 + ,"Program Can Modify User Data",uifcYesNoOpts); + if(!k && !(cfg.xtrn[i]->misc&MODUSERDAT)) { + cfg.xtrn[i]->misc|=MODUSERDAT; + uifc.changes=TRUE; + } + else if(k==1 && (cfg.xtrn[i]->misc&MODUSERDAT)) { + cfg.xtrn[i]->misc&=~MODUSERDAT; + uifc.changes=TRUE; + } + break; + case 13: + k=0; + strcpy(opt[k++],"No"); + strcpy(opt[k++],"Logon"); + strcpy(opt[k++],"Logoff"); + strcpy(opt[k++],"New User"); + strcpy(opt[k++],"Birthday"); + strcpy(opt[k++],"Message Posted"); + strcpy(opt[k++],"File Uploaded"); + strcpy(opt[k++],"File Downloaded"); + opt[k][0]=0; + k=cfg.xtrn[i]->event; + SETHELP(WHERE); +/* +`Execute Online Program on Event:` + +If you would like this online program to automatically execute on a +specific user event, select the event. Otherwise, select `No`. +*/ + k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0 + ,"Execute on Event",opt); + if(k==-1) + break; + if(cfg.xtrn[i]->event!=k) { + cfg.xtrn[i]->event=k; + uifc.changes=TRUE; + } + if(!cfg.xtrn[i]->event) { + if(cfg.xtrn[i]->misc&EVENTONLY) { + cfg.xtrn[i]->misc&=~EVENTONLY; + uifc.changes=TRUE; + } + break; + } + k=(cfg.xtrn[i]->misc&EVENTONLY) ? 0:1; + SETHELP(WHERE); +/* +`Execute Online Program as Event Only:` + +If you would like this online program to execute as an event only +(not available to users on the online program menu), set this option +to `Yes`. +*/ + k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k + ,0,"Execute as Event Only" + ,uifcYesNoOpts); + if(!k && !(cfg.xtrn[i]->misc&EVENTONLY)) { + cfg.xtrn[i]->misc|=EVENTONLY; + uifc.changes=TRUE; + } + else if(k==1 && (cfg.xtrn[i]->misc&EVENTONLY)) { + cfg.xtrn[i]->misc&=~EVENTONLY; + uifc.changes=TRUE; + } + break; + case 14: + k=(cfg.xtrn[i]->misc&XTRN_PAUSE) ? 0:1; + SETHELP(WHERE); +/* +`Pause Screen After Execution:` + +Set this option to ~Yes~ if you would like an automatic screen pause +(`[Hit a key]` prompt) to appear after the program executes. + +This can be useful if the program displays information just before exiting +or you want to debug a program with a program not running correctly. +*/ + k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0 + ,"Pause After Execution",uifcYesNoOpts); + if((!k && !(cfg.xtrn[i]->misc&XTRN_PAUSE)) + || (k && (cfg.xtrn[i]->misc&XTRN_PAUSE))) { + cfg.xtrn[i]->misc^=XTRN_PAUSE; + uifc.changes=TRUE; + } + break; + case 15: + k=0; + strcpy(opt[k++],"None"); + sprintf(opt[k++],"%-15s %s","Synchronet","XTRN.DAT"); + sprintf(opt[k++],"%-15s %s","WWIV","CHAIN.TXT"); + sprintf(opt[k++],"%-15s %s","GAP","DOOR.SYS"); + sprintf(opt[k++],"%-15s %s","RBBS/QuickBBS","DORINFO#.DEF"); + sprintf(opt[k++],"%-15s %s","Wildcat","CALLINFO.BBS"); + sprintf(opt[k++],"%-15s %s","PCBoard","PCBOARD.SYS"); + sprintf(opt[k++],"%-15s %s","SpitFire","SFDOORS.DAT"); + sprintf(opt[k++],"%-15s %s","MegaMail","UTIDOOR.TXT"); + sprintf(opt[k++],"%-15s %s","Solar Realms","DOORFILE.SR"); + sprintf(opt[k++],"%-15s %s","RBBS/QuickBBS","DORINFO1.DEF"); + sprintf(opt[k++],"%-15s %s","TriBBS","TRIBBS.SYS"); + sprintf(opt[k++],"%-15s %s","Mystic","DOOR32.SYS"); + opt[k][0]=0; + k=cfg.xtrn[i]->type; + SETHELP(WHERE); +/* +`Online Program BBS Drop File Type:` + +If this online program requires a specific BBS data (drop) file +format, select the file format from the list. +*/ + k=uifc.list(WIN_MID|WIN_ACT,0,0,0,&k,0 + ,"BBS Drop File Type",opt); + if(k==-1) + break; + if(cfg.xtrn[i]->type!=k) { + cfg.xtrn[i]->type=k; + if(cfg.xtrn[i]->type==XTRN_DOOR32) + cfg.xtrn[i]->misc|=XTRN_NATIVE; + uifc.changes=TRUE; + } + if(cfg.xtrn[i]->type && cfg.uq&UQ_ALIASES) { + k=(cfg.xtrn[i]->misc&REALNAME) ? 0:1; + k=uifc.list(WIN_MID,0,0,0,&k,0,"Use Real Names",uifcYesNoOpts); + if(k==0 && !(cfg.xtrn[i]->misc&REALNAME)) { + cfg.xtrn[i]->misc|=REALNAME; + uifc.changes=TRUE; + } + else if(k==1 && (cfg.xtrn[i]->misc&REALNAME)) { + cfg.xtrn[i]->misc&=~REALNAME; + uifc.changes=TRUE; + } + } + if(cfg.xtrn[i]->type) { + k=(cfg.xtrn[i]->misc&XTRN_LWRCASE) ? 0:1; + k=uifc.list(WIN_MID,0,0,0,&k,0,"Lowercase Filename",uifcYesNoOpts); + if(k==0 && !(cfg.xtrn[i]->misc&XTRN_LWRCASE)) { + cfg.xtrn[i]->misc|=XTRN_LWRCASE; + uifc.changes=TRUE; + } + else if(k==1 && (cfg.xtrn[i]->misc&XTRN_LWRCASE)) { + cfg.xtrn[i]->misc&=~XTRN_LWRCASE; + uifc.changes=TRUE; + } + } + break; + case 16: + k=0; + strcpy(opt[0],"Node Directory"); + strcpy(opt[1],"Start-up Directory"); + opt[2][0]=0; + SETHELP(WHERE); +/* +`Directory for Drop File:` + +You can have the data file created in the current `Node Directory` or the +`Start-up Directory` (if one is specified). +*/ + k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0,"Create Drop File In" + ,opt); + if(!k && cfg.xtrn[i]->misc&STARTUPDIR) { + cfg.xtrn[i]->misc&=~STARTUPDIR; + uifc.changes=TRUE; + } + else if(k==1 && !(cfg.xtrn[i]->misc&STARTUPDIR)) { + cfg.xtrn[i]->misc|=STARTUPDIR; + uifc.changes=TRUE; + } + break; + case 17: + while(1) { + k=0; + if(cfg.xtrn[i]->textra) + sprintf(str,"%u minutes",cfg.xtrn[i]->textra); + else + strcpy(str,"None"); + sprintf(opt[k++],"%-25.25s%s","Extra Time",str); + if(cfg.xtrn[i]->maxtime) + sprintf(str,"%u minutes",cfg.xtrn[i]->maxtime); + else + strcpy(str,"None"); + sprintf(opt[k++],"%-25.25s%s","Maximum Time",str); + sprintf(opt[k++],"%-25.25s%s","Suspended (Free) Time" + ,cfg.xtrn[i]->misc&FREETIME ? "Yes" : "No"); + sprintf(opt[k++],"%-25.25s%s","Monitor Time Left" + ,cfg.xtrn[i]->misc&XTRN_CHKTIME ? "Yes" : "No"); + opt[k][0]=0; + SETHELP(WHERE); +/* +`Online Program Time Options:` + +This sub-menu allows you to define specific preferences regarding the +time users spend running this program. +*/ + k=uifc.list(WIN_SAV|WIN_ACT|WIN_RHT|WIN_BOT,0,0,40 + ,&time_dflt,0 + ,"Online Program Time Options",opt); + if(k==-1) + break; + switch(k) { + case 0: + ultoa(cfg.xtrn[i]->textra,str,10); + SETHELP(WHERE); +/* +`Extra Time to Give User in Program:` + +If you want to give users extra time while in this online program, +set this value to the number of minutes to add to their current time +left online. +*/ + uifc.input(WIN_MID|WIN_SAV,0,0 + ,"Extra Time to Give User (in minutes)" + ,str,2,K_EDIT|K_NUMBER); + cfg.xtrn[i]->textra=atoi(str); + break; + case 1: + ultoa(cfg.xtrn[i]->maxtime,str,10); + SETHELP(WHERE); +/* +`Maximum Time Allowed in Program:` + +If this program supports a drop file that contains the number of minutes +left online for the current user, this option allows the sysop to set +the maximum number of minutes that will be allowed in the drop file. + +Setting this option to `0`, disables this feature. +*/ + uifc.input(WIN_MID|WIN_SAV,0,0 + ,"Maximum Time (in minutes, 0=disabled)" + ,str,2,K_EDIT|K_NUMBER); + cfg.xtrn[i]->maxtime=atoi(str); + break; + case 2: + k=(cfg.xtrn[i]->misc&FREETIME) ? 0:1; + SETHELP(WHERE); +/* +`Suspended (Free) Time:` + +If you want the user's time online to be suspended while running this +online program (e.g. Free Time), set this option to `Yes`. +*/ + k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0 + ,"Suspended (Free) Time",uifcYesNoOpts); + if(!k && !(cfg.xtrn[i]->misc&FREETIME)) { + cfg.xtrn[i]->misc|=FREETIME; + uifc.changes=TRUE; + } + else if(k==1 && (cfg.xtrn[i]->misc&FREETIME)) { + cfg.xtrn[i]->misc&=~FREETIME; + uifc.changes=TRUE; + } + break; + case 3: + k=(cfg.xtrn[i]->misc&XTRN_CHKTIME) ? 0:1; + SETHELP(WHERE); +/* +`Monitor Time Left:` + +If you want Synchronet to monitor the user's time left online while this +program runs (and disconnect the user if their time runs out), set this +option to `Yes`. +*/ + k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0 + ,"Monitor Time Left",uifcYesNoOpts); + if(!k && !(cfg.xtrn[i]->misc&XTRN_CHKTIME)) { + cfg.xtrn[i]->misc|=XTRN_CHKTIME; + uifc.changes=TRUE; + } + else if(k==1 && (cfg.xtrn[i]->misc&XTRN_CHKTIME)) { + cfg.xtrn[i]->misc&=~XTRN_CHKTIME; + uifc.changes=TRUE; + } + break; + } + } + break; + } + } + } +} + +void xedit_cfg() +{ + static int dflt,dfltopt,bar; + char str[81],code[81],done=0,*p; + int j,k; + uint i; + static xedit_t savxedit; + +while(1) { + for(i=0;icode,cfg.xedit[i]->rcmd); + opt[i][0]=0; + j=WIN_SAV|WIN_ACT|WIN_CHE|WIN_RHT; + if(cfg.total_xedits) + j|=WIN_DEL|WIN_GET; + if(cfg.total_xeditsi;j--) + cfg.xedit[j]=cfg.xedit[j-1]; + if((cfg.xedit[i]=(xedit_t *)malloc(sizeof(xedit_t)))==NULL) { + errormsg(WHERE,ERR_ALLOC,nulstr,sizeof(xedit_t)); + continue; + } + memset((xedit_t *)cfg.xedit[i],0,sizeof(xedit_t)); + strcpy(cfg.xedit[i]->name,str); + strcpy(cfg.xedit[i]->code,code); + cfg.total_xedits++; + uifc.changes=TRUE; + continue; + } + if((i&MSK_ON)==MSK_DEL) { + i&=MSK_OFF; + free(cfg.xedit[i]); + cfg.total_xedits--; + for(j=i;jname); + sprintf(opt[k++],"%-32.32s%s","Internal Code",cfg.xedit[i]->code); + sprintf(opt[k++],"%-32.32s%.40s","Command Line",cfg.xedit[i]->rcmd); + sprintf(opt[k++],"%-32.32s%.40s","Access Requirements",cfg.xedit[i]->arstr); + sprintf(opt[k++],"%-32.32s%s%s","Intercept I/O" + ,cfg.xedit[i]->misc&XTRN_STDIO ? "Standard" + :cfg.xedit[i]->misc&XTRN_CONIO ? "Console":"No" + ,(cfg.xedit[i]->misc&(XTRN_STDIO|WWIVCOLOR)) + ==(XTRN_STDIO|WWIVCOLOR) ? ", WWIV Color" : nulstr); + sprintf(opt[k++],"%-32.32s%s","Native Executable" + ,cfg.xedit[i]->misc&XTRN_NATIVE ? "Yes" : "No"); + sprintf(opt[k++],"%-32.32s%s","Use Shell to Execute" + ,cfg.xedit[i]->misc&XTRN_SH ? "Yes" : "No"); + sprintf(opt[k++],"%-32.32s%s","Word Wrap Quoted Text" + ,cfg.xedit[i]->misc"EWRAP ? "Yes":"No"); + sprintf(opt[k++],"%-32.32s%s","Automatically Quoted Text" + ,cfg.xedit[i]->misc"EALL ? "All":cfg.xedit[i]->misc"ENONE + ? "None" : "Prompt User"); + sprintf(opt[k++],"%-32.32s%s","Editor Information Files" + ,cfg.xedit[i]->misc&QUICKBBS ? "QuickBBS MSGINF/MSGTMP":"WWIV EDITOR.INF/RESULT.ED"); + sprintf(opt[k++],"%-32.32s%s","Expand Line Feeds to CRLF" + ,cfg.xedit[i]->misc&EXPANDLF ? "Yes":"No"); + sprintf(opt[k++],"%-32.32s%s","Strip FidoNet Kludge Lines" + ,cfg.xedit[i]->misc&STRIPKLUDGE ? "Yes":"No"); + sprintf(opt[k++],"%-32.32s%s","BBS Drop File Type" + ,dropfile(cfg.xedit[i]->type,cfg.xedit[i]->misc)); + opt[k][0]=0; + SETHELP(WHERE); +/* +`External Editor Configuration:` + +This menu allows you to change the settings for the selected external +message editor. External message editors are very common on BBSs. Some +popular editors include `SyncEdit`, `WWIVedit`, `FEdit`, `GEdit`, `IceEdit`, +and many others. +*/ + + sprintf(str,"%s Editor",cfg.xedit[i]->name); + switch(uifc.list(WIN_SAV|WIN_ACT|WIN_L2R|WIN_BOT,0,0,70,&dfltopt,0 + ,str,opt)) { + case -1: + done=1; + break; + case 0: + SETHELP(WHERE); +/* +`External Editor Name:` + +This is the name or description of the external editor. +*/ + strcpy(str,cfg.xedit[i]->name); + if(!uifc.input(WIN_MID|WIN_SAV,0,10,"External Editor Name" + ,cfg.xedit[i]->name,sizeof(cfg.xedit[i]->name)-1,K_EDIT)) + strcpy(cfg.xedit[i]->name,str); + break; + case 1: + strcpy(str,cfg.xedit[i]->code); + SETHELP(WHERE); +/* +`External Editor Internal Code:` + +Every external editor must have its own unique internal code for +Synchronet to reference it by. It is helpful if this code is an +abreviation of the name. +*/ + uifc.input(WIN_MID|WIN_SAV,0,17,"Internal Code (unique)" + ,str,LEN_CODE,K_EDIT|K_UPPER); + if(code_ok(str)) + strcpy(cfg.xedit[i]->code,str); + else { + uifc.helpbuf=invalid_code; + uifc.msg("Invalid Code"); + uifc.helpbuf=0; + } + break; + case 2: + SETHELP(WHERE); +/* +`External Editor Command Line:` + +This is the command line to execute when using this editor. +*/ + uifc.input(WIN_MID|WIN_SAV,0,10,"Command" + ,cfg.xedit[i]->rcmd,sizeof(cfg.xedit[i]->rcmd)-1,K_EDIT); + break; + case 3: + sprintf(str,"%s External Editor",cfg.xedit[i]->name); + getar(str,cfg.xedit[i]->arstr); + break; + case 4: + switch(cfg.xedit[i]->misc&(XTRN_STDIO|XTRN_CONIO)) { + case XTRN_STDIO: + k=0; + break; + case XTRN_CONIO: + k=1; + break; + default: + k=2; + break; + } + strcpy(opt[0],"Standard"); + strcpy(opt[1],"Console"); + strcpy(opt[2],"No"); + opt[3][0]=0; + SETHELP(WHERE); +/* +`Intercept I/O:` + +If this program uses FOSSIL, Socket, or UART communications, +set this option to `No`. +*/ + switch(uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0,"Intercept I/O" ,opt)) { + case 0: /* Standard */ + if((cfg.xedit[i]->misc&(XTRN_STDIO|XTRN_CONIO)) != XTRN_STDIO) { + cfg.xedit[i]->misc|=XTRN_STDIO; + cfg.xedit[i]->misc&=~XTRN_CONIO; + uifc.changes=TRUE; + } + k=(cfg.xedit[i]->misc&WWIVCOLOR) ? 0:1; + SETHELP(WHERE); +/* +.Editor Uses WWIV Color Codes:. + +If this editor was written for use exclusively under WWIV, set this +option to .Yes.. +*/ + k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0 + ,"Editor Uses WWIV Color Codes",uifcYesNoOpts); + if(!k && !(cfg.xedit[i]->misc&WWIVCOLOR)) { + cfg.xedit[i]->misc|=WWIVCOLOR; + uifc.changes=TRUE; + } + else if(k==1 && (cfg.xedit[i]->misc&WWIVCOLOR)) { + cfg.xedit[i]->misc&=~WWIVCOLOR; + uifc.changes=TRUE; + } + break; + case 1: /* Console */ + if((cfg.xedit[i]->misc&(XTRN_STDIO|XTRN_CONIO)) != XTRN_CONIO) { + cfg.xedit[i]->misc|=XTRN_CONIO; + cfg.xedit[i]->misc&=~(XTRN_STDIO|WWIVCOLOR); + uifc.changes=TRUE; + } + break; + case 2: /* No */ + if((cfg.xedit[i]->misc&(XTRN_STDIO|XTRN_CONIO)) != 0) { + cfg.xedit[i]->misc&=~(XTRN_CONIO|XTRN_STDIO|WWIVCOLOR); + uifc.changes=TRUE; + } + break; + } + break; + case 5: + k=(cfg.xedit[i]->misc&XTRN_NATIVE) ? 0:1; + SETHELP(WHERE); +/* +`Native Executable:` + +If this editor is a native (non-DOS) executable, set this option to `Yes`. +*/ + k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0 + ,"Native",uifcYesNoOpts); + if(!k && !(cfg.xedit[i]->misc&XTRN_NATIVE)) { + cfg.xedit[i]->misc|=XTRN_NATIVE; + uifc.changes=TRUE; + } + else if(k==1 && (cfg.xedit[i]->misc&XTRN_NATIVE)) { + cfg.xedit[i]->misc&=~XTRN_NATIVE; + uifc.changes=TRUE; + } + break; + case 6: + k=(cfg.xedit[i]->misc&XTRN_SH) ? 0:1; + SETHELP(WHERE); +/* +`Use Shell to Execute Command:` + +If this command-line requires the system command shell to execute, (Unix +shell script or DOS batch file), set this option to ~Yes~. +*/ + k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0 + ,"Use Shell",uifcYesNoOpts); + if(!k && !(cfg.xedit[i]->misc&XTRN_SH)) { + cfg.xedit[i]->misc|=XTRN_SH; + uifc.changes=TRUE; + } else if(k==1 && (cfg.xedit[i]->misc&XTRN_SH)) { + cfg.xedit[i]->misc&=~XTRN_SH; + uifc.changes=TRUE; + } + break; + case 7: + k=(cfg.xedit[i]->misc"EWRAP) ? 0:1; + SETHELP(WHERE); +/* +`Word Wrap Quoted Text:` + +FIXME +*/ + switch(uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0 + ,"Word Wrap Quoted Text",uifcYesNoOpts)) { + case 0: + if(!(cfg.xedit[i]->misc"EWRAP)) { + cfg.xedit[i]->misc|=QUOTEWRAP; + uifc.changes=TRUE; + } + break; + case 1: + if(cfg.xedit[i]->misc"EWRAP) { + cfg.xedit[i]->misc&=~QUOTEWRAP; + uifc.changes=TRUE; + } + break; + } + break; + case 8: + k=3; + strcpy(opt[0],"All"); + strcpy(opt[1],"None"); + strcpy(opt[2],"Prompt User"); + opt[3][0]=0; + SETHELP(WHERE); +/* +`Automatically Quoted Text:` + +If you want all the message text to be automatically entered into the +message input file (e.g. `INPUT.MSG` or `MSGTMP`), select `All`. + +If you want the user to be prompted for which lines to quote before +running the editor, select `Prompt User`. + +If you want none of the lines to be automatically quoted, select `None`. +This option is mainly for use with editors that support the `QUOTES.TXT` +drop file (like `SyncEdit v2.x`). +*/ + k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0,"Automatically Quoted Text" + ,opt); + if(!k && !(cfg.xedit[i]->misc"EALL)) { + cfg.xedit[i]->misc|=QUOTEALL; + cfg.xedit[i]->misc&=~QUOTENONE; + uifc.changes=TRUE; + } + else if(k==1 && !(cfg.xedit[i]->misc"ENONE)) { + cfg.xedit[i]->misc|=QUOTENONE; + cfg.xedit[i]->misc&=~QUOTEALL; + uifc.changes=TRUE; + } + else if(k==2 && cfg.xedit[i]->misc&(QUOTENONE|QUOTEALL)) { + cfg.xedit[i]->misc&=~(QUOTENONE|QUOTEALL); + uifc.changes=TRUE; + } + break; + case 9: + k=cfg.xedit[i]->misc&QUICKBBS ? 0:1; + strcpy(opt[0],"QuickBBS MSGINF/MSGTMP"); + strcpy(opt[1],"WWIV EDITOR.INF/RESULT.ED"); + opt[2][0]=0; + SETHELP(WHERE); +/* +`Editor Information File:` + +If this external editor uses the QuickBBS style MSGTMP interface, set +this option to ~QuickBBS MSGINF/MSGTMP~, otherwise set to ~WWIV EDITOR.INF/RESULT.ED~. +*/ + k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0,"Editor Information Files" + ,opt); + if(!k && !(cfg.xedit[i]->misc&QUICKBBS)) { + cfg.xedit[i]->misc|=QUICKBBS; + uifc.changes=TRUE; + } + else if(k==1 && (cfg.xedit[i]->misc&QUICKBBS)) { + cfg.xedit[i]->misc&=~QUICKBBS; + uifc.changes=TRUE; + } + break; + case 10: + k=(cfg.xedit[i]->misc&EXPANDLF) ? 0:1; + SETHELP(WHERE); +/* +`Expand Line Feeds to Carriage Return/Line Feed Pairs:` + +If this external editor saves new lines as a single line feed character +instead of a carriage return/line feed pair, set this option to `Yes`. +*/ + k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0,"Expand LF to CRLF" + ,uifcYesNoOpts); + if(!k && !(cfg.xedit[i]->misc&EXPANDLF)) { + cfg.xedit[i]->misc|=EXPANDLF; + uifc.changes=TRUE; + } + else if(k==1 && (cfg.xedit[i]->misc&EXPANDLF)) { + cfg.xedit[i]->misc&=~EXPANDLF; + uifc.changes=TRUE; + } + break; + case 11: + k=(cfg.xedit[i]->misc&STRIPKLUDGE) ? 0:1; + SETHELP(WHERE); +/* +`Strip FidoNet Kludge Lines From Messages:` + +If this external editor adds FidoNet Kludge lines to the message text, +set this option to `Yes` to strip those lines from the message. +*/ + k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0 + ,"Strip FidoNet Kludge Lines" + ,uifcYesNoOpts); + if(!k && !(cfg.xedit[i]->misc&STRIPKLUDGE)) { + cfg.xedit[i]->misc|=STRIPKLUDGE; + uifc.changes=TRUE; + } + else if(k==1 && (cfg.xedit[i]->misc&STRIPKLUDGE)) { + cfg.xedit[i]->misc&=~STRIPKLUDGE; + uifc.changes=TRUE; + } + break; + case 12: + k=0; + strcpy(opt[k++],"None"); + sprintf(opt[k++],"%-15s %s","Synchronet","XTRN.DAT"); + sprintf(opt[k++],"%-15s %s","WWIV","CHAIN.TXT"); + sprintf(opt[k++],"%-15s %s","GAP","DOOR.SYS"); + sprintf(opt[k++],"%-15s %s","RBBS/QuickBBS","DORINFO#.DEF"); + sprintf(opt[k++],"%-15s %s","Wildcat","CALLINFO.BBS"); + sprintf(opt[k++],"%-15s %s","PCBoard","PCBOARD.SYS"); + sprintf(opt[k++],"%-15s %s","SpitFire","SFDOORS.DAT"); + sprintf(opt[k++],"%-15s %s","MegaMail","UTIDOOR.TXT"); + sprintf(opt[k++],"%-15s %s","Solar Realms","DOORFILE.SR"); + sprintf(opt[k++],"%-15s %s","RBBS/QuickBBS","DORINFO1.DEF"); + sprintf(opt[k++],"%-15s %s","TriBBS","TRIBBS.SYS"); + sprintf(opt[k++],"%-15s %s","Mystic","DOOR32.SYS"); + opt[k][0]=0; + k=cfg.xedit[i]->type; + SETHELP(WHERE); +/* +`External Program BBS Drop File Type:` + +If this external editor requires a specific BBS data (drop) file +format, select the file format from the list. +*/ + k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0 + ,"BBS Drop File Type",opt); + if(k==-1) + break; + if(cfg.xedit[i]->type!=k) { + cfg.xedit[i]->type=k; + if(cfg.xedit[i]->type==XTRN_DOOR32) + cfg.xedit[i]->misc|=XTRN_NATIVE; + uifc.changes=TRUE; + } + if(cfg.xedit[i]->type) { + k=(cfg.xedit[i]->misc&XTRN_LWRCASE) ? 0:1; + k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0,"Lowercase Filename",uifcYesNoOpts); + if(k==0 && !(cfg.xedit[i]->misc&XTRN_LWRCASE)) { + cfg.xedit[i]->misc|=XTRN_LWRCASE; + uifc.changes=TRUE; + } + else if(k==1 && (cfg.xedit[i]->misc&XTRN_LWRCASE)) { + cfg.xedit[i]->misc&=~XTRN_LWRCASE; + uifc.changes=TRUE; + } + } + break; + } + } + } +} + +int natvpgm_cfg() +{ + static int dflt,bar; + char str[81]; + int j; + uint i; + +while(1) { + for(i=0;iname); + opt[i][0]=0; + j=WIN_ACT|WIN_CHE|WIN_L2R|WIN_SAV; + if(cfg.total_natvpgms) + j|=WIN_DEL; + if(cfg.total_natvpgmsi;j--) + cfg.natvpgm[j]=cfg.natvpgm[j-1]; + if((cfg.natvpgm[i]=(natvpgm_t *)malloc(sizeof(natvpgm_t)))==NULL) { + errormsg(WHERE,ERR_ALLOC,nulstr,sizeof(natvpgm_t)); + continue; + } + memset((natvpgm_t *)cfg.natvpgm[i],0,sizeof(natvpgm_t)); + strcpy(cfg.natvpgm[i]->name,str); + cfg.total_natvpgms++; + uifc.changes=TRUE; + continue; + } + if((i&MSK_ON)==MSK_DEL) { + i&=MSK_OFF; + free(cfg.natvpgm[i]); + cfg.total_natvpgms--; + for(j=i;jname); + if(uifc.input(WIN_MID|WIN_SAV,0,5,"Native Program Name",str,12 + ,K_EDIT)>0) + strcpy(cfg.natvpgm[i]->name,str); + } +return(0); +} + + +void xtrnsec_cfg() +{ + static int xtrnsec_dflt,xtrnsec_opt; + char str[81],code[9],done=0,*p; + int j,k; + uint i; + static xtrnsec_t savxtrnsec; + +while(1) { + for(i=0;iname); + opt[i][0]=0; + j=WIN_SAV|WIN_ACT|WIN_CHE|WIN_BOT; + if(cfg.total_xtrnsecs) + j|=WIN_DEL|WIN_GET; + if(cfg.total_xtrnsecsi;j--) + cfg.xtrnsec[j]=cfg.xtrnsec[j-1]; + for(j=0;jsec>=i) + cfg.xtrn[j]->sec++; + } + + + if((cfg.xtrnsec[i]=(xtrnsec_t *)malloc(sizeof(xtrnsec_t)))==NULL) { + errormsg(WHERE,ERR_ALLOC,nulstr,sizeof(xtrnsec_t)); + continue; + } + memset((xtrnsec_t *)cfg.xtrnsec[i],0,sizeof(xtrnsec_t)); + strcpy(cfg.xtrnsec[i]->name,str); + strcpy(cfg.xtrnsec[i]->code,code); + cfg.total_xtrnsecs++; + uifc.changes=TRUE; + continue; + } + if((i&MSK_ON)==MSK_DEL) { + i&=MSK_OFF; + free(cfg.xtrnsec[i]); + for(j=0;jsec==i) { /* delete xtrns of this group */ + free(cfg.xtrn[j]); + cfg.total_xtrns--; + k=j; + while(ksec>i) + cfg.xtrn[j]->sec--; + cfg.total_xtrnsecs--; + while(iname); + sprintf(opt[k++],"%-27.27s%s","Internal Code",cfg.xtrnsec[i]->code); + sprintf(opt[k++],"%-27.27s%.40s","Access Requirements" + ,cfg.xtrnsec[i]->arstr); + sprintf(opt[k++],"%s","Available Online Programs..."); + opt[k][0]=0; + sprintf(str,"%s Program Section",cfg.xtrnsec[i]->name); + switch(uifc.list(WIN_SAV|WIN_ACT|WIN_MID,0,0,60,&xtrnsec_opt,0,str + ,opt)) { + case -1: + done=1; + break; + case 0: + SETHELP(WHERE); +/* +`Online Program Section Name:` + +This is the name of this section. +*/ + strcpy(str,cfg.xtrnsec[i]->name); /* save */ + if(!uifc.input(WIN_MID|WIN_SAV,0,10 + ,"Program Section Name" + ,cfg.xtrnsec[i]->name,sizeof(cfg.xtrnsec[i]->name)-1,K_EDIT)) + strcpy(cfg.xtrnsec[i]->name,str); + break; + case 1: + strcpy(str,cfg.xtrnsec[i]->code); + SETHELP(WHERE); +/* +`Online Program Section Internal Code:` + +Every online program section must have its own unique internal code +for Synchronet to reference it by. It is helpful if this code is an +abreviation of the name. +*/ + uifc.input(WIN_MID|WIN_SAV,0,17,"Internal Code (unique)" + ,str,LEN_CODE,K_EDIT|K_UPPER); + if(code_ok(str)) + strcpy(cfg.xtrnsec[i]->code,str); + else { + uifc.helpbuf=invalid_code; + uifc.msg("Invalid Code"); + uifc.helpbuf=0; + } + break; + case 2: + getar(cfg.xtrnsec[i]->name,cfg.xtrnsec[i]->arstr); + break; + case 3: + xtrn_cfg(i); + break; + } + } + } +} + +void hotkey_cfg(void) +{ + static int dflt,dfltopt,bar; + char str[81],done=0; + int j,k; + uint i; + static hotkey_t savhotkey; + +while(1) { + for(i=0;ikey+'@' + ,cfg.hotkey[i]->cmd); + opt[i][0]=0; + j=WIN_SAV|WIN_ACT|WIN_CHE|WIN_RHT; + if(cfg.total_hotkeys) + j|=WIN_DEL|WIN_GET; + if(cfg.total_hotkeysi;j--) + cfg.hotkey[j]=cfg.hotkey[j-1]; + if((cfg.hotkey[i]=(hotkey_t *)malloc(sizeof(hotkey_t)))==NULL) { + errormsg(WHERE,ERR_ALLOC,nulstr,sizeof(hotkey_t)); + continue; + } + memset((hotkey_t *)cfg.hotkey[i],0,sizeof(hotkey_t)); + cfg.hotkey[i]->key=str[0]-'@'; + cfg.total_hotkeys++; + uifc.changes=TRUE; + continue; + } + if((i&MSK_ON)==MSK_DEL) { + i&=MSK_OFF; + free(cfg.hotkey[i]); + cfg.total_hotkeys--; + for(j=i;jkey+'@'); + sprintf(opt[k++],"%-27.27s%.40s","Command Line",cfg.hotkey[i]->cmd); + opt[k][0]=0; + SETHELP(WHERE); +/* +`Global Hot Key Event:` + +This menu allows you to change the settings for the selected global +hot key event. Hot key events are control characters that are used to +execute an external program or module anywhere in the BBS. +*/ + sprintf(str,"Ctrl-%c Hot Key Event",cfg.hotkey[i]->key+'@'); + switch(uifc.list(WIN_SAV|WIN_ACT|WIN_L2R|WIN_BOT,0,0,60,&dfltopt,0 + ,str,opt)) { + case -1: + done=1; + break; + case 0: + SETHELP(WHERE); +/* +`Global Hot-Ctrl Key:` + +This is the global control key used to execute this event. +*/ + sprintf(str,"%c",cfg.hotkey[i]->key+'@'); + if(uifc.input(WIN_MID|WIN_SAV,0,10,"Global Hot Ctrl-Key" + ,str,1,K_EDIT|K_UPPER)>0) + cfg.hotkey[i]->key=str[0]-'@'; + break; + case 1: + SETHELP(WHERE); +/* +`Hot Key Event Command Line:` + +This is the command line to execute when this hot key is pressed. +*/ + uifc.input(WIN_MID|WIN_SAV,0,10,"Command" + ,cfg.hotkey[i]->cmd,sizeof(cfg.hotkey[i]->cmd)-1,K_EDIT); + break; + } } } + +}