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.