home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / INFO / MODEM / UWPC201.ZIP / UW-SRC.ZIP / CONFIG.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1991-11-13  |  21.0 KB  |  647 lines

  1. //-------------------------------------------------------------------------
  2. //
  3. // CONFIG.CPP - Configuration objects for UW/PC.
  4. // 
  5. //  This file is part of UW/PC - a multi-window comms package for the PC.
  6. //  Copyright (C) 1990-1991  Rhys Weatherley
  7. //
  8. //  This program is free software; you can redistribute it and/or modify
  9. //  it under the terms of the GNU General Public License as published by
  10. //  the Free Software Foundation; either version 1, or (at your option)
  11. //  any later version.
  12. //
  13. //  This program is distributed in the hope that it will be useful,
  14. //  but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16. //  GNU General Public License for more details.
  17. //
  18. //  You should have received a copy of the GNU General Public License
  19. //  along with this program; if not, write to the Free Software
  20. //  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  21. //
  22. // Revision History:
  23. // ================
  24. //
  25. //  Version  DD/MM/YY  By  Description
  26. //  -------  --------  --  --------------------------------------
  27. //    1.0    23/03/91  RW  Original Version of CONFIG.CPP
  28. //    1.1    30/10/91  RW  Modify to make it work with Windows 3.0
  29. //
  30. // You may contact the author by:
  31. // =============================
  32. //
  33. //  e-mail: rhys@cs.uq.oz.au
  34. //    mail: Rhys Weatherley
  35. //          5 Horizon Drive
  36. //          Jamboree Heights
  37. //          Queensland 4074
  38. //        Australia
  39. //
  40. //-------------------------------------------------------------------------
  41.  
  42. #define    NOWINMESSAGES    1    // Don't include some windows.h for extra space
  43. #define NOWINSTYLES    1    // otherwise it won't compile under BCC -W.
  44. #define    NOGDI        1
  45.  
  46. #include "config.h"        // Declarations for this module.
  47. #include "comms.h"        // Communications routines.
  48. #include "client.h"        // Client manipulation classes.
  49. #include "opcodes.h"        // Opcodes for terminal emulations.
  50. #include "screen.h"        // Screen attributes defined here.
  51. #include <stdio.h>        // Standard I/O routines.
  52. #include <string.h>        // String processing routines.
  53. #include <ctype.h>        // Character type macros.
  54. #include <stdlib.h>        // "exit" was defined here.
  55. #include <alloc.h>        // Memory allocation routines.
  56. #include <errno.h>        // Error message declarations.
  57.  
  58. //
  59. // Define the main UW/PC configuration object.
  60. //
  61. UWConfiguration    UWConfig;
  62.  
  63. //
  64. // Global information for this module.
  65. //
  66. #ifdef    UWPC_WINDOWS
  67. static    CATCHBUF    CatchBuf;
  68. #define    SPRINTF        wsprintf
  69. #define    STRING        LPSTR
  70. #else
  71. #define    SPRINTF        sprintf
  72. #define    STRING        char *
  73. #endif
  74. static    char        ErrorBuffer[256];
  75.  
  76. //
  77. // Report an error during configuration.  If "perr" is TRUE then
  78. // use the message for the current "perror" error message.
  79. //
  80. static    void    ConfigError (char *msg,int perr=0)
  81. {
  82. #ifdef    UWPC_DOS
  83.   // Report DOS configuration errors on the standard output //
  84.   if (!perr)
  85.     fprintf (stderr,"%s\n",msg);
  86.    else
  87.     perror (msg);
  88.   exit (1);        // Abort the program completely.
  89. #else
  90.   // Report Windows 3.0 configuration errors in message boxes //
  91.   if (!perr)
  92.     MessageBox (NULL,msg,NULL,MB_OK | MB_ICONEXCLAMATION);
  93.    else
  94.     MessageBox (NULL,sys_errlist[errno],msg,MB_OK | MB_ICONEXCLAMATION);
  95.   Throw (CatchBuf,1);    // Throw back to the "doconfig" function.
  96. #endif
  97. } /* ConfigError */
  98.  
  99. // Setup the default configuration.
  100. UWConfiguration::UWConfiguration (void)
  101. {
  102.   int key;
  103.   ComPort = 1;
  104.   ComParams = BAUD_2400 | BITS_8 | PARITY_NONE | STOP_1;
  105.   StripHighBit = 0;
  106.   DisableStatusLine = 0;
  107.   P0TermType = 0;
  108.   P1TermType = &ADM31_Driver;
  109.   strcpy (InitString,"ATZ^M~~~AT S7=45 S0=0 V1 X1^M~");
  110.   strcpy (HangupString,"~~~+++~~~ATH0^M");
  111.   CarrierInit = 1;
  112.   XonXoffFlag = 1;
  113.   BeepEnable = 1;
  114.   SwapBSKeys = 0;
  115.   strcpy (DialString,"ATDT");
  116.   strcpy (CommandString,"uw^M");
  117.   strcpy (FtpString,"uwftp^M");
  118.   strcpy (MailString,"uwmail^M");
  119.   for (key = 0;key < 10;++key)
  120.     FKeys[key][0] = '\0';
  121.   strcpy (StatusFormat," ALT-Z for Help %v %e %v %p %v %u %v Windows: %a");
  122.   StatusPosn = STATUS_LEFT;
  123.   NumTermDescs = 0;
  124.   for (key = 0;key < 5;++key)
  125.     NewAttrs[key] = 0;
  126.   PopUpNewWindow = 0;
  127.   DisableUW = 0;
  128.   strcpy (ZModemCommand,"DSZ");
  129.   EnableMouse = 1;
  130.   MailBoxName[0] = '\0';        // Use the default system mailbox.
  131.   Password[0] = '\0';            // No password to start with.
  132.   CursorSize = CURS_UNDERLINE;
  133.   strcpy (FontFace,"System");        // Font information for Windows 3.0.
  134.   FontHeight = 8;
  135. } // UWConfigration::UWConfiguration //
  136.  
  137. // Abort the configuration with an error.
  138. void    UWConfiguration::error (char *msg)
  139. {
  140.   SPRINTF (ErrorBuffer,"Configuration line %d: %s",linenum,(STRING)msg);
  141.   ConfigError (ErrorBuffer);
  142. } // UWConfiguration::error //
  143.  
  144. // Abort the configuration with an "illegal" config message.
  145. void    UWConfiguration::illegal (char *msg)
  146. {
  147.   SPRINTF (ErrorBuffer,"Configuration line %d: Illegal %s",linenum,(STRING)msg);
  148.   ConfigError (ErrorBuffer);
  149. } // UWConfiguration::illegal //
  150.  
  151. // Load a new terminal type from the specified filename.
  152. void    *UWConfiguration::LoadTerminal (char *filename)
  153. {
  154.   FILE *file;
  155.   long filesize;
  156.   void *desc;
  157.  
  158.   // Open the terminal description file for reading //
  159.   if ((file = fopen (filename,"rb")) == NULL)
  160.     ConfigError (filename,1);    // Report a "perror".
  161.  
  162.   // Get the length of the file and return to the start //
  163.   if (fseek (file,0L,SEEK_END) ||
  164.       (filesize = ftell (file)) == -1L ||
  165.       fseek (file,0L,SEEK_SET))
  166.     {
  167.       int err;
  168.       err = errno;
  169.       fclose (file);
  170.       errno = err;
  171.       ConfigError (filename);
  172.     }
  173.  
  174.   // Allocate some memory for the terminal description //
  175.   if (filesize > 17000L ||
  176.       (desc = (void *)malloc ((size_t)filesize)) == NULL)
  177.     {
  178.       SPRINTF (ErrorBuffer,"%s : Not enough memory",(STRING)filename);
  179.       ConfigError (ErrorBuffer);
  180.     }
  181.  
  182.   // Read the contents of the terminal description //
  183.   if (fread (desc,1,(size_t)filesize,file) != ((size_t)filesize))
  184.     {
  185.       int err;
  186.       err = errno;
  187.       fclose (file);
  188.       errno = err;
  189.       ConfigError (filename);
  190.     }
  191.  
  192.   // Close the file and return the loaded terminal description //
  193.   fclose (file);
  194.   return (desc);
  195. } // UWConfiguration::LoadTerminal //
  196.  
  197. // Find a terminal description in the loaded descriptions.
  198. // Returns NULL if the terminal type could not be found.
  199. unsigned char far *UWConfiguration::FindTerminal (char *type)
  200. {
  201.   int index=0;
  202.  
  203.   // Search for a type in the loaded emulations //
  204.   while (index < NumTermDescs)
  205.     {
  206.       // Check the name of the wanted emulation against loaded emulation //
  207.       if (!stricmp (((char *)(TermDescs[index])) + TERM_HEADER_SIZE,type))
  208.         return ((unsigned char far *)(TermDescs[index]));
  209.       ++index;
  210.     }
  211.  
  212.   // Test for the standard terminal types //
  213.   if (!stricmp (type,"adm31"))
  214.     return ((unsigned char far *)&ADM31_Driver);
  215.    else if (!stricmp (type,"vt52"))
  216.     return ((unsigned char far *)&VT52_Driver);
  217.    else if (!stricmp (type,"ansi"))
  218.     return ((unsigned char far *)&ANSI_Driver);
  219.    else
  220.     return (NULL);
  221. } // UWConfiguration::FindTerminal //
  222.  
  223. #define    CONFIG_NAME_LEN        20
  224. #define    TYPE_NUMBER        0
  225. #define TYPE_IDENT        1
  226. #define TYPE_STRING        2
  227.  
  228. // Process a configuration line.
  229. void    UWConfiguration::processline (char *line)
  230. {
  231.   int index,type;
  232.   unsigned number;
  233.   static char ConfigName[CONFIG_NAME_LEN + 1];
  234.   static char ConfigParam[STR_LEN];
  235.   char *errmsg="Illegal configuration command format";
  236.  
  237.   while (*line && isspace (*line))    // Skip initial white space.
  238.     ++line;
  239.   if (!(*line) || *line == '#')
  240.     return;                // Comment line - ignore.
  241.   index = 0;                // Get configuration option name.
  242.   while (index < CONFIG_NAME_LEN && *line &&
  243.          (isalpha (*line) || isdigit (*line)))
  244.     ConfigName[index++] = *line++;
  245.   ConfigName[index] = '\0';
  246.   while (*line && isspace (*line))    // Skip white space before "=".
  247.     ++line;
  248.   if (index <= 0 || *line != '=')
  249.     error (errmsg);
  250.   ++line;                // Skip "=" in config option.
  251.   while (*line && isspace (*line))    // Skip white space after "=".
  252.     ++line;
  253.   if (*line == '0' && *(line + 1) == 'x')
  254.     {
  255.       // Recognise a hexadecimal constant.
  256.       line += 2;
  257.       number = 0;
  258.       while (isxdigit (*line))
  259.         {
  260.       number = number * 16;
  261.       if (isdigit (*line))
  262.         number += *line - '0';
  263.        else
  264.         number += ((*line & 0x5F) - 'A' + 10);
  265.       ++line;
  266.     }
  267.       type = TYPE_NUMBER;
  268.     }
  269.    else if (*line == '0')
  270.     {
  271.       // Recognise an octal constant.
  272.       number = 0;
  273.       while (isdigit (*line) && *line < '8')
  274.         number = (number * 8) + (*line++ - '0');
  275.       type = TYPE_NUMBER;
  276.     }
  277.    else if (isdigit (*line))
  278.     {
  279.       // Recognise a decimal constant.
  280.       number = 0;
  281.       while (isdigit (*line))
  282.         number = (number * 10) + (*line++ - '0');
  283.       type = TYPE_NUMBER;
  284.     }
  285.    else if (isalpha (*line))
  286.     {
  287.       // Recognise an identifier.
  288.       index = 0;
  289.       while (isalpha (*line) || isdigit (*line))
  290.         ConfigParam[index++] = *line++;
  291.       ConfigParam[index] = '\0';
  292.       type = TYPE_IDENT;
  293.     }
  294.    else if (*line == '"')
  295.     {
  296.       // Recognise a string.
  297.       ++line;
  298.       index = 0;
  299.       while (index < (STR_LEN - 1) && *line && *line != '"')
  300.         ConfigParam[index++] = *line++;
  301.       ConfigParam[index] = '\0';
  302.       if (*line != '"')
  303.         illegal ("string constant");
  304.       ++line;
  305.       type = TYPE_STRING;
  306.     }
  307.    else
  308.     error (errmsg);
  309.   while (*line && isspace (*line))    // Skip white space after "=".
  310.     ++line;
  311.   if (*line != '\0' && *line != '#')    // Abort if not at line end.
  312.     error (errmsg);
  313.  
  314.   // Determine the configuration option to the changed //
  315.   if (!stricmp (ConfigName,"port") && type == TYPE_NUMBER)
  316.     {
  317.       if (number >= 1 && number <= 4)
  318.         ComPort = number;
  319.        else
  320.         illegal ("port number");
  321.     }
  322.    else if (!stricmp (ConfigName,"address") && type == TYPE_NUMBER)
  323.     {
  324.       comports[ComPort - 1] = number;    // Set the COM port address.
  325.     }
  326.    else if (!stricmp (ConfigName,"baud") && type == TYPE_NUMBER)
  327.     {
  328.       static unsigned baudrates[] = {110,150,300,600,1200,2400,
  329.                            4800,9600,19200,38400,57600};
  330.       int baud=0;
  331.       while (baud < 11 && number != baudrates[baud])
  332.         ++baud;
  333.       if (baud < 11)
  334.         ComParams = (ComParams & ~BAUD_RATE) | baud;
  335.        else
  336.         illegal ("baud rate");
  337.     }
  338.    else if (!stricmp (ConfigName,"parity") && type == TYPE_IDENT)
  339.     {
  340.       int parity;
  341.       if (!stricmp (ConfigParam,"none"))
  342.         parity = PARITY_NONE;
  343.        else if (!stricmp (ConfigParam,"even"))
  344.         parity = PARITY_EVEN;
  345.        else if (!stricmp (ConfigParam,"odd"))
  346.         parity = PARITY_ODD;
  347.        else
  348.         illegal ("parity value");
  349.       ComParams = (ComParams & ~PARITY_GET) | parity;
  350.     }
  351.    else if (!stricmp (ConfigName,"stop") && type == TYPE_NUMBER)
  352.     {
  353.       if (number == 1)
  354.         ComParams &= ~STOP_2;
  355.        else if (number == 2)
  356.         ComParams |= STOP_2;
  357.        else
  358.         illegal ("number of stop bits");
  359.     }
  360.    else if (!stricmp (ConfigName,"bits") && type == TYPE_NUMBER)
  361.     {
  362.       if (number == 7)
  363.         ComParams &= ~BITS_8;
  364.        else if (number == 8)
  365.         ComParams |= BITS_8;
  366.        else
  367.         illegal ("number of data bits");
  368.     }
  369.    else if (!stricmp (ConfigName,"font") && type == TYPE_STRING)
  370.     {
  371.       if (strlen (ConfigParam) >= FONT_STR_LEN)
  372.         illegal ("font facename - too long");
  373.       strcpy (FontFace,ConfigParam);
  374.     }
  375.    else if (!stricmp (ConfigName,"fontsize") && type == TYPE_NUMBER)
  376.     {
  377.       if (number < 1 || number > 50)
  378.         illegal ("font height - must be between 1 and 50");
  379.       FontHeight = number;
  380.     }
  381.    else if (!stricmp (ConfigName,"init") && type == TYPE_STRING)
  382.     {
  383.       strcpy (InitString,ConfigParam);
  384.     }
  385.    else if (!stricmp (ConfigName,"cinit") && type == TYPE_IDENT)
  386.     {
  387.       if (!stricmp (ConfigParam,"yes"))
  388.         CarrierInit = 1;
  389.        else if (!stricmp (ConfigParam,"no"))
  390.         CarrierInit = 0;
  391.        else
  392.         illegal ("value: must be 'yes' or 'no'");
  393.     }
  394.    else if (!stricmp (ConfigName,"disable") && type == TYPE_IDENT)
  395.     {
  396.       if (!stricmp (ConfigParam,"yes"))
  397.         DisableUW = 1;
  398.        else if (!stricmp (ConfigParam,"no"))
  399.         DisableUW = 0;
  400.        else
  401.         illegal ("value: must be 'yes' or 'no'");
  402.     }
  403.    else if (!stricmp (ConfigName,"cursor") && type == TYPE_IDENT)
  404.     {
  405.       if (!stricmp (ConfigParam,"underline"))
  406.         CursorSize = CURS_UNDERLINE;
  407.        else if (!stricmp (ConfigParam,"halfheight"))
  408.         CursorSize = CURS_HALF_HEIGHT;
  409.        else if (!stricmp (ConfigParam,"fullheight"))
  410.         CursorSize = CURS_FULL_HEIGHT;
  411.        else
  412.         illegal ("value: must be 'underline', 'halfheight' or 'fullheight'");
  413.     }
  414.    else if (!stricmp (ConfigName,"hangup") && type == TYPE_STRING)
  415.     {
  416.       strcpy (HangupString,ConfigParam);
  417.     }
  418.    else if (!stricmp (ConfigName,"terminal") && type == TYPE_STRING)
  419.     {
  420.       if (NumTermDescs >= MAX_DESCS)
  421.         error ("Too many extra loaded terminal descriptions");
  422.       TermDescs[NumTermDescs++] = LoadTerminal (ConfigParam);
  423.     }
  424.    else if (!stricmp (ConfigName,"emul") &&
  425.            (type == TYPE_IDENT || type == TYPE_STRING))
  426.     {
  427.       void *desc;
  428.       if ((desc = FindTerminal (ConfigParam)) == NULL)
  429.         illegal ("terminal type");
  430.       P1TermType = (unsigned char far *)desc;
  431.     }
  432.    else if (!stricmp (ConfigName,"emul0") &&
  433.            (type == TYPE_IDENT || type == TYPE_STRING))
  434.     {
  435.       void *desc;
  436.       if ((desc = FindTerminal (ConfigParam)) == NULL)
  437.         illegal ("terminal type");
  438.       P0TermType = (unsigned char far *)desc;
  439.     }
  440.    else if (!stricmp (ConfigName,"xonxoff") && type == TYPE_IDENT)
  441.     {
  442.       if (!stricmp (ConfigParam,"encoded"))
  443.         XonXoffFlag = 1;
  444.        else if (!stricmp (ConfigParam,"direct"))
  445.         XonXoffFlag = 0;
  446.        else
  447.         illegal ("value: must be 'encoded' or 'direct'");
  448.     }
  449.    else if (!stricmp (ConfigName,"beep") && type == TYPE_IDENT)
  450.     {
  451.       if (!stricmp (ConfigParam,"on"))
  452.         BeepEnable = 1;
  453.        else if (!stricmp (ConfigParam,"off"))
  454.         BeepEnable = 0;
  455.        else
  456.         illegal ("value: must be 'on' or 'off'");
  457.     }
  458.    else if (!stricmp (ConfigName,"popup") && type == TYPE_IDENT)
  459.     {
  460.       if (!stricmp (ConfigParam,"on"))
  461.         PopUpNewWindow = 1;
  462.        else if (!stricmp (ConfigParam,"off"))
  463.         PopUpNewWindow = 0;
  464.        else
  465.         illegal ("value: must be 'on' or 'off'");
  466.     }
  467.    else if (!stricmp (ConfigName,"strip") && type == TYPE_IDENT)
  468.     {
  469.       if (!stricmp (ConfigParam,"on"))
  470.         StripHighBit = 1;
  471.        else if (!stricmp (ConfigParam,"off"))
  472.         StripHighBit = 0;
  473.        else
  474.         illegal ("value: must be 'on' or 'off'");
  475.     }
  476.    else if (!stricmp (ConfigName,"mouse") && type == TYPE_IDENT)
  477.     {
  478.       if (!stricmp (ConfigParam,"on"))
  479.         EnableMouse = 1;
  480.        else if (!stricmp (ConfigParam,"off"))
  481.         EnableMouse = 0;
  482.        else
  483.         illegal ("value: must be 'on' or 'off'");
  484.     }
  485.    else if (!stricmp (ConfigName,"swapbs") && type == TYPE_IDENT)
  486.     {
  487.       if (!stricmp (ConfigParam,"on"))
  488.         SwapBSKeys = 1;
  489.        else if (!stricmp (ConfigParam,"off"))
  490.         SwapBSKeys = 0;
  491.        else
  492.         illegal ("value: must be 'on' or 'off'");
  493.     }
  494.    else if (!stricmp (ConfigName,"status") && type == TYPE_IDENT)
  495.     {
  496.       if (!stricmp (ConfigParam,"on"))
  497.         DisableStatusLine = 0;
  498.        else if (!stricmp (ConfigParam,"off"))
  499.         DisableStatusLine = 1;
  500.        else
  501.         illegal ("value: must be 'on' or 'off'");
  502.     }
  503.    else if (!stricmp (ConfigName,"sformat") && type == TYPE_STRING)
  504.     strcpy (StatusFormat,ConfigParam);
  505.    else if (!stricmp (ConfigName,"mailbox") && type == TYPE_STRING)
  506.     strcpy (MailBoxName,ConfigParam);
  507.    else if (!stricmp (ConfigName,"password") && type == TYPE_STRING)
  508.     strcpy (Password,ConfigParam);
  509.    else if (!stricmp (ConfigName,"sposn") && type == TYPE_IDENT)
  510.     {
  511.       if (!stricmp (ConfigParam,"left"))
  512.         StatusPosn = STATUS_LEFT;
  513.        else if (!stricmp (ConfigParam,"right"))
  514.         StatusPosn = STATUS_RIGHT;
  515.        else if (!stricmp (ConfigParam,"center") ||
  516.                    !stricmp (ConfigParam,"centre"))
  517.     StatusPosn = STATUS_CENTRE;
  518.        else if (!stricmp (ConfigParam,"leftsquash"))
  519.         StatusPosn = STATUS_LEFT_SQUASH;
  520.        else if (!stricmp (ConfigParam,"rightsquash"))
  521.         StatusPosn = STATUS_RIGHT_SQUASH;
  522.        else if (!stricmp (ConfigParam,"centersquash") ||
  523.                !stricmp (ConfigParam,"centresquash"))
  524.     StatusPosn = STATUS_CENTRE_SQUASH;
  525.        else
  526.         illegal ("status position");
  527.     }
  528.    else if (!stricmp (ConfigName,"dial") && type == TYPE_STRING)
  529.     strcpy (DialString,ConfigParam);
  530.    else if (!stricmp (ConfigName,"uw") && type == TYPE_STRING)
  531.     strcpy (CommandString,ConfigParam);
  532.    else if (!stricmp (ConfigName,"uwftp") && type == TYPE_STRING)
  533.     strcpy (FtpString,ConfigParam);
  534.    else if (!stricmp (ConfigName,"uwmail") && type == TYPE_STRING)
  535.     strcpy (MailString,ConfigParam);
  536.    else if (!stricmp (ConfigName,"zmodem") && type == TYPE_STRING)
  537.     strcpy (ZModemCommand,ConfigParam);
  538.    else if (!stricmp (ConfigName,"f1") && type == TYPE_STRING)
  539.     strcpy (FKeys[0],ConfigParam);
  540.    else if (!stricmp (ConfigName,"f2") && type == TYPE_STRING)
  541.     strcpy (FKeys[1],ConfigParam);
  542.    else if (!stricmp (ConfigName,"f3") && type == TYPE_STRING)
  543.     strcpy (FKeys[2],ConfigParam);
  544.    else if (!stricmp (ConfigName,"f4") && type == TYPE_STRING)
  545.     strcpy (FKeys[3],ConfigParam);
  546.    else if (!stricmp (ConfigName,"f5") && type == TYPE_STRING)
  547.     strcpy (FKeys[4],ConfigParam);
  548.    else if (!stricmp (ConfigName,"f6") && type == TYPE_STRING)
  549.     strcpy (FKeys[5],ConfigParam);
  550.    else if (!stricmp (ConfigName,"f7") && type == TYPE_STRING)
  551.     strcpy (FKeys[6],ConfigParam);
  552.    else if (!stricmp (ConfigName,"f8") && type == TYPE_STRING)
  553.     strcpy (FKeys[7],ConfigParam);
  554.    else if (!stricmp (ConfigName,"f9") && type == TYPE_STRING)
  555.     strcpy (FKeys[8],ConfigParam);
  556.    else if (!stricmp (ConfigName,"f10") && type == TYPE_STRING)
  557.     strcpy (FKeys[9],ConfigParam);
  558.    else if (!stricmp (ConfigName,"colnormal") && type == TYPE_NUMBER)
  559.     NewAttrs[ATTR_NORMAL] = number;
  560.    else if (!stricmp (ConfigName,"colinverse") && type == TYPE_NUMBER)
  561.     NewAttrs[ATTR_INVERSE] = number;
  562.    else if (!stricmp (ConfigName,"colhighlight") && type == TYPE_NUMBER)
  563.     NewAttrs[ATTR_HIGHLIGHT] = number;
  564.    else if (!stricmp (ConfigName,"colstatus") && type == TYPE_NUMBER)
  565.     NewAttrs[ATTR_STATUS] = number;
  566.    else if (!stricmp (ConfigName,"colhighstatus") && type == TYPE_NUMBER)
  567.     NewAttrs[ATTR_HIGH_STATUS] = number;
  568.    else
  569.     error (errmsg);
  570. } // UWConfiguration::processline //
  571.  
  572. // Do the configuration for UW/PC.
  573. int    UWConfiguration::doconfig (char *argv0)
  574. {
  575.   static char *BaudRates[] = {"110","150","300","600","1200","2400",
  576.                   "4800","9600","19200","38400","57600",
  577.                   "115200"};
  578.   static char Parities[] = "NOE?";
  579.   static char ConfigBuffer[BUFSIZ];
  580.   char *FileName = "UW.CFG";
  581.   FILE *file=NULL;
  582.  
  583. #ifdef    UWPC_WINDOWS
  584.   // Catch any errors that occur during Windows 3.0 configuration.
  585.   if (Catch (CatchBuf))
  586.     {
  587.       if (file != NULL)
  588.         fclose (file);
  589.       return (0);        // Configuration failed.
  590.     } /* if */
  591. #endif
  592.  
  593.   // Find the configuration file (if present).
  594.   strcpy (ConfigBuffer,FileName);
  595.   if ((file = fopen (ConfigBuffer,"r")) == NULL)
  596.     {
  597.       int len;
  598.       strcpy (ConfigBuffer,argv0);
  599.       len = strlen (ConfigBuffer);
  600.       while (len > 0 && ConfigBuffer[len - 1] != '\\' &&
  601.              ConfigBuffer[len - 1] != '/')
  602.     --len;
  603.       strcpy (ConfigBuffer + len,FileName);
  604.       file = fopen (ConfigBuffer,"r");
  605.     }
  606.   if (file != NULL)
  607.     {
  608.       linenum = 1;
  609.       while (fgets (ConfigBuffer,BUFSIZ,file) != NULL)
  610.         {
  611.       processline (ConfigBuffer);
  612.       ++linenum;
  613.     }
  614.       fclose (file);
  615.     }
  616.  
  617.   // Set high bit stripping always for 7-bit transmission.
  618.   if (!(ComParams & BITS_8))
  619.     StripHighBit = 1;
  620.  
  621.   // Setup the string version of the COM parameters //
  622.   SPRINTF (DeviceParameters,"COM%d %s %c-%c-%c",
  623.         ComPort,
  624.         (STRING)(BaudRates[ComParams & BAUD_RATE]),
  625.         Parities[(ComParams & PARITY_GET) >> 6],
  626.         ((ComParams & BITS_8) ? '8' : '7'),
  627.         ((ComParams & STOP_2) ? '2' : '1'));
  628.  
  629.   // Set the default Protocol 0 terminal type if not set already //
  630.   if (P0TermType == 0)
  631.     P0TermType = P1TermType;
  632.  
  633. #ifdef    UWPC_WINDOWS
  634.   // Set the screen attributes for use by the Windows 3.0 version //
  635.   static unsigned char colrattrs[NUM_ATTRS] = {0x70,0x07,0x07,0x07,0x07};
  636.   int attr;
  637.   for (attr = 0;attr < 5;++attr)
  638.     {
  639.       // If the attribute isn't set yet, then set it //
  640.       if (!NewAttrs[attr])
  641.         NewAttrs[attr] = colrattrs[attr];
  642.     } /* for */
  643. #endif    /* UWPC_WINDOWS */
  644.  
  645.   return (1);            // Configuration succeeded.
  646. } // UWConfiguration::doconfig //
  647.