home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-385-Vol-1of3.iso / t / tel2305s.zip / ENGINE / CONFILE.C < prev    next >
C/C++ Source or Header  |  1992-03-08  |  34KB  |  1,311 lines

  1. /*
  2. *   Confile.c
  3. *   Split from util.c 5/88
  4. *   Reads and stores the appropriate information for the config file
  5. *
  6. *   version 2, full session layer, TK started 6/17/87
  7. *
  8. *****************************************************************************
  9. *                                                                            *
  10. *      part of:                                                                *
  11. *      Network kernel for NCSA Telnet                                        *
  12. *      by Tim Krauskopf                                                        *
  13. *                                                                            *
  14. *      National Center for Supercomputing Applications                        *
  15. *      152 Computing Applications Building                                    *
  16. *      605 E. Springfield Ave.                                                *
  17. *      Champaign, IL  61820                                                    *
  18. *                                                                            *
  19. *     This program is in the public domain.                                 *
  20. *                                                                           *
  21. *****************************************************************************
  22. *
  23. *    Revision History:
  24. *
  25. *    Initial release - 11/87 TK
  26. *    Cleanup for 2.3 release - 6/89 QK
  27. *
  28. */
  29.  
  30. /*
  31. *    Includes
  32. */
  33. /*#define DEBUG */         /* define this to enable debugging print statements */
  34. #include "debug.h"
  35.  
  36. #ifdef DEBUG
  37. #include <conio.h>
  38. #endif
  39. #ifdef __TURBOC__
  40. #include "turboc.h"
  41. #endif
  42. #include <stdio.h>
  43. #include <stdlib.h>
  44. #include <string.h>
  45. #include <ctype.h>
  46. #ifdef __WATCOMC__
  47. #include <process.h>
  48. #endif
  49. #ifdef MSC
  50. #ifdef __TURBOC__
  51. #include <alloc.h>
  52. #else
  53. #include <malloc.h>
  54. #endif
  55. #endif
  56. #include "whatami.h"
  57. #include "hostform.h"
  58. #include "externs.h"
  59. #define CONFIG_MASTER
  60. #include "confile.h"
  61.  
  62. /* STATIC function declarations */
  63. static FILE *pfopen(char *name,char *mode);    /* open file with required mode */
  64.  
  65. /************************************************************************/
  66. /*  Sreadhosts
  67. *   read in the hosts file into our in-memory data structure.
  68. *   Handle everything by keyword, see docs for specifications about file.
  69. */
  70. int Sreadhosts(void)
  71. {
  72.     FILE *fp;
  73.     int c,retval,i,j;
  74.     char *envstr, envnam[8];
  75.  
  76.     Smachlist=Smptr=NULL;
  77.     mno=0;
  78.     Sspace=malloc(256);                /* get room for gathering stuff */
  79.     if(Sspace==NULL) {
  80.         Serrline(901);
  81.         return(1);
  82.       } /* end if */
  83.  
  84.     position=constate=inquote=lineno=0;   /* state vars */    
  85.     if(NULL==(fp=pfopen(Smachfile,"r"))) {    /* open the configuration file */
  86.         Serrline(900);
  87.         return(1);
  88.       } /* end if */
  89.     retval=0;
  90.     while(!retval) {
  91.         c=fgetc(fp);
  92.         if(c=='#' && !inquote)
  93.             while(c!=EOF && c!='\n' && c!='\r')        /* skip to EOL */
  94.                 c=fgetc(fp);
  95.         if(c=='\n' || c=='\r')
  96.             lineno++;
  97.          retval=Scontoken(c);        /* add character to token */
  98.       } /* end while */
  99.     fclose(fp);
  100.  
  101.     position=constate=inquote=0;
  102.     for(i=0; i<100; i++) {
  103.         sprintf(envnam,"NCSA%2.2d",i);
  104.         if(envstr=getenv(envnam)) {
  105.             if(*envstr=='\"')
  106.                 *(envstr+strlen(envstr++)-2)=(char)NULL;
  107.             for(j=0,retval=0; *(envstr+j) && !retval; j++) {
  108.                 if((*(envstr+j)=='~') || (*(envstr+j)==' '))
  109.                     *(envstr+j)='=';
  110.                 retval=Scontoken(*(envstr+j));
  111.               } /* end for */
  112.             Scontoken(';');     /* make sure last token is taken */
  113.           } /* end if */
  114.       } /* end for */
  115.  
  116.     if(commandLineOveride) {
  117.         position=constate=inquote=0;
  118.         for(i=0,retval=0; *(commandLineOveride+i) && !retval; i++) {
  119.             if((*(commandLineOveride+i)=='~') || (*(commandLineOveride+i)==' '))
  120.                 *(commandLineOveride+i)='=';
  121.             retval=Scontoken(*(commandLineOveride+i));
  122.           } /* end for */
  123.         free(commandLineOveride);
  124.       } /* end if */
  125.  
  126.     free(Sspace);
  127.     Smadd("default");               /* make sure name is in list */
  128.     if(retval==EOF)                /* EOF is normal end */
  129.         return(0);
  130.     else
  131.         return(retval);
  132. }
  133.  
  134. /************************************************************************/
  135. /*  ncstrcmp
  136. *   No case string compare.
  137. *   Only returns 0=match, 1=no match, does not compare greater or less
  138. *   There is a tiny bit of overlap with the | 32 trick, but shouldn't be
  139. *   a problem.  It causes some different symbols to match.
  140. */
  141. int ncstrcmp(char *sa,char *sb)
  142. {
  143.     while(*sa && *sa<33)        /* don't compare leading spaces */
  144.         sa++;
  145.     while(*sb && *sb<33)
  146.         sb++;
  147.     while(*sa && *sb) {
  148.         if((*sa!=*sb) && ((*sa | 32)!=(*sb | 32)))
  149.             return(1);
  150.         sa++;
  151.         sb++;
  152.       }    /* end while */
  153.     if(!*sa && !*sb)        /* if both at end of string */
  154.         return(0);
  155.     else
  156.         return(1);
  157. }    /* end ncstrcmp() */
  158.  
  159. /************************************************************************/
  160. /*  Serrline
  161. *   prints the line number of the host file error and posts the event
  162. *   for the line number error and posts the hosts file error.
  163. */
  164. void Serrline(int n)
  165. {
  166.     char *p;
  167.  
  168.     p=neterrstring(-1);
  169.     sprintf(p,"Config file: error at line %4d",lineno+1);
  170.     netposterr(-1);
  171.     netposterr(n);
  172. }
  173.  
  174. /************************************************************************/
  175. /* Scontoken
  176. *  tokenize the strings which get passed to Sconfile.
  177. *  Handles quotes and uses separators:  <33, ;:=
  178. */
  179. int Scontoken(int c)
  180. {
  181.     int retval;
  182.  
  183.     if(c==EOF) {
  184.         Sspace[position++]='\0';
  185.         Sconfile(Sspace);
  186.         if(!Sflags[0]) {            /* make sure last entry gets copied */
  187.             if(ncstrcmp("default",Smptr->sname))
  188.                 Scopyfrom("default");
  189.             else
  190.                 Scopyfrom("==");
  191.         }
  192.         return(-1);
  193.     }
  194.     if(!position && Sissep(c))        /* skip over junk before token */
  195.         return(0);
  196.     if(inquote || !Sissep(c)) {
  197.         if(position>200) {
  198.             Serrline(903);
  199.             return(1);
  200.           }
  201. /*
  202. *  check for quotes, a little mixed up here, could be reorganized
  203. */
  204.         if(c=='"' ) {
  205.             if(!inquote) {            /* beginning of quotes */
  206.                 inquote=1;
  207.                 return(0);
  208.             }
  209.             else
  210.                 inquote=0;        /* turn off flag and drop through */
  211.         }
  212.         else {
  213.             if(c=='\n') {            /* check for EOL inside quotes */
  214.                 Serrline(904);
  215.                 return(1);
  216.             }
  217.             Sspace[position++]=(char)c;    /* include in current string */
  218.             return(0);
  219.         }
  220.     }
  221.     Sspace[position++]='\0';
  222.     retval=Sconfile(Sspace);            /* pass the token along */
  223.     position=0;
  224.     inquote=0;
  225.     Sspace[0]='\0';
  226.     return(retval);
  227. }
  228.  
  229. /************************************************************************/
  230. /*  Sconfile
  231. *   take the characters read from the file and parse them for keywords
  232. *   which require configuration action.
  233. */
  234. int Sconfile(char *s)
  235. {
  236.     int i,a,b,c,d;
  237.  
  238. #ifdef QAK
  239. printf("Sconfile: %s\n",s);
  240. #endif
  241.  
  242.     switch(constate) {
  243.         case 0:                                /* lookup keyword */
  244.             if(!(*s))                        /* empty token */
  245.                 return(0);
  246.  
  247.             for(i=1; *Skeyw[i] && ncstrcmp(Skeyw[i],s); i++);    /* search the keyboard list for this keyword */
  248.  
  249.             if(!(*Skeyw[i])) {            /* not in list */
  250.                 Serrline(902);
  251.                 return(0);                /* don't die - helps backward compatibility */
  252.               }    /* end if */
  253.             constate=100+i;    /* change to state for keyword */
  254. /*
  255. *  check if this is a machine specific parm without a machine to
  256. *  give it to.  "name" being the only machine specific parm allowed, of course
  257. */
  258.             if(Smptr==NULL && constate>CONNAME && constate<=NUMSPECS) {
  259.                 Serrline(905);
  260.                 return(1);
  261.               }
  262.             break;
  263.  
  264.         case CONNAME:        /* session name */
  265. /*
  266. *  allocate space for upcoming parameters
  267. */
  268.             constate=0;             /* back to new keyword */
  269.             if(Smachlist==NULL) {
  270.                 Smachlist=(struct machinfo *)malloc(sizeof(struct machinfo));
  271.                 if(Smachlist==NULL) {   /* check for bad malloc */
  272.                     Serrline(901);
  273.                     return(0);              /* don't die - helps backward compatibility */
  274.                   } /* end if */
  275.                 Smptr=Smachlist;
  276.               }
  277.             else {
  278.                 if(!Sflags[0]) {
  279.                     if(ncstrcmp("default",Smptr->sname))
  280.                         Scopyfrom("default");
  281.                     else
  282.                         Scopyfrom("==");    /* to make sure 'default' gets set */
  283.                   }
  284.                 Smptr->next=(struct machinfo *)malloc(sizeof(struct machinfo));
  285.                 if(Smptr->next==NULL) {     /* check for bad malloc */
  286.                     Serrline(901);
  287.                     return(0);              /* don't die - helps backward compatibility */
  288.                   } /* end if */
  289.                 Smptr=Smptr->next;
  290.               }
  291.             Smptr->next=NULL;
  292.             Smptr->hname=NULL;                /* guarantee to be null */
  293.             Smptr->sname=malloc(position);    /* size of name string */
  294.             if(Smptr->sname!=NULL)          /* try to avoid copying into a bad allocation */
  295.                 strcpy(Smptr->sname,s);         /* keep name field */
  296.             Smptr->ftpoptions=NULL;         /* no options */
  297.             for(i=0; i<NUMSPECS-99; i++)
  298.                 Sflags[i]=0;                /* we have no parms */
  299.             Smptr->mno=++mno;                /* new machine number */
  300.             break;
  301.  
  302.         case CONHOST:    /* also a host name */
  303.             constate=0;
  304.             Smptr->hname=malloc(position);
  305.             if(Smptr->hname==NULL) {    /* check for bad allocate */
  306.                 Serrline(901);
  307.                 return(0);              /* don't die - helps backward compatibility */
  308.               } /* end if */
  309.             strcpy(Smptr->hname,s);
  310.             Sflags[CONHOST-100]=1;    /* set the flag to indicate hostname is found */
  311.             break;
  312.  
  313.         case CONIP:        /* IP number for host */
  314.             if(4!=sscanf(s,"%d.%d.%d.%d",&a,&b,&c,&d)) {
  315.                 Serrline(906);
  316.                 return(3);
  317.               }
  318.             Smptr->hostip[0]=(char)a;     /* keep number */
  319.             Smptr->hostip[1]=(char)b;
  320.             Smptr->hostip[2]=(char)c;
  321.             Smptr->hostip[3]=(char)d;
  322.             Smptr->mstat=HFILE;
  323.             constate=0;
  324.             Sflags[CONIP-100]=1;        /* set the flag to indicate ip number found */
  325.             break;
  326.  
  327.         case CONGATE:    /* this machine is a gateway */
  328.             Smptr->gateway=(unsigned char)atoi(s);        /* gateway level */
  329.             constate=0;
  330.             Sflags[CONGATE-100]=1;        /* set the flag for this name being a gateway */
  331.             break;
  332.  
  333.         case CONCOLOR:        /* support old color format */
  334.             Smptr->nfcolor=s[1]-48;
  335.             Smptr->nbcolor=s[0]-48;
  336.             Smptr->ufcolor=s[3]-48;
  337.             Smptr->ubcolor=s[2]-48;
  338.             Smptr->bfcolor=s[5]-48;
  339.             Smptr->bbcolor=s[4]-48;
  340.             constate=0;
  341.             Sflags[CONNF-100]=1;        /* sets them all at one shot */
  342.             Sflags[CONNB-100]=1;
  343.             Sflags[CONBF-100]=1;
  344.             Sflags[CONBB-100]=1;
  345.             Sflags[CONUF-100]=1;
  346.             Sflags[CONUB-100]=1;
  347.             break;
  348.  
  349.         case CONBKSP:   /* backspace parameter */
  350.             if(!ncstrcmp(s,"backspace"))
  351.                 Smptr->bksp=8;
  352.             else
  353.                 Smptr->bksp=127;
  354.             constate=0;
  355.             Sflags[CONBKSP-100]=1;
  356.             break;
  357.  
  358.         case CONBKSC:        /* the number of line for scrollback */
  359.             Smptr->bkscroll=atoi(s);
  360.             constate=0;
  361.             Sflags[CONBKSC-100]=1;
  362.             break;
  363.  
  364.         case CONRETR:        /* how long before retransmitting */
  365.             Smptr->retrans=atoi(s);
  366.             constate=0;
  367.             Sflags[CONRETR-100]=1;
  368.             break;
  369.  
  370.         case CONWIND:        /* transmission window for this host */
  371.             Smptr->window=atoi(s);
  372.             constate=0;
  373.             Sflags[CONWIND-100]=1;
  374.             break;
  375.  
  376.         case CONSEG:        /* segment size */
  377.             Smptr->maxseg=atoi(s);
  378.             constate=0;
  379.             Sflags[CONSEG-100]=1;
  380.             break;
  381.  
  382.         case CONMTU:    /* maximum transmission unit */
  383.             Smptr->mtu=atoi(s);
  384.             constate=0;
  385.             Sflags[CONMTU-100]=1;
  386.             break;
  387.  
  388.         case CONNS:        /* nameserver level */
  389.             Smptr->nameserv=(unsigned char)atoi(s);
  390.             if(!Sns || (Sns->nameserv>Smptr->nameserv))    /* keep NS */
  391.                 Sns=Smptr;
  392.             constate=0;
  393.             Sflags[CONNS-100]=1;
  394.             break;
  395.  
  396.         case CONTO:        /* time until time out */
  397.             i=atoi(s);
  398.             if(i>2) {
  399.                 Smptr->conto=i;
  400.                 Sflags[CONTO-100]=1;
  401.               }
  402.             constate=0;
  403.             break;
  404.  
  405.         case CONCRMAP:        /* carriage return mapping */
  406.             if(!ncstrcmp(s,"4.3BSDCRNUL")) 
  407.                 Smptr->crmap=0;
  408.             else
  409.                 Smptr->crmap=10;
  410.             Sflags[CONCRMAP-100]=1;
  411.             constate=0;
  412.             break;
  413.  
  414.         case CONDUP:        /* duplex */
  415.             if(!ncstrcmp(s,"half")) {
  416.                 Smptr->halfdup=1;
  417.                 Sflags[CONDUP-100]=1;
  418.               }
  419.             constate=0;
  420.             break;
  421.  
  422.         case CONWRAP:        /* whether lines wrap */
  423.             if('Y'==toupper(s[0])) 
  424.                 Smptr->vtwrap=1;
  425.             else
  426.                 Smptr->vtwrap=0;
  427.             Sflags[CONWRAP-100]=1;
  428.             constate=0;
  429.             break;
  430.  
  431.         case CONWIDE:        /* how wide the screen is */
  432.             if(132==atoi(s)) 
  433.                 Smptr->vtwidth=132;
  434.             else
  435.                 Smptr->vtwidth=80;
  436.             Sflags[CONWIDE-100]=1;
  437.             constate=0;
  438.             break;
  439.  
  440.         case CONFONT:        /* the font type */
  441.             constate=0;
  442.             Smptr->font=malloc(position);
  443.             if(Smptr->font==NULL) {    /* check for bad allocate */
  444.                 Serrline(901);
  445.                 return(0);              /* don't die - helps backward compatibility */
  446.               } /* end if */
  447.             strcpy(Smptr->font,s);
  448.             Sflags[CONFONT-100]=1;
  449.             break;
  450.  
  451.         case CONFSIZE:        /* the font point size */
  452.             Smptr->fsize=(unsigned char)atoi(s);
  453.             Sflags[CONFSIZE-100]=1;
  454.             constate=0;
  455.             break;
  456.  
  457.         case CONNF:        /* foreground normal color */
  458.             Scolorset(&Smptr->nfcolor,s);
  459.             Sflags[CONNF-100]=1;
  460.             constate=0;
  461.             break;
  462.  
  463.         case CONNB:        /* background normal color */
  464.             Scolorset(&Smptr->nbcolor,s);
  465.             Sflags[CONNB-100]=1;
  466.             constate=0;
  467.             break;
  468.  
  469.         case CONRF:
  470.         case CONBF:        /* blink foreg color */
  471.             Scolorset(&Smptr->bfcolor,s);
  472.             Sflags[CONBF-100]=1;    /* in copyfrom, r's are really b's */
  473.             constate=0;
  474.             break;
  475.  
  476.         case CONRB:
  477.         case CONBB:        /* blink bg color */
  478.             Scolorset(&Smptr->bbcolor,s);
  479.             Sflags[CONBB-100]=1;
  480.             constate=0;
  481.             break;
  482.  
  483.         case CONUF:        /* foreground underline color */
  484.             Scolorset(&Smptr->ufcolor,s);
  485.             Sflags[CONUF-100]=1;
  486.             constate=0;
  487.             break;
  488.  
  489.         case CONUB:        /* bg underline color */
  490.             Scolorset(&Smptr->ubcolor,s);
  491.             Sflags[CONUB-100]=1;
  492.             constate=0;
  493.             break;
  494.  
  495.         case CONCLMODE:        /* save cleared lines */
  496.             if('N'==toupper(s[0])) 
  497.                 Smptr->clearsave=0;
  498.             else
  499.                 Smptr->clearsave=1;
  500.             Sflags[CONCLMODE-100]=1;
  501.             constate=0;
  502.             break;
  503.  
  504.         case CONPORT:        /* the port number */
  505.             i=atoi(s);
  506.             if(i<1)
  507.                 i=23;
  508.             Smptr->port=i;
  509.             Sflags[CONPORT-100]=1;
  510.             constate=0;
  511.             break;
  512.  
  513.         case CONFTPBAK:        /* the options for the ftp command line */
  514.             constate=0;
  515.             Smptr->ftpoptions=malloc(position);
  516.             if(Smptr->ftpoptions==NULL) {    /* check for bad allocate */
  517.                 Serrline(901);
  518.                 return(0);              /* don't die - helps backward compatibility */
  519.               } /* end if */
  520.             strcpy(Smptr->ftpoptions,s);
  521.             Sflags[CONFTPBAK-100]=1;
  522.             break;
  523.  
  524.         case CONDEBUGCONSOLE:     /* the debugging level for console output */
  525.             constate=0;
  526.             i=atoi(s);
  527.             if(i<0)
  528.                 i=0;
  529.             else if(i>3)
  530.                 i=3;
  531.             Smptr->consoledebug=i;
  532.             Sflags[CONDEBUGCONSOLE-100]=1;
  533.             break;
  534.  
  535.         case CONMAPOUTPUT:     /* the output mapping flag for each machine */
  536.             if('Y'==toupper(s[0]))
  537.                 Smptr->mapoutflag=1;
  538.             else
  539.                 Smptr->mapoutflag=0;
  540.             Sflags[CONMAPOUTPUT-100]=1;
  541.             constate=0;
  542.             break;
  543.  
  544. /*
  545. *  now the one-time entries
  546. *  Generally this information goes into the "Scon" structure for later
  547. *  retrieval by other routines.
  548. *
  549. */
  550.         case CONNDOM:                /* DOMAIN number of retries */
  551.             i=atoi(s);
  552.             if(i>1)
  553.                 Scon.ndom=i;
  554.             constate=0;
  555.             break;
  556.  
  557.         case CONMASK:        /* the subnet mask */
  558.             if(4!=sscanf(s,"%d.%d.%d.%d",&a,&b,&c,&d)) {
  559.                 Serrline(907);
  560.                 return(3);
  561.               }
  562.             Scon.netmask[0]=(unsigned char)a;
  563.             Scon.netmask[1]=(unsigned char)b;
  564.             Scon.netmask[2]=(unsigned char)c;
  565.             Scon.netmask[3]=(char)d;
  566.             Scon.havemask=1;
  567.             constate=0;
  568.             break;
  569.  
  570.         case CONMYIP:        /* what my ip number is */
  571.             constate=0;
  572.             if(!ncstrcmp(s,"rarp")) {
  573.                 movebytes(Scon.myipnum,s,4);
  574.                 netsetip("RARP");
  575.                 break;
  576.               }
  577.             if(!ncstrcmp(s,"bootp")) {
  578.                 movebytes(Scon.myipnum,s,4);
  579.                 netsetip("BOOT");
  580.                 break;
  581.               }
  582. #ifdef    NETX25
  583.             if(!ncstrcmp(s,"x25")) {
  584.                 movebytes(Scon.myipnum,s,3);
  585.                 netsetip("X25");
  586.                 break;
  587.               }
  588. #endif
  589.             if(4!=sscanf(s,"%d.%d.%d.%d",&a,&b,&c,&d)) {
  590.                 Serrline(908);
  591.                 return(3);
  592.               }
  593.             Scon.myipnum[0]=(char)a;     /* put number back in s */
  594.             Scon.myipnum[1]=(char)b;
  595.             Scon.myipnum[2]=(char)c;
  596.             Scon.myipnum[3]=(char)d;
  597.             netsetip(Scon.myipnum);        /* make permanent set */
  598.             break;
  599.  
  600.         case CONHPF:                /* File name for HP dump */
  601.             Snewhpfile(s);
  602.             constate=0;
  603.             break;
  604.  
  605.         case CONPSF:                /* File name for PS dump */
  606.             Snewpsfile(s);
  607.             constate=0;
  608.             break;
  609.  
  610.         case CONTEKF:                /* File name for Tek dump */
  611.             Snewtekfile(s);
  612.             constate=0;
  613.             break;
  614.  
  615.         case CONME:                /* what my name is */
  616.             strncpy(Scon.me,s,30);
  617.             Scon.me[30]='\0';
  618.             constate=0;
  619.             break;
  620.  
  621.         case CONCCOL:        /* set all the colors */
  622.             for(i=0; i<3; i++)
  623.                 Scon.color[i]=(unsigned char)(((s[i*2]-48)<<4)+(s[i*2+1]-48));
  624.             constate=0;
  625.             break;
  626.  
  627.         case CONHW:            /* what hardware are we using? */
  628.             i=strlen(s);
  629.             if(i>9) i=9;
  630.             s[i]='\0';
  631.             i--;
  632.             while(i--)
  633.                 s[i]=(char)tolower((int)s[i]);
  634.             strcpy(Scon.hw,s);
  635.             constate=0;
  636.             break;
  637.  
  638.         case CONADDR:        /* segment address for board */
  639.             sscanf(s,"%x",&i);
  640.             Scon.address=i;
  641.             constate=0;
  642.             break;
  643.  
  644.         case CONIOA:        /* io address for board */
  645.             sscanf(s,"%x",&i);
  646.             Scon.ioaddr=i;
  647.             constate=0;
  648.             break;
  649.  
  650.         case CONDEF:                        /* default domain */
  651.             constate=0;
  652.             Scon.defdom=malloc(position);   /* space for name */
  653.             if(Scon.defdom==NULL) {    /* check for bad allocate */
  654.                 Serrline(901);
  655.                 return(0);              /* don't die - helps backward compatibility */
  656.               } /* end if */
  657.             strcpy(Scon.defdom,s);          /* copy it in */
  658.             break;
  659.  
  660.         case CONINT:            /* what IRQ to use */
  661.             sscanf(s,"%x",&i);
  662.             Scon.irqnum=(char)i;
  663.             constate=0;
  664.             break;
  665.  
  666.         case CONBIOS:        /* use BIOS screen writes */
  667.             if(toupper(*s)=='Y') {
  668.                 Scwritemode(0);
  669.                 Scon.bios=1;
  670.               }
  671.             constate=0;
  672.             break;
  673.  
  674.         case CONTEK:    /* whether to support tek graphics */
  675.             if(toupper(*s)=='N') {
  676.                 Stekmode(0);
  677.                 Scon.tek=0;
  678.               }
  679.             constate=0;
  680.             break;
  681.  
  682.         case CONVIDEO:        /* what type of screen we have */
  683.             i=strlen(s);
  684.             if(i>9)
  685.                 i=9;
  686.             s[i]='\0';
  687.             if(!strcmp(s,"ega43") || !strcmp(s,"vga50") ) {        /* check for special video modes */
  688.                 if(!strcmp(s,"ega43")) {
  689.                     Scon.ega43=1;
  690.                     strcpy(s,"ega");
  691.                  }    /* end if */
  692.                 else{
  693.                     Scon.ega43=2;
  694.                     strcpy(s,"vga");
  695.                 }
  696.             } else {
  697.                 Scon.ega43=0;
  698.                 strcpy(s,"ega");
  699.             }
  700.             strcpy(Scon.video,s);
  701.             i--;
  702.             while(i--)
  703.                 s[i]=(char)tolower((int)s[i]);
  704.             constate=0;
  705.             break;
  706.  
  707.         case CONFTP:        /* is ftp enabled? */
  708.             if(toupper(*s)=='N') 
  709.                 Scon.ftp=0;
  710.             else
  711.                 Scon.ftp=1;
  712.             constate=0;
  713.             break;
  714.  
  715.         case CONRCP:    /* is rcp enabled? */
  716.             if(toupper(*s)=='N')
  717.                 Scon.rcp=0;
  718.             else
  719.                 Scon.rcp=1;
  720.             constate=0;
  721.             break;
  722.  
  723.         case CONPASS:        /* do we need a password for ftp? */
  724.             constate=0;
  725.             Scon.pass=malloc(position); /* space for name */
  726.             if(Scon.pass==NULL) {    /* check for bad allocate */
  727.                 Serrline(901);
  728.                 return(0);              /* don't die - helps backward compatibility */
  729.               } /* end if */
  730.             strcpy(Scon.pass,s);            /* copy it in */
  731.             break;
  732.  
  733.         case CONCAP:    /* capture file name */
  734.             Snewcap(s);
  735.             constate=0;
  736.             break;
  737.  
  738.         case CONTTYPE:        /* what terminal type to emulate */
  739.             constate=0;
  740.             Scon.termtype=malloc(position);
  741.             if(Scon.termtype==NULL) {    /* check for bad allocate */
  742.                 Serrline(901);
  743.                 return(0);              /* don't die - helps backward compatibility */
  744.               } /* end if */
  745.             strcpy(Scon.termtype,s);
  746.             break;
  747.  
  748.         case CONFROM:    /* copy the rest from another entry in the table */
  749.             Scopyfrom(s);
  750.             Sflags[0]=1;    /* indicate did copy from */
  751.             constate=0;
  752.             break;
  753.  
  754.         case CONARPTO:    /* need to lengthen arp time-out (secs) */
  755.             i=atoi(s);
  756.             if(i>0)
  757.                 netarptime(i);
  758.             constate=0;
  759.             break;
  760.  
  761.         case CONZONE:        /* the appletalk zone we are in */
  762. #ifdef KIPCARD
  763.             KIPsetzone(s);
  764. #endif
  765.             constate=0;
  766.             break;
  767.  
  768.         case CONDOMTO:                /* DOMAIN timeout value */
  769.             i=atoi(s);
  770.             if(i>1)
  771.                 Scon.domto=i;
  772.             constate=0;
  773.             break;
  774.  
  775.         case CONKBFILE:                /* File name for alternate keyboard map */
  776.             read_keyboard_file(s);    /* read in the kermit compatible keymapping file */
  777.             constate=0;
  778.             break;
  779.  
  780.         case CONWIRE:            /* set the wire type for 3C503 board */
  781.             if(!strcmp(s,"thick"))
  782.                 Scon.wire=0;
  783.             if(!strcmp(s,"thin"))
  784.                 Scon.wire=1;
  785.             constate=0;
  786.             break;
  787.  
  788.         case CONCURSORTOP:        /* what scan line the cursor starts on */
  789.             Scon.cursortop=atoi(s);
  790.             constate=0;
  791.             break;
  792.  
  793.         case CONCURSORBOTTOM:    /* what scan line the cursor ends on */
  794.             Scon.cursorbottom=atoi(s);
  795.             constate=0;
  796.             break;
  797.  
  798.         case CONWINDOWGOAWAY:    /* whether windows go away when they close, or whether they wait for a keypress */
  799.             if(toupper(*s)=='Y')
  800.                 Scon.wingoaway=1;
  801.             if(toupper(*s)=='N')
  802.                 Scon.wingoaway=0;
  803.             constate=0;
  804.             break;
  805.  
  806.         case CONAUTOSCROLL:        /* do we automatically scroll in scrollback */
  807.             if(!strcmp(s,"no"))
  808.                 Scon.autoscroll=0;
  809.             else
  810.                 Scon.autoscroll=1;
  811.             constate=0;
  812.             break;
  813.  
  814.         case CONCLOCK:            /* display the clock? */
  815.             if(!strcmp(s,"no") || !strcmp(s,"off"))
  816.                 Scon.clock=0;
  817.             else
  818.                 Scon.clock=1;
  819.             constate=0;
  820.             break;
  821.  
  822.         case CONBROADCAST:        /* broadcast IP number for network */
  823.             if(4!=sscanf(s,"%d.%d.%d.%d",&a,&b,&c,&d)) {
  824.                 Serrline(908);
  825.                 return(3);
  826.               }
  827.             Scon.broadip[0]=(char)a;     /* keep number */
  828.             Scon.broadip[1]=(char)b;
  829.             Scon.broadip[2]=(char)c;
  830.             Scon.broadip[3]=(char)d;
  831.             constate=0;
  832.             break;
  833.  
  834.         case CONOUTPUTMAP:  /* File name for alternate output mapping */
  835.             read_output_file(s);    /* read in the output mapping file */
  836.             constate=0;
  837.             default_mapoutput=1;
  838.             break;
  839.  
  840.         case CONBEEP:   /* turn musical note on */
  841.             if('Y'==toupper(s[0]))
  842.                 beep_notify=1;
  843.             constate=0;
  844.             break;
  845.  
  846.         case CONSERVICES:        /* path to services file */
  847.             service_file(s);
  848.             constate=0;
  849.             break;
  850.  
  851.         default:
  852.             constate=0;
  853.             break;
  854.       }
  855.     return(0);
  856. }
  857.  
  858. /************************************************************************/
  859. /*  Scopyfrom
  860. *   Look at the Sflags array to determine which elements to copy from
  861. *   a previous machine's entries.  If a machine name as been given as
  862. *   "default", the state machine will fill in the fields from that
  863. *   machine's entries.
  864. *
  865. *   If the machine name to copyfrom is not present in the list, set the
  866. *   program default values for each field.
  867. */
  868. void Scopyfrom(char *s)
  869. {
  870.     struct machinfo *m;
  871.     int i;
  872.  
  873.     m=Shostlook(s);            /* search list */
  874.  
  875.     for(i=3; i<=NUMSPECS-100; i++)         /* through list of parms */
  876.         if(!Sflags[i]) {
  877.             if(m)                             /* copy old value */
  878.                 switch(100+i) {
  879.                     case CONHOST:
  880.                         Smptr->hname=m->hname;
  881.                         break;
  882.  
  883.                     case CONIP:
  884.                         movebytes(Smptr->hostip,m->hostip,4);
  885.                         Smptr->mstat=m->mstat;
  886.                         break;
  887.  
  888.                     case CONGATE:            /* gateways cannot be copied from */
  889.                         Smptr->gateway=0;
  890.                         break;
  891.  
  892.                     case CONNS:                    /* can't copy nameservers either */
  893.                         Smptr->nameserv=0;
  894.                         break;
  895.  
  896.                     case CONBKSP:
  897.                         Smptr->bksp=m->bksp;
  898.                         break;
  899.  
  900.                     case CONBKSC:
  901.                         Smptr->bkscroll=m->bkscroll;
  902.                         break;
  903.  
  904.                     case CONCLMODE:
  905.                         Smptr->clearsave=m->clearsave;
  906.                         break;
  907.  
  908.                     case CONRETR:
  909.                         Smptr->retrans=m->retrans;
  910.                         break;
  911.  
  912.                     case CONWIND:
  913.                         Smptr->window=m->window;
  914.                         break;
  915.  
  916.                     case CONSEG:
  917.                         Smptr->maxseg=m->maxseg;
  918.                         break;
  919.  
  920.                     case CONMTU:
  921.                         Smptr->mtu=m->mtu;
  922.                         break;
  923.  
  924.                     case CONTO:
  925.                         Smptr->conto=m->conto;
  926.                         break;
  927.  
  928.                     case CONCRMAP:
  929.                         Smptr->crmap=m->crmap;
  930.                         break;
  931.  
  932.                     case CONDUP:
  933.                         Smptr->halfdup=m->halfdup;
  934.                         break;
  935.  
  936.                     case CONWRAP:
  937.                         Smptr->vtwrap=m->vtwrap;
  938.                         break;
  939.  
  940.                     case CONWIDE:
  941.                         Smptr->vtwidth=m->vtwidth;
  942.                         break;
  943.  
  944.                     case CONNF:
  945.                         Smptr->nfcolor=m->nfcolor;
  946.                         break;
  947.  
  948.                     case CONNB:
  949.                         Smptr->nbcolor=m->nbcolor;
  950.                         break;
  951.  
  952.                     case CONBF:
  953.                         Smptr->bfcolor=m->bfcolor;
  954.                         break;
  955.  
  956.                     case CONBB:
  957.                         Smptr->bbcolor=m->bbcolor;
  958.                         break;
  959.  
  960.                     case CONUF:
  961.                         Smptr->ufcolor=m->ufcolor;
  962.                         break;
  963.  
  964.                     case CONUB:
  965.                         Smptr->ubcolor=m->ubcolor;
  966.                         break;
  967.  
  968.                     case CONFONT:
  969.                         Smptr->font=m->font;
  970.                         break;
  971.  
  972.                     case CONFSIZE:
  973.                         Smptr->fsize=m->fsize;
  974.                         break;
  975.  
  976.                     case CONPORT:
  977.                         Smptr->port=m->port;
  978.                         break;
  979.  
  980.                     case CONFTPBAK:
  981.                         Smptr->ftpoptions=m->ftpoptions;
  982.                         break;
  983.  
  984.                     case CONDEBUGCONSOLE:
  985.                         Smptr->consoledebug=m->consoledebug;
  986.                         break;
  987.  
  988.                     case CONMAPOUTPUT:
  989.                         Smptr->mapoutflag=m->mapoutflag;
  990.                         break;
  991.  
  992.                     default:
  993.                         break;
  994.                   }    /* end switch */
  995.             else
  996.                 switch(100+i) {        /* m=NULL, install default values */
  997.                     case CONHOST:
  998.                         Smptr->hname=NULL;
  999.                         break;
  1000.  
  1001.                     case CONIP:
  1002.                         Smptr->mstat=NOIP;
  1003.                         break;
  1004.  
  1005.                     case CONGATE:            /* gateways cannot be copied from */
  1006.                         Smptr->gateway=0;
  1007.                         break;
  1008.  
  1009.                     case CONBKSP:
  1010.                         Smptr->bksp=127;
  1011.                         break;
  1012.  
  1013.                     case CONBKSC:
  1014.                         Smptr->bkscroll=0;
  1015.                         break;
  1016.  
  1017.                     case CONCLMODE:
  1018.                         Smptr->clearsave=1;
  1019.                         break;
  1020.  
  1021.                     case CONRETR:
  1022.                         Smptr->retrans=SMINRTO;
  1023.                         break;
  1024.  
  1025.                     case CONWIND:
  1026.                         Smptr->window=DEFWINDOW;
  1027.                         break;
  1028.  
  1029.                     case CONSEG:
  1030.                         Smptr->maxseg=DEFSEG;
  1031.                         break;
  1032.  
  1033.                     case CONMTU:
  1034.                         Smptr->mtu=TSENDSIZE;
  1035.                         break;
  1036.  
  1037.                     case CONNS:                    /* can't copy nameservers either */
  1038.                         Smptr->nameserv=0;
  1039.                         break;
  1040.  
  1041.                     case CONTO:
  1042.                         Smptr->conto=CONNWAITTIME;
  1043.                         break;
  1044.  
  1045.                     case CONCRMAP:
  1046.                         Smptr->crmap=10;
  1047.                         break;
  1048.  
  1049.                     case CONDUP:
  1050.                         Smptr->halfdup=0;
  1051.                         break;
  1052.  
  1053.                     case CONWRAP:
  1054.                         Smptr->vtwrap=0;
  1055.                         break;
  1056.  
  1057.                     case CONWIDE:
  1058.                         Smptr->vtwidth=80;
  1059.                         break;
  1060.  
  1061.                     case CONNF:
  1062.                         Smptr->nfcolor=NFDEF;
  1063.                         break;
  1064.  
  1065.                     case CONNB:
  1066.                         Smptr->nbcolor=NBDEF;
  1067.                         break;
  1068.  
  1069.                     case CONBF:
  1070.                         Smptr->bfcolor=BFDEF;
  1071.                         break;
  1072.  
  1073.                     case CONBB:
  1074.                         Smptr->bbcolor=BBDEF;
  1075.                         break;
  1076.  
  1077.                     case CONUF:
  1078.                         Smptr->ufcolor=UFDEF;
  1079.                         break;
  1080.  
  1081.                     case CONUB:
  1082.                         Smptr->ubcolor=UBDEF;
  1083.                         break;
  1084.  
  1085.                     case CONFONT:
  1086.                         Smptr->font="Monaco";
  1087.                         break;
  1088.  
  1089.                     case CONFSIZE:
  1090.                         Smptr->fsize=9;
  1091.                         break;
  1092.  
  1093.                     case CONPORT:
  1094.                         Smptr->port=23;            /* the telnet port */
  1095.                         break;
  1096.  
  1097.                     case CONFTPBAK:     /* ftp back to workstation option string */
  1098.                         Smptr->ftpoptions=NULL;
  1099.                         break;
  1100.  
  1101.                     case CONDEBUGCONSOLE:   /* console debugging setting */
  1102.                         Smptr->consoledebug=0;
  1103.                         break;
  1104.  
  1105.                     case CONMAPOUTPUT:      /* output mapping flag */
  1106.                         Smptr->mapoutflag=0;
  1107.                         break;
  1108.  
  1109.                     default:
  1110.                         break;
  1111.                   }    /* end switch */
  1112.           }    /* end if */
  1113.     Sflags[0]=1;                    /* set that this machine was copied */
  1114. }
  1115.  
  1116. /************************************************************************/
  1117. /* Shostfile
  1118. *   if the user wants to change the host file name from 'config.tel' to
  1119. *   something else.
  1120. */
  1121. void Shostfile(char *ptr)
  1122. {
  1123.     Smachfile=ptr;    
  1124. /*
  1125. *  note that the area with the file name must stay allocated for
  1126. *  later reference, typically it is in some argv[] parm.
  1127. */
  1128. }
  1129.  
  1130. #ifdef OLD_WAY
  1131. /************************************************************************/
  1132. /* Shostpath
  1133. *   if the user wants to change the host path name
  1134. */
  1135. void Shostpath(char *ptr)
  1136. {
  1137.     Smachpath=ptr;
  1138. /*
  1139. *  note that the area with the file name must stay allocated for
  1140. *  later reference, typically it is in some argv[] parm.
  1141. */
  1142. }
  1143. #endif
  1144.  
  1145.  
  1146. /************************************************************************/
  1147. /*  get host by name
  1148. *   Given the name of a host machine, search our database to see if we
  1149. *   have that host ip number.  Search first the name field, and then the
  1150. *   hostname field.  If the IP # is given, returns a ptr to the
  1151. *   default machine record with that IP # installed.
  1152. *   Returns the pointer to a valid record, or NULL if the IP # cannot
  1153. *   be deciphered.  
  1154. */
  1155. struct machinfo *Sgethost(char *machine)
  1156. {
  1157.     int i,j,k,l;
  1158.     unsigned char ipto[4],myipnum[4],xmask[4];
  1159.     unsigned long hnum;
  1160.     struct machinfo *m=NULL;
  1161.  
  1162. /*
  1163. *  First, check for the pound sign character which means we should use
  1164. *  the current netmask to build an IP number for the local network.
  1165. *  Take the host number, install it in the ipto[] array.  Then mask
  1166. *  in my IP number's network portion to build the final IP address.
  1167. */
  1168.     if('#'==machine[0]) {        /* on my local network */
  1169.         netgetip(myipnum);
  1170.         netgetmask(xmask);            /* mask of network portion of IP # */
  1171.         sscanf(&machine[1],"%ld",&hnum);/* host number for local network */
  1172.         for(i=3; i>=0; i--)
  1173.             ipto[i]=(unsigned char)((hnum>>(i*8)) & 255L);    /* take off a byte */
  1174.         for(i=0; i<4; i++) 
  1175.             ipto[i] |= (myipnum[i] & xmask[i]);        /* mask new one in */
  1176.       }
  1177. /*
  1178. *  next, is it an IP number?  We take it if the number is in four
  1179. *  parts, separated by periods.
  1180. */
  1181.     else 
  1182.         if(4==sscanf(machine,"%d.%d.%d.%d",&i,&j,&k,&l)) {    /* given ip num */
  1183.             ipto[0]=(unsigned char)i;
  1184.             ipto[1]=(unsigned char)j;
  1185.             ipto[2]=(unsigned char)k;
  1186.             ipto[3]=(unsigned char)l;
  1187.           }
  1188. /*
  1189. *  lastly, it must be a name, first check the local host table
  1190. *  A first number of 127 means that it doesn't have an IP number, but
  1191. *  is in the table(strange occurrence)
  1192. */
  1193.         else {                                    /* look it up */
  1194.             m=Shostlook(machine);
  1195.             if(m==NULL) {
  1196.                 netposterr(805);            /* informative */
  1197.                 return(NULL);
  1198.               } 
  1199.             if(m->mstat<HAVEIP) {
  1200.                 netposterr(806);            /* informative */
  1201.                 return(NULL);
  1202.               }
  1203.           }
  1204.     if(!m) {
  1205.         m=Shostlook("default");
  1206.         movebytes(m->hostip,ipto,4);        /* copy in newest host # */
  1207.         m->mstat=HAVEIP;                    /* we have the IP # */
  1208.       }
  1209.     return(m);
  1210. }
  1211.  
  1212. /**************************************************************************/
  1213. /*  Sissep
  1214. *   is the character a valid separator for the hosts file?
  1215. *   separators are white space, special chars and :;=
  1216. *
  1217. */
  1218. int Sissep(int c)
  1219. {
  1220.     if(c<33 || c==':' || c==';' || c=='=')
  1221.         return(1);
  1222.     return(0);
  1223. }
  1224.  
  1225. /************************************************************************/
  1226. /*  Ssetgates
  1227. *   set up the gateway machines and the subnet mask after netinit()
  1228. *   and start up ftp and rcp for them.
  1229. */
  1230. void Ssetgates(void)
  1231. {
  1232.     struct machinfo *m;
  1233.     int level,again;
  1234.  
  1235.     BUG("Ssetgates");
  1236.     if(Scon.havemask) {                    /* leave default unless specified */
  1237.         netsetmask(Scon.netmask);
  1238.       }    /* end if */
  1239. /*
  1240. *  Search the list of machines for gateway flags.
  1241. *  Invoke netsetgate in increasing order of gateway level #s.
  1242. *  Terminates when it gets through list without finding next higher number.
  1243. */
  1244.     level=0;
  1245.     BUG("looking for gateway");
  1246.     do {
  1247.         level++;
  1248.         again=0;
  1249.         m=Smachlist;
  1250.         while(m!=NULL) {
  1251.             BUG("checking a machine");
  1252.             if(m->gateway==(unsigned char)level && m->mstat>=HAVEIP) {
  1253.                 BUG("have gateway");
  1254.                 netsetgate(m->hostip);
  1255.             }    /* end if */
  1256.             BUG("after first if");
  1257.             if((m->gateway) == (unsigned char)(level+1))
  1258.                 again=1;
  1259.             BUG("after second if");
  1260.             m=m->next;
  1261.         }
  1262.         BUG("need to go through machlist again?");
  1263. #ifdef DEBUG
  1264.         getch();
  1265. #endif
  1266.     } while(again);
  1267.     BUG("about to set ftp mode");
  1268.     Sftpmode(Scon.ftp);
  1269.     BUG("need to go through machlist again?");
  1270.     BUG("about to set rcp mode");
  1271.     Srcpmode(Scon.rcp);
  1272.  
  1273.     BUG("returning from Ssetgates");
  1274. }
  1275.  
  1276. /**********************************************************************
  1277. *  Function    :    pfopen
  1278. *  Purpose    :    open the file in the current directory, and if it is not
  1279. *                there, then search the DOS PATH variable for it
  1280. *  Parameters    :
  1281. *            name - the filename to open
  1282. *            mode - the mode to open the file in (see fopen())
  1283. *  Returns    :    a pointer to a FILE, or NULL for file not found
  1284. *  Calls    :    getenv(), fopen()
  1285. *  Called by    :    Sreadhosts()
  1286. **********************************************************************/
  1287. static FILE *pfopen(char *name,char *mode)
  1288. {
  1289.     char *path,                /* pointer to the PATH variable in the environment */
  1290.         filename[80],        /* storage for the pathes in the PATH variable */
  1291.         *fn;                /* temporary pointer to filename[] */
  1292.     FILE *fp;                /* pointer to the FILE opened */
  1293.  
  1294.     if((fp=fopen(name,mode))!=NULL)    /* check for the file being in the current directory */
  1295.         return(fp);
  1296.     path=getenv("PATH");        /* set the pointer to the PATH environment variable */
  1297.     if(path==NULL)    /* no PATH */
  1298.         return(NULL);
  1299.     while(*path) {    /* search for the file along the path */
  1300.         fn=filename;    /* reset the filename pointer */
  1301.         while(*path!=';' && *path)    /* copy the path into the array */
  1302.             *fn++=*path++;
  1303.         strcpy(fn,name);    /* append the name to the path */
  1304.         if((fp=fopen(filename,mode))!=NULL)    /* check for the file in that path */
  1305.             return(fp);
  1306.         if(*path)    /* skip the ';' */
  1307.             path++;
  1308.       }    /* end while */
  1309.     return(NULL);    /* file not on the path either */
  1310. }    /* end pfopen() */
  1311.