BTCONFIG.C

37.6 KB 62dc5a9639a9df08…
/*--------------------------------------------------------------------------*/
/*                                                                          */
/*                                                                          */
/*      ------------         Bit-Bucket Software, Co.                       */
/*      \ 10001101 /         Writers and Distributors of                    */
/*       \ 011110 /          Freely Available<tm> Software.                 */
/*        \ 1011 /                                                          */
/*         ------                                                           */
/*                                                                          */
/*  (C) Copyright 1987-91, Bit Bucket Software Co., a Delaware Corporation. */
/*                                                                          */
/*                                                                          */
/*               This module was written by Vince Perriello                 */
/*                                                                          */
/*                                                                          */
/*                  BinkleyTerm Configuration File Parser                   */
/*                                                                          */
/*                                                                          */
/*    For complete  details  of the licensing restrictions, please refer    */
/*    to the License  agreement,  which  is published in its entirety in    */
/*    the MAKEFILE and BT.C, and also contained in the file LICENSE.250.    */
/*                                                                          */
/*    USE  OF THIS FILE IS SUBJECT TO THE  RESTRICTIONS CONTAINED IN THE    */
/*    BINKLEYTERM  LICENSING  AGREEMENT.  IF YOU DO NOT FIND THE TEXT OF    */
/*    THIS  AGREEMENT IN ANY OF THE  AFOREMENTIONED FILES,  OR IF YOU DO    */
/*    NOT HAVE THESE FILES,  YOU  SHOULD  IMMEDIATELY CONTACT BIT BUCKET    */
/*    SOFTWARE CO.  AT ONE OF THE  ADDRESSES  LISTED BELOW.  IN NO EVENT    */
/*    SHOULD YOU  PROCEED TO USE THIS FILE  WITHOUT HAVING  ACCEPTED THE    */
/*    TERMS  OF  THE  BINKLEYTERM  LICENSING  AGREEMENT,  OR  SUCH OTHER    */
/*    AGREEMENT AS YOU ARE ABLE TO REACH WITH BIT BUCKET SOFTWARE, CO.      */
/*                                                                          */
/*                                                                          */
/* You can contact Bit Bucket Software Co. at any one of the following      */
/* addresses:                                                               */
/*                                                                          */
/* Bit Bucket Software Co.        FidoNet  1:104/501, 1:343/491             */
/* P.O. Box 460398                AlterNet 7:491/0                          */
/* Aurora, CO 80046               BBS-Net  86:2030/1                        */
/*                                Internet f491.n343.z1.fidonet.org         */
/*                                                                          */
/* Please feel free to contact us at any time to share your comments about  */
/* our software and/or licensing policies.                                  */
/*                                                                          */
/*--------------------------------------------------------------------------*/

/* Include this file before any other includes or defines! */

#include "includes.h"

char *ctl_slash_string (char *);
static int Zone = 1;

void cfg_macro (char *);
void cfg_dial_string (char *);
void cfg_mdm_trans (char *);
void cfg_domain (char *);
void cfg_Janus (char *);

void parse_config (char *config_file)
{
   FILE *stream;
   char temp[256];
   char *c;
   int i;
   unsigned temp_num;
   char *p;
   ADDR temp_addr;                               /* Used to get address */

   (void) sprintf (temp, "%s%s", BINKpath, config_file);
   if ((stream = share_fopen (temp, "rt", DENY_WRITE)) == NULL)     /* OK, let's open the file   */
      return;                                    /* no file, no work to do    */

   while ((fgets (temp, 255, stream)) != NULL)   /* Now we parse the file ... */
      {
      c = temp;                                  /* Check out the first char  */
      if ((*c == '%') || (*c == ';'))            /* See if it's a comment
                                                  * line */
         continue;

      i = (int) strlen (temp);                         /* how long this line is     */

      if (i < 3)
         continue;                               /* If too short, ignore it   */

      c = &temp[--i];                            /* point at last character   */
      if (*c == '\n')                            /* if it's a newline,        */
         *c = '\0';                              /* strip it off              */

      if ((i = parse (temp, config_lines)) != 0)
         {
         c = &temp [(config_lines [i - 1]).p_length];
         }

      switch (i)
         {
         case 1:                                /* "SameRing"      */
            modemring = 1;
            break;

         case 2:                                /* "NewNodeList"   */
         case 129:                              /* "Version6"      */
            newnodelist = 1;
            break;

         case 3:                                /* "QuickNodeList" */
#ifdef QUICK_LIST
            nodefunc = QuickLookup;
            newnodelist = 0;
#endif
            break;

         case 4:                                /* "Answerback"  */
            answerback = ctl_string (c);
            break;

         case 5:                                /* "Macro"         */
            cfg_macro (c);
            break;

         case 6:                                /* "Shell"        */
            c = skip_blanks (c);
            i = atoi (c);
            if ((i <= 0) || (i > 9))
               {
               (void) printf ("%s %d %s\n", MSG_TXT(M_SHELL_NUMBER), i, MSG_TXT(M_OUT_OF_RANGE));
               break;
               }
            c = skip_to_blank (c);
            c = skip_blanks (c);
            shells[i - 1] = calloc (1, strlen (c) + 1);
            (void) strcpy (shells[i - 1], c);
            (void) strupr (shells[i - 1]);
            break;

         case 7:                                /* "Dial"         */
            cfg_dial_string (c);
            break;

         case 8:                                /* "Event"        */
            c = skip_blanks (c);
            (void) parse_event (c);
            break;

         case 9:                                /* "Zone"         */
            c = skip_blanks (c);
            Zone = atoi (c);
            if (!Zone)                          /* if we didn't find a zone  */
               (void) printf (MSG_TXT(M_ILLEGAL_ZONE), &temp[4]);
            break;

         case 10:                               /* "MaxReq"       */
            (void) sscanf (c, "%d %d", &DEFAULT.rq_Limit, &DEFAULT.rq_Cum_Limit);
            if (!DEFAULT.rq_Limit)              /* No requests??? */
               (void) printf ("0 %s\n", MSG_TXT(M_REQUESTS_ALLOWED));
            break;

         case 11:                               /* "LogLevel"     */
            c = skip_blanks (c);
            i = atoi (c);
            if ((i <= 5) && (i > 0))
               {
               loglevel = i;
               }
            else
               {
               (void) printf (MSG_TXT(M_BAD_LOGLEVEL), &temp[8]);
               }
            break;

         case 12:                               /* "Baud"         */
            temp_num = (unsigned int) atoi (c);
            max_baud.rate_value = 0;
            for (i = 0; btypes[i].rate_value; i++)
               {
               if (btypes[i].rate_value == temp_num)
                  {
                  max_baud.rate_mask = btypes[i].rate_mask;
                  max_baud.rate_value = temp_num;
                  break;
                  }
               }
            if (!max_baud.rate_value)
               goto bad_line;
            break;

         case 13:                               /* "MaxPort"      */
            c = skip_blanks (c);
            i = atoi (c);                        /* make it binary            */
            if ((i > 0) && (i < 33))             /* if range is reasonable,   */
               MAXport = i;                      /* Make it the max value     */
            else
               (void) printf (MSG_TXT(M_BAD_MAXPORT), &temp[7]);
            break;

         case 14:                               /* "Port"         */
            c = skip_blanks (c);
            i = atoi (c);                        /* make it binary            */
            if ((i > 0) || (i < 33))             /* see if it's OK            */
               {
               port_ptr = i - 1;                 /* store it if so            */
               if (MAXport < i)                  /* See if MAXport is less    */
                  MAXport = i;                   /* If so, increase MAXport   */
               original_port = port_ptr;
               }
            else
               (void) printf (MSG_TXT(M_ILLEGAL_PORT), &temp[4]);
            break;

         case 15:                               /* "Carrier"      */
            c = skip_blanks (c);
            i = 0;
            (void) sscanf (c, "%x", &i);         /* convert it to binary      */
            if (i != 0)                          /* if we got anything        */
               carrier_mask = (unsigned int) i;
            else
               (void) printf (MSG_TXT(M_ILLEGAL_CARRIER), &temp[7]);
            break;

         case 16:                               /* "StatusLog"    */
            log_name = ctl_string (c);
            if ((status_log = share_fopen (log_name, "at", DENY_WRITE)) == NULL)
               {
               free (log_name);
               log_name = NULL;
               }
            else
               {
               (void) fprintf (status_log, "\n");
               (void) fflush (status_log);
               (void) real_flush (fileno (status_log));
               }
            break;

         case 17:                               /* "Reader"       */
            BBSreader = ctl_string (c);
            break;

         case 18:                               /* "BossPhone"    */
            BOSSphone = ctl_string (c);
            break;

         case 19:                               /* "BossPwd"      */
            BOSSpwd = ctl_string (c);
            break;

         case 20:                               /* "Protocol"     */
            if (extern_index == 5)
               break;
            protocols[extern_index++] = ctl_string (c);
            break;

         case 21:                               /* "System"       */
            system_name = ctl_string (c);
            break;

         case 22:                               /* "Sysop"        */
            sysop = ctl_string (c);
            break;

         case 23:                               /* "Boss"         */
            c = skip_blanks (c);
            (void) parse_address (c, &boss_addr);
            break;

         case 24:                               /* "Point"        */
         case 25:                               /* "Aka"          */
         case 94:                               /* "Address"      */
            c = skip_blanks (c);
            if (num_addrs == 0)
               alias[0].Zone = Zone;
            (void) parse_address (c, &temp_addr);
            alias[num_addrs] = temp_addr;
            Zone = (int) alias[0].Zone;         /* First is real default */
            ++num_addrs;
            break;

         case 26:                               /* "Hold"         */
            hold_area = ctl_slash_string (c);
            domain_area = strdup (hold_area);

            domain_area[strlen (domain_area) - 1] = '\0';
            p = strrchr (domain_area, '\\');
            if (p == NULL)
               {
               p = strrchr (domain_area, '/');
               if (p == NULL)
                  {
                  p = strrchr (domain_area, ':');
                  if (p == NULL)
                     p = domain_area;
                  }
               }
            if (p != domain_area)
               ++p;

            domain_loc = p;
            *p = '\0';
            break;

         case 27:                               /* "DownLoads"    */
            download_path = ctl_slash_string (c);
            break;

         case 28:                               /* "NetFile"      */
            DEFAULT.sc_Inbound = ctl_slash_string (c);
            break;

         case 29:                               /* "Init"         */
            modem_init = ctl_string (c);
            break;

         case 30:                               /* "Busy"         */
            modem_busy = ctl_string (c);
            break;

         case 31:                               /* "Prefix"       */
            predial = ctl_string (c);
            normprefix = predial;
            break;

         case 32:                               /* "NodeList"     */
            net_info = ctl_slash_string (c);
            break;

         case 33:                               /* "Avail"        */
            DEFAULT.rq_FILES = ctl_string (c);
            break;

         case 34:                               /* "OKFile"       */
            DEFAULT.rq_OKFile = ctl_string (c);
            break;

         case 35:                               /* "About"        */
            DEFAULT.rq_About = ctl_string (c);
            break;

         case 36:                               /* "MAILnote"     */
            MAILnote = ctl_string (c);
            break;

         case 37:                               /* "Banner"       */
            BBSbanner = ctl_string (c);
            break;

         case 38:                               /* "UnAttended"   */
            un_attended = 1;
            command_line_un = 1;
            break;

         case 39:                               /* "OverWrite"    */
            overwrite = 1;
            break;

         case 40:                               /* "Rev3"         */
            rev3 = 1;
            break;

         case 41:                               /* "ReqOnUs"      */
            on_our_nickel = 1;
            break;

         case 42:                               /* "LockBaud"     */
            c = skip_blanks (c);                /* Skip to baud   */

            if (*c == '\0')                     /* Case 1: no arg */
               {
               lock_baud = 1;                   /* Always lock    */
               break;
               }

            if (isdigit (*c))                   /* Case 2: baud   */
               {
               lock_baud = (unsigned)(atoi (c));/* Lock at >= baud*/
               break;
               }

            i = 1 + strlen (c);                 /* Case 3: ARQ    */
            if (ARQs > 16)                      /* Only 16 allowed*/
               break;
            p = calloc (1, i);                  /* Allocate space */
            if (p == NULL)                      /* Give up if none*/
               break;
            (void) strcpy (p, c);               /* Copy ARQ string*/
            ARQ[ARQs++] = p;                    /* Update array   */
            break;


         case 43:                               /* "TimeOut"      */
            c = skip_blanks (c);
            BBStimeout = (unsigned) (atoi (c) * 100);
            if (BBStimeout < 2000)
               BBStimeout = 2000;
            break;

         case 44:                               /* "NoSLO"        */
            no_overdrive = 1;
            break;

         case 45:                               /* "SlowModem"    */
            slowmodem = 1;
            break;

         case 46:                               /* "SmallWindow"  */
            small_window = 1;
            break;

         case 47:                               /* "NoPickup"     */
            no_pickup = 1;
            break;

         case 48:                               /* "NoRequests"   */
            no_requests = 1;
            break;

         case 49:                               /* "NetMail"      */
            netmail = ctl_slash_string(c);
            break;                              /* for BTCTL & MAIL.SYS */

         case 50:                               /* "Suffix"       */
            postdial = ctl_string (c);
            normsuffix = postdial;
            break;

         case 51:                               /* "NoFullScreen" */
#ifndef MILQ
            fullscreen = 0;
#endif
            break;

         case 52:                               /* "AutoBaud"     */
            autobaud = 1;
            break;

         case 53:                               /* "Gong"         */
            gong_allowed = 1;
            break;

         case 54:                               /* "NoCollide"    */
            no_collide = 1;
            break;

         case 55:                               /* "TBBSlist"     */
#ifdef OLDTBBSLIST
            nodefunc = TBBSLookup;
            newnodelist = 0;
#endif
            break;

         case 56:                               /* "TaskView"     */
         case 57:                               /* "TopView"      */
            have_tv = 1;
            break;

         case 58:                               /* "ExtrnMail"    */
            c = skip_blanks (c);
            if (isdigit (*c))
               {
               lev_ext_mail[num_ext_mail] = atoi (c);
               while ((*c) && (!isspace (*c)))
                  ++c;
               }
            else
               {
               lev_ext_mail[num_ext_mail] = 99;
               }
            ext_mail_string[num_ext_mail++] = ctl_string (c);
            break;

         case 59:                               /* "BBSnote"      */
            BBSnote = ctl_string (c);
            break;

         case 60:                               /* "BBS"          */
            BBSopt = ctl_string (c);
            break;

         case 61:                               /* "ScriptPath"   */
            script_path = ctl_slash_string (c);
            break;

         case 62:                               /* "BoxType"      */
            c = skip_blanks (c);
            boxtype = atoi (c);
            if ((boxtype > 4) || (boxtype < 0))
               boxtype = 1;
            break;

         case 63:                               /* "MultiLink"    */
            have_ml = 1;
            break;

         case 64:                               /* "Include"      */
            c = skip_blanks (c);
            parse_config (c);
            break;

         case 65:                               /* "CaptureFile"  */
            logptr = ctl_string (c);
            break;

         case 66:                               /* "CursorCol"    */
            c = skip_blanks (c);
            cursor_col = atoi (c) - 1;
            break;

         case 67:                               /* "CursorRow"    */
            c = skip_blanks (c);
            cursor_row = atoi (c) - 1;
            break;

         case 68:                               /* "DoingMail"    */
            c = skip_blanks (c);
            (void) sprintf (junk, "\r\r%s\r\r", c);
            noBBS = calloc (1, strlen (junk) + 1);
            (void) strcpy (noBBS, junk);
            break;

         case 69:                               /* "EnterBBS"     */
            c = skip_blanks (c);
            (void) sprintf (junk, "\r%s\r", c);
            BBSesc = calloc (1, strlen (junk) + 1);
            (void) strcpy (BBSesc, junk);
            break;

         case 70:                               /* "PrivateNet"   */
            c = skip_blanks (c);
            pvtnet = atoi (c);
            break;

         case 71:                               /* "Packer"       */
            packer = ctl_string (c);
            break;

         case 72:                               /* "Cleanup"      */
            cleanup = ctl_string (c);
            break;

         case 73:                               /* "AfterMail"    */
            aftermail = ctl_string (c);
            break;

         case 74:                               /* "Colors"       */
            sscanf (c, "%d %d %d %d %d %d %d %d",
                  &colors.background, &colors.settings, &colors.history,
                  &colors.hold, &colors.call, &colors.file,
                  &colors.calling, &colors.popup);
            break;

         case 75:                               /* "JanusBaud"    */
            c = skip_blanks (c);
            janus_baud = (unsigned) atoi(c);
            break;

         case 76:                               /* "ReqTemplate"  */
            DEFAULT.rq_Template = ctl_string (c);
            break;

         case 77:                               /* "KnownAvail"   */
            KNOWN.rq_FILES = ctl_string(c);
            break;

         case 78:                               /* "KnownReqList" */
            KNOWN.rq_OKFile = ctl_string(c);
            break;

         case 79:                               /* "KnownAbout"   */
            KNOWN.rq_About = ctl_string (c);
            break;

         case 80:                               /* "KnownInbound" */
            KNOWN.sc_Inbound = ctl_slash_string (c);
            break;

         case 81:                               /* "KnownReqLim"  */
            (void) sscanf (c, "%d %d", &KNOWN.rq_Limit, &KNOWN.rq_Cum_Limit);
            break;

         case 82:                               /* "KnownReqTpl"  */
            KNOWN.rq_Template = ctl_string (c);
            break;

         case 83:                               /* "ProtAvail"   */
            PROT.rq_FILES = ctl_string(c);
            break;

         case 84:                               /* "ProtReqList" */
            PROT.rq_OKFile = ctl_string(c);
            break;

         case 85:                               /* "ProtAbout"   */
            PROT.rq_About = ctl_string (c);
            break;

         case 86:                               /* "ProtInbound" */
            PROT.sc_Inbound = ctl_slash_string (c);
            break;

         case 87:                               /* "ProtReqLim"  */
            (void) sscanf (c, "%d %d", &PROT.rq_Limit, &PROT.rq_Cum_Limit);
            break;

         case 88:                               /* "ProtReqTpl"  */
            PROT.rq_Template = ctl_string (c);
            break;

         case 89:                               /* "Application" */
            break;

         case 90:                               /* "NoZones"     */
            no_zones = 1;
            break;

         case 91:                               /* "Answer"        */
            ans_str = ctl_string (c);
            break;

         case 92:                               /* "PollTries"   */
            c = skip_blanks (c);
            poll_tries = atoi (c);
            break;

         case 93:                               /* "SwapDir"     */
            c = skip_blanks (c);
            i = (int) strlen (c);
            swapdir = calloc (1, i + 2);
            (void) strcpy (swapdir, c);
            (void) add_backslash (swapdir);
            break;

         case 95:                               /* "Curmudgeon"  */
            ++curmudgeon;                       /* Do it like Randy */
            break;

         case 96:                               /* "NoWaZOO"     */
            no_WaZOO_Session = ++no_WaZOO;      /* FTSC sessions */
            break;

         case 97:                               /* "ScreenBlank" */
            do_screen_blank = 1;
            p = skip_blanks (c);
            if (strnicmp (p, MSG_TXT(M_KEY), 3) == 0)
               {
               blank_on_key = 1;
               }
            else if (strnicmp (p, MSG_TXT(M_CALL), 4) == 0)
               {
               blank_on_key = 0;
               }
            break;

         case 98:                               /* "Mark_Kromm"  */

            /* These colors from Mark Kromm, Fidonet 1:261/1034  */

            colors.background = 112;            /* The           */
            colors.settings   =   9;            /* Great         */
            colors.history    =  10;            /* BinkleyTerm   */
            colors.hold       =  11;            /* Colors        */
            colors.call       =  14;            /* Contest       */
            colors.file       =  12;            /* Winner!!!!    */
            colors.calling    =  56;
            colors.popup      =  15;
            break;

         case 99:                               /* "Server"      */
            server_mode = 1;
            break;

         case 100:                              /* "ModemTrans"  */
            cfg_mdm_trans (c);
            break;

         case 101:                              /* "PreDial" */
            dial_setup = ctl_string (c);
            break;

         case 102:                              /* "PreInit" */
            init_setup = ctl_string (c);
            break;

         case 103:                              /* "DTRHigh" */
            leave_dtr_high = 1;
            break;

         case 104:                              /* "Debug" */
            debugging_log = !debugging_log;
            break;

         case 105:                              /* "NoZedZap" */
            no_zapzed = !no_zapzed;
            break;

         case 106:                              /* "NoResync" */
            no_resync = !no_resync;
            break;

         case 107:                              /* "NoSEAlink" */
            no_sealink = !no_sealink;
            break;

         case 108:                              /* "FTS-0001" */
            no_sealink = 1;
            no_resync = 1;
            no_overdrive = 1;
            ++no_WaZOO;                         /* FTSC sessions */
            break;

         case 109:                              /* "LineUpdate" */
            immed_update = !immed_update;
            break;

         case 110:                              /* "JanusOK"      */
            cfg_Janus (c);
            break;

         case 111:                              /* "TermInit"     */
            term_init = ctl_string (c);
            break;

         case 112:                              /* "Domain"       */
            cfg_domain (c);
            break;

         case 113:                               /* "Snoop"        */
#ifdef Snoop
            if (getenv("SNOOPPIPE") == NULL)
                strcpy(pipename, skip_blanks(c));
            else
                strcpy(pipename, getenv("SNOOPPIPE"));

            if (pipename[0] != '\0')
                snoop_open(pipename);
#endif /* Snoop */
            break;

         case 114:                               /* "Flags"        */
            flag_dir = ctl_slash_string (c);
            break;

         case 115:                               /* "Tasknumber"   */
            c = skip_blanks (c);
            TaskNumber = atoi (c);
            break;

         case 116:                               /* "MaxBytes"     */
            (void) sscanf (c, "%ld %ld", &DEFAULT.byte_Limit, &DEFAULT.byte_Cum_Limit);
            break;

         case 117:                               /* "KnownMaxBytes"*/
            (void) sscanf (c, "%ld %ld", &KNOWN.byte_Limit, &KNOWN.byte_Cum_Limit);
            break;

         case 118:                               /* "ProtMaxBytes" */
            (void) sscanf (c, "%ld %ld", &PROT.byte_Limit, &PROT.byte_Cum_Limit);
            break;

         case 119:                               /* "StartBlkLen"  */
            c = skip_blanks (c);
            fstblklen = atoi (c);
            if ((fstblklen < 64) || (fstblklen > 2048))
               fstblklen = 1024;
            break;

         case 120:                               /* "MaxTime"      */
            (void) sscanf (c, "%d %ld", &DEFAULT.time_Limit, &DEFAULT.time_Cum_Limit);
            DEFAULT.time_Limit *= 60;
            DEFAULT.time_Cum_Limit *= 60;
            break;

         case 121:                               /* "KnownMaxTime" */
            (void) sscanf (c, "%d %ld", &KNOWN.time_Limit, &KNOWN.time_Cum_Limit);
            KNOWN.time_Limit *= 60;
            KNOWN.time_Cum_Limit *= 60;
            break;

         case 122:                               /* "ProtMaxTime"  */
            (void) sscanf (c, "%d %ld", &PROT.time_Limit, &PROT.time_Cum_Limit);
            PROT.time_Limit *= 60;
            PROT.time_Cum_Limit *= 60;
            break;

         case 123:                               /* "RingTries"    */
            c = skip_blanks (c);
            ring_tries = atoi (c);
            break;

         case 124:                               /* "NoSharing"    */
            no_sharing = 1;
            break;

         case 125:                               /* "Version7"     */
            version7 = 1;
            nodefunc = ver7find;
            userfunc = opususer;
            newnodelist = 0;
            break;

         case 126:                               /* "BlankWait"    */
            c = skip_blanks (c);
            blank_time = (unsigned int)100 * (unsigned int)atoi (c);
            break;

         case 127:                               /* "Serial"       */
            c = skip_blanks (c);
            if (isdigit (*c))
               serial = atoi (c);
            break;

         case 128:                               /* "NoDietIfna"   */
            no_dietifna = 1;
            break;

         case 130:
            winslice = 1;                        /* "WinSlice"     */
            break;

         case 131:                               /* "NoSize"       */
            no_size = 1;
            break;

bad_line:
         default:
            (void) printf (MSG_TXT(M_UNKNOWN_LINE), temp);
         }
      }
   (void) fclose (stream);                       /* close input file */

   if (debugging_log)
      loglevel = 6;
}

char *ctl_string (char *source)                  /* malloc & copy to ctl      */
{
   char *dest, *c;
   int i;

   c = skip_blanks (source);                     /* get over the blanks       */
   i = (int) strlen (c);                         /* get length of remainder   */
   if (i < 1)                                    /* must have at least 1      */
      return (NULL);                             /* if not, return NULL       */
   dest = calloc (1, (unsigned int) (++i));      /* allocate space for string */
   if (dest == NULL)                             /* If we failed to get it,   */
      return (NULL);                             /* Just return NULL          */
   (void) strcpy (dest, c);                      /* copy the stuff over       */
   return (dest);                                /* and return the address    */
}

char *ctl_slash_string (char *source)            /* malloc & copy to ctl      */
{
   char *dest, *c;
   int i;
   struct stat buffer;

   c = skip_blanks (source);                     /* get over the blanks       */
   i = (int) strlen (c);                         /* get length of remainder   */
   if (i < 1)                                    /* must have at least 1      */
      return (NULL);                             /* if not, return NULL       */
   dest = calloc (1, (unsigned int) (i+2));      /* allocate space for string */
   if (dest == NULL)                             /* If we failed to get it,   */
      return (NULL);                             /* Just return NULL          */
   (void) strcpy (dest, c);                      /* copy the stuff over       */
   (void) delete_backslash (dest);               /* get rid of trailing stuff */
   /* Check to see if the directory exists */
   i = stat (dest, &buffer);
   if (i || (!(buffer.st_mode & S_IFDIR)))
      {
      (void) printf (MSG_TXT(M_BAD_DIR), dest);
      (void) printf (MSG_TXT(M_FAIL_EXEC));
      return(NULL);
      }
   (void) add_backslash (dest);                         /* add the backslash         */
   return (dest);                                /* return the directory name */
}


char *add_backslash (char *str)
{
   char *p;

   p = str + strlen (str) - 1;

   if (p >= str)
      {
      /* Strip off the trailing blanks */
      while ((p >= str) && (isspace (*p)))
         {
         *p = '\0';
         --p;
         }

      /* Put a backslash if there isn't one */
      if ((p >=str) && (*p != '\\') && (*p != '/'))
         {
         *(++p) = '\\';
         *(++p) = '\0';
         }
      }

   return (fancy_str (str));
}

char *delete_backslash (char *str)
{
   char *p;

   p = str + strlen (str) - 1;

   if (p >= str)
      {
      /* Strip off the trailing blanks */
      while ((p >= str) && (isspace (*p)))
         {
         *p = '\0';
         --p;
         }

      /* Get rid of backslash if there is one */
      if ((p >=str) && ((*p == '\\') || (*p == '/')))
         {
         if ((p > str) && (*(p-1) != ':'))      /* Don't delete on root */
            *p = '\0';
         }
      }

   return (fancy_str (str));
}

void cfg_macro (char *c)
{
   int i;
   char *p;

   c = skip_blanks (c);
   i = atoi (c);
   if ((i <= 0) || (i > 9))
      {
      (void) printf ("%s %d %s\n", MSG_TXT(M_MACRO_NUMBER), i, MSG_TXT(M_OUT_OF_RANGE));
      return;
      }
   c = skip_to_blank (c);
   c = skip_blanks (c);
   keys[i - 1] = calloc (1, strlen (c) + 1);
   p = keys[i - 1];
   while (*c && (*c != '\n'))
      {
      if (*c == '|')
         *p++ = '\r';
      else *p++ = *c;
      ++c;
      }
   *p = '\0';
}

void cfg_dial_string (char *c)
{
   char *p, *p1;
   PN_TRNS *tpn;

   p = c;
   while ((*p) && (isspace (*p)))
      ++p;

   if ((*p == ';') || (*p == '\0'))
      {
      return;
      }

   tpn = (PN_TRNS *) calloc (1, sizeof (PN_TRNS));

   p1 = tpn->num;
   while ((*p) && (!isspace (*p)))
      {
      *p1++ = *p++;
      }
   *p1 = '\0';

   while ((*p) && (isspace (*p)))
      {
      ++p;
      }

   p1 = tpn->pre;
   while ((*p) && (*p != '/') && (!isspace (*p)))
      {
      *p1++ = *p++;
      }
   *p1 = '\0';

   p1 = tpn->suf;
   if ((*p == '\0') || (isspace (*p)))
      {
      *p1 = '\0';
      }
   else
      {
      ++p;

      while ((*p) && (!isspace (*p)))
         {
         *p1++ = *p++;
         }
      *p1 = '\0';
      }

   tpn->len = (int) strlen (tpn->num);
   tpn->next = NULL;
   if (pn_head == NULL)
      {
      pn_head = tpn;
      }
   else
      {
      pn->next = tpn;
      }
   pn = tpn;
}

void cfg_mdm_trans (char *c)
{
   char *p, *p1;
   MDM_TRNS *tmm;

   p = c;
   while ((*p) && (isspace (*p)))
      ++p;

   if ((*p == ';') || (*p == '\0'))
      {
      return;
      }

   tmm = (MDM_TRNS *) calloc (1, sizeof (MDM_TRNS));

   tmm->mdm = (byte) atoi (p);
   while ((*p) && (!isspace (*p)))
      {
      p++;
      }

   while ((*p) && (isspace (*p)))
      {
      ++p;
      }

   p1 = tmm->pre;
   while ((*p) && (*p != '/') && (!isspace (*p)))
      {
      *p1++ = *p++;
      }
   *p1 = '\0';

   p1 = tmm->suf;
   if ((*p == '\0') || (isspace (*p)))
      {
      *p1 = '\0';
      }
   else
      {
      ++p;

      while ((*p) && (!isspace (*p)))
         {
         *p1++ = *p++;
         }
      *p1 = '\0';
      }

   tmm->next = NULL;
   if (mm_head == NULL)
      {
      mm_head = tmm;
      }
   else
      {
      mm->next = tmm;
      }
   mm = tmm;
}

void cfg_domain (char *c)
{
   char *p, *p1, *p2;
   int i;

   p = skip_blanks (c);
   p = strtok (p, "; \t\r\n");
   if (p != NULL)
      {
      /* Have the domain name, now get the abbreviated name */
      p2 = strtok (NULL, "; \t\r\n");
      if (strlen (p2) > 8)
         *(p2 + 8) = '\0';
      if (p2 != NULL)
         {
         /* Have the domain name and abbreviated, now get the list name */
         p1 = strtok (NULL, "; \t\r\n");
         if (p1 == NULL)
            p1 = p2;

         /* Have the list name and the domain name, now use them */
         for (i = 0; domain_name[i] != NULL; i++)
            {
            if (strnicmp (domain_name[i], p, strlen (domain_name[i])) == 0)
               {
               domain_nodelist[i] = strdup (p1);
               domain_abbrev[i] = strdup (p2);
               break;
               }
            }
         if ((domain_name[i] == NULL) && (i < 49))
            {
            domain_name[i] = strdup (p);
            domain_abbrev[i] = strdup (p2);
            domain_nodelist[i] = strdup (p1);
            }
         }
      }
}

void cfg_Janus (char *c)
{
   J_TYPES *tjt;
   char *p, *p1;

   p = c;
   while ((*p) && (isspace (*p)))
      ++p;

   if ((*p == ';') || (*p == '\0'))
      {
      return;
      }

   tjt = (J_TYPES *) calloc (1, sizeof (J_TYPES));

   p1 = tjt->j_match;
   while ((*p) && (!isspace (*p)))
      {
      *p1++ = *p++;
      }
   *p1 = '\0';

   tjt->next = NULL;

   if (j_top == NULL)
      {
      j_top = tjt;
      }
   else
      {
      j_next->next = tjt;
      }
   j_next = tjt;
}