home *** CD-ROM | disk | FTP | other *** search
/ ProfitPress Mega CDROM2 …eeware (MSDOS)(1992)(Eng) / ProfitPress-MegaCDROM2.B6I / MISC / NETWORK / TEL23SRC.ZIP / ENGINE / NEW_CON.C < prev    next >
Encoding:
C/C++ Source or Header  |  1991-07-24  |  31.1 KB  |  1,333 lines

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