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