/* * Confile.c * Split from util.c 5/88 * Reads and stores the appropriate information for the config file * */ #include "stdio.h" #include "memory.h" #include "whatami.h" #include "hostform.h" #ifdef PC #include "string.h" #else #define strchr(A,B) index(A,B) #endif #define NUMSPECS 131 char /* special function types */ *neterrstring(); int32 time(); /* don't forget this sucker! */ static struct machinfo *Smachlist,*Smptr; struct machinfo *Sns=NULL; static unsigned char *Smachfile = {"config.tel"}, Sflags[NUMSPECS-95], /* which parms we have or have not */ *Sspace; struct config Scon = { 0,0,0,0, 0, 3, 127,0,0,1, "", 7,1,0x70, "atalk", "ega", 0, 1, 1, 1, 0, "DEC-VT100", "*", NULL, NULL, NULL, NULL, NULL, NULL, 1, 4, 3, -1, 120, 0x0d000, 0x0300 }; int Sxxnf[3] = NFDEF, Sxxnb[3] = NBDEF, Sxxbf[3] = BFDEF, Sxxbb[3] = BBDEF, Sxxuf[3] = UFDEF, Sxxub[3] = UBDEF; static int mno=0, /* how many machines in host file */ lineno, /* line number in hosts file */ position, /* position for scanning string */ constate, /* state for config file parser */ inquote; /* flag, inside quotes now */ /* * States for config file reading state machine. * One for each type of keyword and some for controlling. */ #define CONNAME 101 #define CONHOST 102 #define CONIP 103 #define CONGATE 104 #define CONCOLOR 105 #define CONBKSP 106 #define CONBKSC 107 #define CONRETR 108 #define CONWIND 109 #define CONSEG 110 #define CONMTU 111 #define CONNS 112 #define CONTO 113 #define CONCRMAP 114 #define CONDUP 115 #define CONWRAP 116 #define CONWIDE 117 #define CONFONT 118 #define CONFSIZE 119 #define CONNF 120 #define CONNB 121 #define CONBF 122 #define CONBB 123 #define CONUF 124 #define CONUB 125 #define CONRF 126 #define CONRB 127 #define CONCLMODE 128 #define CONPORT 129 #define CONLINES 130 #define CONLKEYS 131 /* * above this line are per machine entries, below are configuration entries */ #define CONMYIP 132 #define CONHPF 133 #define CONPSF 134 #define CONTEKF 135 #define CONJTIME 136 #define CONME 137 #define CONCCOL 138 #define CONHW 139 #define CONADDR 140 #define CONIOA 141 #define CONDEF 142 #define CONCKEYS 143 #define CONINT 144 #define CONBIOS 145 #define CONTEK 146 #define CONVIDEO 147 #define CONFTP 148 #define CONRCP 149 #define CONPASS 150 #define CONCAP 151 #define CONTTYPE 152 #define CONNSTYPE 153 #define CONFROM 154 #define CONARPTO 155 #define CONZONE 156 #define CONNDOM 157 #define CONDOMTO 158 #define CONBLOCK 159 #define CONMASK 160 char *Skeyw[] = { "", "name", /* name of session */ "host", /* name of host */ "hostip", /* IP number */ "gateway", /* gateway level */ "color", /* color code ==5== */ "erase", /* value to use for backspace */ "scrollback", /* how many lines to backscroll */ "retrans", /* initial retrans time */ "rwin", /* window to allow for this host */ "maxseg", /* maximum transfer size (in) ==10== */ "mtu", /* transfer unit (out) */ "nameserver", /* name server level */ "contime", /* timeout for opening connection */ "crmap", /* map for Berkeley 4.3 compatibility */ "duplex", /* half duplex for IBM machines */ "vtwrap", /* should VT wrap? */ "vtwidth", /* width of VT100 screen */ "font", /* font to use, when given a choice */ "fsize", /* font size, in points */ "nfcolor", /* normal foreground color */ "nbcolor", /* normal background color */ "bfcolor", /* blink foreground color */ "bbcolor", /* blink background color */ "ufcolor", /* underline foreground color */ "ubcolor", /* underline background color */ "rfcolor", /* reverse foreground color */ "rbcolor", /* reverse background color */ "clearsave", /* clear screen saves lines */ "port", /* TCP port to go for */ "vtlines", /* number of lines for the VT100 window */ "localkeys", /* keys to use for int,susp,resume */ /* * following are one-time entries, above are part of the data structure */ "myip", /* local machine's IP # */ "hpfile", /* HPGL output file */ "psfile", /* postscript output file */ "tekfile", /* tektronix output file */ "timeslice", /* timer slice for multi-tasking */ "myname", /* identifying info ==15==*/ "concolor", /* console colors */ "hardware", /* network hardware */ "address", /* Address of hardware */ "ioaddr", /* ioaddress of hardware */ "domain", /* default domain for lookup */ "commandkeys", /* use command keys on mac */ "interrupt", /* interrupt request 3 or 5 */ "bios", /* use BIOS screen */ "tek", /* tektronix graphics ==20==*/ "video", /* type of video hardware */ "ftp", /* enable ftp? */ "rcp", /* enable rcp? */ "passfile", /* password file name */ "capfile", /* capture file name */ "termtype", /* terminal type */ "nameservertype", /* nameserver type */ "copyfrom", /* copy from another machine */ "arptime", /* time-out for ARPs */ "zone", /* NBP zone for Macs */ "domainretry", /* # of retries */ "domaintime", /* time-out for DOMAIN */ "block", /* blocking for network update */ "netmask", /* subnetting mask */ "" }; /************************************************************************/ /* Sgetconfig * copy the configuration information into the user's data structure * directly. The user can do with it what he feels like. */ Sgetconfig(cp) struct config *cp; { movenbytes(cp,&Scon,sizeof(struct config)); return(0); } /************************************************************************/ /* Sreadhosts * read in the hosts file into our in-memory data structure. * Handle everything by keyword, see docs for specifications about file. */ Sreadhosts() { FILE *fp; int c,retval; Smachlist = Smptr = NULL; mno = 0; Sspace = (char *)NewPtr(256); /* get room for gathering stuff */ if (Sspace == NULL) { Serrline(901); return(1); } position = constate = inquote = lineno = 0; /* state vars */ if (NULL == (fp = fopen(Smachfile,"r"))) { Serrline(900); return(1); } retval = 0; while (!retval) { c = fgetc(fp); if (c == '#' && !inquote) { while (c != EOF && c != '\n' && c != '\r') /* skip to EOL */ c = fgetc(fp); } if (c == '\n' || c == '\r') lineno++; retval = Scontoken(c); } fclose(fp); DisposPtr ((Ptr)Sspace); Smadd("default"); /* make sure name is in list */ if (retval == EOF) /* EOF is normal end */ return(0); else return(retval); } /************************************************************************/ /* ncstrcmp * No case string compare. * Only returns 0=match, 1=no match, does not compare greater or less * There is a tiny bit of overlap with the | 32 trick, but shouldn't be * a problem. It causes some different symbols to match. */ ncstrcmp(sa,sb) char *sa,*sb; { while (*sa && *sa < 33) /* don't compare leading spaces */ sa++; while (*sb && *sb < 33) sb++; while (*sa && *sb) { if ((*sa != *sb) && ((*sa | 32) != (*sb | 32))) return(1); sa++;sb++; } if (!*sa && !*sb) /* if both at end of string */ return(0); else return(1); } /************************************************************************/ /* Serrline * prints the line number of the host file error and posts the event * for the line number error and posts the hosts file error. */ Serrline(n) int n; { char *p; p = neterrstring(-1); sprintf(p,"Config file: error in line %4d",lineno+1); netposterr(-1); netposterr(n); } /************************************************************************/ /* Scontoken * tokenize the strings which get passed to Sconfile. * Handles quotes and uses separators: <33, ;:= */ Scontoken(c) int c; { int retval; if (c == EOF) { Sspace[position++] = '\0'; Sconfile(Sspace); if (!Sflags[0]) { /* make sure last entry gets copied */ if (ncstrcmp("default",Smptr->sname)) Scopyfrom("default"); else Scopyfrom("=="); } return(-1); } if (!position && Sissep(c)) /* skip over junk before token */ return(0); if (inquote || !Sissep(c)) { if (position > 200) { Serrline(903); return(1); } /* * check for quotes, a little mixed up here, could be reorganized */ if (c == '"' ) { if (!inquote) { /* beginning of quotes */ inquote = 1; return(0); } else inquote = 0; /* turn off flag and drop through */ } else { if (c == '\n') { /* check for EOL inside quotes */ Serrline(904); return(1); } Sspace[position++] = c; /* include in current string */ return(0); } } Sspace[position++] = '\0'; retval = Sconfile(Sspace); /* pass the token along */ position = 0; inquote = 0; Sspace[0] = '\0'; return(retval); } /************************************************************************/ /* Sconfile * take the characters read from the file and parse them for keywords * which require configuration action. */ Sconfile(s) char *s; { int i,a,b,c,d; switch (constate) { case 0: /* lookup keyword */ if (!(*s)) /* empty token */ return(0); for (i=1; *Skeyw[i] && ncstrcmp(Skeyw[i],s); i++) ; if (!(*Skeyw[i])) { /* not in list */ Serrline(902); return(0); /* don't die - helps backward compatibility */ } constate = 100+i; /* change to state for keyword */ /* * check if this is a machine specific parm without a machine to * give it to. "name" being the only machine specific parm allowed, of course */ if (Smptr == NULL && constate > 101 && constate <= NUMSPECS) { Serrline(905); return(1); } break; case CONNAME: /* * allocate space for upcoming parameters */ if (Smachlist == NULL) { Smachlist = (struct machinfo *)NewPtr(sizeof(struct machinfo)); Smptr = Smachlist; Smptr->sname = NULL; Smptr->hname = NULL; } else { if (!Sflags[0]) { if (ncstrcmp("default",Smptr->sname)) Scopyfrom("default"); else Scopyfrom("=="); /* to make sure 'default' gets set */ } Smptr->next = (struct machinfo *)NewPtr(sizeof(struct machinfo)); Smptr = Smptr->next; } Smptr->next = NULL; Smptr->hname = NULL; /* guarantee to be null */ Smptr->sname = (char *)NewPtr(position); /* size of name string */ strcpy(Smptr->sname,s); /* keep name field */ constate = 0; /* back to new keyword */ for (i=0; imno = ++mno; /* new machine number */ break; case CONHOST: /* also a name */ Smptr->hname = (char *)NewPtr(position); strcpy(Smptr->hname,s); constate = 0; Sflags[CONHOST-100] = 1; break; case CONIP: /* IP number for host */ if ( 4 != sscanf(s,"%d.%d.%d.%d",&a,&b,&c,&d)) { Serrline(906); return(3); } Smptr->hostip[0]=a; Smptr->hostip[1] =b; /* keep number */ Smptr->hostip[2]=c; Smptr->hostip[3] =d; Smptr->mstat = HFILE; constate = 0; Sflags[CONIP-100] = 1; break; case CONGATE: Smptr->gateway = atoi(s); /* gateway level */ constate = 0; Sflags[CONGATE-100] = 1; break; case CONCOLOR: /* support old format */ Smptr->nfcolor[0] = s[1]-48; Smptr->nbcolor[0] = s[0]-48; Smptr->bfcolor[0] = s[5]-48; Smptr->bbcolor[0] = s[4]-48; Smptr->ufcolor[0] = s[3]-48; Smptr->ubcolor[0] = s[2]-48; constate = 0; Sflags[CONNF-100] = 1; /* sets them all at one shot */ Sflags[CONNB-100] = 1; Sflags[CONBF-100] = 1; Sflags[CONBB-100] = 1; Sflags[CONUF-100] = 1; Sflags[CONUB-100] = 1; break; case CONNF: /* foreground normal color */ if (Scolorset(Smptr->nfcolor,s)) Sflags[CONNF-100] = 1; constate = 0; break; case CONNB: /* background normal color */ if (Scolorset(Smptr->nbcolor,s)) Sflags[CONNB-100] = 1; constate = 0; break; case CONRF: case CONBF: /* blink foreg color */ if (Scolorset(Smptr->bfcolor,s)) Sflags[CONBF-100] = 1; /* in copyfrom, r's are really b's */ constate = 0; break; case CONRB: case CONBB: /* blink bg color */ if (Scolorset(Smptr->bbcolor,s)) Sflags[CONBB-100] = 1; constate = 0; break; case CONUF: /* foreground underline color */ if (Scolorset(Smptr->ufcolor,s)) Sflags[CONUF-100] = 1; constate = 0; break; case CONUB: /* bg underline color */ if (Scolorset(Smptr->ubcolor,s)) Sflags[CONUB-100] = 1; constate = 0; break; case CONLKEYS: /* local key bindings */ { int a,b,c; if (3!=sscanf(s,"{%d,%d,%d}", &a, &b, &c)) Smptr->ckey = Smptr->skey = Smptr->qkey = 0; /* default = off */ else { Smptr->ckey = a; Smptr->skey = b; Smptr->qkey = c; } } Sflags[CONLKEYS-100] = 1; constate = 0; break; case CONBKSP: if (!ncstrcmp(s,"backspace")) Smptr->bksp = 8; else Smptr->bksp = 127; constate = 0; Sflags[CONBKSP-100] = 1; break; case CONBKSC: Smptr->bkscroll = atoi(s); constate = 0; Sflags[CONBKSC-100] = 1; break; case CONRETR: Smptr->retrans = atoi(s); constate = 0; Sflags[CONRETR-100] = 1; break; case CONWIND: Smptr->window = atoi(s); constate = 0; Sflags[CONWIND-100] = 1; break; case CONSEG: Smptr->maxseg = atoi(s); constate = 0; Sflags[CONSEG-100] = 1; break; case CONMTU: Smptr->mtu = atoi(s); constate = 0; Sflags[CONMTU-100] = 1; break; case CONNS: Smptr->nameserv = atoi(s); if (!Sns || (Sns->nameserv > Smptr->nameserv)) /* keep NS */ Sns = Smptr; constate = 0; Sflags[CONNS-100] = 1; break; case CONTO: i = atoi(s); if (i > 2) { Smptr->conto = i; Sflags[CONTO-100] = 1; } constate = 0; break; case CONCRMAP: if (!ncstrcmp(s,"4.3BSDCRNUL")) Smptr->crmap = 0; else Smptr->crmap = 10; Sflags[CONCRMAP-100] = 1; constate = 0; break; case CONDUP: if (!ncstrcmp(s,"half")) { Smptr->halfdup = 1; Sflags[CONDUP-100] = 1; } constate = 0; break; case CONWRAP: if ('Y' == toupper(s[0])) Smptr->vtwrap = 1; else Smptr->vtwrap = 0; Sflags[CONWRAP-100] = 1; constate = 0; break; case CONCLMODE: if ('N' == toupper(s[0])) Smptr->clearsave = 0; else Smptr->clearsave = 1; Sflags[CONCLMODE-100] = 1; constate = 0; break; case CONFONT: Smptr->font = (char *)NewPtr(position); strcpy(Smptr->font,s); Sflags[CONFONT-100] = 1; constate = 0; break; case CONFSIZE: Smptr->fsize = atoi(s); Sflags[CONFSIZE-100] = 1; constate = 0; break; case CONWIDE: if (132 == atoi(s)) Smptr->vtwidth = 132; else Smptr->vtwidth = 80; Sflags[CONWIDE-100] = 1; constate = 0; break; case CONLINES: i = atoi(s); if (i > 6 && i < 100) Smptr->nlines = i; else Smptr->nlines = 24; /* default is 24 lines */ Sflags[CONLINES-100] = 1; constate = 0; break; case CONPORT: /* File name for Tek dump */ i = atoi(s); if (i < 1) i = 23; Smptr->port = i; Sflags[CONPORT-100] = 1; constate = 0; break; /* * now the one-time entries * Generally this information goes into the "Scon" structure for later * retrieval by other routines. * */ #ifdef PC case CONMASK: if ( 4 != sscanf(s,"%d.%d.%d.%d",&a,&b,&c,&d)) { Serrline(907); return(3); } Scon.netmask[0]=a; Scon.netmask[1] =b; Scon.netmask[2]=c; Scon.netmask[3] =d; Scon.havemask=1; constate = 0; break; case CONMYIP: constate = 0; if (!ncstrcmp(s,"rarp")) { movebytes(Scon.myipnum,s,4); netsetip("RARP"); break; } if ( 4 != sscanf(s,"%d.%d.%d.%d",&a,&b,&c,&d)) { Serrline(908); return(3); } Scon.myipnum[0]=a; Scon.myipnum[1] =b; /* put number back in s */ Scon.myipnum[2]=c; Scon.myipnum[3] =d; netsetip(Scon.myipnum); /* make permanent set */ break; #endif case CONME: /* what my name is */ strncpy(Scon.me,s,30); Scon.me[30] = '\0'; constate = 0; break; case CONHW: /* what hardware are we using? */ i = strlen(s); if (i > 9) i = 9; s[i] = '\0'; i--; while (i--) s[i] = tolower(s[i]); strcpy(Scon.hw,s); constate = 0; break; #ifdef PC case CONINT: /* what IRQ to use */ sscanf(s,"%x",&i); Scon.irqnum = i; constate = 0; break; case CONBIOS: if (toupper(*s) == 'Y') { Scwritemode(0); Scon.bios = 1; } constate = 0; break; case CONADDR: /* segment address for board */ sscanf(s,"%x",&i); Scon.address = i; constate = 0; break; case CONIOA: /* io address for board */ sscanf(s,"%x",&i); Scon.ioaddr = i; constate = 0; break; #endif #ifdef MAC case CONCKEYS: if (toupper(*s) == 'Y') { Scon.comkeys = 1; } constate = 0; break; case CONZONE: Scon.zone = (char *)NewPtr(position); /* space for name */ strcpy(Scon.zone,s); /* copy it in */ constate = 0; break; case CONJTIME: /* Time slice */ i = atoi(s); if (i > 1) Scon.timesl = i; constate = 0; break; #endif case CONTEK: if (toupper(*s) == 'N') { Stekmode(0); Scon.tek = 0; } constate = 0; break; case CONVIDEO: i = strlen(s); if (i > 9) i = 9; s[i] = '\0'; strcpy(Scon.video,s); i--; while (i--) s[i] = tolower(s[i]); constate = 0; break; case CONTTYPE: Scon.termtype = (char *)NewPtr(position); strcpy(Scon.termtype,s); constate = 0; break; case CONCCOL: for (i=0; i<3; i++) Scon.color[i] = ((s[i*2]-48)<<4) + (s[i*2+1]-48); constate = 0; break; case CONFTP: if (toupper(*s) == 'N') Scon.ftp = 0; constate = 0; break; case CONRCP: if (toupper(*s) == 'N') Scon.rcp = 0; constate = 0; break; case CONPASS: Scon.pass = (char *)NewPtr(position); /* space for name */ strcpy(Scon.pass,s); /* copy it in */ constate = 0; break; case CONDEF: /* default domain */ Scon.defdom = (char *)NewPtr(position); /* space for name */ strcpy(Scon.defdom,s); /* copy it in */ constate = 0; break; case CONCAP: /* capture file name */ Snewcap(s); constate = 0; break; case CONFROM: /* copy the rest from another */ /* entry in the table */ if (Scopyfrom(s)) return(1); Sflags[0] = 1; /* indicate did copy from */ constate = 0; break; case CONARPTO: /* need to lengthen arp time-out (secs) */ i = atoi(s); if (i > 0) netarptime(i); constate = 0; /* don't forget me! */ break; case CONBLOCK: /* blocking factor for text */ i = atoi(s); if (i > 4096) i = 4096; if (i > 0) Scon.textblock = i; constate = 0; /* don't forget me! */ break; case CONDOMTO: /* DOMAIN timeout value */ i = atoi(s); if (i > 1) Scon.domto = i; constate = 0; break; case CONNDOM: /* DOMAIN number of retries */ i = atoi(s); if (i > 1) Scon.ndom = i; constate = 0; break; case CONHPF: /* File name for HP dump */ Snewhpfile(s); constate = 0; break; case CONPSF: /* File name for PS dump */ Snewpsfile(s); constate = 0; break; case CONTEKF: /* File name for Tek dump */ Snewtekfile(s); constate = 0; break; default: constate = 0; break; } return(0); } /************************************************************************/ /* Scopyfrom * Look at the Sflags array to determine which elements to copy from * a previous machine's entries. If a machine name as been given as * "default", the state machine will fill in the fields from that * machine's entries. * * If the machine name to copyfrom is not present in the list, set the * program default values for each field. */ Scopyfrom(s) char *s; { struct machinfo *m; int i; m = Shostlook(s); /* search list */ for (i=3; i <= NUMSPECS-100; i++) /* through list of parms */ if (!Sflags[i]) { if (m) /* copy old value */ switch (100+i) { case CONHOST: Smptr->hname = m->hname; break; case CONIP: movebytes(Smptr->hostip,m->hostip,4); Smptr->mstat = m->mstat; break; case CONGATE: /* gateways cannot be copied from */ Smptr->gateway = 0; break; casecCONNS: /* can't copy nameservers either */ Smptr->nameserv = 0; break; case CONBKSP: Smptr->bksp = m->bksp; break; case CONBKSC: Smptr->bkscroll = m->bkscroll; break; case CONCLMODE: Smptr->clearsave = m->clearsave; break; case CONRETR: Smptr->retrans = m->retrans; break; case CONWIND: Smptr->window = m->window; break; case CONSEG: Smptr->maxseg = m->maxseg; break; case CONMTU: Smptr->mtu = m->mtu; break; case CONTO: Smptr->conto = m->conto; break; case CONCRMAP: Smptr->crmap = m->crmap; break; case CONDUP: Smptr->halfdup = m->halfdup; break; case CONWRAP: Smptr->vtwrap = m->vtwrap; break; case CONWIDE: Smptr->vtwidth = m->vtwidth; break; case CONLINES: Smptr->nlines = m->nlines; break; case CONNF: movebytes(Smptr->nfcolor,m->nfcolor,3*sizeof(int)); break; case CONNB: movebytes(Smptr->nbcolor, m->nbcolor,3*sizeof(int)); break; case CONBF: movebytes(Smptr->bfcolor,m->bfcolor,3*sizeof(int)); break; case CONBB: movebytes(Smptr->bbcolor,m->bbcolor,3*sizeof(int)); break; case CONUF: movebytes(Smptr->ufcolor,m->ufcolor,3*sizeof(int)); break; case CONUB: movebytes(Smptr->ubcolor,m->ubcolor,3*sizeof(int)); break; case CONLKEYS: Smptr->ckey = m->ckey; Smptr->skey = m->skey; Smptr->qkey = m->qkey; break; case CONFONT: Smptr->font = m->font; break; case CONFSIZE: Smptr->fsize = m->fsize; break; case CONPORT: Smptr->port = m->port; break; default: break; } else switch (100+i) { /* m=NULL, install default values */ case CONHOST: Smptr->hname = NULL; break; case CONIP: Smptr->mstat = NOIP; break; case CONGATE: /* gateways cannot be copied from */ Smptr->gateway = 0; break; case CONBKSP: Smptr->bksp = 127; break; case CONBKSC: Smptr->bkscroll = 0; break; case CONCLMODE: Smptr->clearsave = 1; break; case CONRETR: Smptr->retrans = SMINRTO; break; case CONWIND: #ifdef MAC Smptr->window = 512; #else Smptr->window = DEFWINDOW; #endif break; case CONSEG: #ifdef MAC Smptr->maxseg = 512; #else Smptr->maxseg = DEFSEG; #endif break; case CONMTU: #ifdef MAC Smptr->mtu = 512; #else Smptr->mtu = TSENDSIZE; #endif break; case CONNS: /* can't copy nameservers either */ Smptr->nameserv = 0; break; case CONTO: Smptr->conto = CONNWAITTIME; break; case CONCRMAP: Smptr->crmap = 10; break; case CONDUP: Smptr->halfdup = 0; break; case CONWRAP: Smptr->vtwrap = 0; break; case CONWIDE: Smptr->vtwidth = 80; break; case CONLINES: Smptr->nlines = 24; /* overall default to 24 lines */ break; case CONNF: movebytes(Smptr->nfcolor,Sxxnf,3*sizeof(int)); break; case CONNB: movebytes(Smptr->nbcolor,Sxxnb,3*sizeof(int)); break; case CONBF: movebytes(Smptr->bfcolor,Sxxbf,3*sizeof(int)); break; case CONBB: movebytes(Smptr->bbcolor,Sxxbb,3*sizeof(int)); break; case CONUF: movebytes(Smptr->ufcolor,Sxxuf,3*sizeof(int)); break; case CONUB: movebytes(Smptr->ubcolor,Sxxub,3*sizeof(int)); break; case CONLKEYS: Smptr->ckey = 3; /* Ctrl-C */ Smptr->skey = 19; /* Ctrl-S */ Smptr->qkey = 17; /* Ctrl-Q */ break; case CONFONT: Smptr->font = "Monaco"; break; case CONFSIZE: Smptr->fsize = 9; break; case CONPORT: Smptr->port = 23; /* the telnet port */ break; default: break; } } Sflags[0] = 1; /* set that this machine was copied */ return(0); } /************************************************************************/ /* Smadd * Add a machine to the list. Increments machine number of machine. * Puts in parameters copied from the "default" entry. * */ struct machinfo *Smadd(mname) char *mname; { int i; struct machinfo *m; /* * First, do we have the name already? */ m = Shostlook(mname); if (m) return(m); /* * Don't have name, add another record */ Smptr = (struct machinfo *)NewPtr(sizeof(struct machinfo)); if (Smptr == NULL) return(NULL); for (i=0; i < NUMSPECS-99; i++) Sflags[i] = 0; /* we have no parms */ Scopyfrom("default"); Smptr->sname = NULL; Smptr->hname = (char *)NewPtr(strlen(mname)+1); if (Smptr->hname) strcpy(Smptr->hname,mname); /* copy in name of machine */ Smptr->mno = ++mno; Smptr->mstat = NOIP; Smptr->next = Smachlist; /* add to front of machlist */ Smachlist = Smptr; return(Smptr); } /************************************************************************/ /* Shostfile * if the user wants to change the host file name from 'config.tel' to * something else. */ Shostfile(ptr) char *ptr; { Smachfile = ptr; /* * note that the area with the file name must stay allocated for * later reference, typically it is in some argv[] parm. */ } /************************************************************************/ /* get host by name * Given the name of a host machine, search our database to see if we * have that host ip number. Search first the name field, and then the * hostname field. * Returns the pointer to the correct record, or pointer to the default * record if the number is not available */ struct machinfo *Sgethost(machine) char *machine; { int i,j,k,l; unsigned char ipto[4],myipnum[4],xmask[4]; unsigned long hnum; struct machinfo *m; m = NULL; /* * First, check for the pound sign character which means we should use * the current netmask to build an IP number for the local network. * Take the host number, install it in the ipto[] array. Then mask * in my IP number's network portion to build the final IP address. */ if ('#' == machine[0]) { /* on my local network */ netgetip(myipnum); netgetmask(xmask); /* mask of network portion of IP # */ sscanf(&machine[1],"%ld",&hnum);/* host number for local network */ for (i=3; i >= 0; i--) { ipto[i] = hnum & 255L; /* take off a byte */ hnum >>= 8; /* shift it over */ } for (i=0; i < 4; i++) ipto[i] |= (myipnum[i] & xmask[i]); /* mask new one in */ } /* * next, is it an IP number? We take it if the number is in four * parts, separated by periods. */ else if (4 == sscanf(machine,"%d.%d.%d.%d",&i,&j,&k,&l)) { /* given ip num */ ipto[0] = i; ipto[1] = j; ipto[2] = k; ipto[3] = l; } /* * lastly, it must be a name, first check the local host table * A first number of 127 means that it doesn't have an IP number, but * is in the table (strange occurrence) */ else { /* look it up */ m = Shostlook(machine); if (m == NULL) { netposterr(805); /* informative */ return(NULL); } if (m->mstat < HAVEIP) { netposterr(806); /* informative */ return(NULL); } } if (!m) { m = Shostlook("default"); movebytes(m->hostip,ipto,4); /* copy in newest host # */ m->mstat = HAVEIP; /* we have the IP # */ } return(m); } struct machinfo *Shostlook(hname) char *hname; { struct machinfo *m; m = Smachlist; while (m != NULL) { if (m->sname && !ncstrcmp(hname,m->sname)) return(m); m = m->next; } m = Smachlist; while (m != NULL) { if (m->hname && !ncstrcmp(hname,m->hname)) return(m); m = m->next; } return(NULL); } /************************************************************************/ /* Slooknum * get the host record by machine number, used primarily in DOMAIN name * lookup. */ struct machinfo *Slooknum(num) int num; { struct machinfo *m; m = Smachlist; while (m) { if (m->mno == num) return(m); m = m->next; } return(NULL); } /**************************************************************************/ /* Slookip * For FTP to look up the transfer options to use when running * */ struct machinfo *Slookip(ipnum) unsigned char *ipnum; { struct machinfo *m; m = Smachlist; while (m) { if (comparen(m->hostip,ipnum,4)) return(m); m = m->next; } return(NULL); } /**************************************************************************/ /* Sissep * is the character a valid separator for the hosts file? * separators are white space, special chars and :;= * */ Sissep(c) int c; { if (c < 33) return(1); if (c == ':' || c == ';' || c == '=') return(1); return(0); } /*********************************************************************/ /* Snewns() * Rotate to the next nameserver * Chooses the next highest number from the nameserv field */ Snewns() { struct machinfo *m,*low; int i; if (!Sns) /* safety, should never happen */ Sns = Smachlist; low = Sns; i = Sns->nameserv; /* what is value now? */ m = Smachlist; while (m) { if (m->nameserv == i+1) { Sns = m; return(0); } if ((m->nameserv > 0) && (m->nameserv < low->nameserv)) low = m; m = m->next; } if (Sns == low) return(1); /* no alternate */ else Sns = low; return(0); } Ssetns(ipn) unsigned char ipn[4]; { struct machinfo *m; int i; i = 0; if (NULL == (m = Slookip(ipn))) { /* have already? */ m = Smadd("=nameserv="); movebytes(m->hostip,ipn,4); m->mstat = FROMKIP; i = 1; } m->nameserv = 1; Sns = m; return(i); } /************************************************************************/ /* setgates * set up the gateway machines and the subnet mask after netinit() * and start up ftp and rcp for them. */ Ssetgates() { struct machinfo *m; int level,again; if (Scon.havemask) /* leave default unless specified */ netsetmask(Scon.netmask); /* * Search the list of machines for gateway flags. * Invoke netsetgate in increasing order of gateway level #s. * Terminates when it gets through list without finding next higher number. */ level = 0; do { level++; again = 0; m = Smachlist; while (m != NULL) { if (m->gateway == level && m->mstat >= HAVEIP) netsetgate(m->hostip); if (m->gateway == level+1) again=1; m = m->next; } } while (again); Sftpmode(Scon.ftp); #ifdef PC Srcpmode(Scon.rcp); #endif return(0); }