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