home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 2 BBS / 02-BBS.zip / BTMTSRC3.ZIP / BTCTL.C < prev    next >
C/C++ Source or Header  |  1991-08-07  |  29KB  |  787 lines

  1. /*--------------------------------------------------------------------------*/
  2. /*                                                                          */
  3. /*                                                                          */
  4. /*      ------------         Bit-Bucket Software, Co.                       */
  5. /*      \ 10001101 /         Writers and Distributors of                    */
  6. /*       \ 011110 /          Freely Available<tm> Software.                 */
  7. /*        \ 1011 /                                                          */
  8. /*         ------                                                           */
  9. /*                                                                          */
  10. /*  (C) Copyright 1987-90, Bit Bucket Software Co., a Delaware Corporation. */
  11. /*                                                                          */
  12. /*                                                                          */
  13. /*               This module was written by Vince Perriello                 */
  14. /*                                                                          */
  15. /*                                                                          */
  16. /*                 BinkleyTerm OMMM Control File Generator                  */
  17. /*                                                                          */
  18. /*                                                                          */
  19. /*    For complete  details  of the licensing restrictions, please refer    */
  20. /*    to the License  agreement,  which  is published in its entirety in    */
  21. /*    the MAKEFILE and BT.C, and also contained in the file LICENSE.240.    */
  22. /*                                                                          */
  23. /*    USE  OF THIS FILE IS SUBJECT TO THE  RESTRICTIONS CONTAINED IN THE    */
  24. /*    BINKLEYTERM  LICENSING  AGREEMENT.  IF YOU DO NOT FIND THE TEXT OF    */
  25. /*    THIS  AGREEMENT IN ANY OF THE  AFOREMENTIONED FILES,  OR IF YOU DO    */
  26. /*    NOT HAVE THESE FILES,  YOU  SHOULD  IMMEDIATELY CONTACT BIT BUCKET    */
  27. /*    SOFTWARE CO.  AT ONE OF THE  ADDRESSES  LISTED BELOW.  IN NO EVENT    */
  28. /*    SHOULD YOU  PROCEED TO USE THIS FILE  WITHOUT HAVING  ACCEPTED THE    */
  29. /*    TERMS  OF  THE  BINKLEYTERM  LICENSING  AGREEMENT,  OR  SUCH OTHER    */
  30. /*    AGREEMENT AS YOU ARE ABLE TO REACH WITH BIT BUCKET SOFTWARE, CO.      */
  31. /*                                                                          */
  32. /*                                                                          */
  33. /* You can contact Bit Bucket Software Co. at any one of the following      */
  34. /* addresses:                                                               */
  35. /*                                                                          */
  36. /* Bit Bucket Software Co.        FidoNet  1:104/501, 1:132/491, 1:141/491  */
  37. /* P.O. Box 460398                AlterNet 7:491/0                          */
  38. /* Aurora, CO 80046               BBS-Net  86:2030/1                        */
  39. /*                                Internet f491.n132.z1.fidonet.org         */
  40. /*                                                                          */
  41. /* Please feel free to contact us at any time to share your comments about  */
  42. /* our software and/or licensing policies.                                  */
  43. /*                                                                          */
  44. /*--------------------------------------------------------------------------*/
  45.  
  46. #include <stdio.h>
  47. #include <signal.h>
  48. #include <ctype.h>
  49. #include <conio.h>
  50. #include <stdlib.h>
  51. #include <string.h>
  52. #include <sys/types.h>
  53. #include <sys/stat.h>
  54.  
  55. #ifdef __TURBOC__
  56. #include <alloc.h>
  57. #else
  58. #include <malloc.h>
  59. #endif
  60.  
  61. typedef unsigned bit;
  62. typedef unsigned int word;
  63. typedef unsigned char byte;
  64.  
  65. struct parse_list
  66.     {
  67.     int p_length;
  68.     char *p_string;
  69.     };
  70.  
  71. /*--------------------------------------------------------------------------*/
  72. /* The following is excerpted from the control structures used by Opus 1.10 */
  73. /* as it is currently implemented. The only part that really concerns BTCTL */
  74. /* is that part of the _PRM structure that contains the version number and  */
  75. /* the network address. Only those parts are actually handled by this code. */
  76. /* We suspect that no changes will be made in that part of the structure    */
  77. /* between now and the release of Opus 1.10. If I were you, I would make    */
  78. /* no such assumptions about the rest.                                      */
  79. /*--------------------------------------------------------------------------*/
  80.  
  81. #define THIS_CTL_VERSION  16       /* PRM structure version number         */
  82.  
  83. #define CTLSIZE 1
  84. #define OFS     char*
  85.  
  86. #define MAX_EXTERN         8       /* max. number of external programs     */
  87. #define MAXCLASS          12       /* number of possible priv levels       */
  88. #define ALIAS_CNT         15       /* number of matrix addresses           */
  89.  
  90. /*--------------------------------------------------------------------------*/
  91. /* FIDONET ADDRESS STRUCTURE                                                */
  92. /*--------------------------------------------------------------------------*/
  93. typedef struct _ADDRESS
  94.     {
  95.     word Zone;
  96.     word Net;
  97.     word Node;
  98.     word Point;
  99.     } ADDR;
  100.  
  101. /*--------------------------------------------------------------------------*/
  102. /* Attributes of a given class of users                                     */
  103. /*--------------------------------------------------------------------------*/
  104. struct class_rec
  105.     {
  106.     byte ClassPriv;
  107.     byte class_fill;
  108.     int max_time;      /* max cume time per day         */
  109.     int max_call;      /* max time for one call         */
  110.     int max_dl;        /* max dl bytes per day          */
  111.     word ratio;         /* ul:dl ratio                   */
  112.     word min_baud;      /* speed needed for logon        */
  113.     word min_file_baud; /* speed needed for file xfer    */
  114.     };
  115.  
  116. /*--------------------------------------------------------------------------*/
  117. /* Registers to pass to a FOSSIL appendage                                  */
  118. /*--------------------------------------------------------------------------*/
  119. struct _FOSREGS
  120.    {
  121.     word ax;
  122.     word bx;
  123.     word cx;
  124.     word dx;
  125.     };
  126.  
  127. /*--------------------------------------------------------------------------*/
  128. /* The format of the PRM file, VERSION 16                                   */
  129. /*                                                                          */
  130. /* THIS IS AN EXPLOSIVE STRUCTURE.  IT IS SUBJECT TO CHANGE WITH NO NOTICE. */
  131. /*                                                                          */
  132. /* Offsets to the following item(s) are guaranteed:                         */
  133. /*                                                                          */
  134. /*      byte   version;        /* OFFSET 0, all versions                    */
  135. /*      byte   task_num;       /* OFFSET 1, 16+                             */
  136. /*                                                                          */
  137. /*--------------------------------------------------------------------------*/
  138.  
  139. struct _PRM
  140.     {
  141.     /*-----------------------------------------------------------*/
  142.     /* DATA                                                      */
  143.     /*-----------------------------------------------------------*/
  144.     byte version;        /* for safety                          STABLE*/
  145.     byte task_num;       /* for multi-tasking systems           STABLE*/
  146.     ADDR alias[ALIAS_CNT];
  147.  
  148.     byte video;          /* 0=Dos, 1=Fossil 2=IBM                     */
  149.     byte testmode;       /* input from keyboard, not modem            */
  150.  
  151.     word carrier_mask;
  152.     word handshake_mask;
  153.     word max_baud;       /* fastest speed we can use                  */
  154.     word com_port;       /* Com1=0, Com2=1, FF=keyboard               */
  155.  
  156.     byte multitasker;    /* flag for DoubleDos (see below)            */
  157.     byte mailer_type;    /* 0=Opus, 1=load external, 2=call external  */
  158.  
  159.     byte ModemFlag;      /* (See MODEM FLAG below)                    */
  160.     byte LogFlag;        /* (See LOG FLAG below)                      */
  161.  
  162.     byte StyleFlag;      /* (See STYLE FLAG below)                    */
  163.     byte FWDflag;        /* Bits to control IN TRANSIT messages       */
  164.  
  165.     byte Flags;          /* See "FLAGS" below                         */
  166.     byte Flags2;         /* See "FLAGS 2" below                       */
  167.  
  168.     byte edit_exit;      /* ERRORLEVEL to use if Matrix area changed  */
  169.     byte exit_val;       /* ERRORLEVEL to use after caller            */
  170.  
  171.     byte crashexit;      /* non-zero= ErrorLevel exit                 */
  172.     byte arc_exit;       /* ErrorLevel for after incomming ARCmail    */
  173.  
  174.     byte echo_exit;      /* ERRORLEVEL for after inbound echomail     */
  175.     byte UDB_Flags;      /* User data base flags                      */
  176.  
  177.     word min_baud;       /* minimum baud to get on-line               */
  178.     word color_baud;     /* min baud for graphics                     */
  179.     word date_style;     /* Used for FILES.BBS display                */
  180.  
  181.     byte logon_priv;     /* Access level for new users                */
  182.     byte seenby_priv;    /* Min priv to see SEEN_BY line              */
  183.  
  184.     byte ctla_priv;      /* Priv to see CONTROL-A lines in messages   */
  185.     byte FromFilePriv;   /* Priv. for doing message from file         */
  186.  
  187.     byte AskPrivs[16];   /* Array of privs. for message attr ask's    */
  188.     byte AssumePrivs[16];/* Array of privs. for message attr assume's */
  189.  
  190.     word logon_time;     /* time to give for logons                   */
  191.  
  192.     word matrix_mask;
  193.          
  194.     word MinNetBaud;     /* minimum baud rate for remote netmail      */
  195.     word MaxJanusBaud;   /* fastest baud to use Ianus                 */
  196.  
  197.     struct class_rec class[MAXCLASS];
  198.     struct _FOSREGS FosRegs[10];
  199.  
  200.     word F_Reward;       /* File upload time reward percentage        */
  201.  
  202.     word last_area;      /* Highest msg area presumed to exist        */
  203.     word last_farea;     /* Highest file area presumed to exist       */
  204.  
  205.     word PRM_FILL3[17];
  206.  
  207.  
  208.     /*-----------------------------------------------------------*/
  209.     /* OFFSETS                                                   */
  210.     /*-----------------------------------------------------------*/
  211.  
  212.     /*-------------------------------------------*/
  213.     /* MODEM COMMAND STRINGS                     */
  214.     /*-------------------------------------------*/
  215.     OFS MDM_Init;       /* modem initialization string               */
  216.     OFS MDM_PreDial;    /* modem dial command sent before number     */
  217.     OFS MDM_PostDial;   /* modem command sent after dialed number    */
  218.     OFS MDM_LookBusy;   /* mdm cmd to take modem off hook            */
  219.  
  220.     /*-------------------------------------------*/
  221.     /* PRIMROSE PATHS                            */
  222.     /*-------------------------------------------*/
  223.     OFS misc_path;      /* path to BBS/GBS files                     */
  224.     OFS sys_path;       /* path to SYSTEM?.BBS files                 */
  225.     OFS temppath;       /* place to put temporary files              */
  226.     OFS net_info;       /* path to NODELIST files                    */
  227.     OFS mailpath;       /* place to put received netmail bundles     */
  228.     OFS filepath;       /* place to put received netmail files       */
  229.     OFS hold_area;      /* path to pending outbound matrix traffic   */
  230.  
  231.     /*-------------------------------------------*/
  232.     /* DATA FILE NAMES                           */
  233.     /*-------------------------------------------*/
  234.     OFS user_file;      /* path/filename of User.Bbs                 */
  235.     OFS sched_name;     /* name of file with _sched array            */
  236.     OFS syl;            /* default system language file              */
  237.     OFS usl;            /* default user language file                */
  238.  
  239.     /*-------------------------------------------*/
  240.     /* MISCELLANEOUS TEXT                        */
  241.     /*-------------------------------------------*/
  242.     OFS system_name;    /* board's name                              */
  243.     OFS sysop;          /* sysop's name                              */
  244.     OFS timeformat;
  245.     OFS dateformat;
  246.     OFS protocols[MAX_EXTERN]; /* external file protocol programs    */
  247.  
  248.     /*-------------------------------------------*/
  249.     /* BBS/GBS SUPPORT FILES                     */
  250.     /*-------------------------------------------*/
  251.     OFS logo;           /* first file shown to a caller              */
  252.     OFS welcome;        /* shown after logon                         */
  253.     OFS newuser1;
  254.     OFS newuser2;
  255.     OFS rookie;
  256.  
  257.     OFS HLP_Editor;     /* Intro to msg editor for novices.          */
  258.     OFS HLP_Replace;    /* Explain the Msg.Editor E)dit command      */
  259.     OFS HLP_Inquire;    /* Explain the Msg. I)nquire command         */
  260.     OFS HLP_Locate;     /* Explain the Files L)ocate command         */
  261.     OFS HLP_Contents;   /* Explain the Files C)ontents command       */
  262.     OFS HLP_OPed;       /* help file for the full-screen editor      */
  263.     OFS OUT_Leaving;    /* Bon Voyage                                */
  264.     OFS OUT_Return;     /* Welcome back from O)utside                */
  265.     OFS ERR_DayLimit;   /* Sorry, you've been on too long...         */
  266.     OFS ERR_TimeWarn;   /* warning about forced hangup               */
  267.     OFS ERR_TooSlow;    /* explains minimum logon baud rate          */
  268.     OFS ERR_XferBaud;   /* explains minimum file transfer baud rate  */
  269.     OFS LIST_MsgAreas;  /* dump file... used instead of Dir.Bbs      */
  270.     OFS LIST_FileAreas; /* dump file... used instead of Dir.Bbs      */
  271.         
  272.     OFS FREQ_MyFiles;   /* file to send when FILES is file requested */
  273.     OFS FREQ_OKList;    /* list of files approved for file requests  */
  274.     OFS FREQ_About;     /* File Request: ABOUT file                  */
  275.  
  276.     OFS OEC_Quotes;
  277.     OFS byebye;         /* file displayed at logoff                  */
  278.     OFS ocal_editor;   /* text editor to use in keyboard mode       */
  279.     OFS barricade;
  280.     OFS Files_BBS;      /* FILES.BBS filename override for CD ROM    */
  281.     OFS mailer;         /* full external mailer command              */
  282.     OFS common;         /* File with data common to all tasks        */
  283.  
  284.     OFS OFS_Filler[13];
  285.  
  286.     /*-----------------------------------------------------------*/
  287.     /* Log_Name must always be the last offset in this struct    */
  288.     /* because Bbs_Init uses that symbol to flag the end of      */
  289.     /* the offsets.                                              */
  290.     /*-----------------------------------------------------------*/
  291.     OFS log_name;       /* name of the log file                      */
  292.  
  293.  
  294.     /*-----------------------------------------------------------*/
  295.     /* Big blob of stuff                                         */
  296.     /* It's a sequence of null-terminated character arrays...    */
  297.     /* pointed-to by the offsets (above).                        */
  298.     /*-----------------------------------------------------------*/
  299.     char buf[CTLSIZE];
  300.     };
  301.  
  302. /* Stuff used later on here */
  303.  
  304. void main(void);
  305. void errxit(char *);
  306. char *fancy_str(char *);
  307. char *add_backslash(char *);
  308. char *delete_backslash(char *);
  309. char *ctl_string(char *);
  310. char *ctl_slash_string(char *);
  311. char *skip_blanks(char *);
  312. void parse_config(char *);
  313. void b_initvars(void);
  314. void b_defaultvars(void);
  315. int parse(char *, struct parse_list *);
  316.  
  317. char *BTCTL_ANN = "BTCtl - Revision 2.40\n\n";
  318. char *config_name = "Binkley.Cfg";
  319. char *BINKpath = NULL;
  320. int pvtnet = 0;
  321. int net_params = 0;
  322. int Zone = 1;
  323.  
  324. /*--------------------------------------------------------------------------*/
  325. /* BTCTL                                                                    */
  326. /* Parse the BINKLEY.CFG file and write out a BINKLEY.PRM file (for use by  */
  327. /* OMMM) and a MAIL.SYS file (for use by FASTTOSS, SCANMAIL, SIRIUS, etc).  */
  328. /* If the environment variable BINKLEY exists use the path specified for    */
  329. /* ALL input and output files.                                              */
  330. /*--------------------------------------------------------------------------*/
  331.  
  332. /*--------------------------------------------------------------------------*/
  333. /* MAIL.SYS file structure                                                  */
  334. /*--------------------------------------------------------------------------*/
  335. struct _mail
  336.     {
  337.     int pri_node;       /* Our node number                          */
  338.     float fudge;        /* Unknown/unused                           */
  339.     int rate;           /* Maximum baud rate                        */
  340.     char mailpath[80];  /* Path for incomming messages              */
  341.     char filepath[80];  /* Path for incomming files                 */
  342.     int pri_net;        /* Our network number                       */
  343.     int alt_node;       /* Alternate node number (mainly for HOSTS) */
  344.     int alt_net;        /* Alternate net number (mainly for HOSTS)  */
  345.     };
  346.  
  347. struct _mail mailsys;        /* MAIL.SYS used by SIRIUS  */
  348. struct _PRM ctl;             /* where the .CTL stuff is  */
  349.  
  350. int num_addrs = 0;
  351.  
  352. void main()
  353.     {
  354.     char *envptr;
  355.     FILE *stream;
  356.     char temp[80];
  357.     char *skip_blanks();
  358.     struct stat statbuf;
  359.     int k;
  360.  
  361.     printf(BTCTL_ANN);
  362.  
  363.     b_initvars();
  364.  
  365.     envptr = getenv("BINKLEY");                /* get path from environment */
  366.     if ((envptr != NULL) && (stat(config_name,&statbuf) != 0))
  367.         {                                                    /* No BINKLEY.CFG locally,   */
  368.         BINKpath = malloc(strlen(envptr) + 2);  /* If there was one, and     */
  369.         strcpy(BINKpath, envptr);               /* make room for new */
  370.         add_backslash(BINKpath);                    /* use BINKLEY as our path   */
  371.         }
  372.  
  373.     parse_config("Binkley.Evt");
  374.     parse_config(config_name);
  375.  
  376.     b_defaultvars();
  377.  
  378.     /*
  379.         * Print out what we got.
  380.         */
  381.  
  382.     if (ctl.system_name != NULL)
  383.         printf("System: %s\n",ctl.system_name);
  384.  
  385.     if (ctl.sysop != NULL)
  386.         printf("Sysop:  %s\n",ctl.sysop);
  387.  
  388.     for (k = 0; k < ALIAS_CNT; k++)               /* And the alias list        */
  389.         {
  390.         if (!ctl.alias[k].Zone)
  391.             break;
  392.         printf("Address %u:%u/%u.%u\n",ctl.alias[k].Zone,ctl.alias[k].Net,ctl.alias[k].Node,ctl.alias[k].Point);
  393.         }
  394.  
  395.     if (ctl.mailpath != NULL)
  396.         printf("Net Mailpath %s\n",ctl.mailpath);
  397.  
  398.     if (ctl.filepath != NULL)
  399.         printf("Net Filepath %s\n",ctl.filepath);
  400.  
  401.     printf("\n");
  402.  
  403.     if (!net_params)
  404.         errxit("Not enough information to establish Netmail session");
  405.  
  406.     /*
  407.     * Okay, we have the nodelist data from the BINKLEY.CFG file.
  408.     * Now write it into a BINKLEY.PRM file.
  409.     */
  410.  
  411.     if (BINKpath != NULL)                         /* If there was a BINKLEY,   */
  412.         {
  413.         strcpy(temp, BINKpath);                   /* use it here too           */
  414.         }
  415.     else
  416.         temp[0] = '\0';
  417.     strcat(temp, "Binkley.Prm");                 /* add in the file name      */
  418.  
  419.     if ((stream = fopen(temp, "wb")) == NULL)    /* OK, let's open the file   */
  420.         errxit("Unable to open BINKLEY.PRM");
  421.     if (fwrite(&ctl, sizeof(ctl), 1, stream) != 1) /* Try to write data out  */
  422.         errxit("Could not write control file data to BINKLEY.PRM");
  423.     fclose(stream);                              /* close output file         */
  424.     printf("Version 16 Control file successfully written\n");
  425.     printf("oMMM 1.30 or above is required to use it\n\n");
  426.  
  427.     /*
  428.     * BINKLEY.PRM now written. Let's write a MAIL.SYS file too.
  429.     */
  430.  
  431.     mailsys.pri_node = ctl.alias[0].Node;
  432.     mailsys.pri_net  = ctl.alias[0].Net;
  433.     mailsys.alt_node = ctl.alias[1].Node;
  434.     mailsys.alt_net  = ctl.alias[1].Net;
  435.     strcpy(mailsys.mailpath, ctl.mailpath);
  436.     strcpy(mailsys.filepath, ctl.filepath);
  437.  
  438.     if (BINKpath != NULL)                         /* If there was a BINKLEY,   */
  439.         {
  440.         strcpy(temp, BINKpath);                   /* use it here too           */
  441.         }
  442.     else
  443.         temp[0] = '\0';
  444.     strcat(temp, "Mail.Sys");                    /* add in the file name      */
  445.  
  446.     if ((stream = fopen(temp, "wb")) == NULL)    /* OK, let's open the file   */
  447.         errxit("Could not open MAIL.SYS");        /* no file, no work to do    */
  448.     if (fwrite(&mailsys, sizeof(mailsys), 1, stream) != 1)
  449.         errxit("Unable to write data to MAIL.SYS");  /* Try to write data out  */
  450.     fclose(stream);                              /* close output file         */
  451.    printf("MAIL.SYS file successfully written\n"); /* Notify user of success */
  452.     }
  453.  
  454. /**
  455.  ** b_initvars -- called before parse_config. Sets defaults that we want
  456.  ** to have set FIRST.
  457.  **/
  458.  
  459.  
  460. void b_initvars()
  461.     {
  462.     int k;
  463.  
  464.     ctl.version = 16;
  465.     for (k = 0; k < ALIAS_CNT; k++)               /* And the alias list        */
  466.         {
  467.         ctl.alias[k].Zone = ctl.alias[k].Net =
  468.             ctl.alias[k].Node = ctl.alias[k].Point = 0;
  469.         }
  470.  
  471.     ctl.alias[0].Zone = 1;                        /* Make sure we have a zone  */
  472.     ctl.alias[0].Net = ctl.alias[0].Node = -1;    /* Default Fidonet address   */
  473.     ctl.alias[0].Point = 0;
  474.  
  475.     ctl.system_name = ctl.sysop =    ctl.hold_area = ctl.mailpath = ctl.filepath = NULL;
  476.     }
  477.  
  478. /**
  479.  ** b_defaultvars -- called after all parse_config passes complete.
  480.  ** sets anything not handled by parse_config to default if we know it.
  481.  **/
  482.  
  483.  
  484. void b_defaultvars()
  485.     {
  486.     /* Set up "point" address correctly if we can */
  487.    
  488.     if (ctl.alias[0].Point)
  489.         {
  490.         ctl.alias[0].Net   = pvtnet;
  491.         ctl.alias[0].Node  = ctl.alias[0].Point;
  492.         ctl.alias[0].Point = 0;
  493.         }
  494.  
  495.     /* If we have the minimum information to do netmail, set the flag */
  496.  
  497.     if ((ctl.alias[0].Zone  != 0)
  498.         &&  (ctl.alias[0].Net   != 0)
  499.         &&  (ctl.system_name    != NULL)
  500.         &&  (ctl.sysop          != NULL)
  501.         &&  (ctl.hold_area      != NULL)
  502.         &&  (ctl.filepath       != NULL)
  503.         &&  (ctl.mailpath       != NULL))
  504.         net_params = 1;
  505.     }
  506.  
  507.  
  508. struct parse_list config_lines[] =
  509.  { {4,  "Zone"},
  510.     {6,  "System"},
  511.     {5,  "Sysop"},
  512.     {4,  "Boss"},
  513.     {5,  "Point"},
  514.     {3,  "Aka"},
  515.     {7,  "Address"},
  516.     {4,  "Hold"},
  517.     {7,  "NetFile"},
  518.     {7,  "NetMail"},
  519.     {7,  "Include"},
  520.     {10, "PrivateNet"},
  521.     {0, NULL} };
  522.  
  523.  
  524. void parse_config(config_file)
  525. char *config_file;
  526.     {
  527.     FILE *stream;
  528.     char temp[256];
  529.     char *c;
  530.     int i;
  531.     int boss_net = 0;
  532.     int boss_node = 0;
  533.  
  534.     if (BINKpath != NULL)
  535.         sprintf(temp, "%s%s", BINKpath, config_file);
  536.     else
  537.         strcpy(temp, config_file);
  538.  
  539.     if ((stream = fopen(temp, "rt")) == NULL)    /* OK, let's open the file   */
  540.         return;                                    /* no file, no work to do    */
  541.  
  542.     while ((fgets(temp, 255, stream)) != NULL)   /* Now we parse the file ... */
  543.         {
  544.         c = temp;                                  /* Check out the first char  */
  545.         if ((*c == '%') || (*c == ';'))            /* See if it's a comment
  546.             * line */
  547.             continue;
  548.  
  549.         i = strlen(temp);                         /* how long this line is     */
  550.  
  551.         if (i < 3)
  552.             continue;                               /* If too short, ignore it   */
  553.  
  554.         c = &temp[--i];                            /* point at last character   */
  555.         if (*c == '\n')                            /* if it's a newline,        */
  556.             *c = '\0';                              /* strip it off              */
  557.  
  558.         switch (parse(temp, config_lines))
  559.             {
  560.             case 1:                                /* "Zone"         */
  561.                 c = skip_blanks(&temp[4]);
  562.                 Zone = atoi(c);
  563.                 if (!Zone)                          /* if we didn't find a zone  */
  564.                     printf("Illegal zone: %s\n", &temp[4]);
  565.                 break;
  566.  
  567.             case 2:                                /* "System"       */
  568.                 ctl.system_name = ctl_string(&temp[6]);
  569.                 break;
  570.  
  571.             case 3:                                /* "Sysop"        */
  572.                 ctl.sysop = ctl_string(&temp[5]);
  573.                 break;
  574.  
  575.             case 4:                                /* "Boss"         */
  576.                 c = skip_blanks(&temp[4]);
  577.                 sscanf(c, "%d/%d", &boss_net, &boss_node);
  578.                 if (boss_net)
  579.                     pvtnet = boss_net;
  580.                 break;
  581.  
  582.             case 5:                                /* "Point"        */
  583.                 i = 5;
  584.                 goto address;
  585.  
  586.             case 6:                                /* "Aka"          */
  587.                 i = 3;
  588.                 goto address;
  589.  
  590.             case 7:                                /* "Address"      */
  591.                 i = 7;
  592. address:
  593.                 ctl.alias[num_addrs].Point = 0;
  594.                 c = skip_blanks(&temp[i]);
  595.                 i = sscanf(c, "%d:%d/%d.%d",
  596.                     &ctl.alias[num_addrs].Zone,
  597.                     &ctl.alias[num_addrs].Net,
  598.                     &ctl.alias[num_addrs].Node,
  599.                     &ctl.alias[num_addrs].Point);
  600.                 if (i < 3)
  601.                     {
  602.                     i = sscanf(c, "%d/%d.%d",
  603.                         &ctl.alias[num_addrs].Net,
  604.                         &ctl.alias[num_addrs].Node,
  605.                         &ctl.alias[num_addrs].Point);
  606.                     if (i < 2)
  607.                         break;
  608.                     ctl.alias[num_addrs].Zone = Zone;
  609.                     }
  610.                 Zone = ctl.alias[0].Zone;           /* First is real default */
  611.                 ++num_addrs;
  612.                 break;
  613.  
  614.             case 8:                               /* "Hold"         */
  615.                 ctl.hold_area = ctl_slash_string(&temp[4]);
  616.                 break;
  617.  
  618.             case 9:                               /* "NetFile"      */
  619.                 ctl.filepath = ctl_slash_string(&temp[7]);
  620.                 break;
  621.  
  622.             case 10:                              /* "NetMail"      */
  623.                 ctl.mailpath = ctl_slash_string(&temp[7]);
  624.                 break;
  625.  
  626.             case 11:                               /* "Include"      */
  627.                 c = skip_blanks(&temp[7]);
  628.                 parse_config(c);
  629.                 break;
  630.  
  631.             case 12:                               /* "PrivateNet"   */
  632.                 c = skip_blanks(&temp[10]);
  633.                 pvtnet = atoi(c);
  634.                 break;
  635.  
  636.             default:
  637.                 break;
  638.                 }
  639.             }
  640.         fclose(stream);                              /* close input file          */
  641.     }
  642.  
  643. int parse(input, list)
  644. char *input;
  645. struct parse_list list[];
  646.     {
  647.     int i;
  648.  
  649.     for (i = 0; list[i].p_length; i++)
  650.         {
  651.         if (strnicmp(input, list[i].p_string, list[i].p_length) == 0)
  652.             return(++i);
  653.         }
  654.     return(-1);
  655.     }
  656.  
  657. void errxit(error)
  658. char *error;
  659.     {
  660.     printf("\r\n%s\n", error);
  661.     exit(0);
  662.     }
  663.  
  664. char *fancy_str(string)
  665. char *string;
  666.     {
  667.     register int flag = 0;
  668.     char *s;
  669.  
  670.     s = string;
  671.  
  672.     while (*string)
  673.         {
  674.         if (isalpha(*string))                     /* If alphabetic,     */
  675.             {
  676.             if (flag)                               /* already saw one?   */
  677.                 *string = tolower(*string);         /* Yes, lowercase it  */
  678.             else
  679.                 {
  680.                 flag = 1;                            /* first one, flag it */
  681.                 *string = toupper(*string);         /* Uppercase it       */
  682.                 }
  683.             }
  684.         else /* if not alphabetic  */ flag = 0;    /* reset alpha flag   */
  685.         string++;
  686.         }
  687.  
  688.    return(s);
  689.     }
  690.  
  691. char *add_backslash(str)
  692. char *str;
  693.     {
  694.     char *p;
  695.  
  696.     p = str + strlen(str) - 1;
  697.  
  698.     /* Strip off the trailing blanks */
  699.     while ((p >= str) && (isspace(*p)))
  700.         {
  701.         *p = '\0';
  702.         --p;
  703.         }
  704.  
  705.     /* Put a backslash if there isn't one */
  706.     if ((*p != '\\') && (*p != '/'))
  707.         {
  708.         *(++p) = '\\';
  709.         *(++p) = '\0';
  710.         }
  711.  
  712.     return(fancy_str(str));
  713.     }
  714.  
  715. char *delete_backslash(str)
  716. char *str;
  717.     {
  718.     char *p;
  719.  
  720.     p = str + strlen(str) - 1;
  721.  
  722.     if (p >= str)
  723.         {
  724.         /* Strip off the trailing blanks */
  725.         while ((p >= str) && (isspace(*p)))
  726.             {
  727.             *p = '\0';
  728.             --p;
  729.             }
  730.  
  731.         /* Get rid of backslash if there is one */
  732.         if ((p >=str) && ((*p == '\\') || (*p == '/')))
  733.             {
  734.             if ((p > str) && (*(p-1) != ':'))      /* Don't delete on root */
  735.                 *p = '\0';
  736.             }
  737.         }
  738.  
  739.     return(fancy_str(str));
  740.     }
  741.  
  742.  
  743. char *ctl_string(source)             /* malloc & copy to ctl      */
  744. char *source;
  745.     {
  746.     char *dest, *c;
  747.  
  748.     c = skip_blanks(source);    /* get over the blanks       */
  749.     dest = malloc(strlen(c) + 1);      /* allocate space for string */
  750.     strcpy(dest, c);            /* copy the stuff over       */
  751.     return(dest);               /* and return the address    */
  752.     }
  753.  
  754. char *ctl_slash_string(source)       /* malloc & copy to ctl      */
  755. char *source;
  756.     {
  757.     char *dest, *c, *t;
  758.     int i;
  759.     struct stat buffer;
  760.  
  761.     c = skip_blanks(source);                     /* get over the blanks       */
  762.     i = strlen(c);                               /* get length of remainder   */
  763.     if (i < 1)                                    /* must have at least 1      */
  764.         return(NULL);                             /* if not, return NULL       */
  765.     t = dest = malloc(i+2);                      /* allocate space for string */
  766.     strcpy(dest, c);                             /* copy the stuff over       */
  767.     delete_backslash(dest);                      /* get rid of trailing stuff */
  768.     /* Check to see if the directory exists */
  769.     i = stat(dest, &buffer);
  770.     if (i || (!(buffer.st_mode & S_IFDIR)))
  771.         {
  772.         printf("Directory '%s' does not exist!\n", dest);
  773.         printf("  BinkleyTerm may fail to execute properly because of this!\n");
  774.         return(NULL);
  775.         }
  776.     add_backslash(dest);                         /* add the backslash         */
  777.     return(dest);                                /* return the directory name */
  778.     }
  779.  
  780. char *skip_blanks(string)
  781. char *string;
  782.     {
  783.     while (*string == ' ' || *string == '\t')
  784.         ++string;
  785.     return(string);
  786.     }
  787.