home *** CD-ROM | disk | FTP | other *** search
/ PC Online 1998 September / PCO_0998.ISO / filesbbs / dos / sbbs_src.exe / SBBS / SCFG / SCFGXTRN.C < prev    next >
Encoding:
Text File  |  1997-04-13  |  48.7 KB  |  1,799 lines

  1. #line 2 "SCFGXTRN.C"
  2.  
  3. /* Developed 1990-1997 by Rob Swindell; PO Box 501, Yorba Linda, CA 92885 */
  4.  
  5. extern char *wday[];
  6.  
  7. char *daystr(char days);
  8.  
  9.  
  10. /****************************************************************************/
  11. /* Synchronet configuration utility                                         */
  12. /****************************************************************************/
  13.  
  14. #include "scfg.h"
  15.  
  16. void xprogs_cfg()
  17. {
  18.     static int xprogs_dflt;
  19.     int     i;
  20.     char    str[81];
  21.  
  22. while(1) {
  23.     i=0;
  24.     strcpy(opt[i++],"Fixed Events");
  25.     strcpy(opt[i++],"Timed Events");
  26.     strcpy(opt[i++],"Global Swap List");
  27.     strcpy(opt[i++],"OS/2 Program List");
  28.     strcpy(opt[i++],"External Editors");
  29.     strcpy(opt[i++],"Online Programs");
  30.     opt[i][0]=0;
  31.     SETHELP(WHERE);
  32. /*
  33. Online External Programs:
  34.  
  35. From this menu, you can configure external events, external editors, or
  36. online external programs (doors).
  37. */
  38.     switch(ulist(WIN_ORG|WIN_CHE|WIN_ACT,0,0,0,&xprogs_dflt,0
  39.         ,"External Programs",opt)) {
  40.         case -1:
  41.             i=save_changes(WIN_MID);
  42.             if(i==-1)
  43.                 break;
  44.             if(!i) {
  45.                 write_xtrn_cfg();
  46.                 write_main_cfg(); }
  47.             return;
  48.         case 0:
  49.             fevents_cfg();
  50.             break;
  51.         case 1:
  52.             tevents_cfg();
  53.             break;
  54.         case 2:
  55.             swap_cfg();
  56.             break;
  57.         case 3:
  58.             os2pgm_cfg();
  59.             break;
  60.         case 4:
  61.             xedit_cfg();
  62.             break;
  63.         case 5:
  64.             xtrnsec_cfg();
  65.             break; } }
  66. }
  67.  
  68. void fevents_cfg()
  69. {
  70.     static int event_dflt;
  71.     char str[81],*p;
  72.     int i;
  73.  
  74. while(1) {
  75.     i=0;
  76.     sprintf(opt[i++],"%-32.32s%.40s","Logon Event",sys_logon);
  77.     sprintf(opt[i++],"%-32.32s%.40s","Logout Event",sys_logout);
  78.     sprintf(opt[i++],"%-32.32s%.40s","Daily Event",sys_daily);
  79.     opt[i][0]=0;
  80.     savnum=0;
  81.     SETHELP(WHERE);
  82. /*
  83. External Events:
  84.  
  85. From this menu, you can configure the logon and logout events, and the
  86. system daily event.
  87. */
  88.     switch(ulist(WIN_ACT|WIN_SAV|WIN_CHE|WIN_BOT|WIN_RHT,0,0,60,&event_dflt,0
  89.         ,"Fixed Events",opt)) {
  90.         case -1:
  91.             return;
  92.         case 0:
  93.             SETHELP(WHERE);
  94. /*
  95. Logon Event:
  96.  
  97. This is the command line for a program that will execute during the
  98. logon sequence of every user. The program cannot have user interaction.
  99. The program will be executed after the LOGON message is displayed and
  100. before the logon user list is displayed. If you wish to place a program
  101. in the logon sequence of users that includes interaction or requires
  102. account information, you probably want to use an online external
  103. program configured to run as a logon event.
  104. */
  105.             uinput(WIN_MID|WIN_SAV,0,0,"Logon Event"
  106.                 ,sys_logon,50,K_EDIT);
  107.             break;
  108.         case 1:
  109.             SETHELP(WHERE);
  110. /*
  111. Logout Event:
  112.  
  113. This is the command line for a program that will execute during the
  114. logout sequence of every user. This program cannot have user
  115. interaction because it is executed after carrier is dropped. If you
  116. wish to have a program execute before carrier is dropped, you probably
  117. want to use an Online External Program configured to run as a logoff
  118. event.
  119. */
  120.             uinput(WIN_MID|WIN_SAV,0,0,"Logout Event"
  121.                 ,sys_logout,50,K_EDIT);
  122.             break;
  123.         case 2:
  124.             SETHELP(WHERE);
  125. /*
  126. Daily Event:
  127.  
  128. This is the command line for a program that will run after the first
  129. user that logs on after midnight, logs off (regardless of what node).
  130. */
  131.             uinput(WIN_MID|WIN_SAV,0,0,"Daily Event"
  132.                 ,sys_daily,50,K_EDIT);
  133.  
  134.             break; } }
  135. }
  136.  
  137. void tevents_cfg()
  138. {
  139.     static int dflt,dfltopt,bar;
  140.     char str[81],done=0,*p;
  141.     int j,k;
  142.     uint i;
  143.     static event_t savevent;
  144.  
  145. while(1) {
  146.     for(i=0;i<total_events && i<MAX_OPTS;i++)
  147.         sprintf(opt[i],"%-8.8s      %.50s",event[i]->code,event[i]->cmd);
  148.     opt[i][0]=0;
  149.     j=WIN_SAV|WIN_ACT|WIN_CHE|WIN_RHT;
  150.     savnum=0;
  151.     if(total_events)
  152.         j|=WIN_DEL|WIN_GET;
  153.     if(total_events<MAX_OPTS)
  154.         j|=WIN_INS|WIN_INSACT;
  155.     if(savevent.code[0])
  156.         j|=WIN_PUT;
  157.     SETHELP(WHERE);
  158. /*
  159. Timed Events:
  160.  
  161. This is a list of the configured timed external events.
  162.  
  163. To add an event hit  INS .
  164.  
  165. To delete an event, select it and hit  DEL .
  166.  
  167. To configure an event, select it and hit  ENTER .
  168. */
  169.     i=ulist(j,0,0,45,&dflt,&bar,"Timed Events",opt);
  170.     if((signed)i==-1)
  171.         return;
  172.     if((i&MSK_ON)==MSK_INS) {
  173.         i=total_events;
  174.         SETHELP(WHERE);
  175. /*
  176. Timed Event Internal Code:
  177.  
  178. This is the internal code for the timed event.
  179. */
  180.         if(uinput(WIN_MID|WIN_SAV,0,0,"Event Internal Code",str,8
  181.             ,K_UPPER)<1)
  182.             continue;
  183.         if((event=(event_t **)REALLOC(event
  184.             ,sizeof(event_t *)*(total_events+1)))==NULL) {
  185.             errormsg(WHERE,ERR_ALLOC,nulstr,total_events+1);
  186.             total_events=0;
  187.             bail(1);
  188.             continue; }
  189.         if((event[i]=(event_t *)MALLOC(sizeof(event_t)))==NULL) {
  190.             errormsg(WHERE,ERR_ALLOC,nulstr,sizeof(event_t));
  191.             continue; }
  192.         memset((event_t *)event[i],0,sizeof(event_t));
  193.         strcpy(event[i]->code,str);
  194.         event[i]->node=1;
  195.         event[i]->days=0xff;
  196.         total_events++;
  197.         changes=1;
  198.         continue; }
  199.     if((i&MSK_ON)==MSK_DEL) {
  200.         i&=MSK_OFF;
  201.         FREE(event[i]);
  202.         total_events--;
  203.         for(j=i;j<total_events;j++)
  204.             event[j]=event[j+1];
  205.         changes=1;
  206.         continue; }
  207.     if((i&MSK_ON)==MSK_GET) {
  208.         i&=MSK_OFF;
  209.         savevent=*event[i];
  210.         continue; }
  211.     if((i&MSK_ON)==MSK_PUT) {
  212.         i&=MSK_OFF;
  213.         *event[i]=savevent;
  214.         changes=1;
  215.         continue; }
  216.     done=0;
  217.     while(!done) {
  218.         k=0;
  219.         sprintf(opt[k++],"%-32.32s%s","Internal Code",event[i]->code);
  220.         sprintf(opt[k++],"%-32.32s%.40s","Start-up Directory",event[i]->dir);
  221.         sprintf(opt[k++],"%-32.32s%.40s","Command Line",event[i]->cmd);
  222.         sprintf(opt[k++],"%-32.32s%u","Execution Node",event[i]->node);
  223.         sprintf(opt[k++],"%-32.32s%s","Execution Days",daystr(event[i]->days));
  224.         sprintf(opt[k++],"%-32.32s%02u:%02u","Execution Time"
  225.             ,event[i]->time/60,event[i]->time%60);
  226.         sprintf(opt[k++],"%-32.32s%s","Requires Exclusive Execution"
  227.             ,event[i]->misc&EVENT_EXCL ? "Yes":"No");
  228.         sprintf(opt[k++],"%-32.32s%s","Force Users Off-line For Event"
  229.             ,event[i]->misc&EVENT_FORCE ? "Yes":"No");
  230.         opt[k][0]=0;
  231.         SETHELP(WHERE);
  232. /*
  233. Timed Event:
  234.  
  235. This is the configuration menu for a timed event. An event is an
  236. external program that performs some type of automated function on the
  237. system. Use this menu to configure how and when this event will be
  238. executed.
  239.  
  240. If you need the BBS to swap out of memory for this event (to make more
  241. available memory), add the program name (first word of the command line)
  242. to Global Swap List from the External Programs menu.
  243. */
  244.         savnum=1;
  245.         sprintf(str,"%s Timed Event",event[i]->code);
  246.         switch(ulist(WIN_SAV|WIN_ACT|WIN_L2R|WIN_BOT,0,0,70,&dfltopt,0
  247.             ,str,opt)) {
  248.             case -1:
  249.                 done=1;
  250.                 break;
  251.             case 0:
  252.                 strcpy(str,event[i]->code);
  253.                 SETHELP(WHERE);
  254. /*
  255. Timed Event Internal Code:
  256.  
  257. Every timed event must have its own unique internal code for Synchronet
  258. to reference it by. It is helpful if this code is an abreviation of the
  259. command line.
  260. */
  261.                 uinput(WIN_MID|WIN_SAV,0,17,"Internal Code (unique)"
  262.                     ,str,8,K_EDIT|K_UPPER);
  263.                 if(code_ok(str))
  264.                     strcpy(event[i]->code,str);
  265.                 else {
  266.                     helpbuf=invalid_code;
  267.                     umsg("Invalid Code");
  268.                     helpbuf=0; }
  269.                 break;
  270.             case 1:
  271.                 SETHELP(WHERE);
  272. /*
  273. Timed Event Start-up Directory:
  274.  
  275. This is the DOS drive/directory where the event program is located.
  276. If a path is specified here, it will be made the current directory
  277. before the event's command line is executed. This eliminates the need
  278. for batch files that just change the current drive and directory before
  279. executing the event.
  280.  
  281. If this option is not used, the current NODE's directory will be the
  282. current DOS drive/directory before the command line is executed.
  283. */
  284.                 uinput(WIN_MID|WIN_SAV,0,10,"Directory"
  285.                     ,event[i]->dir,50,K_EDIT|K_UPPER);
  286.                 break;
  287.             case 2:
  288.                 SETHELP(WHERE);
  289. /*
  290. Timed Event Command Line:
  291.  
  292. This is the command line to execute upon this timed event.
  293. */
  294.                 uinput(WIN_MID|WIN_SAV,0,10,"Command"
  295.                     ,event[i]->cmd,50,K_EDIT);
  296.                 break;
  297.             case 3:
  298.                 SETHELP(WHERE);
  299. /*
  300. Timed Event Node:
  301.  
  302. This is the node number to execute the timed event.
  303. */
  304.                 sprintf(str,"%u",event[i]->node);
  305.                 uinput(WIN_MID|WIN_SAV,0,0,"Node Number"
  306.                     ,str,3,K_EDIT|K_NUMBER);
  307.                 event[i]->node=atoi(str);
  308.                 break;
  309.             case 4:
  310.                 j=0;
  311.                 while(1) {
  312.                     for(k=0;k<7;k++)
  313.                         sprintf(opt[k],"%s        %s"
  314.                             ,wday[k],(event[i]->days&(1<<k)) ? "Yes":"No");
  315.                     opt[k][0]=0;
  316.                     savnum=2;
  317.                     SETHELP(WHERE);
  318. /*
  319. Days to Execute Event:
  320.  
  321. These are the days of the week that this event will be executed.
  322. */
  323.                     k=ulist(WIN_MID|WIN_SAV,0,0,0,&j,0
  324.                         ,"Days to Execute Event",opt);
  325.                     if(k==-1)
  326.                         break;
  327.                     event[i]->days^=(1<<k);
  328.                     changes=1; }
  329.                 break;
  330.             case 5:
  331.                 sprintf(str,"%2.2d:%2.2d",event[i]->time/60
  332.                     ,event[i]->time%60);
  333.                 SETHELP(WHERE);
  334. /*
  335. Time to Execute Event:
  336.  
  337. This is the time (in 24 hour HH:MM format) to execute the event.
  338. */
  339.                 if(uinput(WIN_MID|WIN_SAV,0,0
  340.                     ,"Time to Execute Event (HH:MM)"
  341.                     ,str,5,K_UPPER|K_EDIT)>0) {
  342.                     event[i]->time=atoi(str)*60;
  343.                     if((p=strchr(str,':'))!=NULL)
  344.                         event[i]->time+=atoi(p+1); }
  345.                 break;
  346.             case 6:
  347.                 k=1;
  348.                 strcpy(opt[0],"Yes");
  349.                 strcpy(opt[1],"No");
  350.                 opt[2][0]=0;
  351.                 savnum=2;
  352.                 SETHELP(WHERE);
  353. /*
  354. Exclusive Event Execution:
  355.  
  356. If this event must be run exclusively (all nodes inactive), set this
  357. option to Yes.
  358. */
  359.                 k=ulist(WIN_MID|WIN_SAV,0,0,0,&k,0,"Exclusive Execution"
  360.                     ,opt);
  361.                 if(!k && !(event[i]->misc&EVENT_EXCL)) {
  362.                     event[i]->misc|=EVENT_EXCL;
  363.                     changes=1; }
  364.                 else if(k==1 && event[i]->misc&EVENT_EXCL) {
  365.                     event[i]->misc&=~EVENT_EXCL;
  366.                     changes=1; }
  367.                 break;
  368.             case 7:
  369.                 k=1;
  370.                 strcpy(opt[0],"Yes");
  371.                 strcpy(opt[1],"No");
  372.                 opt[2][0]=0;
  373.                 savnum=2;
  374.                 SETHELP(WHERE);
  375. /*
  376. Force Users Off-line for Event:
  377.  
  378. If you want to have your users' on-line time reduced so the event can
  379. execute precisely on time, set this option to Yes.
  380. */
  381.                 k=ulist(WIN_MID|WIN_SAV,0,0,0,&k,0
  382.                     ,"Force Users Off-line for Event",opt);
  383.                 if(!k && !(event[i]->misc&EVENT_FORCE)) {
  384.                     event[i]->misc|=EVENT_FORCE;
  385.                     changes=1; }
  386.                 else if(k==1 && event[i]->misc&EVENT_FORCE) {
  387.                     event[i]->misc&=~EVENT_FORCE;
  388.                     changes=1; }
  389.                 break;
  390.  
  391.                 } } }
  392. }
  393.  
  394.  
  395. void xtrn_cfg(uint section)
  396. {
  397.     static int ext_dflt,ext_bar,opt_dflt,time_dflt;
  398.     char str[128],code[9],done=0,*p;
  399.     int j,k;
  400.     uint i,n,xtrnnum[MAX_OPTS+1];
  401.     static xtrn_t savxtrn;
  402.  
  403. while(1) {
  404.     for(i=0,j=0;i<total_xtrns && j<MAX_OPTS;i++)
  405.         if(xtrn[i]->sec==section) {
  406.             sprintf(opt[j],"%-25s",xtrn[i]->name);
  407.             xtrnnum[j++]=i; }
  408.     xtrnnum[j]=total_xtrns;
  409.     opt[j][0]=0;
  410.     savnum=2;
  411.     i=WIN_ACT|WIN_CHE|WIN_SAV|WIN_RHT;
  412.     if(j)
  413.         i|=WIN_DEL|WIN_GET;
  414.     if(total_xtrns<MAX_OPTS)
  415.         i|=WIN_INS|WIN_INSACT|WIN_XTR;
  416.     if(savxtrn.name[0])
  417.         i|=WIN_PUT;
  418.     SETHELP(WHERE);
  419. /*
  420. Online External Programs:
  421.  
  422. This is a list of the configured online external programs (doors).
  423.  
  424. To add a program, select the desired location with the arrow keys and
  425. hit  INS .
  426.  
  427. To delete a program, select it with the arrow keys and hit  DEL .
  428.  
  429. To configure a program, select it with the arrow keys and hit  ENTER .
  430. */
  431.     sprintf(str,"%s Online Programs",xtrnsec[section]->name);
  432.     i=ulist(i,0,0,45,&ext_dflt,&ext_bar,str,opt);
  433.     if((signed)i==-1)
  434.         return;
  435.     if((i&MSK_ON)==MSK_INS) {
  436.         i&=MSK_OFF;
  437.         SETHELP(WHERE);
  438. /*
  439. Online Program Name:
  440.  
  441. This is the name or description of the online program (door).
  442. */
  443.         if(uinput(WIN_MID|WIN_SAV,0,0,"Online Program Name",str,25
  444.             ,0)<1)
  445.             continue;
  446.         sprintf(code,"%.8s",str);
  447.         p=strchr(code,SP);
  448.         if(p) *p=0;
  449.         strupr(code);
  450.         SETHELP(WHERE);
  451. /*
  452. Online Program Internal Code:
  453.  
  454. Every online program must have its own unique code for Synchronet to
  455. refer to it internally. This code is usually an abreviation of the
  456. online program name.
  457. */
  458.         if(uinput(WIN_MID|WIN_SAV,0,0,"Internal Code"
  459.             ,code,8,K_EDIT|K_UPPER)<1)
  460.             continue;
  461.         if(!code_ok(code)) {
  462.             helpbuf=invalid_code;
  463.             umsg("Invalid Code");
  464.             helpbuf=0;
  465.             continue; }
  466.         if((xtrn=(xtrn_t **)REALLOC(xtrn,sizeof(xtrn_t *)*(total_xtrns+1)))
  467.             ==NULL) {
  468.             errormsg(WHERE,ERR_ALLOC,nulstr,total_xtrns+1);
  469.             total_xtrns=0;
  470.             bail(1);
  471.             continue; }
  472.         if(j)
  473.             for(n=total_xtrns;n>xtrnnum[i];n--)
  474.                 xtrn[n]=xtrn[n-1];
  475.         if((xtrn[xtrnnum[i]]=(xtrn_t *)MALLOC(sizeof(xtrn_t)))==NULL) {
  476.             errormsg(WHERE,ERR_ALLOC,nulstr,sizeof(xtrn_t));
  477.             continue; }
  478.         memset((xtrn_t *)xtrn[xtrnnum[i]],0,sizeof(xtrn_t));
  479.         strcpy(xtrn[xtrnnum[i]]->name,str);
  480.         strcpy(xtrn[xtrnnum[i]]->code,code);
  481.         xtrn[xtrnnum[i]]->sec=section;
  482.         total_xtrns++;
  483.         changes=1;
  484.         continue; }
  485.     if((i&MSK_ON)==MSK_DEL) {
  486.         i&=MSK_OFF;
  487.         FREE(xtrn[xtrnnum[i]]);
  488.         total_xtrns--;
  489.         for(j=xtrnnum[i];j<total_xtrns;j++)
  490.             xtrn[j]=xtrn[j+1];
  491.         changes=1;
  492.         continue; }
  493.     if((i&MSK_ON)==MSK_GET) {
  494.         i&=MSK_OFF;
  495.         savxtrn=*xtrn[xtrnnum[i]];
  496.         continue; }
  497.     if((i&MSK_ON)==MSK_PUT) {
  498.         i&=MSK_OFF;
  499.         *xtrn[xtrnnum[i]]=savxtrn;
  500.         xtrn[xtrnnum[i]]->sec=section;
  501.         changes=1;
  502.         continue; }
  503.     done=0;
  504.     i=xtrnnum[i];
  505.     while(!done) {
  506.         k=0;
  507.         sprintf(opt[k++],"%-27.27s%s","Name",xtrn[i]->name);
  508.         sprintf(opt[k++],"%-27.27s%s","Internal Code",xtrn[i]->code);
  509.         sprintf(opt[k++],"%-27.27s%.40s","Start-up Directory",xtrn[i]->path);
  510.         sprintf(opt[k++],"%-27.27s%.40s","Command Line",xtrn[i]->cmd);
  511.         sprintf(opt[k++],"%-27.27s%.40s","Clean-up Command Line",xtrn[i]->clean);
  512.         if(xtrn[i]->cost)
  513.             sprintf(str,"%lu credits",xtrn[i]->cost);
  514.         else
  515.             strcpy(str,"None");
  516.         sprintf(opt[k++],"%-27.27s%s","Execution Cost",str);
  517.         sprintf(opt[k++],"%-27.27s%.40s","Access Requirements",xtrn[i]->ar);
  518.         sprintf(opt[k++],"%-27.27s%.40s","Execution Requirements"
  519.             ,xtrn[i]->run_ar);
  520.         sprintf(opt[k++],"%-27.27s%s","Multiple Concurrent Users"
  521.             ,xtrn[i]->misc&MULTIUSER ? "Yes" : "No");
  522.         sprintf(opt[k++],"%-27.27s%s%s","Intercept I/O Interrupts"
  523.             ,xtrn[i]->misc&IO_INTS ? "Yes" : "No"
  524.             ,xtrn[i]->misc&WWIVCOLOR ? ", WWIV" : nulstr);
  525.         sprintf(opt[k++],"%-27.27s%s","Swap BBS out of Memory"
  526.             ,xtrn[i]->misc&SWAP ? "Yes" : "No");
  527.         sprintf(opt[k++],"%-27.27s%s","Modify User Data"
  528.             ,xtrn[i]->misc&MODUSERDAT ? "Yes" : "No");
  529.         switch(xtrn[i]->event) {
  530.             case EVENT_LOGON:
  531.                 strcpy(str,"Logon");
  532.                 break;
  533.             case EVENT_LOGOFF:
  534.                 strcpy(str,"Logoff");
  535.                 break;
  536.             case EVENT_NEWUSER:
  537.                 strcpy(str,"New User");
  538.                 break;
  539.             case EVENT_BIRTHDAY:
  540.                 strcpy(str,"Birthday");
  541.                 break;
  542.             default:
  543.                 strcpy(str,"No");
  544.                 break; }
  545.         if(xtrn[i]->misc&EVENTONLY && xtrn[i]->event)
  546.             strcat(str,", Only");
  547.         sprintf(opt[k++],"%-27.27s%s","Execute on Event",str);
  548.         switch(xtrn[i]->type) {
  549.             case XTRN_SBBS:
  550.                 sprintf(str,"%-15s %s","Synchronet","XTRN.DAT");
  551.                 break;
  552.             case XTRN_WWIV:
  553.                 sprintf(str,"%-15s %s","WWIV","CHAIN.TXT");
  554.                 break;
  555.             case XTRN_GAP:
  556.                 sprintf(str,"%-15s %s","GAP","DOOR.SYS");
  557.                 break;
  558.             case XTRN_RBBS:
  559.                 sprintf(str,"%-15s %s","RBBS/QuickBBS","DORINFO#.DEF");
  560.                 break;
  561.             case XTRN_RBBS1:
  562.                 sprintf(str,"%-15s %s","RBBS/QuickBBS","DORINFO1.DEF");
  563.                 break;
  564.             case XTRN_WILDCAT:
  565.                 sprintf(str,"%-15s %s","Wildcat","CALLINFO.BBS");
  566.                 break;
  567.             case XTRN_PCBOARD:
  568.                 sprintf(str,"%-15s %s","PCBoard","PCBOARD.SYS");
  569.                 break;
  570.             case XTRN_SPITFIRE:
  571.                 sprintf(str,"%-15s %s","SpitFire","SFDOORS.DAT");
  572.                 break;
  573.             case XTRN_UTI:
  574.                 sprintf(str,"%-15s %s","MegaMail","UTIDOOR.TXT");
  575.                 break;
  576.             case XTRN_SR:
  577.                 sprintf(str,"%-15s %s","Solar Realms","DOORFILE.SR");
  578.                 break;
  579.             case XTRN_TRIBBS:
  580.                 sprintf(str,"%-15s %s","TriBBS","TRIBBS.SYS");
  581.                 break;
  582.             default:
  583.                 strcpy(str,"None");
  584.                 break; }
  585.         sprintf(opt[k++],"%-23.23s%-4s%s","BBS Drop File Type"
  586.             ,xtrn[i]->misc&REALNAME ? "(R)":nulstr,str);
  587.         sprintf(opt[k++],"%-27.27s%s","Place Drop File In"
  588.             ,xtrn[i]->misc&STARTUPDIR ? "Start-Up Directory":"Node Directory");
  589.         sprintf(opt[k++],"Time Options...");
  590.         opt[k][0]=0;
  591.         savnum=3;
  592.         SETHELP(WHERE);
  593. /*
  594. Online Program Configuration:
  595.  
  596. This menu is for configuring the selected online program.
  597. */
  598.         switch(ulist(WIN_SAV|WIN_ACT|WIN_MID,0,0,60,&opt_dflt,0,xtrn[i]->name
  599.             ,opt)) {
  600.             case -1:
  601.                 done=1;
  602.                 break;
  603.             case 0:
  604.                 SETHELP(WHERE);
  605. /*
  606. Online Program Name:
  607.  
  608. This is the name or description of the online program (door).
  609. */
  610.                 strcpy(str,xtrn[i]->name);
  611.                 if(!uinput(WIN_MID|WIN_SAV,0,10,"Online Program Name"
  612.                     ,xtrn[i]->name,25,K_EDIT))
  613.                     strcpy(xtrn[i]->name,str);
  614.                 break;
  615.             case 1:
  616.                 SETHELP(WHERE);
  617. /*
  618. Online Program Internal Code:
  619.  
  620. Every online program must have its own unique code for Synchronet to
  621. refer to it internally. This code is usually an abreviation of the
  622. online program name.
  623. */
  624.                 strcpy(str,xtrn[i]->code);
  625.                 uinput(WIN_MID|WIN_SAV,0,10,"Internal Code"
  626.                     ,str,8,K_UPPER|K_EDIT);
  627.                 if(code_ok(str))
  628.                     strcpy(xtrn[i]->code,str);
  629.                 else {
  630.                     helpbuf=invalid_code;
  631.                     umsg("Invalid Code");
  632.                     helpbuf=0; }
  633.                 break;
  634.             case 2:
  635.                 SETHELP(WHERE);
  636. /*
  637. Online Program Start-up Directory:
  638.  
  639. This is the DOS drive/directory where the online program is located.
  640. If a path is specified here, it will be made the current directory
  641. before the program's command line is executed. This eliminates the need
  642. for batch files that just change the current drive and directory before
  643. executing the program.
  644.  
  645. If this option is not used, the current NODE's directory will be the
  646. current DOS drive/directory before the command line is executed.
  647. */
  648.                 uinput(WIN_MID|WIN_SAV,0,10,"Directory"
  649.                     ,xtrn[i]->path,50,K_EDIT|K_UPPER);
  650.                 break;
  651.             case 3:
  652.                 SETHELP(WHERE);
  653. /*
  654. Online Program Command Line:
  655.  
  656. This is the command line to execute to run the online program.
  657. */
  658.                 uinput(WIN_MID|WIN_SAV,0,10,"Command"
  659.                     ,xtrn[i]->cmd,50,K_EDIT);
  660.                 break;
  661.             case 4:
  662.                 SETHELP(WHERE);
  663. /*
  664. Online Program Clean-up Command:
  665.  
  666. This is the command line to execute after the main command line. This
  667. option is usually only used for multiuser online programs.
  668. */
  669.                 uinput(WIN_MID|WIN_SAV,0,10,"Clean-up"
  670.                     ,xtrn[i]->clean,50,K_EDIT);
  671.                 break;
  672.             case 5:
  673.                 ultoa(xtrn[i]->cost,str,10);
  674.                 SETHELP(WHERE);
  675. /*
  676. Online Program Cost to Run:
  677.  
  678. If you want users to be charged credits to run this online program,
  679. set this value to the number of credits to charge. If you want this
  680. online program to be free, set this value to 0.
  681. */
  682.                 uinput(WIN_MID|WIN_SAV,0,0,"Cost to Run (in Credits)"
  683.                     ,str,10,K_EDIT|K_NUMBER);
  684.                 xtrn[i]->cost=atol(str);
  685.                 break;
  686.             case 6:
  687.                 savnum=4;
  688.                 sprintf(str,"%s Access",xtrn[i]->name);
  689.                 getar(str,xtrn[i]->ar);
  690.                 break;
  691.             case 7:
  692.                 savnum=4;
  693.                 sprintf(str,"%s Execution",xtrn[i]->name);
  694.                 getar(str,xtrn[i]->run_ar);
  695.                 break;
  696.             case 8:
  697.                 k=1;
  698.                 strcpy(opt[0],"Yes");
  699.                 strcpy(opt[1],"No");
  700.                 opt[2][0]=0;
  701.                 SETHELP(WHERE);
  702. /*
  703. Supports Multiple Users:
  704.  
  705. If this online program supports multiple simultaneous users (nodes),
  706. set this option to Yes.
  707. */
  708.                 savnum=4;
  709.                 k=ulist(WIN_MID|WIN_SAV,0,0,0,&k,0,"Supports Multiple Users"
  710.                     ,opt);
  711.                 if(!k && !(xtrn[i]->misc&MULTIUSER)) {
  712.                     xtrn[i]->misc|=MULTIUSER;
  713.                     changes=1; }
  714.                 else if(k==1 && xtrn[i]->misc&MULTIUSER) {
  715.                     xtrn[i]->misc&=~MULTIUSER;
  716.                     changes=1; }
  717.                 break;
  718.             case 9:
  719.                 k=1;
  720.                 strcpy(opt[0],"Yes");
  721.                 strcpy(opt[1],"No");
  722.                 opt[2][0]=0;
  723.                 SETHELP(WHERE);
  724. /*
  725. Intercept I/O Interrupts:
  726.  
  727. If this online program has its own serial communication abilities, set
  728. this option to No.
  729. */
  730.                 savnum=4;
  731.                 k=ulist(WIN_MID|WIN_SAV,0,0,0,&k,0,"Intercept I/O Interrupts"
  732.                     ,opt);
  733.                 if(!k && !(xtrn[i]->misc&IO_INTS)) {
  734.                     xtrn[i]->misc|=IO_INTS;
  735.                     changes=1; }
  736.                 else if(k==1 && xtrn[i]->misc&IO_INTS) {
  737.                     xtrn[i]->misc&=~(IO_INTS|WWIVCOLOR);
  738.                     changes=1; }
  739.                 if(!(xtrn[i]->misc&IO_INTS))
  740.                     break;
  741.                 k=1;
  742.                 strcpy(opt[0],"Yes");
  743.                 strcpy(opt[1],"No");
  744.                 opt[2][0]=0;
  745.                 SETHELP(WHERE);
  746. /*
  747. Program Uses WWIV Color Codes:
  748.  
  749. If this program was written for use exclusively under WWIV, set this
  750. option to Yes.
  751. */
  752.                 savnum=4;
  753.                 k=ulist(WIN_MID|WIN_SAV,0,0,0,&k,0
  754.                     ,"Program Uses WWIV Color Codes"
  755.                     ,opt);
  756.                 if(!k && !(xtrn[i]->misc&WWIVCOLOR)) {
  757.                     xtrn[i]->misc|=WWIVCOLOR;
  758.                     changes=1; }
  759.                 else if(k==1 && xtrn[i]->misc&WWIVCOLOR) {
  760.                     xtrn[i]->misc&=~WWIVCOLOR;
  761.                     changes=1; }
  762.                 break;
  763.             case 10:
  764.                 k=0;
  765.                 strcpy(opt[0],"Yes");
  766.                 strcpy(opt[1],"No");
  767.                 opt[2][0]=0;
  768.                 SETHELP(WHERE);
  769. /*
  770. Swap BBS out of Memory to Run Executable:
  771.  
  772. If this online programs requires a large amount of free memory,
  773. set this option to Yes to have the BBS swapped out of memory.
  774. */
  775.                 savnum=4;
  776.                 k=ulist(WIN_MID|WIN_SAV,0,0,0,&k,0
  777.                     ,"Swap BBS out of Memory",opt);
  778.                 if(!k && !(xtrn[i]->misc&SWAP)) {
  779.                     xtrn[i]->misc|=SWAP;
  780.                     changes=1; }
  781.                 else if(k==1 && xtrn[i]->misc&SWAP) {
  782.                     xtrn[i]->misc&=~SWAP;
  783.                     changes=1; }
  784.                 break;
  785.             case 11:
  786.                 k=1;
  787.                 strcpy(opt[0],"Yes");
  788.                 strcpy(opt[1],"No");
  789.                 opt[2][0]=0;
  790.                 SETHELP(WHERE);
  791. /*
  792. Program Can Modify User Data:
  793.  
  794. If this online programs recognizes the Synchronet MODUSER.DAT format
  795. or the RBBS/QuickBBS EXITINFO.BBS format and you want it to be able to
  796. modify the data of users who run the program, set this option to Yes.
  797. */
  798.                 savnum=4;
  799.                 k=ulist(WIN_MID|WIN_SAV,0,0,0,&k,0
  800.                     ,"Program Can Modify User Data",opt);
  801.                 if(!k && !(xtrn[i]->misc&MODUSERDAT)) {
  802.                     xtrn[i]->misc|=MODUSERDAT;
  803.                     changes=1; }
  804.                 else if(k==1 && xtrn[i]->misc&MODUSERDAT) {
  805.                     xtrn[i]->misc&=~MODUSERDAT;
  806.                     changes=1; }
  807.                 break;
  808.             case 12:
  809.                 k=0;
  810.                 strcpy(opt[k++],"No");
  811.                 strcpy(opt[k++],"Logon");
  812.                 strcpy(opt[k++],"Logoff");
  813.                 strcpy(opt[k++],"New User");
  814.                 strcpy(opt[k++],"Birthday");
  815.                 opt[k][0]=0;
  816.                 switch(xtrn[i]->event) {
  817.                     default:
  818.                         k=0;
  819.                         break;
  820.                     case EVENT_LOGON:
  821.                         k=1;
  822.                         break;
  823.                     case EVENT_LOGOFF:
  824.                         k=2;
  825.                         break;
  826.                     case EVENT_NEWUSER:
  827.                         k=3;
  828.                         break;
  829.                     case EVENT_BIRTHDAY:
  830.                         k=4;
  831.                         break; }
  832.                 SETHELP(WHERE);
  833. /*
  834. Execute Online Program on Event:
  835.  
  836. If you would like this online program to automatically execute on a
  837. specific user event, select the event. Otherwise, select No.
  838. */
  839.                 savnum=4;
  840.                 k=ulist(WIN_MID|WIN_SAV,0,0,0,&k,0
  841.                     ,"Execute on Event",opt);
  842.                 if(k==-1)
  843.                     break;
  844.                 if(xtrn[i]->event!=k) {
  845.                     xtrn[i]->event=k;
  846.                     changes=1; }
  847.                 if(!xtrn[i]->event)
  848.                     break;
  849.                 k=1;
  850.                 strcpy(opt[0],"Yes");
  851.                 strcpy(opt[1],"No");
  852.                 opt[2][0]=0;
  853.                 SETHELP(WHERE);
  854. /*
  855. Execute Online Program as Event Only:
  856.  
  857. If you would like this online program to execute as an event only
  858. (not available to users on the online program menu), set this option
  859. to Yes.
  860. */
  861.                 savnum=4;
  862.                 k=ulist(WIN_MID|WIN_SAV,0,0,0,&k
  863.                     ,0,"Execute as Event Only"
  864.                     ,opt);
  865.                 if(!k && !(xtrn[i]->misc&EVENTONLY)) {
  866.                     xtrn[i]->misc|=EVENTONLY;
  867.                     changes=1; }
  868.                 else if(k==1 && xtrn[i]->misc&EVENTONLY) {
  869.                     xtrn[i]->misc&=~EVENTONLY;
  870.                     changes=1; }
  871.                 break;
  872.             case 13:
  873.                 k=0;
  874.                 strcpy(opt[k++],"None");
  875.                 sprintf(opt[k++],"%-15s %s","Synchronet","XTRN.DAT");
  876.                 sprintf(opt[k++],"%-15s %s","WWIV","CHAIN.TXT");
  877.                 sprintf(opt[k++],"%-15s %s","GAP","DOOR.SYS");
  878.                 sprintf(opt[k++],"%-15s %s","RBBS/QuickBBS","DORINFO#.DEF");
  879.                 sprintf(opt[k++],"%-15s %s","Wildcat","CALLINFO.BBS");
  880.                 sprintf(opt[k++],"%-15s %s","PCBoard","PCBOARD.SYS");
  881.                 sprintf(opt[k++],"%-15s %s","SpitFire","SFDOORS.DAT");
  882.                 sprintf(opt[k++],"%-15s %s","MegaMail","UTIDOOR.TXT");
  883.                 sprintf(opt[k++],"%-15s %s","Solar Realms","DOORFILE.SR");
  884.                 sprintf(opt[k++],"%-15s %s","RBBS/QuickBBS","DORINFO1.DEF");
  885.                 sprintf(opt[k++],"%-15s %s","TriBBS","TRIBBS.SYS");
  886.                 opt[k][0]=0;
  887.                 k=xtrn[i]->type;
  888.                 SETHELP(WHERE);
  889. /*
  890. Online Program BBS Drop File Type:
  891.  
  892. If this online program requires a specific BBS data (drop) file
  893. format, select the file format from the list.
  894. */
  895.                 savnum=4;
  896.                 k=ulist(WIN_MID|WIN_SAV,0,0,0,&k,0
  897.                     ,"BBS Drop File Type",opt);
  898.                 if(k==-1)
  899.                     break;
  900.                 if(xtrn[i]->type!=k) {
  901.                     xtrn[i]->type=k;
  902.                     changes=1; }
  903.                 if(xtrn[i]->type && uq&UQ_ALIASES) {
  904.                     strcpy(opt[0],"Yes");
  905.                     strcpy(opt[1],"No");
  906.                     opt[2][0]=0;
  907.                     k=1;
  908.                     k=ulist(WIN_MID|WIN_SAV,0,0,0,&k,0,"Use Real Names",opt);
  909.                     if(k==0 && !(xtrn[i]->misc&REALNAME)) {
  910.                         xtrn[i]->misc|=REALNAME;
  911.                         changes=1; }
  912.                     else if(k==1 && xtrn[i]->misc&REALNAME) {
  913.                         xtrn[i]->misc&=~REALNAME;
  914.                         changes=1; } }
  915.                 break;
  916.             case 14:
  917.                 k=0;
  918.                 strcpy(opt[0],"Node Directory");
  919.                 strcpy(opt[1],"Start-up Directory");
  920.                 opt[2][0]=0;
  921.                 SETHELP(WHERE);
  922. /*
  923. Directory for Drop File:
  924.  
  925. You can have the data file created in the current Node Directory or the
  926. Start-up Directory (if one is specified).
  927. */
  928.                 savnum=4;
  929.                 k=ulist(WIN_MID|WIN_SAV,0,0,0,&k,0,"Create Drop File In"
  930.                     ,opt);
  931.                 if(!k && xtrn[i]->misc&STARTUPDIR) {
  932.                     xtrn[i]->misc&=~STARTUPDIR;
  933.                     changes=1; }
  934.                 else if(k==1 && !(xtrn[i]->misc&STARTUPDIR)) {
  935.                     xtrn[i]->misc|=STARTUPDIR;
  936.                     changes=1; }
  937.                 break;
  938.             case 15:
  939.                 while(1) {
  940.                     k=0;
  941.                     if(xtrn[i]->textra)
  942.                         sprintf(str,"%u minutes",xtrn[i]->textra);
  943.                     else
  944.                         strcpy(str,"None");
  945.                     sprintf(opt[k++],"%-25.25s%s","Extra Time",str);
  946.                     if(xtrn[i]->maxtime)
  947.                         sprintf(str,"%u minutes",xtrn[i]->maxtime);
  948.                     else
  949.                         strcpy(str,"None");
  950.                     sprintf(opt[k++],"%-25.25s%s","Maximum Time",str);
  951.                     sprintf(opt[k++],"%-25.25s%s","Suspended (Free) Time"
  952.                         ,xtrn[i]->misc&FREETIME ? "Yes" : "No");
  953.                     opt[k][0]=0;
  954.                     SETHELP(WHERE);
  955. /*
  956. Online Program Time Options:
  957.  
  958. This sub-menu allows you to define specific preferences regarding the
  959. time users spend running this program.
  960. */
  961.                     savnum=4;
  962.                     k=ulist(WIN_SAV|WIN_ACT|WIN_RHT|WIN_BOT,0,0,40
  963.                         ,&time_dflt,0
  964.                         ,"Online Program Time Options",opt);
  965.                     if(k==-1)
  966.                         break;
  967.                     savnum=5;
  968.                     switch(k) {
  969.                         case 0:
  970.                             itoa(xtrn[i]->textra,str,10);
  971.                             SETHELP(WHERE);
  972. /*
  973. Extra Time to Give User in Program:
  974.  
  975. If you want to give users extra time while in this online program,
  976. set this value to the number of minutes to add to their current time
  977. left online.
  978. */
  979.                             uinput(WIN_MID|WIN_SAV,0,0
  980.                                 ,"Extra Time to Give User (in minutes)"
  981.                                 ,str,2,K_EDIT|K_NUMBER);
  982.                             xtrn[i]->textra=atoi(str);
  983.                             break;
  984.                         case 1:
  985.                             itoa(xtrn[i]->maxtime,str,10);
  986.                             SETHELP(WHERE);
  987. /*
  988. Maximum Time Allowed in Program:
  989.  
  990. If this program supports a drop file that contains the number of minutes
  991. left online for the current user, this option allows the sysop to set
  992. the maximum number of minutes that will be allowed in the drop file.
  993.  
  994. Setting this option to 0, disables this feature.
  995. */
  996.                             uinput(WIN_MID|WIN_SAV,0,0
  997.                                 ,"Maximum Time (in minutes, 0=disabled)"
  998.                                 ,str,2,K_EDIT|K_NUMBER);
  999.                             xtrn[i]->maxtime=atoi(str);
  1000.                             break;
  1001.                         case 2:
  1002.                             k=1;
  1003.                             strcpy(opt[0],"Yes");
  1004.                             strcpy(opt[1],"No");
  1005.                             opt[2][0]=0;
  1006.                             SETHELP(WHERE);
  1007. /*
  1008. Suspended (Free) Time:
  1009.  
  1010. If you want the user's time online to be suspended while running this
  1011. online program (e.g. Free Time), set this option to Yes.
  1012. */
  1013.                             k=ulist(WIN_MID|WIN_SAV,0,0,0,&k,0
  1014.                                 ,"Suspended (Free) Time",opt);
  1015.                             if(!k && !(xtrn[i]->misc&FREETIME)) {
  1016.                                 xtrn[i]->misc|=FREETIME;
  1017.                                 changes=1; }
  1018.                             else if(k==1 && xtrn[i]->misc&FREETIME) {
  1019.                                 xtrn[i]->misc&=~FREETIME;
  1020.                                 changes=1; }
  1021.                             break; } }
  1022.                     break;
  1023.  
  1024.                 } } }
  1025. }
  1026.  
  1027. void xedit_cfg()
  1028. {
  1029.     static int dflt,dfltopt,bar;
  1030.     char str[81],code[81],done=0,*p;
  1031.     int j,k;
  1032.     uint i;
  1033.     static xedit_t savxedit;
  1034.  
  1035. while(1) {
  1036.     for(i=0;i<total_xedits && i<MAX_OPTS;i++)
  1037.         sprintf(opt[i],"%-8.8s    %.40s",xedit[i]->code,xedit[i]->lcmd);
  1038.     opt[i][0]=0;
  1039.     j=WIN_SAV|WIN_ACT|WIN_CHE|WIN_RHT;
  1040.     savnum=0;
  1041.     if(total_xedits)
  1042.         j|=WIN_DEL|WIN_GET;
  1043.     if(total_xedits<MAX_OPTS)
  1044.         j|=WIN_INS|WIN_INSACT|WIN_XTR;
  1045.     if(savxedit.name[0])
  1046.         j|=WIN_PUT;
  1047.     SETHELP(WHERE);
  1048. /*
  1049. External Editors:
  1050.  
  1051. This is a list of the configured external editors.
  1052.  
  1053. To add an editor, select the desired location and hit  INS .
  1054.  
  1055. To delete an editor, select it and hit  DEL .
  1056.  
  1057. To configure an editor, select it and hit  ENTER .
  1058. */
  1059.     i=ulist(j,0,0,45,&dflt,&bar,"External Editors",opt);
  1060.     if((signed)i==-1)
  1061.         return;
  1062.     if((i&MSK_ON)==MSK_INS) {
  1063.         i&=MSK_OFF;
  1064.         SETHELP(WHERE);
  1065. /*
  1066. External Editor Name:
  1067.  
  1068. This is the name or description of the external editor.
  1069. */
  1070.         if(uinput(WIN_MID|WIN_SAV,0,0,"External Editor Name",str,40
  1071.             ,0)<1)
  1072.             continue;
  1073.         sprintf(code,"%.8s",str);
  1074.         p=strchr(code,SP);
  1075.         if(p) *p=0;
  1076.         strupr(code);
  1077.         SETHELP(WHERE);
  1078. /*
  1079. External Editor Internal Code:
  1080.  
  1081. This is the internal code for the external editor.
  1082. */
  1083.         if(uinput(WIN_MID|WIN_SAV,0,0,"External Editor Internal Code",code,8
  1084.             ,K_UPPER|K_EDIT)<1)
  1085.             continue;
  1086.         if(!code_ok(code)) {
  1087.             helpbuf=invalid_code;
  1088.             umsg("Invalid Code");
  1089.             helpbuf=0;
  1090.             continue; }
  1091.  
  1092.         if((xedit=(xedit_t **)REALLOC(xedit
  1093.             ,sizeof(xedit_t *)*(total_xedits+1)))==NULL) {
  1094.             errormsg(WHERE,ERR_ALLOC,nulstr,total_xedits+1);
  1095.             total_xedits=0;
  1096.             bail(1);
  1097.             continue; }
  1098.         if(total_xedits)
  1099.             for(j=total_xedits;j>i;j--)
  1100.                 xedit[j]=xedit[j-1];
  1101.         if((xedit[i]=(xedit_t *)MALLOC(sizeof(xedit_t)))==NULL) {
  1102.             errormsg(WHERE,ERR_ALLOC,nulstr,sizeof(xedit_t));
  1103.             continue; }
  1104.         memset((xedit_t *)xedit[i],0,sizeof(xedit_t));
  1105.         strcpy(xedit[i]->name,str);
  1106.         strcpy(xedit[i]->code,code);
  1107.         total_xedits++;
  1108.         changes=1;
  1109.         continue; }
  1110.     if((i&MSK_ON)==MSK_DEL) {
  1111.         i&=MSK_OFF;
  1112.         FREE(xedit[i]);
  1113.         total_xedits--;
  1114.         for(j=i;j<total_xedits;j++)
  1115.             xedit[j]=xedit[j+1];
  1116.         changes=1;
  1117.         continue; }
  1118.     if((i&MSK_ON)==MSK_GET) {
  1119.         i&=MSK_OFF;
  1120.         savxedit=*xedit[i];
  1121.         continue; }
  1122.     if((i&MSK_ON)==MSK_PUT) {
  1123.         i&=MSK_OFF;
  1124.         *xedit[i]=savxedit;
  1125.         changes=1;
  1126.         continue; }
  1127.     done=0;
  1128.     while(!done) {
  1129.         k=0;
  1130.         sprintf(opt[k++],"%-32.32s%s","Name",xedit[i]->name);
  1131.         sprintf(opt[k++],"%-32.32s%s","Internal Code",xedit[i]->code);
  1132.         sprintf(opt[k++],"%-32.32s%.40s","Local Command Line",xedit[i]->lcmd);
  1133.         sprintf(opt[k++],"%-32.32s%.40s","Remote Command Line",xedit[i]->rcmd);
  1134.         sprintf(opt[k++],"%-32.32s%.40s","Access Requirements",xedit[i]->ar);
  1135.         sprintf(opt[k++],"%-32.32s%s%s","Intercept I/O Interrupts"
  1136.             ,xedit[i]->misc&IO_INTS ? "Yes":"No"
  1137.             ,xedit[i]->misc&WWIVCOLOR ? ", WWIV" : nulstr);
  1138.         sprintf(opt[k++],"%-32.32s%s","Quoted Text"
  1139.             ,xedit[i]->misc"EALL ? "All":xedit[i]->misc"ENONE
  1140.                 ? "None" : "Prompt User");
  1141.         sprintf(opt[k++],"%-32.32s%s","QuickBBS Style (MSGTMP)"
  1142.             ,xedit[i]->misc&QUICKBBS ? "Yes":"No");
  1143.         sprintf(opt[k++],"%-32.32s%s","Expand Line Feeds to CRLF"
  1144.             ,xedit[i]->misc&EXPANDLF ? "Yes":"No");
  1145.         switch(xedit[i]->type) {
  1146.             case XTRN_SBBS:
  1147.                 sprintf(str,"%-15s %s","Synchronet","XTRN.DAT");
  1148.                 break;
  1149.             case XTRN_WWIV:
  1150.                 sprintf(str,"%-15s %s","WWIV","CHAIN.TXT");
  1151.                 break;
  1152.             case XTRN_GAP:
  1153.                 sprintf(str,"%-15s %s","GAP","DOOR.SYS");
  1154.                 break;
  1155.             case XTRN_RBBS:
  1156.                 sprintf(str,"%-15s %s","RBBS/QuickBBS","DORINFO#.DEF");
  1157.                 break;
  1158.             case XTRN_RBBS1:
  1159.                 sprintf(str,"%-15s %s","RBBS/QuickBBS","DORINFO1.DEF");
  1160.                 break;
  1161.             case XTRN_WILDCAT:
  1162.                 sprintf(str,"%-15s %s","Wildcat","CALLINFO.BBS");
  1163.                 break;
  1164.             case XTRN_PCBOARD:
  1165.                 sprintf(str,"%-15s %s","PCBoard","PCBOARD.SYS");
  1166.                 break;
  1167.             case XTRN_SPITFIRE:
  1168.                 sprintf(str,"%-15s %s","SpitFire","SFDOORS.DAT");
  1169.                 break;
  1170.             case XTRN_UTI:
  1171.                 sprintf(str,"%-15s %s","MegaMail","UTIDOOR.TXT");
  1172.                 break;
  1173.             case XTRN_SR:
  1174.                 sprintf(str,"%-15s %s","Solar Realms","DOORFILE.SR");
  1175.                 break;
  1176.             case XTRN_TRIBBS:
  1177.                 sprintf(str,"%-15s %s","TriBBS","TRIBBS.SYS");
  1178.                 break;
  1179.             default:
  1180.                 strcpy(str,"None");
  1181.                 break; }
  1182.         sprintf(opt[k++],"%-32.32s%s","BBS Drop File Type",str);
  1183.         opt[k][0]=0;
  1184.         SETHELP(WHERE);
  1185. /*
  1186. External Editor Configuration:
  1187.  
  1188. This menu allows you to change the settings for the selected external
  1189. message editor. External message editors are very common on BBSs. Some
  1190. popular editors include SyncEdit, WWIVedit, FEdit, GEdit, IceEdit,
  1191. and many others.
  1192. */
  1193.  
  1194.         savnum=1;
  1195.         sprintf(str,"%s Editor",xedit[i]->name);
  1196.         switch(ulist(WIN_SAV|WIN_ACT|WIN_L2R|WIN_BOT,0,0,70,&dfltopt,0
  1197.             ,str,opt)) {
  1198.             case -1:
  1199.                 done=1;
  1200.                 break;
  1201.             case 0:
  1202.                 SETHELP(WHERE);
  1203. /*
  1204. External Editor Name:
  1205.  
  1206. This is the name or description of the external editor.
  1207. */
  1208.                 strcpy(str,xedit[i]->name);
  1209.                 if(!uinput(WIN_MID|WIN_SAV,0,10,"External Editor Name"
  1210.                     ,xedit[i]->name,40,K_EDIT))
  1211.                     strcpy(xedit[i]->name,str);
  1212.                 break;
  1213.             case 1:
  1214.                 strcpy(str,xedit[i]->code);
  1215.                 SETHELP(WHERE);
  1216. /*
  1217. External Editor Internal Code:
  1218.  
  1219. Every external editor must have its own unique internal code for
  1220. Synchronet to reference it by. It is helpful if this code is an
  1221. abreviation of the name.
  1222. */
  1223.                 uinput(WIN_MID|WIN_SAV,0,17,"Internal Code (unique)"
  1224.                     ,str,8,K_EDIT|K_UPPER);
  1225.                 if(code_ok(str))
  1226.                     strcpy(xedit[i]->code,str);
  1227.                 else {
  1228.                     helpbuf=invalid_code;
  1229.                     umsg("Invalid Code");
  1230.                     helpbuf=0; }
  1231.                 break;
  1232.             case 2:
  1233.                 SETHELP(WHERE);
  1234. /*
  1235. External Editor Local Command Line:
  1236.  
  1237. This is the command line to execute when using this editor locally.
  1238. */
  1239.                 uinput(WIN_MID|WIN_SAV,0,10,"Local"
  1240.                     ,xedit[i]->lcmd,50,K_EDIT);
  1241.                 break;
  1242.  
  1243.            case 3:
  1244.                 SETHELP(WHERE);
  1245. /*
  1246. External Editor Remote Command Line:
  1247.  
  1248. This is the command line to execute when using this editor remotely.
  1249. */
  1250.                 uinput(WIN_MID|WIN_SAV,0,10,"Remote"
  1251.                     ,xedit[i]->rcmd,50,K_EDIT);
  1252.                 break;
  1253.             case 4:
  1254.                 savnum=2;
  1255.                 sprintf(str,"%s External Editor",xedit[i]->name);
  1256.                 getar(str,xedit[i]->ar);
  1257.                 break;
  1258.             case 5:
  1259.                 k=1;
  1260.                 strcpy(opt[0],"Yes");
  1261.                 strcpy(opt[1],"No");
  1262.                 opt[2][0]=0;
  1263.                 savnum=2;
  1264.                 SETHELP(WHERE);
  1265. /*
  1266. Intercept I/O Interrupts:
  1267.  
  1268. If this external editor has its own serial communication abilities or
  1269. requires a FOSSIL driver, set this option to No.
  1270. */
  1271.                 k=ulist(WIN_MID|WIN_SAV,0,0,0,&k,0,"Intercept I/O Interrupts"
  1272.                     ,opt);
  1273.                 if(!k && !(xedit[i]->misc&IO_INTS)) {
  1274.                     xedit[i]->misc|=IO_INTS;
  1275.                     changes=1; }
  1276.                 else if(k==1 && xedit[i]->misc&IO_INTS) {
  1277.                     xedit[i]->misc&=~(IO_INTS|WWIVCOLOR);
  1278.                     changes=1; }
  1279.                 if(!(xedit[i]->misc&IO_INTS))
  1280.                     break;
  1281.                 k=1;
  1282.                 strcpy(opt[0],"Yes");
  1283.                 strcpy(opt[1],"No");
  1284.                 opt[2][0]=0;
  1285.                 savnum=2;
  1286.                 SETHELP(WHERE);
  1287. /*
  1288. Editor Uses WWIV Color Codes:
  1289.  
  1290. If this editor was written for use exclusively under WWIV, set this
  1291. option to Yes.
  1292. */
  1293.                 k=ulist(WIN_MID|WIN_SAV,0,0,0,&k,0
  1294.                     ,"Editor Uses WWIV Color Codes",opt);
  1295.                 if(!k && !(xedit[i]->misc&WWIVCOLOR)) {
  1296.                     xedit[i]->misc|=WWIVCOLOR;
  1297.                     changes=1; }
  1298.                 else if(k==1 && xedit[i]->misc&WWIVCOLOR) {
  1299.                     xedit[i]->misc&=~WWIVCOLOR;
  1300.                     changes=1; }
  1301.                 break;
  1302.             case 6:
  1303.                 k=3;
  1304.                 strcpy(opt[0],"All");
  1305.                 strcpy(opt[1],"None");
  1306.                 strcpy(opt[2],"Prompt User");
  1307.                 opt[3][0]=0;
  1308.                 savnum=2;
  1309.                 SETHELP(WHERE);
  1310. /*
  1311. Quoted Text:
  1312.  
  1313. If you want all the message text to be automatically entered into the
  1314. message edit/quote file (INPUT.MSG or MSGTMP), select All.
  1315.  
  1316. If you want the user to be prompted for which lines to quote before
  1317. running the editor, select Prompt User.
  1318.  
  1319. If you want none of the lines to be automatically quoted, select None.
  1320. This option is mainly for use with editors that support the QUOTES.TXT
  1321. drop file (like SyncEdit v2.x).
  1322. */
  1323.                 k=ulist(WIN_MID|WIN_SAV,0,0,0,&k,0,"Quoted Text"
  1324.                     ,opt);
  1325.                 if(!k && !(xedit[i]->misc"EALL)) {
  1326.                     xedit[i]->misc|=QUOTEALL;
  1327.                     xedit[i]->misc&=~QUOTENONE;
  1328.                     changes=1; }
  1329.                 else if(k==1 && !(xedit[i]->misc"ENONE)) {
  1330.                     xedit[i]->misc|=QUOTENONE;
  1331.                     xedit[i]->misc&=~QUOTEALL;
  1332.                     changes=1; }
  1333.                 else if(k==2 && xedit[i]->misc&(QUOTENONE|QUOTEALL)) {
  1334.                     xedit[i]->misc&=~(QUOTENONE|QUOTEALL);
  1335.                     changes=1; }
  1336.                 break;
  1337.             case 7:
  1338.                 k=1;
  1339.                 strcpy(opt[0],"Yes");
  1340.                 strcpy(opt[1],"No");
  1341.                 opt[2][0]=0;
  1342.                 savnum=2;
  1343.                 SETHELP(WHERE);
  1344. /*
  1345. QuickBBS Style (MSGTMP):
  1346.  
  1347. If this external editor uses the QuickBBS style MSGTMP interface, set
  1348. this option to Yes.
  1349. */
  1350.                 k=ulist(WIN_MID|WIN_SAV,0,0,0,&k,0,"QuickBBS Style (MSGTMP)"
  1351.                     ,opt);
  1352.                 if(!k && !(xedit[i]->misc&QUICKBBS)) {
  1353.                     xedit[i]->misc|=QUICKBBS;
  1354.                     changes=1; }
  1355.                 else if(k==1 && xedit[i]->misc&QUICKBBS) {
  1356.                     xedit[i]->misc&=~QUICKBBS;
  1357.                     changes=1; }
  1358.                 break;
  1359.             case 8:
  1360.                 k=1;
  1361.                 strcpy(opt[0],"Yes");
  1362.                 strcpy(opt[1],"No");
  1363.                 opt[2][0]=0;
  1364.                 savnum=2;
  1365.                 SETHELP(WHERE);
  1366. /*
  1367. Expand Line Feeds to Carriage Return/Line Feed Pairs:
  1368.  
  1369. If this external editor saves new lines as a single line feed character
  1370. instead of a carriage return/line feed pair, set this option to Yes.
  1371. */
  1372.                 k=ulist(WIN_MID|WIN_SAV,0,0,0,&k,0,"Expand LF to CRLF"
  1373.                     ,opt);
  1374.                 if(!k && !(xedit[i]->misc&EXPANDLF)) {
  1375.                     xedit[i]->misc|=EXPANDLF;
  1376.                     changes=1; }
  1377.                 else if(k==1 && xedit[i]->misc&EXPANDLF) {
  1378.                     xedit[i]->misc&=~EXPANDLF;
  1379.                     changes=1; }
  1380.                 break;
  1381.             case 9:
  1382.                 k=0;
  1383.                 strcpy(opt[k++],"None");
  1384.                 sprintf(opt[k++],"%-15s %s","Synchronet","XTRN.DAT");
  1385.                 sprintf(opt[k++],"%-15s %s","WWIV","CHAIN.TXT");
  1386.                 sprintf(opt[k++],"%-15s %s","GAP","DOOR.SYS");
  1387.                 sprintf(opt[k++],"%-15s %s","RBBS/QuickBBS","DORINFO#.DEF");
  1388.                 sprintf(opt[k++],"%-15s %s","Wildcat","CALLINFO.BBS");
  1389.                 sprintf(opt[k++],"%-15s %s","PCBoard","PCBOARD.SYS");
  1390.                 sprintf(opt[k++],"%-15s %s","SpitFire","SFDOORS.DAT");
  1391.                 sprintf(opt[k++],"%-15s %s","MegaMail","UTIDOOR.TXT");
  1392.                 sprintf(opt[k++],"%-15s %s","Solar Realms","DOORFILE.SR");
  1393.                 sprintf(opt[k++],"%-15s %s","RBBS/QuickBBS","DORINFO1.DEF");
  1394.                 sprintf(opt[k++],"%-15s %s","TriBBS","TRIBBS.SYS");
  1395.                 opt[k][0]=0;
  1396.                 k=xedit[i]->type;
  1397.                 SETHELP(WHERE);
  1398. /*
  1399. External Program BBS Drop File Type:
  1400.  
  1401. If this external editor requires a specific BBS data (drop) file
  1402. format, select the file format from the list.
  1403. */
  1404.                 savnum=2;
  1405.                 k=ulist(WIN_MID|WIN_SAV,0,0,0,&k,0
  1406.                     ,"BBS Drop File Type",opt);
  1407.                 if(k==-1)
  1408.                     break;
  1409.                 if(xedit[i]->type!=k) {
  1410.                     xedit[i]->type=k;
  1411.                     changes=1; }
  1412.                 break;
  1413.  
  1414.                 } } }
  1415. }
  1416.  
  1417.  
  1418. void swap_cfg()
  1419. {
  1420.     static int dflt,bar;
  1421.     char str[81];
  1422.     int j,k;
  1423.     uint i;
  1424.  
  1425. while(1) {
  1426.     for(i=0;i<MAX_OPTS && i<total_swaps;i++)
  1427.         sprintf(opt[i],"%-25s",swap[i]->cmd);
  1428.     opt[i][0]=0;
  1429.     j=WIN_ACT|WIN_CHE|WIN_L2R|WIN_SAV;
  1430.     savnum=0;
  1431.     if(total_swaps)
  1432.         j|=WIN_DEL;
  1433.     if(total_swaps<MAX_OPTS)
  1434.         j|=WIN_INS|WIN_INSACT|WIN_XTR;
  1435.     SETHELP(WHERE);
  1436. /*
  1437. External Program Global Swap List:
  1438.  
  1439. This is a list of the external program (executable file) names to swap
  1440. the BBS out of memory for. They are termed Global because if you add
  1441. a program name to this list, the BBS will swap to run it regardless of
  1442. when, where, or why the program is run from the BBS.
  1443.  
  1444. Use  INS  and  DELETE  to add and remove swappable programs.
  1445.  
  1446. To change the filename of a program, hit  ENTER .
  1447.  
  1448. To swap whenever PKZIP is run, add PKZIP to the list.
  1449.  
  1450. To swap for all DOS Shells, add COMMAND.COM to the list.
  1451. */
  1452.     i=ulist(j,0,0,17,&dflt,&bar,"Global Swap List",opt);
  1453.     if((signed)i==-1)
  1454.         return;
  1455.     if((i&MSK_ON)==MSK_INS) {
  1456.         i&=MSK_OFF;
  1457.         SETHELP(WHERE);
  1458. /*
  1459. Swappable Program Name:
  1460.  
  1461. This is the executable filename of the external program.
  1462. */
  1463.         if(uinput(WIN_MID|WIN_SAV,0,0,"Program Name",str,12
  1464.             ,K_UPPER)<1)
  1465.             continue;
  1466.         if((swap=(swap_t **)REALLOC(swap
  1467.             ,sizeof(swap_t *)*(total_swaps+1)))==NULL) {
  1468.             errormsg(WHERE,ERR_ALLOC,nulstr,total_swaps+1);
  1469.             total_swaps=0;
  1470.             bail(1);
  1471.             continue; }
  1472.         if(total_swaps)
  1473.             for(j=total_swaps;j>i;j--)
  1474.                 swap[j]=swap[j-1];
  1475.         if((swap[i]=(swap_t *)MALLOC(sizeof(swap_t)))==NULL) {
  1476.             errormsg(WHERE,ERR_ALLOC,nulstr,sizeof(swap_t));
  1477.             continue; }
  1478.         memset((swap_t *)swap[i],0,sizeof(swap_t));
  1479.         strcpy(swap[i]->cmd,str);
  1480.         total_swaps++;
  1481.         changes=1;
  1482.         continue; }
  1483.     if((i&MSK_ON)==MSK_DEL) {
  1484.         i&=MSK_OFF;
  1485.         FREE(swap[i]);
  1486.         total_swaps--;
  1487.         for(j=i;j<total_swaps;j++)
  1488.             swap[j]=swap[j+1];
  1489.         changes=1;
  1490.         continue; }
  1491.     SETHELP(WHERE);
  1492. /*
  1493. Swappable Program Name:
  1494.  
  1495. This is the executable filename of the external program.
  1496. */
  1497.     strcpy(str,swap[i]->cmd);
  1498.     if(uinput(WIN_MID|WIN_SAV,0,5,"Program Name",str,12
  1499.         ,K_UPPER|K_EDIT)>0)
  1500.         strcpy(swap[i]->cmd,str); }
  1501. }
  1502.  
  1503. int os2pgm_cfg()
  1504. {
  1505.     static int dflt,bar;
  1506.     char str[81];
  1507.     int j,k;
  1508.     uint i;
  1509.  
  1510. while(1) {
  1511.     for(i=0;i<MAX_OPTS && i<total_os2pgms;i++)
  1512.         sprintf(opt[i],"%-12s %-12s",os2pgm[i]->name
  1513.             ,os2pgm[i]->misc&OS2_POPEN ? "(port open)":nulstr);
  1514.     opt[i][0]=0;
  1515.     j=WIN_ACT|WIN_CHE|WIN_L2R|WIN_SAV;
  1516.     savnum=0;
  1517.     if(total_os2pgms)
  1518.         j|=WIN_DEL;
  1519.     if(total_os2pgms<MAX_OPTS)
  1520.         j|=WIN_INS|WIN_INSACT|WIN_XTR;
  1521.     SETHELP(WHERE);
  1522. /*
  1523. OS/2 Program List:
  1524.  
  1525. This is a list of all native OS/2 external program (executable file)
  1526. names that you may execute under Synchronet for OS/2. This list is not
  1527. used in Synchronet for DOS. Any programs not listed here will be assumed
  1528. to be DOS programs and executed accordingly.
  1529.  
  1530. Use  INS  and  DELETE  to add and remove OS/2 programs.
  1531.  
  1532. To change the filename of a program, hit  ENTER .
  1533. */
  1534.     i=ulist(j,0,0,30,&dflt,&bar,"OS/2 Program List",opt);
  1535.     if((signed)i==-1)
  1536.         break;
  1537.     if((i&MSK_ON)==MSK_INS) {
  1538.         i&=MSK_OFF;
  1539.         SETHELP(WHERE);
  1540. /*
  1541. OS/2 Program Name:
  1542.  
  1543. This is the executable filename of the OS/2 external program.
  1544. */
  1545.         if(uinput(WIN_MID|WIN_SAV,0,0,"OS/2 Program Name",str,12
  1546.             ,K_UPPER)<1)
  1547.             continue;
  1548.         if((os2pgm=(os2pgm_t **)REALLOC(os2pgm
  1549.             ,sizeof(os2pgm_t *)*(total_os2pgms+1)))==NULL) {
  1550.             errormsg(WHERE,ERR_ALLOC,nulstr,total_os2pgms+1);
  1551.             total_os2pgms=0;
  1552.             bail(1);
  1553.             continue; }
  1554.         if(total_os2pgms)
  1555.             for(j=total_os2pgms;j>i;j--)
  1556.                 os2pgm[j]=os2pgm[j-1];
  1557.         if((os2pgm[i]=(os2pgm_t *)MALLOC(sizeof(os2pgm_t)))==NULL) {
  1558.             errormsg(WHERE,ERR_ALLOC,nulstr,sizeof(os2pgm_t));
  1559.             continue; }
  1560.         memset((os2pgm_t *)os2pgm[i],0,sizeof(os2pgm_t));
  1561.         strcpy(os2pgm[i]->name,str);
  1562.  
  1563.         SETHELP(WHERE);
  1564. /*
  1565. Leave COM Port Open During Execution:
  1566.  
  1567. If this program accesses the COM port via handle (currently open COM
  1568. port), set this option to Yes, otherwise set it to No.
  1569. */
  1570.         strcpy(opt[0],"Yes (This Program Uses Port Handle)");
  1571.         strcpy(opt[1],"No  (This Program Uses Port Number)");
  1572.         opt[2][0]=0;
  1573.         j=1;
  1574.         if(ulist(WIN_MID|WIN_SAV,0,0,0,&j,0
  1575.             ,"Leave COM Port Open During Execution?",opt)==0)
  1576.             os2pgm[i]->misc|=OS2_POPEN;
  1577.         total_os2pgms++;
  1578.         changes=1;
  1579.         continue; }
  1580.     if((i&MSK_ON)==MSK_DEL) {
  1581.         i&=MSK_OFF;
  1582.         FREE(os2pgm[i]);
  1583.         total_os2pgms--;
  1584.         for(j=i;j<total_os2pgms;j++)
  1585.             os2pgm[j]=os2pgm[j+1];
  1586.         changes=1;
  1587.         continue; }
  1588.     SETHELP(WHERE);
  1589. /*
  1590. OS/2 Program Name:
  1591.  
  1592. This is the executable filename of the OS/2 external program.
  1593. */
  1594.     strcpy(str,os2pgm[i]->name);
  1595.     if(uinput(WIN_MID|WIN_SAV,0,5,"OS/2 Program Name",str,12
  1596.         ,K_UPPER|K_EDIT)>0)
  1597.         strcpy(os2pgm[i]->name,str);
  1598.  
  1599.     SETHELP(WHERE);
  1600. /*
  1601. Leave COM Port Open During Execution:
  1602.  
  1603. If this program accesses the COM port via handle (currently open COM
  1604. port), set this option to Yes, otherwise set it to No.
  1605. */
  1606.     strcpy(opt[0],"Yes (This Program Uses Port Handle)");
  1607.     strcpy(opt[1],"No  (This Program Uses Port Number)");
  1608.     opt[2][0]=0;
  1609.     j=1;
  1610.     savnum=1;
  1611.     j=ulist(WIN_MID|WIN_SAV,0,0,0,&j,0
  1612.         ,"Leave COM Port Open During Execution",opt);
  1613.     if(j==0 && !(os2pgm[i]->misc&OS2_POPEN)) {
  1614.         os2pgm[i]->misc|=OS2_POPEN;
  1615.         changes=1; }
  1616.     else if(j==1 && os2pgm[i]->misc&OS2_POPEN) {
  1617.         os2pgm[i]->misc&=~OS2_POPEN;
  1618.         changes=1; }
  1619.     }
  1620. return(0);
  1621. }
  1622.  
  1623.  
  1624. void xtrnsec_cfg()
  1625. {
  1626.     static int xtrnsec_dflt,xtrnsec_opt;
  1627.     char str[81],code[9],done=0,*p;
  1628.     int j,k;
  1629.     uint i;
  1630.     static xtrnsec_t savxtrnsec;
  1631.  
  1632. while(1) {
  1633.     for(i=0;i<total_xtrnsecs && i<MAX_OPTS;i++)
  1634.         sprintf(opt[i],"%-25s",xtrnsec[i]->name);
  1635.     opt[i][0]=0;
  1636.     j=WIN_SAV|WIN_ACT|WIN_CHE|WIN_BOT;
  1637.     savnum=0;
  1638.     if(total_xtrnsecs)
  1639.         j|=WIN_DEL|WIN_GET;
  1640.     if(total_xtrnsecs<MAX_OPTS)
  1641.         j|=WIN_INS|WIN_INSACT|WIN_XTR;
  1642.     if(savxtrnsec.name[0])
  1643.         j|=WIN_PUT;
  1644.     SETHELP(WHERE);
  1645. /*
  1646. Online Program Sections:
  1647.  
  1648. This is a list of Online Program Sections configured for your system.
  1649.  
  1650. To add an online program section, select the desired location with the
  1651. arrow keys and hit  INS .
  1652.  
  1653. To delete an online program section, select it and hit  DEL .
  1654.  
  1655. To configure an online program section, select it and hit  ENTER .
  1656. */
  1657.     i=ulist(j,0,0,45,&xtrnsec_dflt,0,"Online Program Sections",opt);
  1658.     if((signed)i==-1)
  1659.         return;
  1660.     if((i&MSK_ON)==MSK_INS) {
  1661.         i&=MSK_OFF;
  1662.         SETHELP(WHERE);
  1663. /*
  1664. Online Program Section Name:
  1665.  
  1666. This is the name of this section.
  1667. */
  1668.         if(uinput(WIN_MID|WIN_SAV,0,0,"Online Program Section Name",str,40
  1669.             ,0)<1)
  1670.             continue;
  1671.         sprintf(code,"%.8s",str);
  1672.         p=strchr(code,SP);
  1673.         if(p) *p=0;
  1674.         strupr(code);
  1675.         SETHELP(WHERE);
  1676. /*
  1677. Online Program Section Internal Code:
  1678.  
  1679. Every online program section must have its own unique internal code
  1680. for Synchronet to reference it by. It is helpful if this code is an
  1681. abreviation of the name.
  1682. */
  1683.         if(uinput(WIN_MID|WIN_SAV,0,0,"Online Program Section Internal Code"
  1684.             ,code,8,K_EDIT|K_UPPER)<1)
  1685.             continue;
  1686.         if(!code_ok(code)) {
  1687.             helpbuf=invalid_code;
  1688.             umsg("Invalid Code");
  1689.             helpbuf=0;
  1690.             continue; }
  1691.         if((xtrnsec=(xtrnsec_t **)REALLOC(xtrnsec
  1692.             ,sizeof(xtrnsec_t *)*(total_xtrnsecs+1)))==NULL) {
  1693.             errormsg(WHERE,ERR_ALLOC,nulstr,total_xtrnsecs+1);
  1694.             total_xtrnsecs=0;
  1695.             bail(1);
  1696.             continue; }
  1697.         if(total_xtrnsecs) {
  1698.             for(j=total_xtrnsecs;j>i;j--)
  1699.                 xtrnsec[j]=xtrnsec[j-1];
  1700.             for(j=0;j<total_xtrns;j++)
  1701.                 if(xtrn[j]->sec>=i)
  1702.                     xtrn[j]->sec++; }
  1703.  
  1704.  
  1705.         if((xtrnsec[i]=(xtrnsec_t *)MALLOC(sizeof(xtrnsec_t)))==NULL) {
  1706.             errormsg(WHERE,ERR_ALLOC,nulstr,sizeof(xtrnsec_t));
  1707.             continue; }
  1708.         memset((xtrnsec_t *)xtrnsec[i],0,sizeof(xtrnsec_t));
  1709.         strcpy(xtrnsec[i]->name,str);
  1710.         strcpy(xtrnsec[i]->code,code);
  1711.         total_xtrnsecs++;
  1712.         changes=1;
  1713.         continue; }
  1714.     if((i&MSK_ON)==MSK_DEL) {
  1715.         i&=MSK_OFF;
  1716.         FREE(xtrnsec[i]);
  1717.         for(j=0;j<total_xtrns;) {
  1718.             if(xtrn[j]->sec==i) {     /* delete xtrns of this group */
  1719.                 FREE(xtrn[j]);
  1720.                 total_xtrns--;
  1721.                 k=j;
  1722.                 while(k<total_xtrns) {     /* move all xtrns down */
  1723.                     xtrn[k]=xtrn[k+1];
  1724.                     k++; } }
  1725.             else j++; }
  1726.         for(j=0;j<total_xtrns;j++)     /* move xtrn group numbers down */
  1727.             if(xtrn[j]->sec>i)
  1728.                 xtrn[j]->sec--;
  1729.         total_xtrnsecs--;
  1730.         while(i<total_xtrnsecs) {
  1731.             xtrnsec[i]=xtrnsec[i+1];
  1732.             i++; }
  1733.         changes=1;
  1734.         continue; }
  1735.     if((i&MSK_ON)==MSK_GET) {
  1736.         i&=MSK_OFF;
  1737.         savxtrnsec=*xtrnsec[i];
  1738.         continue; }
  1739.     if((i&MSK_ON)==MSK_PUT) {
  1740.         i&=MSK_OFF;
  1741.         *xtrnsec[i]=savxtrnsec;
  1742.         changes=1;
  1743.         continue; }
  1744.     done=0;
  1745.     while(!done) {
  1746.         k=0;
  1747.         sprintf(opt[k++],"%-27.27s%s","Name",xtrnsec[i]->name);
  1748.         sprintf(opt[k++],"%-27.27s%s","Internal Code",xtrnsec[i]->code);
  1749.         sprintf(opt[k++],"%-27.27s%.40s","Access Requirements"
  1750.             ,xtrnsec[i]->ar);
  1751.         sprintf(opt[k++],"%s","Available Online Programs...");
  1752.         opt[k][0]=0;
  1753.         savnum=1;
  1754.         sprintf(str,"%s Program Section",xtrnsec[i]->name);
  1755.         switch(ulist(WIN_SAV|WIN_ACT|WIN_MID,0,0,60,&xtrnsec_opt,0,str
  1756.             ,opt)) {
  1757.             case -1:
  1758.                 done=1;
  1759.                 break;
  1760.             case 0:
  1761.                 SETHELP(WHERE);
  1762. /*
  1763. Online Program Section Name:
  1764.  
  1765. This is the name of this section.
  1766. */
  1767.                 strcpy(str,xtrnsec[i]->name);     /* save */
  1768.                 if(!uinput(WIN_MID|WIN_SAV,0,10
  1769.                     ,"Online Program Section Name"
  1770.                     ,xtrnsec[i]->name,40,K_EDIT))
  1771.                     strcpy(xtrnsec[i]->name,str);
  1772.                 break;
  1773.             case 1:
  1774.                 strcpy(str,xtrnsec[i]->code);
  1775.                 SETHELP(WHERE);
  1776. /*
  1777. Online Program Section Internal Code:
  1778.  
  1779. Every online program section must have its own unique internal code
  1780. for Synchronet to reference it by. It is helpful if this code is an
  1781. abreviation of the name.
  1782. */
  1783.                 uinput(WIN_MID|WIN_SAV,0,17,"Internal Code (unique)"
  1784.                     ,str,8,K_EDIT|K_UPPER);
  1785.                 if(code_ok(str))
  1786.                     strcpy(xtrnsec[i]->code,str);
  1787.                 else {
  1788.                     helpbuf=invalid_code;
  1789.                     umsg("Invalid Code");
  1790.                     helpbuf=0; }
  1791.                 break;
  1792.             case 2:
  1793.                 getar(xtrnsec[i]->name,xtrnsec[i]->ar);
  1794.                 break;
  1795.             case 3:
  1796.                 xtrn_cfg(i);
  1797.                 break; } } }
  1798. }
  1799.