This is readconfig.c in view mode; [Download] [Up]
/* ** Copyright (c) 1991 Bolt Beranek and Newman, Inc. ** All rights reserved. ** ** Redistribution and use in source and binary forms are permitted ** provided that: (1) source distributions retain this entire copyright ** notice and comment, and (2) distributions including binaries display ** the following acknowledgement: ``This product includes software ** developed by Bolt Beranek and Newman, Inc. and CREN/CSNET'' in the ** documentation or other materials provided with the distribution and in ** all advertising materials mentioning features or use of this software. ** Neither the name of Bolt Beranek and Newman nor CREN/CSNET may be used ** to endorse or promote products derived from this software without ** specific prior written permission. ** ** THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED ** WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF ** MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include <stdio.h> #include <ctype.h> #include <netdb.h> #include <sgtty.h> #include <sys/types.h> #include <sys/param.h> #include <netinet/in_systm.h> #include <netinet/in.h> #include <netinet/ip.h> #include <arpa/inet.h> #include "dialupip.h" #include "diald.h" /* ** Some systems don't have these in their <netinet/in.h> */ #ifndef IPPROTO_EGP #define IPPROTO_EGP 8 #endif /* IPPROTO_EGP */ #ifndef IPPROTO_RDP #define IPPROTO_RDP 27 #endif /* IPPROTO_EGP */ #define EQ(a, b) (strcmp((a), (b)) == 0) #define nexttok() strtok((char *)NULL, SEPARATORS) static int errorcount; static int linenum; static char SEPARATORS[] = " \t"; static REMOTE *RemoteTable; static int RemoteCount; static char WHERE[] = "readconfig"; /* ** Find this interface in our list. */ REMOTE * findconfig(device) register char *device; { register REMOTE *rp; register int i; for (rp = RemoteTable, i = RemoteCount; --i >= 0; rp++) if (strcmp(device, rp->Device) == 0) return rp; return NULL; } /* ** Is the host (or its network) on the list of hosts and networks? */ int hostinlist(list, addr) struct in_addr *list; struct in_addr addr; { register int i; register int j; j = i = addr.s_addr % MAXHOSTS; do { if (list[j].s_addr == 0) return 0; if (list[j].s_addr == addr.s_addr) return 1; if (inet_lnaof(list[j].s_addr) == 0 && inet_netof(list[j].s_addr) == inet_netof(addr.s_addr)) return 1; if (++j == MAXHOSTS) j = 0; } while (j != i); return 0; } static void yyerror(path, fmt, arg) char *path; char *fmt; char *arg; { char buff[256]; (void)sprintf(buff, "Error near line %d of\n\t \"%s\": %s\n", linenum, path, fmt); d_log(DLOG_GENERAL, WHERE, buff, arg); errorcount++; } static void parseprotocols(path, lp) char *path; u_long *lp; { char *p; int i; while (p = nexttok()) { if (EQ(p, "tcp")) i = IPPROTO_TCP; else if (EQ(p, "rdp")) i = IPPROTO_RDP; else if (EQ(p, "egp")) i = IPPROTO_EGP; else if (EQ(p, "icmp")) i = IPPROTO_ICMP; else if (EQ(p, "udp")) i = IPPROTO_UDP; else if (EQ(p, "ggp")) i = IPPROTO_GGP; else { yyerror(path, "Bad protocol \"%s\"", p); continue; } lp[P_WORD(i)] |= P_BIT(i); } } static int positivenumber(p) char *p; { if (*p == '\0') return 0; for ( ; *p; p++) if (!isdigit(*p)) return 0; return 1; } static long parsetime(path) char *path; { long l; int i; char *p; for (l = 0; p = nexttok(); ) if (!positivenumber(p) || (i = atoi(p)) < 0 || i > 23) yyerror(path, "Bad hour \"%s\"", p); else l |= (1L << i); return l; } static int addhosttolist(list, addr) struct in_addr *list; struct in_addr addr; { register int i; register int j; j = i = addr.s_addr % MAXHOSTS; do { if (list[j].s_addr == 0) { list[j] = addr; return 1; } if (++j == MAXHOSTS) j = 0; } while (j != i); return 0; } static int parseaddresslist(path, list) char *path; struct in_addr *list; { char *p; struct in_addr new; int i; struct hostent *hp; struct netent *np; for (i = 0; p = nexttok(); i++) { if ((new.s_addr = inet_addr(p)) != -1) ; else if (np = getnetbyname(p)) new = inet_makeaddr(np->n_net, 0); else if (hp = gethostbyname(p)) bcopy(hp->h_addr, (caddr_t)&new, sizeof new); else { yyerror(path, "Bad IP address \"%s\"", p); continue; } if (!hostinlist(list, new) && !addhosttolist(list, new)) yyerror(path, "Can't add \"%s\" to address list", p); } return i; } static int readentry(path, rp, line) char *path; REMOTE *rp; char *line; { static char MISSINGFIELD[] = "Required \"%s\" field is missing"; FILE *F; char *sitep; char *ttysp; char *scriptp; char *transp; char *accessp; char *word; char *p; char *fp; char buff[BUFSIZ]; int i; /* Make sure we have six colon-separated fields. */ if ((sitep = strchr(line, ':')) == NULL || (ttysp = strchr(sitep + 1, ':')) == NULL || (scriptp = strchr(ttysp + 1, ':')) == NULL || (transp = strchr(scriptp + 1, ':')) == NULL || (accessp = strchr(transp + 1, ':')) == NULL) { yyerror(path, "Too few fields", (char *)NULL); return 0; } *sitep++ = '\0'; *ttysp++ = '\0'; *scriptp++ = '\0'; *transp++ = '\0'; *accessp++ = '\0'; /* Field one, the interface. */ if (*line == '\0') { yyerror(path, MISSINGFIELD, "interface"); return 0; } (void)strcpy(rp->Device, line); /* Field two, the site name. */ if (*sitep == '\0') { yyerror(path, MISSINGFIELD, "site"); return 0; } (void)strcpy(rp->Sitename, sitep); /* Field three, the tty#baudrate entries. */ if (*ttysp == '\0' || (p = strtok(ttysp, SEPARATORS)) == NULL) { yyerror(path, MISSINGFIELD, "ttys"); return 0; } for (i = 0; p && i < MAXDEVICES; i++, p = nexttok()) { if ((fp = strchr(p, '#')) == NULL) rp->Speeds[i] = -1; else *fp++ = '\0'; (void)strcpy(rp->Lines[i], p); if (fp) switch (atoi(fp)) { default: yyerror(path, "Bad speed \"%s\"\n", fp); break; case 1200: rp->Speeds[i] = B1200; break; case 2400: rp->Speeds[i] = B2400; break; case 4800: rp->Speeds[i] = B4800; break; case 9600: rp->Speeds[i] = B9600; break; case 19200: rp->Speeds[i] = EXTA; break; case 38400: rp->Speeds[i] = EXTB; break; } } if (i >= MAXDEVICES) { yyerror(path, "Too many tty entries", (char *)NULL); return 0; } while (i < MAXDEVICES) rp->Lines[i++][0] = '\0'; /* Field four, the script file and parameters. */ if (*scriptp == '\0' || (p = strtok(scriptp, SEPARATORS)) == NULL) { yyerror(path, "Missing script name", (char *)NULL); return 0; } if (*p == '/') (void)strcpy(rp->Script, p); else (void)sprintf(rp->Script, "%s/%s", CONFIG_DIR, p); for (fp = rp->FieldData, i = 0; i < 10 && (p = nexttok()); i++) { if (fp > &rp->FieldData[sizeof rp->FieldData - 1]) { yyerror(path, "Parameters too long", (char *)NULL); break; } rp->Fields[i] = fp - rp->FieldData; fp += strlen(strcpy(fp, p)); *fp++ = '\0'; } if (i >= 10) { yyerror(path, "Too many parameters", (char *)NULL); return 0; } rp->FieldCount = i; /* Field five, the transcript file. */ if ((p = strchr(transp, '@')) && isdigit(p[1]) && p[2] == '\0') rp->Transtyle = *++p == '0' ? TS_LOW : TS_HIGH; else rp->Transtyle = TS_LOW; if (*transp == '/') (void)strcpy(rp->Transcript, transp); else (void)sprintf(rp->Transcript, "%s/%s", CONFIG_DIR, transp); /* Set access defaults. */ for (i = 0; i < 7; i++) rp->Times[i] = ~0; for (i = 0; i < 8; i++) rp->Protocols[i] = ~0; for (rp->AllowCount = 0, i = 0; i < MAXHOSTS; i++) rp->AllowTo[i].s_addr = 0; for (rp->DisallowCount = 0, i = 0; i < MAXHOSTS; i++) rp->DisallowFrom[i].s_addr = 0; rp->Inactivity = INACT_UNDEF; /* Field five, the access file. */ if (*accessp == '\0') return errorcount == 0; if (*accessp == '/') (void)strcpy(buff, accessp); else (void)sprintf(buff, "%s/%s", CONFIG_DIR, accessp); if ((F = fopen(buff, "r")) == NULL) { yyerror(path, "Can't open access file \"%s\"", accessp); return 0; } /* Read lines. */ for (linenum = 1; fgets(buff, sizeof buff, F); linenum++) { if ((p = strchr(buff, '\n')) == NULL) { yyerror(buff, "Line too long", (char *)NULL); (void)fclose(F); return 0; } *p = '\0'; if (*p == '\0' || *p == '#') continue; if ((word = strtok(buff, SEPARATORS)) == NULL) continue; /* Dispatch on the word to fill in the fields. */ if (EQ(word, "allowto") || EQ(word, "gooddstaddresses")) rp->AllowCount += parseaddresslist(path, rp->AllowTo); else if (EQ(word, "disallowfrom") || EQ(word, "badsrcaddresses")) rp->DisallowCount += parseaddresslist(path, rp->DisallowFrom); else if (EQ(word, "protocols")) parseprotocols(path, rp->Protocols); else if (EQ(word, "inactivity")) { if (p = nexttok()) if (!positivenumber(p)) yyerror(accessp, "Bad number \"%s\"", p); else rp->Inactivity = atoi(p); } else if (EQ(word, "weekdays")) rp->Times[1] = rp->Times[2] = rp->Times[3] = rp->Times[4] = rp->Times[5] = parsetime(path); else if (EQ(word, "weekends")) rp->Times[0] = rp->Times[6] = parsetime(path); else if (EQ(word, "sun") || EQ(word, "sunday")) rp->Times[0] = parsetime(path); else if (EQ(word, "mon") || EQ(word, "monday")) rp->Times[1] = parsetime(path); else if (EQ(word, "tue") || EQ(word, "tuesday")) rp->Times[2] = parsetime(path); else if (EQ(word, "wed") || EQ(word, "wednesday")) rp->Times[3] = parsetime(path); else if (EQ(word, "thu") || EQ(word, "thursday")) rp->Times[4] = parsetime(path); else if (EQ(word, "fri") || EQ(word, "friday")) rp->Times[5] = parsetime(path); else if (EQ(word, "sat") || EQ(word, "saturday")) rp->Times[6] = parsetime(path); else yyerror(accessp, "Bad parameter \"%s\"", word); } (void)fclose(F); return errorcount == 0; } int readconfig(path) char *path; { FILE *F; char *p; char buff[BUFSIZ]; int i; /* Count the number of lines in the file. */ linenum = 0; if ((F = fopen(path, "r")) == NULL) { yyerror(path, "Can't open for reading, %m", (char *)NULL); return 0; } while (fgets(buff, sizeof buff, F)) if (buff[0] != '#') linenum++; rewind(F); /* Allocate space for the table. */ if (RemoteTable) free((char *)RemoteTable); RemoteTable = (REMOTE *)malloc((unsigned int)linenum * sizeof (REMOTE)); if (RemoteTable == NULL) { yyerror(path, "Can't allocate table, %m", (char *)NULL); return 0; } errorcount = 0; for (i = 1, RemoteCount = 0; fgets(buff, sizeof buff, F); i++) { if ((p = strchr(buff, '\n')) == NULL) { yyerror(path, "Line too long", (char *)NULL); (void)fclose(F); return 0; } *p = '\0'; if (buff[0] == '#' || buff[0] == '\0') continue; linenum = i; if (readentry(path, &RemoteTable[RemoteCount], buff)) RemoteCount++; } (void)fclose(F); return errorcount == 0; }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.