home *** CD-ROM | disk | FTP | other *** search
/ PC Online 1998 September / PCO_0998.ISO / filesbbs / dos / sbbs_src.exe / SBBS / SCFG / SCFGNODE.C < prev    next >
Encoding:
Text File  |  1997-05-06  |  65.9 KB  |  2,164 lines

  1. #line 2 "SCFGNODE.C"
  2.  
  3. /* Developed 1990-1997 by Rob Swindell; PO Box 501, Yorba Linda, CA 92885 */
  4.  
  5. /****************************************************************************/
  6. /* Synchronet configuration utility                                         */
  7. /****************************************************************************/
  8.  
  9. #include "scfg.h"
  10. #include "spawno.h"
  11.  
  12. int com_type()
  13. {
  14.     int i;
  15.  
  16. i=0;
  17. strcpy(opt[0],"UART");
  18. strcpy(opt[1],"FOSSIL Int 14h");
  19. strcpy(opt[2],"PC BIOS Int 14h");
  20. strcpy(opt[3],"PS/2 BIOS Int 14h");
  21. strcpy(opt[4],"DigiBoard Int 14h");
  22. opt[5][0]=0;
  23. SETHELP(WHERE);
  24. /*
  25. COM Port Type:
  26.  
  27. Select the type of serial COM port for this node. If you are unsure,
  28. select UART. If you have a FOSSIL driver installed, you do not have to
  29. select FOSSIL unless you specifically want to override Synchronet's
  30. internal COM functions.
  31. */
  32. i=ulist(WIN_MID|WIN_SAV,0,0,0,&i,0
  33.     ,"COM Port Type",opt);
  34. if(i==-1)
  35.     return(0);
  36. changes=1;
  37. if(i) {
  38.     com_irq=com_port-1;
  39.     if(i==1) {
  40.         savnum=0;
  41.         umsg("WARNING: This is not a recommended setting for most systems");
  42.         umsg("The default DSZ command lines will not work with this setting");
  43.         com_base=0xf; }
  44.     else if(i==2)
  45.         com_base=0xb;
  46.     else if(i==3)
  47.         com_base=0xe;
  48.     else if(i==4)
  49.         com_base=0xd; }
  50.  
  51. else {    /* UART */
  52.     if(com_port && com_port<5) {
  53.         i=0;
  54.         strcpy(opt[0],"Yes");
  55.         strcpy(opt[1],"No");
  56.         opt[2][0]=0;
  57.         SETHELP(WHERE);
  58. /*
  59. Use Default UART IRQ and I/O Address:
  60.  
  61. If your COM Port's UART is using the normal IRQ and Base I/O Address
  62. for the configured COM Port number, select Yes. If your COM Port
  63. is using a non-standard IRQ or I/O Address, select No and be sure
  64. to set the UART IRQ and UART I/O Address options. If you are not
  65. sure what IRQ and I/O Address your COM Port is using, select Yes.
  66. */
  67.         i=ulist(WIN_MID|WIN_SAV,0,0,0,&i,0
  68.             ,"Use Default UART IRQ and I/O Address"
  69.             ,opt);
  70.         if(i==0) {
  71.             switch(com_port) {
  72.                 case 1:
  73.                     com_irq=4;
  74.                     com_base=0x3f8;
  75.                     break;
  76.                 case 2:
  77.                     com_irq=3;
  78.                     com_base=0x2f8;
  79.                     break;
  80.                 case 3:
  81.                     com_irq=4;
  82.                     com_base=0x3e8;
  83.                     break;
  84.                 case 4:
  85.                     com_irq=3;
  86.                     com_base=0x2e8;
  87.                     break; }
  88.             changes=1;
  89.             return(1); } }
  90.     else {
  91.         if(com_base<0x100)
  92.             com_base=0x100;
  93.         if(com_irq<2 || com_irq>15)
  94.             com_irq=5; } }
  95. return(0);
  96. }
  97.  
  98. void node_menu()
  99. {
  100.     char    done,str[81],savnode=0;
  101.     int     i,j;
  102.     static int node_menu_dflt,node_bar;
  103.  
  104. while(1) {
  105.     for(i=0;i<sys_nodes;i++)
  106.         sprintf(opt[i],"Node %d",i+1);
  107.     opt[i][0]=0;
  108.     j=WIN_ORG|WIN_ACT|WIN_INSACT|WIN_DELACT;
  109.     if(sys_nodes>1)
  110.         j|=WIN_DEL|WIN_GET;
  111.     if(sys_nodes<MAX_NODES && sys_nodes<MAX_OPTS)
  112.         j|=WIN_INS;
  113.     if(savnode)
  114.         j|=WIN_PUT;
  115. SETHELP(WHERE);
  116. /*
  117. Node List:
  118.  
  119. This is the list of configured nodes in your system.
  120.  
  121. To add a node, hit  INS .
  122.  
  123. To delete a node, hit  DEL .
  124.  
  125. To configure a node, select it using the arrow keys and hit  ENTER .
  126.  
  127. To copy a node's configuration to another node, first select the source
  128. node with the arrow keys and hit  F5 . Then select the destination
  129. node and hit  F6 .
  130. */
  131.  
  132.     i=ulist(j,0,0,13,&node_menu_dflt,&node_bar,"Nodes",opt);
  133.     if(i==-1) {
  134.         if(savnode) {
  135.             free_node_cfg();
  136.             savnode=0; }
  137.         return; }
  138.  
  139.     if((i&MSK_ON)==MSK_DEL) {
  140.         strcpy(opt[0],"Yes");
  141.         strcpy(opt[1],"No");
  142.         opt[2][0]=0;
  143.         sprintf(str,"Delete Node %d",sys_nodes);
  144.         i=1;
  145. SETHELP(WHERE);
  146. /*
  147. Delete Node:
  148.  
  149. If you are positive you want to delete this node, select Yes. Otherwise,
  150. select No or hit  ESC .
  151. */
  152.         i=ulist(WIN_MID,0,0,0,&i,0,str,opt);
  153.         if(!i) {
  154.             --sys_nodes;
  155.             FREE(node_path[sys_nodes]);
  156.             write_main_cfg(); }
  157.         continue; }
  158.     if((i&MSK_ON)==MSK_INS) {
  159.         strcpy(node_dir,node_path[sys_nodes-1]);
  160.         i=sys_nodes+1;
  161.         upop("Reading NODE.CNF...");
  162.         read_node_cfg(txt);
  163.         upop(0);
  164.         sprintf(str,"..\\NODE%d\\",i);
  165.         sprintf(tmp,"Node %d Path",i);
  166. SETHELP(WHERE);
  167. /*
  168. Node Path:
  169.  
  170. This is the path to this node's private directory where its separate
  171. configuration and data files are stored.
  172.  
  173. The drive and directory of this path can be set to any valid DOS
  174. directory that can be accessed by ALL nodes and MUST NOT be on a RAM disk
  175. or other volatile media.
  176.  
  177. If you want to abort the creation of this new node, hit  ESC .
  178. */
  179.         j=uinput(WIN_MID,0,0,tmp,str,50,K_EDIT|K_UPPER);
  180.         changes=0;
  181.         if(j<2)
  182.             continue;
  183.         truncsp(str);
  184.         if((node_path=(char **)REALLOC(node_path,sizeof(char *)*(sys_nodes+1)))
  185.             ==NULL) {
  186.             errormsg(WHERE,ERR_ALLOC,nulstr,sys_nodes+1);
  187.             continue; }
  188.         if((node_path[i-1]=MALLOC(strlen(str)+2))==NULL) {
  189.             errormsg(WHERE,ERR_ALLOC,str,strlen(str)+2);
  190.             continue; }
  191.         strcpy(node_path[i-1],str);
  192.         if(str[strlen(str)-1]=='\\')
  193.             str[strlen(str)-1]=0;
  194.         mkdir(str);
  195.         node_num=++sys_nodes;
  196.         sprintf(node_name,"Node %u",node_num);
  197.         write_node_cfg();
  198.         write_main_cfg();
  199.         free_node_cfg();
  200.         continue; }
  201.     if((i&MSK_ON)==MSK_GET) {
  202.         if(savnode)
  203.             free_node_cfg();
  204.         i&=MSK_OFF;
  205.         strcpy(node_dir,node_path[i]);
  206.         upop("Reading NODE.CNF...");
  207.         read_node_cfg(txt);
  208.         upop(0);
  209.         savnode=1;
  210.         continue; }
  211.     if((i&MSK_ON)==MSK_PUT) {
  212.         i&=MSK_OFF;
  213.         strcpy(node_dir,node_path[i]);
  214.         node_num=i+1;
  215.         write_node_cfg();
  216.         changes=1;
  217.         continue; }
  218.  
  219.     if(savnode) {
  220.         free_node_cfg();
  221.         savnode=0; }
  222.     strcpy(node_dir,node_path[i]);
  223.     upop("Reading NODE.CNF...");
  224.     read_node_cfg(txt);
  225.     upop(0);
  226.     if(node_num!=i+1) {     /* Node number isn't right? */
  227.         node_num=i+1;        /* so fix it */
  228.         write_node_cfg(); } /* and write it back */
  229.     node_cfg();
  230.  
  231.     free_node_cfg(); }
  232. }
  233.  
  234. void node_cfg()
  235. {
  236.     static    int node_dflt;
  237.     char    done,str[81];
  238.     static    int mdm_dflt,adv_dflt,tog_dflt,tog_bar;
  239.     int     i,j,dflt=0,bar=0;
  240.  
  241. while(1) {
  242.     i=0;
  243.     sprintf(opt[i++],"%-27.27s%s","Name",node_name);
  244.     sprintf(opt[i++],"%-27.27s%s","Phone Number",node_phone);
  245.     sprintf(opt[i++],"%-27.27s%ubps","Minimum Connect Rate",node_minbps);
  246.     sprintf(opt[i++],"%-27.27s%.40s","Logon Requirements",node_ar);
  247.     sprintf(opt[i++],"%-27.27s%.40s","Local Text Editor",node_editor);
  248.     sprintf(opt[i++],"%-27.27s%.40s","Local Text Viewer",node_viewer);
  249.     sprintf(opt[i++],"%-27.27s%.40s","Configuration Command",scfg_cmd);
  250.     sprintf(opt[i++],"%-27.27s%.40s","DOS Command Interpreter"
  251.         ,node_comspec[0] ? node_comspec : "%COMSPEC%");
  252.     strcpy(opt[i++],"Toggle Options...");
  253.     strcpy(opt[i++],"Advanced Options...");
  254.     strcpy(opt[i++],"Modem Configuration...");
  255.     strcpy(opt[i++],"Wait for Call Number Keys...");
  256.     strcpy(opt[i++],"Wait for Call Function Keys...");
  257.     opt[i][0]=0;
  258.     sprintf(str,"Node %d Configuration",node_num);
  259. SETHELP(WHERE);
  260. /*
  261. Node Configuration Menu:
  262.  
  263. This is the node configuration menu. The options available from this
  264. menu will only affect the selected node's configuration.
  265.  
  266. Options with a trailing ... will produce a sub-menu of more options.
  267. */
  268.     switch(ulist(WIN_ACT|WIN_CHE|WIN_BOT|WIN_RHT,0,0,60,&node_dflt,0
  269.         ,str,opt)) {
  270.         case -1:
  271.             i=save_changes(WIN_MID);
  272.             if(!i)
  273.                 write_node_cfg();
  274.             if(i!=-1)
  275.                 return;
  276.             break;
  277.         case 0:
  278. SETHELP(WHERE);
  279. /*
  280. Node Name:
  281.  
  282. This is the name of the selected node. It is used for documentary
  283. purposes only.
  284. */
  285.             uinput(WIN_MID|WIN_SAV,0,10,"Name",node_name,40,K_EDIT);
  286.             break;
  287.         case 1:
  288. SETHELP(WHERE);
  289. /*
  290. Node Phone Number:
  291.  
  292. This is the phone number to access the selected node. It is used for
  293. documentary purposes only.
  294. */
  295.             uinput(WIN_MID|WIN_SAV,0,10,"Phone Number",node_phone,12,K_EDIT);
  296.             break;
  297.         case 2:
  298. SETHELP(WHERE);
  299. /*
  300. Minimum Connect Rate:
  301.  
  302. This is the lowest modem connection speed allowed for the selected node.
  303. The speed is a decimal number representing bits per second (bps) or more
  304. inaccurately referred to as baud.
  305.  
  306. If a user attempts to logon this node at a speed lower than the minimum
  307. connect rate, a message is displayed explaining the minimum connect
  308. rate and the user is disconnected.
  309.  
  310. If the file TEXT\TOOSLOW.MSG exists, it will be displayed to the user
  311. before the user is disconnected.
  312.  
  313. Users with the M exemption can log onto any node at any speed.
  314. */
  315.             sprintf(str,"%u",node_minbps);
  316.             uinput(WIN_MID|WIN_SAV,0,10,"Minimum Connect Rate",str,5
  317.                 ,K_NUMBER|K_EDIT);
  318.             node_minbps=atoi(str);
  319.             break;
  320.         case 3:
  321.             sprintf(str,"Node %u Logon",node_num);
  322.             getar(str,node_ar);
  323.             break;
  324.         case 4:
  325. SETHELP(WHERE);
  326. /*
  327. Local Text Editor:
  328.  
  329. This is the command line to execute to edit text files locally in
  330. Synchronet. If this command line is blank, the default editor of the
  331. sysop (user #1) will be used.
  332.  
  333. This command line can be used to create posts and e-mail locally, if the
  334. toggle option Use Editor for Messages is set to Yes.
  335.  
  336. The %f command line specifier is used for the filename to edit.
  337. */
  338.             uinput(WIN_MID|WIN_SAV,0,13,"Editor",node_editor
  339.                 ,50,K_EDIT);
  340.             break;
  341.         case 5:
  342. SETHELP(WHERE);
  343. /*
  344. Local Text Viewer:
  345.  
  346. This is the command line used to view log files from the wait for call
  347. screen.
  348.  
  349. The %f command line specifier is used for the filename to view.
  350. */
  351.             uinput(WIN_MID|WIN_SAV,0,14,"Viewer",node_viewer
  352.                 ,50,K_EDIT);
  353.             break;
  354.         case 6:
  355. SETHELP(WHERE);
  356. /*
  357. Configuration Command Line:
  358.  
  359. This is the command line used to launch the Synchronet configuration
  360. program (SCFG) from this node's Waiting for Call (WFC) screen.
  361. */
  362.             uinput(WIN_MID|WIN_SAV,0,14,"Configuration Command",scfg_cmd
  363.                 ,40,K_EDIT);
  364.             break;
  365.         case 7:
  366. SETHELP(WHERE);
  367. /*
  368. DOS Command Interpreter:
  369.  
  370. This is the complete path to your DOS command interpreter (normally
  371. COMMAND.COM). Leaving this option blank (designated by %COMSPEC%)
  372. specifies that the path contained in the COMSPEC environment variable
  373. should be used.
  374.  
  375. When running Synchronet for OS/2, this option should be set to:
  376. C:\OS2\MDOS\COMMAND.COM.
  377. */
  378.             uinput(WIN_MID|WIN_SAV,0,14,"DOS Command Interpreter"
  379.                 ,node_comspec,40,K_EDIT);
  380.             break;
  381.         case 8:
  382.             done=0;
  383.             while(!done) {
  384.                 i=0;
  385.                 sprintf(opt[i++],"%-27.27s%s","Alarm When Answering"
  386.                     ,node_misc&NM_ANSALARM ? "Yes":"No");
  387.                 sprintf(opt[i++],"%-27.27s%s","Status Screen While WFC"
  388.                     ,node_misc&NM_WFCSCRN ? "Yes":"No");
  389.                 sprintf(opt[i++],"%-27.27s%s","Total Msgs/Files on WFC"
  390.                     ,node_misc&NM_WFCMSGS ? "Yes":"No");
  391.                 sprintf(opt[i++],"%-27.27s%s","Use Editor for Messages"
  392.                     ,node_misc&NM_LCL_EDIT ? "Yes":"No");
  393.                 sprintf(opt[i++],"%-27.27s%s","Use EMS for Overlays"
  394.                     ,node_misc&NM_EMSOVL ? "Yes":"No");
  395.                 sprintf(opt[i++],"%-27.27s%s","Allow Swapping"
  396.                     ,node_swap&SWAP_NONE ? "No":"Yes");
  397.                 sprintf(opt[i++],"%-27.27s%s","Swap to EMS Memory"
  398.                     ,node_swap&SWAP_EMS ? "Yes":"No");
  399.                 sprintf(opt[i++],"%-27.27s%s","Swap to XMS Memory"
  400.                     ,node_swap&SWAP_XMS ? "Yes":"No");
  401.                 sprintf(opt[i++],"%-27.27s%s","Swap to Extended Memory"
  402.                     ,node_swap&SWAP_EXT ? "Yes":"No");
  403.                 sprintf(opt[i++],"%-27.27s%s","Windows/OS2 Time Slice API"
  404.                     ,node_misc&NM_WINOS2 ? "Yes":"No");
  405.                 sprintf(opt[i++],"%-27.27s%s","DESQview Time Slice API"
  406.                     ,node_misc&NM_NODV ? "No":"Yes");
  407.                 sprintf(opt[i++],"%-27.27s%s","DOS Idle Interrupts"
  408.                     ,node_misc&NM_INT28 ? "Yes":"No");
  409.                 sprintf(opt[i++],"%-27.27s%s","Low Priority String Input"
  410.                     ,node_misc&NM_LOWPRIO ? "Yes":"No");
  411.                 sprintf(opt[i++],"%-27.27s%s","Allow Logon by Number"
  412.                     ,node_misc&NM_NO_NUM ? "No":"Yes");
  413.                 sprintf(opt[i++],"%-27.27s%s","Allow Logon by Real Name"
  414.                     ,node_misc&NM_LOGON_R ? "Yes":"No");
  415.                 sprintf(opt[i++],"%-27.27s%s","Always Prompt for Password"
  416.                     ,node_misc&NM_LOGON_P ? "Yes":"No");
  417.                 sprintf(opt[i++],"%-27.27s%s","Disable Local Inactivity"
  418.                     ,node_misc&NM_NO_INACT ? "Yes":"No");
  419.                 sprintf(opt[i++],"%-27.27s%s","Disable Local Keyboard"
  420.                     ,node_misc&NM_NO_LKBRD ? "Yes":"No");
  421.                 sprintf(opt[i++],"%-27.27s%s","Local System Protection"
  422.                     ,node_misc&NM_SYSPW ? "Yes":"No");
  423.                 sprintf(opt[i++],"%-27.27s%s","Beep Locally"
  424.                     ,node_misc&NM_NOBEEP ? "No":"Yes");
  425.                 sprintf(opt[i++],"%-27.27s%s","Allow 8-bit Remote Logons"
  426.                     ,node_misc&NM_7BITONLY ? "No":"Yes");
  427.                 sprintf(opt[i++],"%-27.27s%s","Reset Video Between Calls"
  428.                     ,node_misc&NM_RESETVID ? "Yes":"No");
  429.  
  430.                 opt[i][0]=0;
  431.                 savnum=0;
  432. SETHELP(WHERE);
  433. /*
  434. Node Toggle Options:
  435.  
  436. This is the toggle options menu for the selected node's configuration.
  437.  
  438. The available options from this menu can all be toggled between two or
  439. more states, such as Yes and No.
  440. */
  441.                 switch(ulist(WIN_BOT|WIN_RHT|WIN_ACT|WIN_SAV,3,2,35,&tog_dflt
  442.                     ,&tog_bar,"Toggle Options",opt)) {
  443.                     case -1:
  444.                         done=1;
  445.                         break;
  446.                     case 0:
  447.                         i=1;
  448.                         strcpy(opt[0],"Yes");
  449.                         strcpy(opt[1],"No");
  450.                         opt[2][0]=0;
  451.                         savnum=1;
  452. SETHELP(WHERE);
  453. /*
  454. Alarm When Answering:
  455.  
  456. Set this option to Yes if want this node to make an alarm sound each
  457. time it answers an incoming call. Usually, the modem's speaker is a
  458. sufficient alarm if one is desired.
  459. */
  460.                         i=ulist(WIN_MID|WIN_SAV,0,15,0,&i,0
  461.                             ,"Sound Alarm When Answering",opt);
  462.                         if(i==0 && !(node_misc&NM_ANSALARM)) {
  463.                             node_misc|=NM_ANSALARM;
  464.                             changes=1; }
  465.                         else if(i==1 && (node_misc&NM_ANSALARM)) {
  466.                             node_misc&=~NM_ANSALARM;
  467.                             changes=1; }
  468.                         break;
  469.                     case 1:
  470.                         i=0;
  471.                         strcpy(opt[0],"Yes");
  472.                         strcpy(opt[1],"No");
  473.                         opt[2][0]=0;
  474.                         savnum=1;
  475. SETHELP(WHERE);
  476. /*
  477. Status Screen While WFC:
  478.  
  479. If you want the current system statistics and current status of all
  480. active nodes to be displayed while this node is waiting for a caller,
  481. set this option to Yes.
  482. */
  483.                         i=ulist(WIN_MID|WIN_SAV,0,10,0,&i,0
  484.                             ,"Display Status Screen While Waiting for Call",opt);
  485.                         if(i==0 && !(node_misc&NM_WFCSCRN)) {
  486.                             node_misc|=NM_WFCSCRN;
  487.                             changes=1; }
  488.                         else if(i==1 && (node_misc&NM_WFCSCRN)) {
  489.                             node_misc&=~NM_WFCSCRN;
  490.                             changes=1; }
  491.                         break;
  492.                     case 2:
  493.                         i=0;
  494.                         strcpy(opt[0],"Yes");
  495.                         strcpy(opt[1],"No");
  496.                         opt[2][0]=0;
  497.                         savnum=1;
  498. SETHELP(WHERE);
  499. /*
  500. Total Messages and Files on WFC Status Screen:
  501.  
  502. If you want the total number of messages and files to be retrieved
  503. and displayed on the WFC status screen, set this option to Yes.
  504.  
  505. Setting this option to No will significantly reduce the amount of
  506. time required to retrieve the system statistics on systems with large
  507. numbers of message and file areas.
  508. */
  509.                         i=ulist(WIN_MID|WIN_SAV,0,10,0,&i,0
  510.                             ,"Display Total Messages and Files while WFC",opt);
  511.                         if(i==0 && !(node_misc&NM_WFCMSGS)) {
  512.                             node_misc|=(NM_WFCMSGS|NM_WFCSCRN);
  513.                             changes=1; }
  514.                         else if(i==1 && (node_misc&NM_WFCMSGS)) {
  515.                             node_misc&=~NM_WFCMSGS;
  516.                             changes=1; }
  517.                         break;
  518.                     case 3:
  519.                         i=1;
  520.                         strcpy(opt[0],"Yes");
  521.                         strcpy(opt[1],"No");
  522.                         opt[2][0]=0;
  523.                         savnum=1;
  524. SETHELP(WHERE);
  525. /*
  526. Use Local Text Editor for Messages:
  527.  
  528. If a local text editor command has been specified, it can be used to
  529. create messages (posts and e-mail) locally by setting this option to
  530. Yes.
  531. */
  532.                         i=ulist(WIN_MID|WIN_SAV,0,10,0,&i,0
  533.                             ,"Use Local Text Editor to Create Messages",opt);
  534.                         if(i==0 && !(node_misc&NM_LCL_EDIT)) {
  535.                             node_misc|=NM_LCL_EDIT;
  536.                             changes=1; }
  537.                         else if(i==1 && (node_misc&NM_LCL_EDIT)) {
  538.                             node_misc&=~NM_LCL_EDIT;
  539.                             changes=1; }
  540.                         break;
  541.                     case 4:
  542.                         i=0;
  543.                         strcpy(opt[0],"Yes");
  544.                         strcpy(opt[1],"No");
  545.                         opt[2][0]=0;
  546.                         savnum=1;
  547. SETHELP(WHERE);
  548. /*
  549. Use Available Expanded Memory (EMS) for Swapping Overlays:
  550.  
  551. If you wish to use any available expanded memory (EMS) for swapping
  552. overlays, set this option to Yes. Swapping overlays to memory is much
  553. faster than swapping to disk.
  554.  
  555. If this option is set to Yes, Synchronet will attempt to allocation 360K
  556. of EMS for swapping overlays into.
  557. */
  558.                         i=ulist(WIN_MID|WIN_SAV,0,10,0,&i,0
  559.                             ,"Use Available EMS for Overlays",opt);
  560.                         if(i==0 && !(node_misc&NM_EMSOVL)) {
  561.                             node_misc|=NM_EMSOVL;
  562.                             changes=1; }
  563.                         else if(i==1 && (node_misc&NM_EMSOVL)) {
  564.                             node_misc&=~NM_EMSOVL;
  565.                             changes=1; }
  566.                         break;
  567.                     case 5:
  568.                         i=0;
  569.                         strcpy(opt[0],"Yes");
  570.                         strcpy(opt[1],"No");
  571.                         opt[2][0]=0;
  572.                         savnum=1;
  573.                         SETHELP(WHERE);
  574. /*
  575. Allow Swapping:
  576.  
  577. If this option is set to Yes, Synchronet will use one of the available
  578. Swap to options when swapping out of memory.    If you have no Extended,
  579. EMS, or XMS memory available, and this option is set to Yes, Synchronet
  580. will swap to disk.
  581. */
  582.                         i=ulist(WIN_MID|WIN_SAV,0,10,0,&i,0
  583.                             ,"Allow Swapping",opt);
  584.                         if(i==0 && node_swap&SWAP_NONE) {
  585.                             node_swap&=~SWAP_NONE;
  586.                             changes=1; }
  587.                         else if(i==1 && !(node_swap&SWAP_NONE)) {
  588.                             node_swap|=SWAP_NONE;
  589.                             changes=1; }
  590.                         break;
  591.                     case 6:
  592.                         i=0;
  593.                         strcpy(opt[0],"Yes");
  594.                         strcpy(opt[1],"No");
  595.                         opt[2][0]=0;
  596.                         savnum=1;
  597.                         SETHELP(WHERE);
  598. /*
  599. Swap to EMS Memory:
  600.  
  601. If this option is set to Yes, and the Allow Swapping option is set to
  602. Yes Synchronet will use EMS memory (when available) for swapping out
  603. of memory.
  604. */
  605.                         i=ulist(WIN_MID|WIN_SAV,0,10,0,&i,0
  606.                             ,"Swap to EMS Memory",opt);
  607.                         if(i==1 && node_swap&SWAP_EMS) {
  608.                             node_swap&=~SWAP_EMS;
  609.                             changes=1; }
  610.                         else if(i==0 && !(node_swap&SWAP_EMS)) {
  611.                             node_swap|=SWAP_EMS;
  612.                             changes=1; }
  613.                         break;
  614.                     case 7:
  615.                         i=0;
  616.                         strcpy(opt[0],"Yes");
  617.                         strcpy(opt[1],"No");
  618.                         opt[2][0]=0;
  619.                         savnum=1;
  620.                         SETHELP(WHERE);
  621. /*
  622. Swap to XMS Memory:
  623.  
  624. If this option is set to Yes, and the Allow Swapping option is set to
  625. Yes Synchronet will use XMS memory (when available) for swapping out
  626. of memory.
  627. */
  628.                         i=ulist(WIN_MID|WIN_SAV,0,10,0,&i,0
  629.                             ,"Swap to XMS Memory",opt);
  630.                         if(i==1 && node_swap&SWAP_XMS) {
  631.                             node_swap&=~SWAP_XMS;
  632.                             changes=1; }
  633.                         else if(i==0 && !(node_swap&SWAP_XMS)) {
  634.                             node_swap|=SWAP_XMS;
  635.                             changes=1; }
  636.                         break;
  637.                     case 8:
  638.                         i=0;
  639.                         strcpy(opt[0],"Yes");
  640.                         strcpy(opt[1],"No");
  641.                         opt[2][0]=0;
  642.                         savnum=1;
  643.                         SETHELP(WHERE);
  644. /*
  645. Swap to Extended Memory:
  646.  
  647. If this option is set to Yes, and the Allow Swapping option is set to
  648. Yes Synchronet will use non-XMS Extended memory (when available) for
  649. swapping out of memory.
  650.  
  651. If you are running under a DOS multitasker (e.g. Windows, DESQview, or
  652. OS/2) set this option to No.
  653. */
  654.                         i=ulist(WIN_MID|WIN_SAV,0,10,0,&i,0
  655.                             ,"Swap to Extended Memory",opt);
  656.                         if(i==1 && node_swap&SWAP_EXT) {
  657.                             node_swap&=~SWAP_EXT;
  658.                             changes=1; }
  659.                         else if(i==0 && !(node_swap&SWAP_EXT)) {
  660.                             node_swap|=SWAP_EXT;
  661.                             changes=1; }
  662.                         break;
  663.                     case 9:
  664.                         i=0;
  665.                         strcpy(opt[0],"Yes");
  666.                         strcpy(opt[1],"No");
  667.                         opt[2][0]=0;
  668.                         savnum=1;
  669.                         SETHELP(WHERE);
  670. /*
  671. Windows/OS2 Time Slice API:
  672.  
  673. If you wish to have Synchronet specifically use the Windows and OS/2
  674. API call to surrender time slices when in a low priority task, set this
  675. option to Yes. If setting this option to Yes causes erratic pauses
  676. or performance problems, leave the option on No. This type of behavior
  677. has been witnessed under Windows 3.1 when using this API call.
  678.  
  679. If running in an OS/2 DOS session, you will most likely want this
  680. option set to Yes for the best aggregate performance for your system.
  681. */
  682.                         i=ulist(WIN_MID|WIN_SAV,0,10,0,&i,0
  683.                             ,"Use Windows/OS2 Time Slice API",opt);
  684.                         if(i==0 && !(node_misc&NM_WINOS2)) {
  685.                             node_misc|=NM_WINOS2;
  686.                             changes=1; }
  687.                         else if(i==1 && (node_misc&NM_WINOS2)) {
  688.                             node_misc&=~NM_WINOS2;
  689.                             changes=1; }
  690.                         break;
  691.                     case 10:
  692.                         i=0;
  693.                         strcpy(opt[0],"Yes");
  694.                         strcpy(opt[1],"No");
  695.                         opt[2][0]=0;
  696.                         savnum=1;
  697.                         SETHELP(WHERE);
  698. /*
  699. DESQview Time Slice API:
  700.  
  701. If this option is set to Yes, and this node is run under DESQview,
  702. Synchronet will use the DESQview Time Slice API calls for intelligent
  703. variable time slicing.
  704.  
  705. Since Synchronet automatically detects DESQview, there is no harm in
  706. having this option set to Yes if you are not running DESQview. Only set
  707. this option to No, if you wish to disable the DESQview API for some
  708. reason.
  709. */
  710.                         i=ulist(WIN_MID|WIN_SAV,0,10,0,&i,0
  711.                             ,"DESQview Time Slice API",opt);
  712.                         if(i==0 && node_misc&NM_NODV) {
  713.                             node_misc&=~NM_NODV;
  714.                             changes=1; }
  715.                         else if(i==1 && !(node_misc&NM_NODV)) {
  716.                             node_misc|=NM_NODV;
  717.                             changes=1; }
  718.                         break;
  719.                     case 11:
  720.                         i=0;
  721.                         strcpy(opt[0],"Yes");
  722.                         strcpy(opt[1],"No");
  723.                         opt[2][0]=0;
  724.                         savnum=1;
  725.                         SETHELP(WHERE);
  726. /*
  727. DOS Idle Interrupts:
  728.  
  729. If you want Synchronet to make DOS Idle Interrupts when waiting for user
  730. input or in other low priority loops, set this option to Yes.
  731.  
  732. For best aggregate multinode performance under multitaskers, you should
  733. set this option to Yes.
  734.  
  735. For best single node performance under multitaskers, you should set this
  736. option to No.
  737. */
  738.                         i=ulist(WIN_MID|WIN_SAV,0,10,0,&i,0
  739.                             ,"DOS Idle Interrupts",opt);
  740.                         if(i==0 && !(node_misc&NM_INT28)) {
  741.                             node_misc|=NM_INT28;
  742.                             changes=1; }
  743.                         else if(i==1 && (node_misc&NM_INT28)) {
  744.                             node_misc&=~NM_INT28;
  745.                             changes=1; }
  746.                         break;
  747.                     case 12:
  748.                         i=1;
  749.                         strcpy(opt[0],"Yes");
  750.                         strcpy(opt[1],"No");
  751.                         opt[2][0]=0;
  752.                         savnum=1;
  753.                         SETHELP(WHERE);
  754. /*
  755. Low Priority String Input:
  756.  
  757. Normally, Synchronet will not give up time slices (under a multitasker)
  758. when users are prompted for a string of characters. This is considered
  759. a high priority task.
  760.  
  761. Setting this option to Yes will force Synchronet to give up time slices
  762. during string input, possibly causing jerky keyboard input from the
  763. user, but improving aggregate system performance under multitaskers.
  764. */
  765.                         i=ulist(WIN_MID|WIN_SAV,0,10,0,&i,0
  766.                             ,"Low Priority String Input",opt);
  767.                         if(i==0 && !(node_misc&NM_LOWPRIO)) {
  768.                             node_misc|=NM_LOWPRIO;
  769.                             changes=1; }
  770.                         else if(i==1 && (node_misc&NM_LOWPRIO)) {
  771.                             node_misc&=~NM_LOWPRIO;
  772.                             changes=1; }
  773.                         break;
  774.                     case 13:
  775.                         i=0;
  776.                         strcpy(opt[0],"Yes");
  777.                         strcpy(opt[1],"No");
  778.                         opt[2][0]=0;
  779.                         savnum=1;
  780.                         SETHELP(WHERE);
  781. /*
  782. Allow Logon by Number:
  783.  
  784. If you want users to be able logon using their user number at the NN:
  785. set this option to Yes.
  786. */
  787.                         i=ulist(WIN_MID|WIN_SAV,0,10,0,&i,0
  788.                             ,"Allow Logon by Number",opt);
  789.                         if(i==0 && node_misc&NM_NO_NUM) {
  790.                             node_misc&=~NM_NO_NUM;
  791.                             changes=1; }
  792.                         else if(i==1 && !(node_misc&NM_NO_NUM)) {
  793.                             node_misc|=NM_NO_NUM;
  794.                             changes=1; }
  795.                         break;
  796.                     case 14:
  797.                         i=1;
  798.                         strcpy(opt[0],"Yes");
  799.                         strcpy(opt[1],"No");
  800.                         opt[2][0]=0;
  801.                         savnum=1;
  802.                         SETHELP(WHERE);
  803. /*
  804. Allow Logon by Real Name:
  805.  
  806. If you want users to be able logon using their real name as well as
  807. their alias, set this option to Yes.
  808. */
  809.                         i=ulist(WIN_MID|WIN_SAV,0,10,0,&i,0
  810.                             ,"Allow Logon by Real Name",opt);
  811.                         if(i==0 && !(node_misc&NM_LOGON_R)) {
  812.                             node_misc|=NM_LOGON_R;
  813.                             changes=1; }
  814.                         else if(i==1 && (node_misc&NM_LOGON_R)) {
  815.                             node_misc&=~NM_LOGON_R;
  816.                             changes=1; }
  817.                         break;
  818.                     case 15:
  819.                         i=1;
  820.                         strcpy(opt[0],"Yes");
  821.                         strcpy(opt[1],"No");
  822.                         opt[2][0]=0;
  823.                         savnum=1;
  824.                         SETHELP(WHERE);
  825. /*
  826. Always Prompt for Password:
  827.  
  828. If you want to have attempted logons using an unknown user name still
  829. prompt for a password, set this option to Yes.
  830. */
  831.                         i=ulist(WIN_MID|WIN_SAV,0,10,0,&i,0
  832.                             ,"Always Prompt for Password",opt);
  833.                         if(i==0 && !(node_misc&NM_LOGON_P)) {
  834.                             node_misc|=NM_LOGON_P;
  835.                             changes=1; }
  836.                         else if(i==1 && (node_misc&NM_LOGON_P)) {
  837.                             node_misc&=~NM_LOGON_P;
  838.                             changes=1; }
  839.                         break;
  840.                     case 16:
  841.                         i=1;
  842.                         strcpy(opt[0],"Yes");
  843.                         strcpy(opt[1],"No");
  844.                         opt[2][0]=0;
  845.                         savnum=1;
  846.                         SETHELP(WHERE);
  847. /*
  848. Disable Local Inactivity Warning/Logoff:
  849.  
  850. Setting this option to Yes will disable the user inactivity warning
  851. and automatic logoff for local logons.
  852. */
  853.                         i=ulist(WIN_MID|WIN_SAV,0,10,0,&i,0
  854.                             ,"Disable Local Inactivity",opt);
  855.                         if(i==0 && !(node_misc&NM_NO_INACT)) {
  856.                             node_misc|=NM_NO_INACT;
  857.                             changes=1; }
  858.                         else if(i==1 && (node_misc&NM_NO_INACT)) {
  859.                             node_misc&=~NM_NO_INACT;
  860.                             changes=1; }
  861.                         break;
  862.                     case 17:
  863.                         i=1;
  864.                         strcpy(opt[0],"Yes");
  865.                         strcpy(opt[1],"No");
  866.                         opt[2][0]=0;
  867.                         savnum=1;
  868.                         SETHELP(WHERE);
  869. /*
  870. Disable Local Keyboard (Entirely):
  871.  
  872. Setting this option to Yes will disable the local keyboard when the
  873. BBS is running. Use this option only for the absolute highest degree
  874. of local system security. If this option is set to Yes, the BBS cannot
  875. be exited until the node is downed from another process or the machine
  876. is rebooted.
  877. */
  878.                         i=ulist(WIN_MID|WIN_SAV,0,10,0,&i,0
  879.                             ,"Disable Local Keyboard (Entirely)",opt);
  880.                         if(i==0 && !(node_misc&NM_NO_LKBRD)) {
  881.                             node_misc|=NM_NO_LKBRD;
  882.                             changes=1; }
  883.                         else if(i==1 && (node_misc&NM_NO_LKBRD)) {
  884.                             node_misc&=~NM_NO_LKBRD;
  885.                             changes=1; }
  886.                         break;
  887.                     case 18:
  888.                         i=1;
  889.                         strcpy(opt[0],"Yes");
  890.                         strcpy(opt[1],"No");
  891.                         opt[2][0]=0;
  892.                         savnum=1;
  893.                         SETHELP(WHERE);
  894. /*
  895. Local System Protection:
  896.  
  897. When this option is set to Yes, all local system functions from the
  898. Waiting for Call screen and Alt-Key combinations will require the user
  899. to enter the system password.
  900. */
  901.                         i=ulist(WIN_MID|WIN_SAV,0,10,0,&i,0
  902.                             ,"Local System Protection (Password)",opt);
  903.                         if(i==0 && !(node_misc&NM_SYSPW)) {
  904.                             node_misc|=NM_SYSPW;
  905.                             changes=1; }
  906.                         else if(i==1 && (node_misc&NM_SYSPW)) {
  907.                             node_misc&=~NM_SYSPW;
  908.                             changes=1; }
  909.                         break;
  910.                     case 19:
  911.                         i=0;
  912.                         strcpy(opt[0],"Yes");
  913.                         strcpy(opt[1],"No");
  914.                         opt[2][0]=0;
  915.                         savnum=1;
  916.                         SETHELP(WHERE);
  917. /*
  918. Beep Locally:
  919.  
  920. If you want the local speaker to be disabled for online beeps, set this
  921. option to No.
  922. */
  923.                         i=ulist(WIN_MID|WIN_SAV,0,10,0,&i,0
  924.                             ,"Beep Locally",opt);
  925.                         if(i==1 && !(node_misc&NM_NOBEEP)) {
  926.                             node_misc|=NM_NOBEEP;
  927.                             changes=1; }
  928.                         else if(i==0 && (node_misc&NM_NOBEEP)) {
  929.                             node_misc&=~NM_NOBEEP;
  930.                             changes=1; }
  931.                         break;
  932.                     case 20:
  933.                         i=0;
  934.                         strcpy(opt[0],"Yes");
  935.                         strcpy(opt[1],"No");
  936.                         opt[2][0]=0;
  937.                         savnum=1;
  938.                         SETHELP(WHERE);
  939. /*
  940. Allow 8-bit Remote Input During Logon:
  941.  
  942. If you wish to allow E-7-1 terminals to use this node, you must set this
  943. option to No. This will also eliminate the ability of 8-bit remote users
  944. to send IBM extended ASCII characters during the logon sequence.
  945. */
  946.                         i=ulist(WIN_MID|WIN_SAV,0,10,0,&i,0
  947.                             ,"Allow 8-bit Remote Input During Logon",opt);
  948.                         if(i==1 && !(node_misc&NM_7BITONLY)) {
  949.                             node_misc|=NM_7BITONLY;
  950.                             changes=1; }
  951.                         else if(i==0 && (node_misc&NM_7BITONLY)) {
  952.                             node_misc&=~NM_7BITONLY;
  953.                             changes=1; }
  954.                         break;
  955.                     case 21:
  956.                         i=0;
  957.                         strcpy(opt[0],"Yes");
  958.                         strcpy(opt[1],"No");
  959.                         opt[2][0]=0;
  960.                         savnum=1;
  961.                         SETHELP(WHERE);
  962. /*
  963. Reset Video Mode Between Calls:
  964.  
  965. If you wish to have SBBS reset the video mode between calls, set this
  966. option to Yes. This is to reverse the effects of some external programs
  967. that change the video mode without permission.
  968. */
  969.                         i=ulist(WIN_MID|WIN_SAV,0,10,0,&i,0
  970.                             ,"Reset Video Mode Beteween Calls",opt);
  971.                         if(i==0 && !(node_misc&NM_RESETVID)) {
  972.                             node_misc|=NM_RESETVID;
  973.                             changes=1; }
  974.                         else if(i==1 && (node_misc&NM_RESETVID)) {
  975.                             node_misc&=~NM_RESETVID;
  976.                             changes=1; }
  977.                         break;
  978.                         } }
  979.             break;
  980.         case 9:
  981.             done=0;
  982.             while(!done) {
  983.                 i=0;
  984.                 sprintf(opt[i++],"%-27.27s%s","Validation User"
  985.                     ,node_valuser ? itoa(node_valuser,tmp,10) : "Nobody");
  986.                 sprintf(opt[i++],"%-27.27s%s","Screen Length"
  987.                     ,node_scrnlen ? itoa(node_scrnlen,tmp,10)
  988.                     : "Auto-Detect");
  989.                 sprintf(opt[i++],"%-27.27s%s","Screen Blanker"
  990.                     ,node_scrnblank ? itoa(node_scrnblank,tmp,10)
  991.                     : "Disabled");
  992.                 sprintf(opt[i++],"%-27.27s%u seconds","Semaphore Frequency"
  993.                     ,node_sem_check);
  994.                 sprintf(opt[i++],"%-27.27s%u seconds","Statistics Frequency"
  995.                     ,node_stat_check);
  996.                 sprintf(opt[i++],"%-27.27s%u seconds","Inactivity Warning"
  997.                     ,sec_warn);
  998.                 sprintf(opt[i++],"%-27.27s%u seconds","Inactivity Disconnection"
  999.                     ,sec_hangup);
  1000.                 sprintf(tmp,"$%d.00",node_dollars_per_call);
  1001.                 sprintf(opt[i++],"%-27.27s%s","Cost Per Call",tmp);
  1002.                 sprintf(opt[i++],"%-27.27s%.40s","Daily Event",node_daily);
  1003.                 sprintf(opt[i++],"%-27.27s%.40s","Control Directory",ctrl_dir);
  1004.                 sprintf(opt[i++],"%-27.27s%.40s","Text Directory",text_dir);
  1005.                 sprintf(opt[i++],"%-27.27s%.40s","Temporary Directory"
  1006.                     ,temp_dir);
  1007.                 sprintf(opt[i++],"%-27.27s%.40s","Swap Directory"
  1008.                     ,node_swapdir);
  1009.                 opt[i][0]=0;
  1010.                 savnum=0;
  1011. SETHELP(WHERE);
  1012. /*
  1013. Node Advanced Options:
  1014.  
  1015. This is the advanced options menu for the selected node. The available
  1016. options are of an advanced nature and should not be modified unless you
  1017. are sure of the consequences and necessary preparation.
  1018. */
  1019.                 switch(ulist(WIN_T2B|WIN_RHT|WIN_ACT|WIN_SAV,2,0,60,&adv_dflt,0
  1020.                     ,"Advanced Options",opt)) {
  1021.                     case -1:
  1022.                         done=1;
  1023.                         break;
  1024.                     case 0:
  1025.                         itoa(node_valuser,str,10);
  1026. SETHELP(WHERE);
  1027. /*
  1028. Validation User Number:
  1029.  
  1030. When a caller logs onto the system as New, he or she must send
  1031. validation feedback to the sysop. This feature can be disabled by
  1032. setting this value to 0, allowing new users to logon without sending
  1033. validation feedback. If you want new users on this node to be forced to
  1034. send validation feedback, set this value to the number of the user to
  1035. whom the feedback is sent. The normal value of this option is 1 for
  1036. user number one.
  1037. */
  1038.                         uinput(WIN_MID,0,13,"Validation User Number (0=Nobody)"
  1039.                             ,str,4,K_NUMBER|K_EDIT);
  1040.                         node_valuser=atoi(str);
  1041.                         break;
  1042.                     case 1:
  1043.                         itoa(node_scrnlen,str,10);
  1044. SETHELP(WHERE);
  1045. /*
  1046. Screen Length:
  1047.  
  1048. Synchronet automatically senses the number of lines on your display and
  1049. uses all of them. If for some reason you want to override the detected
  1050. screen length, set this value to the number of lines (rows) you want
  1051. Synchronet to use.
  1052. */
  1053.                         uinput(WIN_MID,0,14,"Screen Length (0=Auto-Detect)"
  1054.                             ,str,2,K_NUMBER|K_EDIT);
  1055.                         node_scrnlen=atoi(str);
  1056.                         break;
  1057.                     case 2:
  1058.                         itoa(node_scrnblank,str,10);
  1059. SETHELP(WHERE);
  1060. /*
  1061. Screen Blanker:
  1062.  
  1063. This option allows you to have this node blank its Waiting for Call
  1064. screen after this number of minutes of inactivity. Setting this option
  1065. to 0 disables the screen blanker.
  1066. */
  1067.                         uinput(WIN_MID|WIN_SAV,0,14
  1068.                             ,"Minutes Inactive Before Blanking Screen "
  1069.                             "(0=Disabled)"
  1070.                             ,str,2,K_NUMBER|K_EDIT);
  1071.                         node_scrnblank=atoi(str);
  1072.                         break;
  1073.                     case 3:
  1074.                         itoa(node_sem_check,str,10);
  1075. SETHELP(WHERE);
  1076. /*
  1077. Semaphore Check Frequency While Waiting for Call (in seconds):
  1078.  
  1079. This is the number of seconds between semaphore checks while this node
  1080. is waiting for a caller. Default is 60 seconds.
  1081. */
  1082.                         uinput(WIN_MID|WIN_SAV,0,14
  1083.                             ,"Seconds Between Semaphore Checks"
  1084.                             ,str,3,K_NUMBER|K_EDIT);
  1085.                         node_sem_check=atoi(str);
  1086.                         break;
  1087.                     case 4:
  1088.                         itoa(node_stat_check,str,10);
  1089. SETHELP(WHERE);
  1090. /*
  1091. Statistics Check Frequency While Waiting for Call (in seconds):
  1092.  
  1093. This is the number of seconds between static checks while this node
  1094. is waiting for a caller. Default is 10 seconds.
  1095. */
  1096.                         uinput(WIN_MID|WIN_SAV,0,14
  1097.                             ,"Seconds Between Statistic Checks"
  1098.                             ,str,3,K_NUMBER|K_EDIT);
  1099.                         node_stat_check=atoi(str);
  1100.                         break;
  1101.                     case 5:
  1102.                         itoa(sec_warn,str,10);
  1103. SETHELP(WHERE);
  1104. /*
  1105. Seconds Before Inactivity Warning:
  1106.  
  1107. This is the number of seconds the user must be inactive before a
  1108. warning will be given. Default is 180 seconds.
  1109. */
  1110.                         uinput(WIN_MID|WIN_SAV,0,14
  1111.                             ,"Seconds Before Inactivity Warning"
  1112.                             ,str,4,K_NUMBER|K_EDIT);
  1113.                         sec_warn=atoi(str);
  1114.                         break;
  1115.                     case 6:
  1116.                         itoa(sec_hangup,str,10);
  1117. SETHELP(WHERE);
  1118. /*
  1119. Seconds Before Inactivity Disconnection:
  1120.  
  1121. This is the number of seconds the user must be inactive before they
  1122. will be automatically disconnected. Default is 300 seconds.
  1123. */
  1124.                         uinput(WIN_MID|WIN_SAV,0,14
  1125.                             ,"Seconds Before Inactivity Disconnection"
  1126.                             ,str,4,K_NUMBER|K_EDIT);
  1127.                         sec_hangup=atoi(str);
  1128.                         break;
  1129.                     case 7:
  1130.                         itoa(node_dollars_per_call,str,10);
  1131. SETHELP(WHERE);
  1132. /*
  1133. Billing Node Cost Per Call:
  1134.  
  1135. If you have an automated billing phone number (usually area code 900
  1136. or prefix 976) and you wish to use this node as an automated billing
  1137. node, set this value to the dollar amount that is billed for the first
  1138. minute. Subsequent minutes should be charged the minimum amount as the
  1139. maximum connect time for a billing node is 90 seconds.
  1140.  
  1141. If this feature is used, when a caller connects to the node, he or she
  1142. will be notified of the eminent charge amount if they do not drop
  1143. carrier within the allotted free period. If the caller is still
  1144. connected after 30 seconds, he or she will be prompted to enter a valid
  1145. user name or number. After a valid user name or number has been entered,
  1146. the caller is disconnected and the entered user is immediately given the
  1147. purchased credits based on this dollar amount multiplied by the
  1148. Credits per Dollar system option.
  1149. */
  1150.                         uinput(WIN_MID,0,0,"Billing Node Cost Per Call "
  1151.                             "(in dollars)",str,2,K_NUMBER|K_EDIT);
  1152.                         node_dollars_per_call=atoi(str);
  1153.                         break;
  1154.                     case 8:
  1155. SETHELP(WHERE);
  1156. /*
  1157. Daily Event:
  1158.  
  1159. If you have an event that this node should run every day, enter the
  1160. command line for that event here.
  1161.  
  1162. An event can be any valid DOS command line. If multiple programs or
  1163. commands are required, use a batch file.
  1164.  
  1165. Remember: The %! command line specifier is an abreviation for your
  1166.           configured EXEC directory path.
  1167. */
  1168.                         uinput(WIN_MID|WIN_SAV,0,10,"Daily Event"
  1169.                             ,node_daily,50,K_EDIT);
  1170.                         break;
  1171.                     case 9:
  1172.                         strcpy(str,ctrl_dir);
  1173.                         if(strstr(str,"\\CTRL\\")!=NULL)
  1174.                             *strstr(str,"\\CTRL\\")=0;
  1175. SETHELP(WHERE);
  1176. /*
  1177. Control Directory Parent:
  1178.  
  1179. Your control directory contains important configuration and data files
  1180. that ALL nodes share. This directory MUST NOT be located on a RAM disk
  1181. or other volatile media.
  1182.  
  1183. This option allows you to change the parent of your control directory.
  1184. The \CTRL\ suffix (sub-directory) cannot be changed or removed.
  1185. */
  1186.                         if(uinput(WIN_MID|WIN_SAV,0,9,"Control Dir Parent"
  1187.                             ,str,50,K_EDIT|K_UPPER)>0) {
  1188.                             if(str[strlen(str)-1]!='\\')
  1189.                                 strcat(str,"\\");
  1190.                             strcat(str,"CTRL\\");
  1191.                             strcpy(ctrl_dir,str); }
  1192.                         break;
  1193.                     case 10:
  1194.                         strcpy(str,text_dir);
  1195.                         if(strstr(str,"\\TEXT\\")!=NULL)
  1196.                             *strstr(str,"\\TEXT\\")=0;
  1197. SETHELP(WHERE);
  1198. /*
  1199. Text Directory Parent:
  1200.  
  1201. Your text directory contains read-only text files. Synchronet never
  1202. writes to any files in this directory so it CAN be placed on a RAM
  1203. disk or other volatile media. This directory contains the system's menus
  1204. and other important text files, so be sure the files and directories are
  1205. moved to this directory if you decide to change it.
  1206.  
  1207. This option allows you to change the parent of your control directory.
  1208. The \TEXT\ suffix (sub-directory) cannot be changed or removed.
  1209. */
  1210.                         if(uinput(WIN_MID|WIN_SAV,0,10,"Text Dir Parent"
  1211.                             ,str,50,K_EDIT|K_UPPER)>0) {
  1212.                             if(str[strlen(str)-1]!='\\')
  1213.                                 strcat(str,"\\");
  1214.                             strcat(str,"TEXT\\");
  1215.                             strcpy(text_dir,str); }
  1216.                         break;
  1217.                     case 11:
  1218.                         strcpy(str,temp_dir);
  1219. SETHELP(WHERE);
  1220. /*
  1221. Temp Directory:
  1222.  
  1223. Your temp directory is where Synchronet stores files of a temporary
  1224. nature for this node. Each node MUST have its own unique temp directory.
  1225. This directory can exist on a RAM disk or other volatile media. For
  1226. the best batch upload performance, it should be located on the same
  1227. drive as the majority of your upload directories.
  1228. */
  1229.                         uinput(WIN_MID|WIN_SAV,0,10,"Temp Directory"
  1230.                             ,str,50,K_EDIT|K_UPPER);
  1231.                         if(!strlen(str))
  1232.                             umsg("Temp directory cannot be blank");
  1233.                         else
  1234.                             strcpy(temp_dir,str);
  1235.                         break;
  1236.                     case 12:
  1237.                         strcpy(str,node_swapdir);
  1238. SETHELP(WHERE);
  1239. /*
  1240. Swap Directory:
  1241.  
  1242. Your swap directory is where Synchronet will swap out to if you have
  1243. swapping enabled, and it is necessary to swap to disk. The default is
  1244. the node directory. If you do specify a swap directory, it must not
  1245. be a relative path (i.e. "..\etc"). Specify the entire path and include
  1246. the drive letter specification (i.e. "D:\SBBS\SWAP").
  1247. */
  1248.                         uinput(WIN_MID|WIN_SAV,0,10,"Swap Directory"
  1249.                             ,str,50,K_EDIT|K_UPPER);
  1250.                         if(str[0] && strcmp(str,".") && strcmp(str,".\\")
  1251.                             && (strstr(str,"..") || str[1]!=':'
  1252.                             || str[2]!='\\'))
  1253.                             umsg("Must specify full path");
  1254.                         else
  1255.                             strcpy(node_swapdir,str);
  1256.                         break; } }
  1257.             break;
  1258.         case 11:
  1259. SETHELP(WHERE);
  1260. /*
  1261. Wait for Call Number Key Commands:
  1262.  
  1263. Each of the number keys (0 through 9) can be assigned a command to
  1264. execute when entered at the wait for call screen. This is a list of
  1265. those keys and the assigned commands. Since Synchronet is still in
  1266. memory when these command are executed, the number keys should be used
  1267. for small program execution or command lines with small memory
  1268. requirements.
  1269.  
  1270. If you have a program or command line with large memory requirements,
  1271. use a Wait for Call Function Key Command.
  1272. */
  1273.             j=0;
  1274.             while(1) {
  1275.                 for(i=0;i<10;i++)
  1276.                     sprintf(opt[i],"%d  %s",i,wfc_cmd[i]);
  1277.                 opt[i][0]=0;
  1278.                 savnum=0;
  1279.  
  1280.                 i=ulist(WIN_T2B|WIN_RHT|WIN_ACT|WIN_SAV,2,0,50,&j,0
  1281.                     ,"Number Key Commands",opt);
  1282.                 if(i==-1)
  1283.                     break;
  1284.                 sprintf(str,"%d Key Command Line",i);
  1285.                 uinput(WIN_MID|WIN_SAV,0,0,str,wfc_cmd[i],50,K_EDIT); }
  1286.             break;
  1287.         case 12:
  1288. SETHELP(WHERE);
  1289. /*
  1290. Wait for Call Function Key Commands:
  1291.  
  1292. Each of the function keys (F1 through F12) can be assigned a command to
  1293. execute when entered at the wait for call screen. This is a list of
  1294. those keys and the currently assigned commands. Synchronet will shrink
  1295. to 16K of RAM before executing one of these command lines.
  1296.  
  1297. If you have a command line with small memory requirements, you should
  1298. probably use a Wait for Call Number Key Command for faster execution.
  1299. */
  1300.             j=0;
  1301.             while(1) {
  1302.                 for(i=0;i<12;i++)
  1303.                     sprintf(opt[i],"F%-2d  %s",i+1,wfc_scmd[i]);
  1304.                 opt[i][0]=0;
  1305.                 savnum=0;
  1306.                 i=ulist(WIN_T2B|WIN_RHT|WIN_ACT|WIN_SAV,2,0,50,&j,0
  1307.                     ,"Function Key (Shrinking) Commands",opt);
  1308.                 if(i==-1)
  1309.                     break;
  1310.                 sprintf(str,"F%d Key Command Line",i+1);
  1311.                 uinput(WIN_MID|WIN_SAV,0,0,str,wfc_scmd[i],50,K_EDIT); }
  1312.             break;
  1313.         case 10:
  1314.             done=0;
  1315.             while(!done) {
  1316.                 i=0;
  1317.                 sprintf(opt[i++],"%-27.27s%s","COM Port"
  1318.                     ,com_port ? itoa(com_port,tmp,10) : "Disabled");
  1319.                 sprintf(opt[i++],"%-27.27s%u"
  1320.                     ,com_base && com_base<0x100 ? "COM Channel"
  1321.                         :"UART IRQ Line"
  1322.                     ,com_irq);
  1323.                 if(com_base==0xd)
  1324.                     strcpy(str,"DigiBoard");
  1325.                 else if(com_base==0xf)
  1326.                     strcpy(str,"FOSSIL");
  1327.                 else if(com_base==0xb)
  1328.                     strcpy(str,"PC BIOS");
  1329.                 else if(com_base==0xe)
  1330.                     strcpy(str,"PS/2 BIOS");
  1331.                 else
  1332.                     sprintf(str,"%Xh",com_base);
  1333.                 sprintf(opt[i++],"%-27.27s%s"
  1334.                     ,com_base<0x100 ? "COM Type":"UART I/O Address",str);
  1335.                 sprintf(opt[i++],"%-27.27s%lu","DTE Rate",com_rate);
  1336.                 sprintf(opt[i++],"%-27.27s%s","Fixed DTE Rate"
  1337.                     ,mdm_misc&MDM_STAYHIGH ? "Yes" : "No");
  1338.                 if(!(mdm_misc&(MDM_RTS|MDM_CTS)))
  1339.                     strcpy(str,"None");
  1340.                 else {
  1341.                     if(mdm_misc&MDM_CTS) {
  1342.                         strcpy(str,"CTS");
  1343.                         if(mdm_misc&MDM_RTS)
  1344.                             strcat(str,"/"); }
  1345.                     else str[0]=0;
  1346.                     if(mdm_misc&MDM_RTS)
  1347.                         strcat(str,"RTS"); }
  1348.                 sprintf(opt[i++],"%-27.27s%s","Hardware Flow Control",str);
  1349.                 sprintf(opt[i++],"%-27.27s%u ring%c","Answer After"
  1350.                     ,mdm_rings,mdm_rings>1 ? 's':' ');
  1351.                 sprintf(opt[i++],"%-27.27s%u second%c","Answer Delay"
  1352.                     ,mdm_ansdelay,mdm_ansdelay>1 ? 's':' ');
  1353.                 sprintf(opt[i++],"%-27.27s%s","Reinitialization Timer"
  1354.                     ,mdm_reinit ? itoa(mdm_reinit,tmp,10) : "Disabled");
  1355.                 strcpy(opt[i++],"Result Codes...");
  1356.                 strcpy(opt[i++],"Toggle Options...");
  1357.                 strcpy(opt[i++],"Control Strings...");
  1358.                 strcpy(opt[i++],"Auto-Configuration...");
  1359.                 strcpy(opt[i++],"Import Configuration...");
  1360.                 strcpy(opt[i++],"Export Configuration...");
  1361.                 opt[i][0]=0;
  1362.                 savnum=0;
  1363. SETHELP(WHERE);
  1364. /*
  1365. Modem Configuration Menu:
  1366.  
  1367. This menu contains the configuration options for this node's modem.
  1368. If you do not have a modem attached to this node or do not want to use
  1369. an attached modem, you can disable the Synchronet modem communications
  1370. by setting the COM Port to 0.
  1371.  
  1372. If your modem is listed in the Auto-Configuration, you should probably
  1373. just set the COM Port and run the auto-configuration for your modem
  1374. type.
  1375. */
  1376.                 switch(ulist(WIN_T2B|WIN_RHT|WIN_ACT|WIN_SAV,2,0,44,&mdm_dflt,0
  1377.                     ,"Modem Configuration",opt)) {
  1378.                     case -1:
  1379.                         done=1;
  1380.                         break;
  1381.                     case 0:
  1382.                         itoa(com_port,str,10);
  1383. SETHELP(WHERE);
  1384. /*
  1385. COM Port:
  1386.  
  1387. This is the serial communications port that the modem for this node is
  1388. connected to. If you do not have a modem connected to this node, or
  1389. do not wish to use a connected modem, you can disable the Synchronet
  1390. modem communications by setting this value to 0.
  1391. */
  1392.                         if(uinput(WIN_MID|WIN_SAV,0,10,"COM Port (0=Disabled)"
  1393.                             ,str,2,K_EDIT|K_NUMBER)==-1)
  1394.                             break;
  1395.                         com_port=atoi(str);
  1396.                         if(!com_port)
  1397.                             break;
  1398.                         savnum=1;
  1399.                         com_type();
  1400.                         break;
  1401.                     case 1:
  1402.                         itoa(com_irq,str,10);
  1403. SETHELP(WHERE);
  1404. /*
  1405. UART IRQ Line or Channel Number:
  1406.  
  1407. If you are using a standard UART serial interface for this COM port,
  1408. this is the IRQ line that your COM Port's UART is using. If you have
  1409. configured your COM Port and selected the default IRQ and I/O address,
  1410. you should not need to change the value of this option.
  1411.  
  1412. If this COM port is accessed via Int 14h, this is the channel number
  1413. for this COM port (normally, the COM port number minus one).
  1414. */
  1415.                         uinput(WIN_MID|WIN_SAV,0,10
  1416.                             ,com_base && com_base<0x100 ? "Channel"
  1417.                             : "UART IRQ Line"
  1418.                             ,str,2,K_EDIT|K_NUMBER);
  1419.                         com_irq=atoi(str);
  1420.                         break;
  1421.                     case 2:
  1422.                         savnum=1;
  1423.                         if(com_type() || com_base<0x100)
  1424.                             break;
  1425. SETHELP(WHERE);
  1426. /*
  1427. UART I/O Address in Hex:
  1428.  
  1429. This is the base I/O address of your COM Port's UART. If you have
  1430. configured your COM Port and selected the default IRQ and I/O address,
  1431. you should not need to change the value of this option. If this node's
  1432. COM Port's UART is using a non-standard I/O address, enter that address
  1433. (in hexadecimal) using this option.
  1434. */
  1435.                         itoa(com_base,str,16);
  1436.                         strupr(str);
  1437.                         uinput(WIN_MID|WIN_SAV,0,10
  1438.                             ,"UART I/O Address in Hex"
  1439.                             ,str,4,K_EDIT|K_UPPER);
  1440.                         com_base=ahtoul(str);
  1441.                         break;
  1442.                     case 3:
  1443.                         savnum=1;
  1444. SETHELP(WHERE);
  1445. /*
  1446. UART (DTE) Rate:
  1447.  
  1448. This is the data transfer rate between your COM Port's UART (Data
  1449. Terminal Equipment) and your modem. This is NOT the connect rate of
  1450. your modem (Data Communications Equipment). Most high-speed (9600bps+)
  1451. modems use a fixed DTE rate that is higher than the highest DCE rate to
  1452. allow for data compression and error correction. This value should be
  1453. set to the highest DTE rate your modem supports. If you have a 1200 or
  1454. 2400bps modem without data compression capabilities, this value should
  1455. be set to 1200 or 2400 respectively. If you have a high-speed modem,
  1456. refer to the modem's manual to find the highest supported DTE rate.
  1457. */
  1458.                         i=0;
  1459.                         strcpy(opt[i++],"300");
  1460.                         strcpy(opt[i++],"1200");
  1461.                         strcpy(opt[i++],"2400");
  1462.                         strcpy(opt[i++],"4800");
  1463.                         strcpy(opt[i++],"9600");
  1464.                         strcpy(opt[i++],"19200");
  1465.                         strcpy(opt[i++],"38400");
  1466.                         strcpy(opt[i++],"57600");
  1467.                         strcpy(opt[i++],"115200");
  1468.                         opt[i][0]=0;
  1469.                         switch(com_rate) {
  1470.                             default:
  1471.                                 i=0;
  1472.                                 break;
  1473.                             case 1200:
  1474.                                 i=1;
  1475.                                 break;
  1476.                             case 2400:
  1477.                                 i=2;
  1478.                                 break;
  1479.                             case 4800:
  1480.                                 i=3;
  1481.                                 break;
  1482.                             case 9600:
  1483.                                 i=4;
  1484.                                 break;
  1485.                             case 19200:
  1486.                                 i=5;
  1487.                                 break;
  1488.                             case 38400:
  1489.                                 i=6;
  1490.                                 break;
  1491.                             case 57600:
  1492.                                 i=7;
  1493.                                 break;
  1494.                             case 115200L:
  1495.                                 i=8;
  1496.                                 break; }
  1497.                         i=ulist(WIN_MID|WIN_SAV,0,0,0,&i,0,"UART (DTE) Rate"
  1498.                             ,opt);
  1499.                         if(i==-1)
  1500.                             break;
  1501.                         changes=1;
  1502.                         switch(i) {
  1503.                             default:
  1504.                                 com_rate=300;
  1505.                                 break;
  1506.                             case 1:
  1507.                                 com_rate=1200;
  1508.                                 break;
  1509.                             case 2:
  1510.                                 com_rate=2400;
  1511.                                 break;
  1512.                             case 3:
  1513.                                 com_rate=4800;
  1514.                                 break;
  1515.                             case 4:
  1516.                                 com_rate=9600;
  1517.                                 break;
  1518.                             case 5:
  1519.                                 com_rate=19200;
  1520.                                 break;
  1521.                             case 6:
  1522.                                 com_rate=38400;
  1523.                                 break;
  1524.                             case 7:
  1525.                                 com_rate=57600;
  1526.                                 break;
  1527.                             case 8:
  1528.                                 com_rate=115200L;
  1529.                                 break; }
  1530.                         break;
  1531.                     case 4:
  1532.                         i=1;
  1533.                         savnum=1;
  1534.                         strcpy(opt[0],"Yes");
  1535.                         strcpy(opt[1],"No");
  1536.                         opt[2][0]=0;
  1537. SETHELP(WHERE);
  1538. /*
  1539. Use Fixed DTE Rate:
  1540.  
  1541. If this node is using a modem with error correction or data compression
  1542. capabilities, set this option to Yes. If you are using a 2400bps or
  1543. slower modem, it is most likely this value should be set to No.
  1544. */
  1545.                         i=ulist(WIN_MID|WIN_SAV,0,0,0,&i,0,"Use Fixed "
  1546.                             "DTE Rate",opt);
  1547.                         if(i==0 && !(mdm_misc&MDM_STAYHIGH)) {
  1548.                             mdm_misc|=MDM_STAYHIGH;
  1549.                             changes=1; }
  1550.                         else if(i==1 && mdm_misc&MDM_STAYHIGH) {
  1551.                             mdm_misc&=~MDM_STAYHIGH;
  1552.                             changes=1; }
  1553.                         break;
  1554.                     case 5:
  1555.                         i=1;
  1556.                         savnum=1;
  1557.                         strcpy(opt[0],"Both");
  1558.                         strcpy(opt[1],"CTS Only");
  1559.                         strcpy(opt[2],"RTS Only");
  1560.                         strcpy(opt[3],"None");
  1561.                         opt[4][0]=0;
  1562.                         i=0;
  1563. SETHELP(WHERE);
  1564. /*
  1565. Hardware Flow Control (CTS/RTS):
  1566.  
  1567. If your modem supports the use of hardware flow control via CTS/RTS
  1568. (Clear to Send/Request to Send), set this option to Both. If are using
  1569. a high-speed modem or a modem with data compression or error correction
  1570. capabilities, it is most likely this option should be set to Both. If
  1571. you are using a 2400bps or slower modem without data compression or
  1572. error correction capabilities, set this option to None.
  1573. */
  1574.                         i=ulist(WIN_MID|WIN_SAV,0,0,0,&i,0,"Hardware "
  1575.                             "Flow Control (CTS/RTS)",opt);
  1576.                         if(i==0
  1577.                             && (mdm_misc&(MDM_CTS|MDM_RTS))
  1578.                                        !=(MDM_CTS|MDM_RTS)) {
  1579.                             mdm_misc|=(MDM_CTS|MDM_RTS);
  1580.                             changes=1; }
  1581.                         else if(i==1
  1582.                             && (mdm_misc&(MDM_CTS|MDM_RTS))!=MDM_CTS) {
  1583.                             mdm_misc|=MDM_CTS;
  1584.                             mdm_misc&=~MDM_RTS;
  1585.                             changes=1; }
  1586.                         else if(i==2
  1587.                             && (mdm_misc&(MDM_CTS|MDM_RTS))!=MDM_RTS) {
  1588.                             mdm_misc|=MDM_RTS;
  1589.                             mdm_misc&=~MDM_CTS;
  1590.                             changes=1; }
  1591.                         else if(i==3
  1592.                             && mdm_misc&(MDM_CTS|MDM_RTS)) {
  1593.                             mdm_misc&=~(MDM_RTS|MDM_CTS);
  1594.                             changes=1; }
  1595.                         break;
  1596.  
  1597.                     case 6:
  1598. SETHELP(WHERE);
  1599. /*
  1600. Number of Rings to Answer After:
  1601.  
  1602. This is the number of rings to let pass before answering the phone.
  1603. */
  1604.                         itoa(mdm_rings,str,10);
  1605.                         uinput(WIN_MID|WIN_SAV,0,0
  1606.                             ,"Number of Rings to Answer After"
  1607.                             ,str,2,K_EDIT|K_NUMBER);
  1608.                         mdm_rings=atoi(str);
  1609.                         if(!mdm_rings)
  1610.                             mdm_rings=1;
  1611.                         break;
  1612.  
  1613.                     case 7:
  1614. SETHELP(WHERE);
  1615. /*
  1616. Seconds to Delay after Answer:
  1617.  
  1618. This is the length of time (in seconds) to delay after connection and
  1619. before the terminal detection sequence is trasmitted to the remote user
  1620. and the logon prompt is displayed.
  1621. */
  1622.                         itoa(mdm_ansdelay,str,10);
  1623.                         uinput(WIN_MID|WIN_SAV,0,0
  1624.                             ,"Answer Delay (in seconds)"
  1625.                             ,str,4,K_EDIT|K_NUMBER);
  1626.                         mdm_ansdelay=atoi(str);
  1627.                         break;
  1628.  
  1629.                     case 8:
  1630. SETHELP(WHERE);
  1631. /*
  1632. Minutes Between Reinitialization:
  1633.  
  1634. If you want your modem to be periodically reinitialized while waiting
  1635. for a caller, set this option to the maximum number of minutes between
  1636. initializations. Setting this value to 0 disables this feature.
  1637. */
  1638.                         itoa(mdm_reinit,str,10);
  1639.                         uinput(WIN_MID|WIN_SAV,0,0
  1640.                             ,"Minutes Between Reinitialization (0=Disabled)"
  1641.                             ,str,4,K_EDIT|K_NUMBER);
  1642.                         mdm_reinit=atoi(str);
  1643.                         break;
  1644.                     case 9:
  1645.                         dflt=bar=0;
  1646.                         while(1) {
  1647.                             for(i=0;i<mdm_results;i++) {
  1648.                                 sprintf(opt[i],"%3u %5ubps %4ucps %s"
  1649.                                     ,mdm_result[i].code,mdm_result[i].rate
  1650.                                     ,mdm_result[i].cps,mdm_result[i].str); }
  1651.                             opt[i][0]=0;
  1652.                             i=WIN_ACT|WIN_SAV|WIN_RHT;
  1653.                             if(mdm_results<MAX_OPTS)
  1654.                                 i|=WIN_INS;
  1655.                             if(mdm_results>1)
  1656.                                 i|=WIN_DEL;
  1657.                             savnum=1;
  1658. SETHELP(WHERE);
  1659. /*
  1660. Modem Result Codes:
  1661.  
  1662. This is the list of configured numeric connection result codes that this
  1663. node's modem supports. If this node is getting Invalid Result Code
  1664. errors when answer incoming calls, those result codes should be added
  1665. to this list. Refer to your modem's manual for a list of supported
  1666. result codes. Using the Auto-Configuration option automatically
  1667. configures this list for you.
  1668. To add a result code, hit  INS .
  1669.  
  1670. To delete a result code, select it using the arrow keys and hit  DEL .
  1671. */
  1672.                             i=ulist(i,0,0,34,&dflt,&bar
  1673.                                 ,"Modem Result Codes",opt);
  1674.                             if(i==-1)
  1675.                                 break;
  1676.                             if((i&MSK_ON)==MSK_DEL) {
  1677.                                 i&=MSK_OFF;
  1678.                                 mdm_results--;
  1679.                                 while(i<mdm_results) {
  1680.                                     mdm_result[i]=mdm_result[i+1];
  1681.                                     i++; }
  1682.                                 changes=1;
  1683.                                 continue; }
  1684.                             if((i&MSK_ON)==MSK_INS) {
  1685.                                 i&=MSK_OFF;
  1686.                                 if((mdm_result=(mdm_result_t *)REALLOC(
  1687.                                     mdm_result,sizeof(mdm_result_t)
  1688.                                     *(mdm_results+1)))==NULL) {
  1689.                                     errormsg(WHERE,ERR_ALLOC,nulstr
  1690.                                         ,mdm_results+1);
  1691.                                     mdm_results=0;
  1692.                                     bail(1);
  1693.                                     continue; }
  1694.                                 for(j=mdm_results;j>i;j--)
  1695.                                     mdm_result[j]=mdm_result[j-1];
  1696.                                 mdm_result[i]=mdm_result[i+1];
  1697.                                 mdm_results++;
  1698.                                 changes=1;
  1699.                                 continue; }
  1700.                             results(dflt); }
  1701.                         break;
  1702.                     case 10:    /* Toggle Options */
  1703.                         dflt=0;
  1704.                         while(1) {
  1705.                             savnum=1;
  1706.                             i=0;
  1707.                             sprintf(opt[i++],"%-27.27s%s"
  1708.                                 ,"Caller Identification"
  1709.                                 ,mdm_misc&MDM_CALLERID ? "Yes" : "No");
  1710.                             sprintf(opt[i++],"%-27.27s%s"
  1711.                                 ,"Dumb Modem Connection"
  1712.                                 ,mdm_misc&MDM_DUMB ? "Yes" : "No");
  1713.                             sprintf(opt[i++],"%-27.27s%s"
  1714.                                 ,"Drop DTR to Hang Up"
  1715.                                 ,mdm_misc&MDM_NODTR ? "No" : "Yes");
  1716.                             sprintf(opt[i++],"%-27.27s%s"
  1717.                                 ,"Use Verbal Result Codes"
  1718.                                 ,mdm_misc&MDM_VERBAL ? "Yes" : "No");
  1719.                             sprintf(opt[i++],"%-27.27s%s"
  1720.                                 ,"Allow Unknown Result Codes"
  1721.                                 ,mdm_misc&MDM_KNOWNRES ? "No" : "Yes");
  1722.                             opt[i][0]=0;
  1723.                             i=ulist(WIN_SAV|WIN_ACT,0,0,0,&dflt,0
  1724.                                 ,"Modem Toggle Options",opt);
  1725.                             savnum=2;
  1726.                             if(i==-1)
  1727.                                 break;
  1728.                             if(i==0) {
  1729.                                 i=1;
  1730.                                 strcpy(opt[0],"Yes");
  1731.                                 strcpy(opt[1],"No");
  1732.                                 opt[2][0]=0;
  1733. SETHELP(WHERE);
  1734. /*
  1735. Caller Identification:
  1736.  
  1737. If your modem supports Caller ID and is configured to return caller
  1738. number delivery messages, set this option to Yes.
  1739.  
  1740. If this option is set to Yes, Synchronet will log caller number delivery
  1741. messages. If a caller attempts to connect with a number listed in the
  1742. file TEXT\CID.CAN, they will be displayed TEXT\BADCID.MSG (if it exists)
  1743. and disconnected. Each user will have their most recent caller ID number
  1744. stored in their note field.
  1745. */
  1746.                                 i=ulist(WIN_MID|WIN_SAV,0,0,0,&i,0
  1747.                                     ,"Caller ID",opt);
  1748.                                 if(i==0 && !(mdm_misc&MDM_CALLERID)) {
  1749.                                     mdm_misc|=MDM_CALLERID;
  1750.                                     changes=1; }
  1751.                                 else if(i==1 && mdm_misc&MDM_CALLERID) {
  1752.                                     mdm_misc&=~MDM_CALLERID;
  1753.                                     changes=1; } }
  1754.                             else if(i==1) {
  1755.                                 i=1;
  1756.                                 strcpy(opt[0],"Yes");
  1757.                                 strcpy(opt[1],"No");
  1758.                                 opt[2][0]=0;
  1759. SETHELP(WHERE);
  1760. /*
  1761. Dumb Modem Connection:
  1762.  
  1763. If this node is connected to a serial line through a dumb modem, set
  1764. this option to Yes to disable all modem commands and answer calls when
  1765. DCD is raised.
  1766. */
  1767.                                 i=ulist(WIN_SAV|WIN_MID,0,0,0,&i,0
  1768.                                     ,"Dumb Modem",opt);
  1769.                                 if(i==0 && !(mdm_misc&MDM_DUMB)) {
  1770.                                     mdm_misc|=MDM_DUMB;
  1771.                                     changes=1; }
  1772.                                 else if(i==1 && mdm_misc&MDM_DUMB) {
  1773.                                     mdm_misc&=~MDM_DUMB;
  1774.                                     changes=1; } }
  1775.                             else if(i==2) {
  1776.                                 i=0;
  1777.                                 strcpy(opt[0],"Yes");
  1778.                                 strcpy(opt[1],"No");
  1779.                                 opt[2][0]=0;
  1780. SETHELP(WHERE);
  1781. /*
  1782. Drop DTR to Hang Up:
  1783.  
  1784. If you wish to have the BBS drop DTR to hang up the modem, set this
  1785. option to Yes. If this option is set to No, the Hang Up String is sent
  1786. to modem instead.
  1787. */
  1788.                                 i=ulist(WIN_SAV|WIN_MID,0,0,0,&i,0
  1789.                                     ,"Drop DTR to Hang Up",opt);
  1790.                                 if(i==0 && mdm_misc&MDM_NODTR) {
  1791.                                     mdm_misc&=~MDM_NODTR;
  1792.                                     changes=1; }
  1793.                                 else if(i==1 && !(mdm_misc&MDM_NODTR)) {
  1794.                                     mdm_misc|=MDM_NODTR;
  1795.                                     changes=1; } }
  1796.                             else if(i==3) {
  1797.                                 i=1;
  1798.                                 strcpy(opt[0],"Yes");
  1799.                                 strcpy(opt[1],"No");
  1800.                                 opt[2][0]=0;
  1801. SETHELP(WHERE);
  1802. /*
  1803. Use Verbal Result Codes:
  1804.  
  1805. If you wish to have the BBS expect verbal (or verbose) result codes
  1806. from the modem instead of numeric (non-verbose) result codes, set this
  1807. option to Yes.
  1808.  
  1809. This option can be useful for modems that insist on returning multiple
  1810. result codes upon connection (CARRIER, PROTOCOL, etc) or modems that
  1811. do not report numeric result codes correctly. While this option is more
  1812. flexible than numeric result codes, it may not be as accurate in
  1813. describing the connection or estimating the CPS rate of the connection.
  1814.  
  1815. If this option is set to Yes, the configured result code list will not
  1816. be used (you may remove all entries from the list if you wish). The
  1817. connection rate, description, and estimated CPS will be automatically
  1818. generated by the BBS.
  1819. */
  1820.                                 i=ulist(WIN_SAV|WIN_MID,0,0,0,&i,0
  1821.                                     ,"Use Verbal Result Codes",opt);
  1822.                                 if(i==0 && !(mdm_misc&MDM_VERBAL)) {
  1823.                                     mdm_misc|=MDM_VERBAL;
  1824.                                     changes=1; }
  1825.                                 else if(i==1 && mdm_misc&MDM_VERBAL) {
  1826.                                     mdm_misc&=~MDM_VERBAL;
  1827.                                     changes=1; } }
  1828.                             else if(i==4) {
  1829.                                 i=0;
  1830.                                 strcpy(opt[0],"Yes");
  1831.                                 strcpy(opt[1],"No");
  1832.                                 opt[2][0]=0;
  1833. SETHELP(WHERE);
  1834. /*
  1835. Allow Unknown Result Codes:
  1836.  
  1837. If you wish to have the BBS allow modem connections with an unknown
  1838. (un-configured) numeric result code by using the last known (configured)
  1839. result code information by default, set this option to Yes.
  1840.  
  1841. This option has no effect if Verbal Result Codes are used.
  1842. */
  1843.                                 i=ulist(WIN_SAV|WIN_MID,0,0,0,&i,0
  1844.                                     ,"Allow Unknown Result Codes",opt);
  1845.                                 if(i==0 && mdm_misc&MDM_KNOWNRES) {
  1846.                                     mdm_misc&=~MDM_KNOWNRES;
  1847.                                     changes=1; }
  1848.                                 else if(i==1 && !(mdm_misc&MDM_KNOWNRES)) {
  1849.                                     mdm_misc|=MDM_KNOWNRES;
  1850.                                     changes=1; } }
  1851.                                     }
  1852.                         break;
  1853.                     case 11:
  1854. SETHELP(WHERE);
  1855. /*
  1856. Modem Control Strings:
  1857.  
  1858. This menu contains a list of available modem control strings. It is usually
  1859. not necessary to modify these except under special circumstances.
  1860. */
  1861.                         j=0;
  1862.                         while(1) {
  1863.                             i=0;
  1864.                             savnum=1;
  1865.                             sprintf(opt[i++],"%-27.27s%.40s"
  1866.                                 ,"Initialization String",mdm_init);
  1867.                             sprintf(opt[i++],"%-27.27s%.40s"
  1868.                                 ,"Special Init String",mdm_spec);
  1869.                             sprintf(opt[i++],"%-27.27s%.40s"
  1870.                                 ,"Terminal Init String",mdm_term);
  1871.                             sprintf(opt[i++],"%-27.27s%.40s"
  1872.                                 ,"Dial String",mdm_dial);
  1873.                             sprintf(opt[i++],"%-27.27s%.40s"
  1874.                                 ,"Off Hook String",mdm_offh);
  1875.                             sprintf(opt[i++],"%-27.27s%.40s"
  1876.                                 ,"Answer String",mdm_answ);
  1877.                             sprintf(opt[i++],"%-27.27s%.40s"
  1878.                                 ,"Hang Up String",mdm_hang);
  1879.                             opt[i][0]=0;
  1880.                             j=ulist(WIN_ACT|WIN_MID|WIN_SAV,0,0,60,&j,0
  1881.                                 ,"Modem Control Strings",opt);
  1882.                             if(j==-1)
  1883.                                 break;
  1884.                             switch(j) {
  1885.                                 case 0:
  1886. SETHELP(WHERE);
  1887. /*
  1888. Initialization String:
  1889.  
  1890. This is one of the strings of characters sent to your modem upon
  1891. modem initialization. If you find it necessary to send additional
  1892. commands to the modem during initialization, use the Special Init String
  1893. for that purpose.
  1894. */
  1895.                                     uinput(WIN_MID|WIN_SAV,0,0
  1896.                                         ,"Initialization"
  1897.                                         ,mdm_init,50,K_EDIT|K_UPPER);
  1898.                                     break;
  1899.                                 case 1:
  1900. SETHELP(WHERE);
  1901. /*
  1902. Special Init String:
  1903.  
  1904. This is an additional optional string of characters to be sent to your
  1905. modem during initialization. Many of the Auto-Configuration options
  1906. automatically set this string. It is used for sending commands that are
  1907. particular to this modem type. If you find it necessary to send
  1908. additional commands to your modem during initialization, use this option
  1909. for that purpose.
  1910. */
  1911.                                     uinput(WIN_MID|WIN_SAV,0,0
  1912.                                         ,"Special Init"
  1913.                                         ,mdm_spec,50,K_EDIT|K_UPPER);
  1914.                                     break;
  1915.                                 case 2:
  1916. SETHELP(WHERE);
  1917. /*
  1918. Terminal Init String:
  1919.  
  1920. This is the string of characters sent to your modem when terminal mode
  1921. is entered from the Synchronet wait for call screen.
  1922. */
  1923.                                     uinput(WIN_MID|WIN_SAV,0,0
  1924.                                         ,"Terminal Init"
  1925.                                         ,mdm_term,50,K_EDIT|K_UPPER);
  1926.                                     break;
  1927.                                 case 3:
  1928. SETHELP(WHERE);
  1929. /*
  1930. Dial String:
  1931.  
  1932. This is the string used to dial the modem in Synchronet Callback
  1933. (an optional callback verification module).
  1934. */
  1935.                                     uinput(WIN_MID|WIN_SAV,0,0
  1936.                                         ,"Dial String",mdm_dial,40
  1937.                                         ,K_EDIT|K_UPPER);
  1938.                                     break;
  1939.                                 case 4:
  1940. SETHELP(WHERE);
  1941. /*
  1942. Off Hook String:
  1943.  
  1944. This is the string of characters sent to your modem to take it off hook
  1945. (make busy).
  1946. */
  1947.                                     uinput(WIN_MID|WIN_SAV,0,0
  1948.                                         ,"Off Hook String",mdm_offh
  1949.                                         ,40,K_EDIT|K_UPPER);
  1950.                                     break;
  1951.                                 case 5:
  1952. SETHELP(WHERE);
  1953. /*
  1954. Answer String:
  1955.  
  1956. This is the string of characters sent to your modem to answer an
  1957. incoming call.
  1958. */
  1959.                                     uinput(WIN_MID|WIN_SAV,0,0
  1960.                                         ,"Answer String",mdm_answ,40
  1961.                                         ,K_EDIT|K_UPPER);
  1962.                                     break;
  1963.                                 case 6:
  1964. SETHELP(WHERE);
  1965. /*
  1966. Hang Up String:
  1967.  
  1968. This is the string of characters sent to your modem to hang up the
  1969. phone line (go on-hook).
  1970. */
  1971.                                     uinput(WIN_MID|WIN_SAV,0,0
  1972.                                         ,"Hang Up String",mdm_hang,40
  1973.                                         ,K_EDIT|K_UPPER);
  1974.                                     break;
  1975.                                     } }
  1976.                         break;
  1977.                     case 12:
  1978.                         dflt=bar=0;
  1979.                         while(1) {
  1980.                             for(i=0;i<mdm_types;i++)
  1981.                                 strcpy(opt[i],mdm_type[i]);
  1982.                             opt[i][0]=0;
  1983.                             savnum=1;
  1984. SETHELP(WHERE);
  1985. /*
  1986. Auto-Configuration Modem Type:
  1987.  
  1988. This is the list of modem types currently supported by Synchronet's
  1989. automatic modem configuration feature. If your modem is listed, select
  1990. it using the arrow keys and hit  ENTER . If your modem is not listed,
  1991. you may want to try using the auto-configuration of a compatible modem
  1992. or one from the same manufacturer. If you have a 2400bps modem, select
  1993. Hayes SmartModem 2400. If you have a high-speed modem that is not
  1994. listed, you may want to try Generic 9600 or Generic 14400 and add
  1995. the additional high-speed result codes by hand. Refer to your modem's
  1996. manual for a list of result codes supported by your modem.
  1997. */
  1998.                             i=ulist(WIN_ACT|WIN_SAV|WIN_RHT,0,0,0
  1999.                                 ,&dflt,&bar,"Modem Type",opt);
  2000.                             if(i==-1)
  2001.                                 break;
  2002.                             strcpy(opt[0],"Yes");
  2003.                             strcpy(opt[1],"No");
  2004.                             opt[2][0]=0;
  2005.                             j=1;
  2006.                             savnum=2;
  2007.  
  2008.                             j=ulist(WIN_MID|WIN_SAV,0,0,0,&j,0
  2009.                                 ,"Continue with Modem Auto-Configuration",opt);
  2010.                             if(!j) {
  2011.                                 mdm_cfg(i);
  2012.                                 changes=1;
  2013.                                 sprintf(str
  2014.                                     ,"Modem configured as %s",mdm_type[i]);
  2015.                                 savnum=1;
  2016.                                 umsg(str); } }
  2017.                         break;
  2018.                     case 13:
  2019. SETHELP(WHERE);
  2020. /*
  2021. Import Modem Configuration File
  2022.  
  2023. Using this option, you can import modem settings from an MDM file in
  2024. your CTRL directory (i.e. To import from CTRL\MYMODEM.MDM, type MYMODEM
  2025. now).
  2026. */
  2027.                         i=changes;
  2028.                         str[0]=0;
  2029.                         uinput(WIN_MID|WIN_SAV,0,0,"MDM Filename",str
  2030.                             ,8,K_UPPER);
  2031.                         if(str[0]) {
  2032.                             FREE(mdm_result);
  2033.                             mdm_result=NULL;
  2034.  
  2035.                             mdm_answ[0]=0;
  2036.                             mdm_hang[0]=0;
  2037.                             mdm_dial[0]=0;
  2038.                             mdm_offh[0]=0;
  2039.                             mdm_term[0]=0;
  2040.                             mdm_init[0]=0;
  2041.                             mdm_spec[0]=0;
  2042.                             mdm_results=0;
  2043.  
  2044.                             if(exec_mdm(str))
  2045.                                 umsg("Imported");
  2046.                             else {
  2047.                                 umsg("File Not Found");
  2048.                                 changes=i; } }
  2049.                         else
  2050.                             changes=i;
  2051.                         break;
  2052.  
  2053.                     case 14:
  2054. SETHELP(WHERE);
  2055. /*
  2056. Export Current Modem Configuration to a File
  2057.  
  2058. Using this option, you can save the current modem settings to a file.
  2059. The file will be placed into the CTRL directory and will be given an
  2060. extension of MDM (i.e. To create CTRL\MYMODEM.MDM, type MYMODEM now).
  2061. */
  2062.                         i=changes;
  2063.                         str[0]=0;
  2064.                         uinput(WIN_MID|WIN_SAV,0,0,"MDM Filename",str
  2065.                             ,8,K_UPPER);
  2066.                         if(str[0]) {
  2067.                             if(export_mdm(str))
  2068.                                 umsg("Exported");
  2069.                             else
  2070.                                 umsg("Error Exporting"); }
  2071.                         changes=i;
  2072.                         break;
  2073.                         } } } }
  2074. }
  2075.  
  2076. void results(int i)
  2077. {
  2078.     char str[81];
  2079.     int n,dflt=0;
  2080.  
  2081. while(1) {
  2082.     n=0;
  2083.     sprintf(opt[n++],"%-22.22s%u","Numeric Code",mdm_result[i].code);
  2084.     sprintf(opt[n++],"%-22.22s%ubps","Modem Connect Rate",mdm_result[i].rate);
  2085.     sprintf(opt[n++],"%-22.22s%ucps","Modem Average CPS",mdm_result[i].cps);
  2086.     sprintf(opt[n++],"%-22.22s%s","Description",mdm_result[i].str);
  2087.     opt[n][0]=0;
  2088.     savnum=2;
  2089. SETHELP(WHERE);
  2090. /*
  2091. Result Code:
  2092.  
  2093. This is one of the configured connect result codes for your modem. The
  2094. available options are:
  2095.  
  2096.     Numeric Code       :  Numeric result code
  2097.     Modem Connect Rate :  Connect speed (in bps) for this result code
  2098.     Modem Average CPS  :  Average file transfer throughput in cps
  2099.     Description        :  Description of this connection type
  2100. */
  2101.     switch(ulist(WIN_SAV|WIN_MID|WIN_ACT,0,0,35,&dflt,0,"Result Code",opt)) {
  2102.         case -1:
  2103.             return;
  2104.         case 0:
  2105.             sprintf(str,"%u",mdm_result[i].code);
  2106. SETHELP(WHERE);
  2107. /*
  2108. Numeric Result Code:
  2109.  
  2110. This is the numeric (as opposed to verbal) result code your modem will
  2111. send to your computer when it establishes a connection with another
  2112. modem with this connect type. Your modem must have the V0 setting
  2113. enabled to return numeric result codes.
  2114. */
  2115.             uinput(WIN_L2R|WIN_SAV,0,15,"Numeric Result Code",str,3
  2116.                 ,K_EDIT|K_NUMBER);
  2117.             mdm_result[i].code=atoi(str);
  2118.             break;
  2119.         case 1:
  2120. SETHELP(WHERE);
  2121. /*
  2122. Connection (DCE) Rate:
  2123.  
  2124. This is the modem (DCE) rate established with this connect type. This is
  2125. NOT the DTE rate of your modem. As an example, a 14,400bps modem may
  2126. have a DTE rate of 38,400bps but a maximum DCE rate of 14,400bps.
  2127. */
  2128.             sprintf(str,"%u",mdm_result[i].rate);
  2129.             uinput(WIN_L2R|WIN_SAV,0,15,"Connection (DCE) Rate",str,5
  2130.                 ,K_EDIT|K_NUMBER);
  2131.             mdm_result[i].rate=atoi(str);
  2132.             break;
  2133.         case 2:
  2134. SETHELP(WHERE);
  2135. /*
  2136. Average File Transfer CPS:
  2137.  
  2138. This is the average file transfer through-put (characters per second)
  2139. of connections with this result code. If you don't know the average
  2140. through-put, just divide the DCE Rate by ten for an approximation.
  2141. As an example, a 9600bps DCE Rate would have an approximate file
  2142. transfer through-put of 960cps.
  2143. */
  2144.             sprintf(str,"%u",mdm_result[i].cps);
  2145.             uinput(WIN_L2R|WIN_SAV,0,15,"Average File Transfer CPS",str,5
  2146.                 ,K_EDIT|K_NUMBER);
  2147.             mdm_result[i].cps=atoi(str);
  2148.             break;
  2149.         case 3:
  2150. SETHELP(WHERE);
  2151. /*
  2152. Modem Description:
  2153.  
  2154. This is a description of the modem type used for a connection with
  2155. this result code. It can be up to eight characters long. This
  2156. description usually just contains the DCE rate and possibly the
  2157. protocol type. Such as 2400 for a 2400bps connection, 9600/V32
  2158. for a 9600bps V.32 connection or 9600/HST for a 9600bps HST connection.
  2159. */
  2160.             uinput(WIN_L2R|WIN_SAV,0,15,"Modem Description"
  2161.                 ,mdm_result[i].str,LEN_MODEM,K_EDIT);
  2162.             break; } }
  2163. }
  2164.