summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTheo de Raadt <deraadt@cvs.openbsd.org>2007-10-13 16:35:23 +0000
committerTheo de Raadt <deraadt@cvs.openbsd.org>2007-10-13 16:35:23 +0000
commit3bc6f4c74e1cc60c05a1ab152805af447144952a (patch)
tree4a68ea922315ee6f6d1396cafc87ae97f4d0d06f
parent3270c1ab5c203bfd16890aaf55afd4c31904e523 (diff)
in all these programs using the same pfctl-derived parse.y, re-unify the
yylex implementation and the code which interacts with yylex. this also brings the future potential for include support to all of the parsers. in the future please do not silly modifications to one of these files without checking if you are de-unifying the code. checked by developers in all these areas.
-rw-r--r--bin/chio/parse.y148
-rw-r--r--sbin/ipsecctl/ipsecctl.c22
-rw-r--r--sbin/ipsecctl/ipsecctl.h4
-rw-r--r--sbin/ipsecctl/parse.y209
-rw-r--r--sbin/pfctl/parse.y287
-rw-r--r--sbin/pfctl/pfctl.c28
-rw-r--r--sbin/pfctl/pfctl_parser.h6
-rw-r--r--usr.sbin/bgpd/bgpd.h3
-rw-r--r--usr.sbin/bgpd/config.c25
-rw-r--r--usr.sbin/bgpd/parse.y184
-rw-r--r--usr.sbin/dvmrpd/dvmrpd.c27
-rw-r--r--usr.sbin/dvmrpd/parse.y217
-rw-r--r--usr.sbin/hostapd/parse.y190
-rw-r--r--usr.sbin/hoststated/parse.y208
-rw-r--r--usr.sbin/ifstated/parse.y200
-rw-r--r--usr.sbin/ntpd/parse.y149
-rw-r--r--usr.sbin/ospf6d/ospf6d.c26
-rw-r--r--usr.sbin/ospf6d/parse.y224
-rw-r--r--usr.sbin/ospfd/ospfd.c26
-rw-r--r--usr.sbin/ospfd/parse.y223
-rw-r--r--usr.sbin/relayd/parse.y208
-rw-r--r--usr.sbin/ripd/parse.y230
-rw-r--r--usr.sbin/ripd/ripd.c26
23 files changed, 1778 insertions, 1092 deletions
diff --git a/bin/chio/parse.y b/bin/chio/parse.y
index a3000e8e39d..2f5dc35c3d3 100644
--- a/bin/chio/parse.y
+++ b/bin/chio/parse.y
@@ -1,4 +1,4 @@
-/* $OpenBSD: parse.y,v 1.7 2007/10/11 14:39:15 deraadt Exp $ */
+/* $OpenBSD: parse.y,v 1.8 2007/10/13 16:35:16 deraadt Exp $ */
/*
* Copyright (c) 2006 Bob Beck <beck@openbsd.org>
@@ -33,6 +33,25 @@
#include <stdio.h>
#include <string.h>
+TAILQ_HEAD(files, file) files = TAILQ_HEAD_INITIALIZER(files);
+static struct file {
+ TAILQ_ENTRY(file) entry;
+ FILE *stream;
+ char *name;
+ int lineno;
+ int errors;
+} *file;
+struct file *pushfile(const char *);
+int popfile(void);
+int yyparse(void);
+int yylex(void);
+int yyerror(const char *, ...);
+int kw_cmp(const void *, const void *);
+int lookup(char *);
+int lgetc(int);
+int lungetc(int);
+int findeol(void);
+
struct changer {
TAILQ_ENTRY(changer) entry;
char *name;
@@ -42,20 +61,6 @@ struct changer {
TAILQ_HEAD(changers, changer) changers;
struct changer *curchanger;
-static FILE *fin = NULL;
-static int lineno = 1;
-static int errors = 0;
-const char *infile;
-
-int yyerror(const char *, ...);
-int yyparse(void);
-int kw_cmp(const void *, const void *);
-int lookup(char *);
-int lgetc(int);
-int lungetc(int);
-int findeol(void);
-int yylex(void);
-
typedef struct {
union {
int64_t number;
@@ -75,8 +80,8 @@ typedef struct {
grammar : /* empty */
| grammar '\n'
- | grammar changer '\n'
- | grammar error '\n' { errors++; }
+ | grammar main '\n'
+ | grammar error '\n' { file->errors++; }
;
optnl : '\n' optnl
@@ -86,7 +91,7 @@ optnl : '\n' optnl
nl : '\n' optnl
;
-changer : CHANGER STRING optnl '{' optnl {
+main : CHANGER STRING optnl '{' optnl {
curchanger = new_changer($2);
}
changeropts_l '}' {
@@ -132,9 +137,9 @@ yyerror(const char *fmt, ...)
va_list ap;
char *nfmt;
- errors = 1;
+ file->errors++;
va_start(ap, fmt);
- if (asprintf(&nfmt, "%s:%d: %s", infile, yylval.lineno, fmt) == -1)
+ if (asprintf(&nfmt, "%s:%d: %s", file->name, yylval.lineno, fmt) == -1)
err(1, "yyerror asprintf");
err(1, nfmt, ap);
va_end(ap);
@@ -175,10 +180,9 @@ char pushback_buffer[MAXPUSHBACK];
int pushback_index = 0;
int
-lgetc(int inquot)
+lgetc(int quotec)
{
- int c, next;
- FILE *f = fin;
+ int c, next;
if (parsebuf) {
/* Read character from the parsebuffer instead of input. */
@@ -194,29 +198,39 @@ lgetc(int inquot)
if (pushback_index)
return (pushback_buffer[--pushback_index]);
- if (inquot) {
- c = getc(f);
+ if (quotec) {
+ if ((c = getc(file->stream)) == EOF) {
+ yyerror("reached end of file while parsing quoted string");
+ if (popfile() == EOF)
+ return (EOF);
+ return (quotec);
+ }
return (c);
}
- while ((c = getc(f)) == '\\') {
- next = getc(f);
+ while ((c = getc(file->stream)) == '\\') {
+ next = getc(file->stream);
if (next != '\n') {
c = next;
break;
}
- yylval.lineno = lineno;
- lineno++;
+ yylval.lineno = file->lineno;
+ file->lineno++;
}
if (c == '\t' || c == ' ') {
/* Compress blanks to a single space. */
do {
- c = getc(f);
+ c = getc(file->stream);
} while (c == '\t' || c == ' ');
- ungetc(c, f);
+ ungetc(c, file->stream);
c = ' ';
}
+ while (c == EOF) {
+ if (popfile() == EOF)
+ return (EOF);
+ c = getc(file->stream);
+ }
return (c);
}
@@ -248,7 +262,7 @@ findeol(void)
while (1) {
c = lgetc(0);
if (c == '\n') {
- lineno++;
+ file->lineno++;
break;
}
if (c == EOF)
@@ -262,14 +276,14 @@ yylex(void)
{
char buf[8096];
char *p;
- int endc, next, c;
+ int quotec, next, c;
int token;
p = buf;
while ((c = lgetc(0)) == ' ')
; /* nothing */
- yylval.lineno = lineno;
+ yylval.lineno = file->lineno;
if (c == '#')
while ((c = lgetc(0)) != '\n' && c != EOF)
; /* nothing */
@@ -277,21 +291,21 @@ yylex(void)
switch (c) {
case '\'':
case '"':
- endc = c;
+ quotec = c;
while (1) {
- if ((c = lgetc(1)) == EOF)
+ if ((c = lgetc(quotec)) == EOF)
return (0);
if (c == '\n') {
- lineno++;
+ file->lineno++;
continue;
} else if (c == '\\') {
- if ((next = lgetc(1)) == EOF)
+ if ((next = lgetc(quotec)) == EOF)
return (0);
- if (next == endc)
+ if (next == quotec)
c = next;
else
lungetc(next);
- } else if (c == endc) {
+ } else if (c == quotec) {
*p = '\0';
break;
}
@@ -365,32 +379,66 @@ nodigits:
return (token);
}
if (c == '\n') {
- yylval.lineno = lineno;
- lineno++;
+ yylval.lineno = file->lineno;
+ file->lineno++;
}
if (c == EOF)
return (0);
return (c);
}
+struct file *
+pushfile(const char *name)
+{
+ struct file *nfile;
+
+ if ((nfile = calloc(1, sizeof(struct file))) == NULL ||
+ (nfile->name = strdup(name)) == NULL)
+ return (NULL);
+ if ((nfile->stream = fopen(nfile->name, "r")) == NULL) {
+ free(nfile->name);
+ free(nfile);
+ return (NULL);
+ }
+ nfile->lineno = 1;
+ TAILQ_INSERT_TAIL(&files, nfile, entry);
+ return (nfile);
+}
+
+int
+popfile(void)
+{
+ struct file *prev;
+
+ if ((prev = TAILQ_PREV(file, files, entry)) != NULL) {
+ prev->errors += file->errors;
+ TAILQ_REMOVE(&files, file, entry);
+ fclose(file->stream);
+ free(file->name);
+ free(file);
+ file = prev;
+ return (0);
+ }
+ return (EOF);
+}
+
char *
parse_tapedev(const char *filename, const char *changer, int drive)
{
struct changer *p;
- char *tapedev = NULL;
+ char *tapedev = NULL;
+ int errors = 0;
- lineno = 1;
- errors = 0;
TAILQ_INIT(&changers);
- if ((fin = fopen(filename, "r")) == NULL)
+ if ((file = pushfile(filename)) == NULL) {
+ warnx("cannot open the main config file!");
goto guess;
-
- infile = filename;
+ }
yyparse();
-
- fclose(fin);
+ errors = file->errors;
+ popfile();
TAILQ_FOREACH(p, &changers, entry) {
if (strcmp(basename(changer), p->name) == 0) {
diff --git a/sbin/ipsecctl/ipsecctl.c b/sbin/ipsecctl/ipsecctl.c
index b92efd126dd..33b04468e45 100644
--- a/sbin/ipsecctl/ipsecctl.c
+++ b/sbin/ipsecctl/ipsecctl.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ipsecctl.c,v 1.68 2007/08/21 18:44:52 hshoexer Exp $ */
+/* $OpenBSD: ipsecctl.c,v 1.69 2007/10/13 16:35:18 deraadt Exp $ */
/*
* Copyright (c) 2004, 2005 Hans-Joerg Hoexer <hshoexer@openbsd.org>
*
@@ -62,7 +62,6 @@ const char *ipsecctl_lookup_option(char *, const char **);
static int unmask(struct ipsec_addr *, sa_family_t);
int sacompare(const void *, const void *);
-const char *infile; /* Used by parse.y */
const char *showopt;
int first_title = 1;
@@ -98,7 +97,6 @@ sacompare(const void *va, const void *vb)
int
ipsecctl_rules(char *filename, int opts)
{
- FILE *fin;
struct ipsecctl ipsec;
int action, error = 0;
@@ -107,18 +105,7 @@ ipsecctl_rules(char *filename, int opts)
TAILQ_INIT(&ipsec.rule_queue);
TAILQ_INIT(&ipsec.group_queue);
- if (strcmp(filename, "-") == 0) {
- fin = stdin;
- infile = "stdin";
- } else {
- if ((fin = ipsecctl_fopen(filename, "r")) == NULL) {
- warn("%s", filename);
- return (1);
- }
- infile = filename;
- }
-
- if (parse_rules(fin, &ipsec) < 0) {
+ if (parse_rules(filename, &ipsec) < 0) {
warnx("Syntax error in config file: ipsec rules not loaded");
error = 1;
} else {
@@ -130,11 +117,6 @@ ipsecctl_rules(char *filename, int opts)
if ((opts & IPSECCTL_OPT_NOACTION) == 0)
error = ipsecctl_commit(action, &ipsec);
}
-
- if (fin != stdin) {
- fclose(fin);
- fin = NULL;
- }
return (error);
}
diff --git a/sbin/ipsecctl/ipsecctl.h b/sbin/ipsecctl/ipsecctl.h
index 50a19a1ae70..60a9348a0db 100644
--- a/sbin/ipsecctl/ipsecctl.h
+++ b/sbin/ipsecctl/ipsecctl.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ipsecctl.h,v 1.54 2007/03/16 20:51:01 markus Exp $ */
+/* $OpenBSD: ipsecctl.h,v 1.55 2007/10/13 16:35:18 deraadt Exp $ */
/*
* Copyright (c) 2004, 2005 Hans-Joerg Hoexer <hshoexer@openbsd.org>
*
@@ -219,7 +219,7 @@ struct ipsecctl {
struct ipsec_group_queue group_queue;
};
-int parse_rules(FILE *, struct ipsecctl *);
+int parse_rules(const char *, struct ipsecctl *);
int cmdline_symset(char *);
int ipsecctl_add_rule(struct ipsecctl *, struct ipsec_rule *);
void ipsecctl_free_rule(struct ipsec_rule *);
diff --git a/sbin/ipsecctl/parse.y b/sbin/ipsecctl/parse.y
index ccfe17cb2b2..0bfd11e8612 100644
--- a/sbin/ipsecctl/parse.y
+++ b/sbin/ipsecctl/parse.y
@@ -1,4 +1,4 @@
-/* $OpenBSD: parse.y,v 1.127 2007/10/11 14:39:16 deraadt Exp $ */
+/* $OpenBSD: parse.y,v 1.128 2007/10/13 16:35:18 deraadt Exp $ */
/*
* Copyright (c) 2002, 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -47,12 +47,41 @@
#include "ipsecctl.h"
+TAILQ_HEAD(files, file) files = TAILQ_HEAD_INITIALIZER(files);
+static struct file {
+ TAILQ_ENTRY(file) entry;
+ FILE *stream;
+ char *name;
+ int lineno;
+ int errors;
+} *file;
+struct file *pushfile(const char *, int);
+int popfile(void);
+int check_file_secrecy(int, const char *);
+int yyparse(void);
+int yylex(void);
+int yyerror(const char *, ...);
+int kw_cmp(const void *, const void *);
+int lookup(char *);
+int lgetc(int);
+int lungetc(int);
+int findeol(void);
+
+TAILQ_HEAD(symhead, sym) symhead = TAILQ_HEAD_INITIALIZER(symhead);
+struct sym {
+ TAILQ_ENTRY(sym) entry;
+ int used;
+ int persist;
+ char *nam;
+ char *val;
+};
+int symset(const char *, const char *, int);
+char *symget(const char *);
+int cmdline_symset(char *);
+
#define KEYSIZE_LIMIT 1024
static struct ipsecctl *ipsec = NULL;
-static FILE *fin = NULL;
-static int lineno = 1;
-static int errors = 0;
static int debug = 0;
const struct ipsec_xf authxfs[] = {
@@ -110,27 +139,6 @@ const struct ipsec_xf groupxfs[] = {
{ NULL, 0, 0, 0 },
};
-int yyerror(const char *, ...);
-int yyparse(void);
-int kw_cmp(const void *, const void *);
-int lookup(char *);
-int lgetc(int);
-int lungetc(int);
-int findeol(void);
-int yylex(void);
-
-TAILQ_HEAD(symhead, sym) symhead = TAILQ_HEAD_INITIALIZER(symhead);
-struct sym {
- TAILQ_ENTRY(sym) entries;
- int used;
- int persist;
- char *nam;
- char *val;
-};
-
-int symset(const char *, const char *, int);
-int cmdline_symset(char *);
-char *symget(const char *);
int atoul(char *, u_long *);
int atospi(char *, u_int32_t *);
u_int8_t x2i(unsigned char *);
@@ -271,7 +279,7 @@ grammar : /* empty */
| grammar sarule '\n'
| grammar tcpmd5rule '\n'
| grammar varset '\n'
- | grammar error '\n' { errors++; }
+ | grammar error '\n' { file->errors++; }
;
comma : ','
@@ -823,11 +831,10 @@ int
yyerror(const char *fmt, ...)
{
va_list ap;
- extern const char *infile;
- errors = 1;
+ file->errors++;
va_start(ap, fmt);
- fprintf(stderr, "%s: %d: ", infile, yylval.lineno);
+ fprintf(stderr, "%s: %d: ", file->name, yylval.lineno);
vfprintf(stderr, fmt, ap);
fprintf(stderr, "\n");
va_end(ap);
@@ -915,10 +922,9 @@ char pushback_buffer[MAXPUSHBACK];
int pushback_index = 0;
int
-lgetc(int inquot)
+lgetc(int quotec)
{
- int c, next;
- FILE *f = fin;
+ int c, next;
if (parsebuf) {
/* Read character from the parsebuffer instead of input. */
@@ -934,29 +940,39 @@ lgetc(int inquot)
if (pushback_index)
return (pushback_buffer[--pushback_index]);
- if (inquot) {
- c = getc(f);
+ if (quotec) {
+ if ((c = getc(file->stream)) == EOF) {
+ yyerror("reached end of file while parsing quoted string");
+ if (popfile() == EOF)
+ return (EOF);
+ return (quotec);
+ }
return (c);
}
- while ((c = getc(f)) == '\\') {
- next = getc(f);
+ while ((c = getc(file->stream)) == '\\') {
+ next = getc(file->stream);
if (next != '\n') {
c = next;
break;
}
- yylval.lineno = lineno;
- lineno++;
+ yylval.lineno = file->lineno;
+ file->lineno++;
}
if (c == '\t' || c == ' ') {
/* Compress blanks to a single space. */
do {
- c = getc(f);
+ c = getc(file->stream);
} while (c == '\t' || c == ' ');
- ungetc(c, f);
+ ungetc(c, file->stream);
c = ' ';
}
+ while (c == EOF) {
+ if (popfile() == EOF)
+ return (EOF);
+ c = getc(file->stream);
+ }
return (c);
}
@@ -988,7 +1004,7 @@ findeol(void)
while (1) {
c = lgetc(0);
if (c == '\n') {
- lineno++;
+ file->lineno++;
break;
}
if (c == EOF)
@@ -1002,7 +1018,7 @@ yylex(void)
{
char buf[8096];
char *p, *val;
- int endc, next, c;
+ int quotec, next, c;
int token;
top:
@@ -1010,7 +1026,7 @@ top:
while ((c = lgetc(0)) == ' ')
; /* nothing */
- yylval.lineno = lineno;
+ yylval.lineno = file->lineno;
if (c == '#')
while ((c = lgetc(0)) != '\n' && c != EOF)
; /* nothing */
@@ -1044,21 +1060,21 @@ top:
switch (c) {
case '\'':
case '"':
- endc = c;
+ quotec = c;
while (1) {
- if ((c = lgetc(1)) == EOF)
+ if ((c = lgetc(quotec)) == EOF)
return (0);
if (c == '\n') {
- lineno++;
+ file->lineno++;
continue;
} else if (c == '\\') {
- if ((next = lgetc(1)) == EOF)
+ if ((next = lgetc(quotec)) == EOF)
return (0);
- if (next == endc)
+ if (next == quotec)
c = next;
else
lungetc(next);
- } else if (c == endc) {
+ } else if (c == quotec) {
*p = '\0';
break;
}
@@ -1132,8 +1148,8 @@ nodigits:
return (token);
}
if (c == '\n') {
- yylval.lineno = lineno;
- lineno++;
+ yylval.lineno = file->lineno;
+ file->lineno++;
}
if (c == EOF)
return (0);
@@ -1141,25 +1157,98 @@ nodigits:
}
int
-parse_rules(FILE *input, struct ipsecctl *ipsecx)
+check_file_secrecy(int fd, const char *fname)
+{
+ struct stat st;
+
+ if (fstat(fd, &st)) {
+ warn("cannot stat %s", fname);
+ return (-1);
+ }
+ if (st.st_uid != 0 && st.st_uid != getuid()) {
+ warnx("%s: owner not root or current user", fname);
+ return (-1);
+ }
+ if (st.st_mode & (S_IRWXG | S_IRWXO)) {
+ warnx("%s: group/world readable/writeable", fname);
+ return (-1);
+ }
+ return (0);
+}
+
+struct file *
+pushfile(const char *name, int secret)
+{
+ struct file *nfile;
+
+ if ((nfile = calloc(1, sizeof(struct file))) == NULL ||
+ (nfile->name = strdup(name)) == NULL)
+ return (NULL);
+ if (TAILQ_FIRST(&files) == NULL && strcmp(nfile->name, "-") == 0) {
+ nfile->stream = stdin;
+ free(nfile->name);
+ if ((nfile->name = strdup("stdin")) == NULL) {
+ free(nfile);
+ return (NULL);
+ }
+ } else if ((nfile->stream = fopen(nfile->name, "r")) == NULL) {
+ free(nfile->name);
+ free(nfile);
+ return (NULL);
+ } else if (secret &&
+ check_file_secrecy(fileno(nfile->stream), nfile->name)) {
+ fclose(nfile->stream);
+ free(nfile->name);
+ free(nfile);
+ return (NULL);
+ }
+ nfile->lineno = 1;
+ TAILQ_INSERT_TAIL(&files, nfile, entry);
+ return (nfile);
+}
+
+int
+popfile(void)
+{
+ struct file *prev;
+
+ if ((prev = TAILQ_PREV(file, files, entry)) != NULL) {
+ prev->errors += file->errors;
+ TAILQ_REMOVE(&files, file, entry);
+ fclose(file->stream);
+ free(file->name);
+ free(file);
+ file = prev;
+ return (0);
+ }
+ return (EOF);
+}
+
+int
+parse_rules(const char *filename, struct ipsecctl *ipsecx)
{
struct sym *sym;
+ int errors = 0;
ipsec = ipsecx;
- fin = input;
- lineno = 1;
- errors = 0;
+
+ if ((file = pushfile(filename, 1)) == NULL) {
+ warn("cannot open the main config file!");
+ return (-1);
+ }
yyparse();
+ errors = file->errors;
+ popfile();
/* Free macros and check which have not been used. */
while ((sym = TAILQ_FIRST(&symhead))) {
if ((ipsec->opts & IPSECCTL_OPT_VERBOSE2) && !sym->used)
fprintf(stderr, "warning: macro '%s' not "
"used\n", sym->nam);
- TAILQ_REMOVE(&symhead, sym, entries);
free(sym->nam);
free(sym->val);
+ TAILQ_REMOVE(&symhead, sym, entry);
free(sym);
}
@@ -1172,16 +1261,16 @@ symset(const char *nam, const char *val, int persist)
struct sym *sym;
for (sym = TAILQ_FIRST(&symhead); sym && strcmp(nam, sym->nam);
- sym = TAILQ_NEXT(sym, entries))
+ sym = TAILQ_NEXT(sym, entry))
; /* nothing */
if (sym != NULL) {
if (sym->persist == 1)
return (0);
else {
- TAILQ_REMOVE(&symhead, sym, entries);
free(sym->nam);
free(sym->val);
+ TAILQ_REMOVE(&symhead, sym, entry);
free(sym);
}
}
@@ -1201,7 +1290,7 @@ symset(const char *nam, const char *val, int persist)
}
sym->used = 0;
sym->persist = persist;
- TAILQ_INSERT_TAIL(&symhead, sym, entries);
+ TAILQ_INSERT_TAIL(&symhead, sym, entry);
return (0);
}
@@ -1232,7 +1321,7 @@ symget(const char *nam)
{
struct sym *sym;
- TAILQ_FOREACH(sym, &symhead, entries)
+ TAILQ_FOREACH(sym, &symhead, entry)
if (strcmp(nam, sym->nam) == 0) {
sym->used = 1;
return (sym->val);
diff --git a/sbin/pfctl/parse.y b/sbin/pfctl/parse.y
index d00a59f38a2..652f83aba93 100644
--- a/sbin/pfctl/parse.y
+++ b/sbin/pfctl/parse.y
@@ -1,4 +1,4 @@
-/* $OpenBSD: parse.y,v 1.526 2007/10/11 14:39:16 deraadt Exp $ */
+/* $OpenBSD: parse.y,v 1.527 2007/10/13 16:35:18 deraadt Exp $ */
/*
* Copyright (c) 2001 Markus Friedl. All rights reserved.
@@ -29,6 +29,7 @@
%{
#include <sys/types.h>
#include <sys/socket.h>
+#include <sys/stat.h>
#include <net/if.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
@@ -43,6 +44,7 @@
#include <altq/altq_hfsc.h>
#include <stdio.h>
+#include <unistd.h>
#include <stdlib.h>
#include <netdb.h>
#include <stdarg.h>
@@ -60,10 +62,7 @@
#include "pfctl.h"
static struct pfctl *pf = NULL;
-static FILE *fin = NULL;
static int debug = 0;
-static int lineno = 1;
-static int errors = 0;
static int rulestate = 0;
static u_int16_t returnicmpdefault =
(ICMP_UNREACH << 8) | ICMP_UNREACH_PORT;
@@ -73,6 +72,39 @@ static int blockpolicy = PFRULE_DROP;
static int require_order = 1;
static int default_statelock;
+TAILQ_HEAD(files, file) files = TAILQ_HEAD_INITIALIZER(files);
+static struct file {
+ TAILQ_ENTRY(file) entry;
+ FILE *stream;
+ char *name;
+ int lineno;
+ int errors;
+} *file;
+struct file *pushfile(const char *, int);
+int popfile(void);
+int check_file_secrecy(int, const char *);
+int yyparse(void);
+int yylex(void);
+int yyerror(const char *, ...);
+int kw_cmp(const void *, const void *);
+int lookup(char *);
+int lgetc(int);
+int lungetc(int);
+int findeol(void);
+
+TAILQ_HEAD(symhead, sym) symhead = TAILQ_HEAD_INITIALIZER(symhead);
+struct sym {
+ TAILQ_ENTRY(sym) entry;
+ int used;
+ int persist;
+ char *nam;
+ char *val;
+};
+int symset(const char *, const char *, int);
+char *symget(const char *);
+
+int atoul(char *, u_long *);
+
enum {
PFCTL_STATE_NONE,
PFCTL_STATE_OPTION,
@@ -255,61 +287,42 @@ struct pool_opts {
struct node_hfsc_opts hfsc_opts;
-int yyerror(const char *, ...);
-int disallow_table(struct node_host *, const char *);
-int disallow_urpf_failed(struct node_host *, const char *);
-int disallow_alias(struct node_host *, const char *);
-int rule_consistent(struct pf_rule *, int);
-int filter_consistent(struct pf_rule *, int);
-int nat_consistent(struct pf_rule *);
-int rdr_consistent(struct pf_rule *);
-int process_tabledef(char *, struct table_opts *);
-int yyparse(void);
-void expand_label_str(char *, size_t, const char *, const char *);
-void expand_label_if(const char *, char *, size_t, const char *);
-void expand_label_addr(const char *, char *, size_t, u_int8_t,
- struct node_host *);
-void expand_label_port(const char *, char *, size_t, struct node_port *);
-void expand_label_proto(const char *, char *, size_t, u_int8_t);
-void expand_label_nr(const char *, char *, size_t);
-void expand_label(char *, size_t, const char *, u_int8_t, struct node_host *,
- struct node_port *, struct node_host *, struct node_port *,
- u_int8_t);
-void expand_rule(struct pf_rule *, struct node_if *, struct node_host *,
- struct node_proto *, struct node_os*, struct node_host *,
- struct node_port *, struct node_host *, struct node_port *,
- struct node_uid *, struct node_gid *, struct node_icmp *,
- const char *);
-int expand_altq(struct pf_altq *, struct node_if *, struct node_queue *,
- struct node_queue_bw bwspec, struct node_queue_opt *);
-int expand_queue(struct pf_altq *, struct node_if *, struct node_queue *,
- struct node_queue_bw, struct node_queue_opt *);
-int expand_skip_interface(struct node_if *);
+int disallow_table(struct node_host *, const char *);
+int disallow_urpf_failed(struct node_host *, const char *);
+int disallow_alias(struct node_host *, const char *);
+int rule_consistent(struct pf_rule *, int);
+int filter_consistent(struct pf_rule *, int);
+int nat_consistent(struct pf_rule *);
+int rdr_consistent(struct pf_rule *);
+int process_tabledef(char *, struct table_opts *);
+void expand_label_str(char *, size_t, const char *, const char *);
+void expand_label_if(const char *, char *, size_t, const char *);
+void expand_label_addr(const char *, char *, size_t, u_int8_t,
+ struct node_host *);
+void expand_label_port(const char *, char *, size_t,
+ struct node_port *);
+void expand_label_proto(const char *, char *, size_t, u_int8_t);
+void expand_label_nr(const char *, char *, size_t);
+void expand_label(char *, size_t, const char *, u_int8_t,
+ struct node_host *, struct node_port *, struct node_host *,
+ struct node_port *, u_int8_t);
+void expand_rule(struct pf_rule *, struct node_if *,
+ struct node_host *, struct node_proto *, struct node_os *,
+ struct node_host *, struct node_port *, struct node_host *,
+ struct node_port *, struct node_uid *, struct node_gid *,
+ struct node_icmp *, const char *);
+int expand_altq(struct pf_altq *, struct node_if *,
+ struct node_queue *, struct node_queue_bw bwspec,
+ struct node_queue_opt *);
+int expand_queue(struct pf_altq *, struct node_if *,
+ struct node_queue *, struct node_queue_bw,
+ struct node_queue_opt *);
+int expand_skip_interface(struct node_if *);
int check_rulestate(int);
-int kw_cmp(const void *, const void *);
-int lookup(char *);
-int lgetc(int);
-int lungetc(int);
-int findeol(void);
-int yylex(void);
-int atoul(char *, u_long *);
int getservice(char *);
int rule_label(struct pf_rule *, char *);
-TAILQ_HEAD(symhead, sym) symhead = TAILQ_HEAD_INITIALIZER(symhead);
-struct sym {
- TAILQ_ENTRY(sym) entries;
- int used;
- int persist;
- char *nam;
- char *val;
-};
-
-
-int symset(const char *, const char *, int);
-char *symget(const char *);
-
void mv_rules(struct pf_ruleset *, struct pf_ruleset *);
void decide_address_family(struct node_host *, sa_family_t *);
void remove_invalid_hosts(struct node_host **, sa_family_t *);
@@ -484,7 +497,7 @@ ruleset : /* empty */
| ruleset antispoof '\n'
| ruleset tabledef '\n'
| '{' fakeanchor '}' '\n';
- | ruleset error '\n' { errors++; }
+ | ruleset error '\n' { file->errors++; }
;
/*
@@ -4113,11 +4126,10 @@ int
yyerror(const char *fmt, ...)
{
va_list ap;
- extern char *infile;
- errors = 1;
+ file->errors++;
va_start(ap, fmt);
- fprintf(stderr, "%s:%d: ", infile, yylval.lineno);
+ fprintf(stderr, "%s:%d: ", file->name, yylval.lineno);
vfprintf(stderr, fmt, ap);
fprintf(stderr, "\n");
va_end(ap);
@@ -5149,10 +5161,9 @@ char pushback_buffer[MAXPUSHBACK];
int pushback_index = 0;
int
-lgetc(int inquot)
+lgetc(int quotec)
{
- int c, next;
- FILE *f = fin;
+ int c, next;
if (parsebuf) {
/* Read character from the parsebuffer instead of input. */
@@ -5168,29 +5179,39 @@ lgetc(int inquot)
if (pushback_index)
return (pushback_buffer[--pushback_index]);
- if (inquot) {
- c = getc(f);
+ if (quotec) {
+ if ((c = getc(file->stream)) == EOF) {
+ yyerror("reached end of file while parsing quoted string");
+ if (popfile() == EOF)
+ return (EOF);
+ return (quotec);
+ }
return (c);
}
- while ((c = getc(f)) == '\\') {
- next = getc(f);
+ while ((c = getc(file->stream)) == '\\') {
+ next = getc(file->stream);
if (next != '\n') {
c = next;
break;
}
- yylval.lineno = lineno;
- lineno++;
+ yylval.lineno = file->lineno;
+ file->lineno++;
}
if (c == '\t' || c == ' ') {
/* Compress blanks to a single space. */
do {
- c = getc(f);
+ c = getc(file->stream);
} while (c == '\t' || c == ' ');
- ungetc(c, f);
+ ungetc(c, file->stream);
c = ' ';
}
+ while (c == EOF) {
+ if (popfile() == EOF)
+ return (EOF);
+ c = getc(file->stream);
+ }
return (c);
}
@@ -5222,7 +5243,7 @@ findeol(void)
while (1) {
c = lgetc(0);
if (c == '\n') {
- lineno++;
+ file->lineno++;
break;
}
if (c == EOF)
@@ -5236,7 +5257,7 @@ yylex(void)
{
char buf[8096];
char *p, *val;
- int endc, next, c;
+ int quotec, next, c;
int token;
top:
@@ -5244,7 +5265,7 @@ top:
while ((c = lgetc(0)) == ' ')
; /* nothing */
- yylval.lineno = lineno;
+ yylval.lineno = file->lineno;
if (c == '#')
while ((c = lgetc(0)) != '\n' && c != EOF)
; /* nothing */
@@ -5278,21 +5299,21 @@ top:
switch (c) {
case '\'':
case '"':
- endc = c;
+ quotec = c;
while (1) {
- if ((c = lgetc(1)) == EOF)
+ if ((c = lgetc(quotec)) == EOF)
return (0);
if (c == '\n') {
- lineno++;
+ file->lineno++;
continue;
} else if (c == '\\') {
- if ((next = lgetc(1)) == EOF)
+ if ((next = lgetc(quotec)) == EOF)
return (0);
- if (next == endc)
+ if (next == quotec)
c = next;
else
lungetc(next);
- } else if (c == endc) {
+ } else if (c == quotec) {
*p = '\0';
break;
}
@@ -5388,8 +5409,8 @@ nodigits:
return (token);
}
if (c == '\n') {
- yylval.lineno = lineno;
- lineno++;
+ yylval.lineno = file->lineno;
+ file->lineno++;
}
if (c == EOF)
return (0);
@@ -5397,13 +5418,80 @@ nodigits:
}
int
-parse_rules(FILE *input, struct pfctl *xpf)
+check_file_secrecy(int fd, const char *fname)
+{
+ struct stat st;
+
+ if (fstat(fd, &st)) {
+ warn("cannot stat %s", fname);
+ return (-1);
+ }
+ if (st.st_uid != 0 && st.st_uid != getuid()) {
+ warnx("%s: owner not root or current user", fname);
+ return (-1);
+ }
+ if (st.st_mode & (S_IRWXG | S_IRWXO)) {
+ warnx("%s: group/world readable/writeable", fname);
+ return (-1);
+ }
+ return (0);
+}
+
+struct file *
+pushfile(const char *name, int secret)
+{
+ struct file *nfile;
+
+ if ((nfile = calloc(1, sizeof(struct file))) == NULL ||
+ (nfile->name = strdup(name)) == NULL)
+ return (NULL);
+ if (TAILQ_FIRST(&files) == NULL && strcmp(nfile->name, "-") == 0) {
+ nfile->stream = stdin;
+ free(nfile->name);
+ if ((nfile->name = strdup("stdin")) == NULL) {
+ free(nfile);
+ return (NULL);
+ }
+ } else if ((nfile->stream = fopen(nfile->name, "r")) == NULL) {
+ free(nfile->name);
+ free(nfile);
+ return (NULL);
+ } else if (secret &&
+ check_file_secrecy(fileno(nfile->stream), nfile->name)) {
+ fclose(nfile->stream);
+ free(nfile->name);
+ free(nfile);
+ return (NULL);
+ }
+ nfile->lineno = 1;
+ TAILQ_INSERT_TAIL(&files, nfile, entry);
+ return (nfile);
+}
+
+int
+popfile(void)
+{
+ struct file *prev;
+
+ if ((prev = TAILQ_PREV(file, files, entry)) != NULL) {
+ prev->errors += file->errors;
+ TAILQ_REMOVE(&files, file, entry);
+ fclose(file->stream);
+ free(file->name);
+ free(file);
+ file = prev;
+ return (0);
+ }
+ return (EOF);
+}
+
+int
+parse_config(char *filename, struct pfctl *xpf)
{
- struct sym *sym, *next;
+ int errors = 0;
+ struct sym *sym;
- fin = input;
pf = xpf;
- lineno = 1;
errors = 0;
rulestate = PFCTL_STATE_NONE;
returnicmpdefault = (ICMP_UNREACH << 8) | ICMP_UNREACH_PORT;
@@ -5412,34 +5500,36 @@ parse_rules(FILE *input, struct pfctl *xpf)
blockpolicy = PFRULE_DROP;
require_order = 1;
+ if ((file = pushfile(filename, 1)) == NULL) {
+ warn("cannot open the main config file!");
+ return (-1);
+ }
+
yyparse();
+ errors = file->errors;
+ popfile();
/* Free macros and check which have not been used. */
- for (sym = TAILQ_FIRST(&symhead); sym != NULL; sym = next) {
- next = TAILQ_NEXT(sym, entries);
+ while ((sym = TAILQ_FIRST(&symhead))) {
if ((pf->opts & PF_OPT_VERBOSE2) && !sym->used)
fprintf(stderr, "warning: macro '%s' not "
"used\n", sym->nam);
free(sym->nam);
free(sym->val);
- TAILQ_REMOVE(&symhead, sym, entries);
+ TAILQ_REMOVE(&symhead, sym, entry);
free(sym);
}
return (errors ? -1 : 0);
}
-/*
- * Over-designed efficiency is a French and German concept, so how about
- * we wait until they discover this ugliness and make it all fancy.
- */
int
symset(const char *nam, const char *val, int persist)
{
struct sym *sym;
for (sym = TAILQ_FIRST(&symhead); sym && strcmp(nam, sym->nam);
- sym = TAILQ_NEXT(sym, entries))
+ sym = TAILQ_NEXT(sym, entry))
; /* nothing */
if (sym != NULL) {
@@ -5448,7 +5538,7 @@ symset(const char *nam, const char *val, int persist)
else {
free(sym->nam);
free(sym->val);
- TAILQ_REMOVE(&symhead, sym, entries);
+ TAILQ_REMOVE(&symhead, sym, entry);
free(sym);
}
}
@@ -5468,7 +5558,7 @@ symset(const char *nam, const char *val, int persist)
}
sym->used = 0;
sym->persist = persist;
- TAILQ_INSERT_TAIL(&symhead, sym, entries);
+ TAILQ_INSERT_TAIL(&symhead, sym, entry);
return (0);
}
@@ -5497,7 +5587,7 @@ symget(const char *nam)
{
struct sym *sym;
- TAILQ_FOREACH(sym, &symhead, entries)
+ TAILQ_FOREACH(sym, &symhead, entry)
if (strcmp(nam, sym->nam) == 0) {
sym->used = 1;
return (sym->val);
@@ -5683,17 +5773,12 @@ int
pfctl_load_anchors(int dev, struct pfctl *pf, struct pfr_buffer *trans)
{
struct loadanchors *la;
- FILE *fin;
TAILQ_FOREACH(la, &loadanchorshead, entries) {
if (pf->opts & PF_OPT_VERBOSE)
fprintf(stderr, "\nLoading anchor %s from %s\n",
la->anchorname, la->filename);
- if ((fin = pfctl_fopen(la->filename, "r")) == NULL) {
- warn("%s", la->filename);
- continue;
- }
- if (pfctl_rules(dev, la->filename, fin, pf->opts, pf->optimize,
+ if (pfctl_rules(dev, la->filename, pf->opts, pf->optimize,
la->anchorname, trans) == -1)
return (-1);
}
diff --git a/sbin/pfctl/pfctl.c b/sbin/pfctl/pfctl.c
index 0aeb0fc7807..5b53c67929e 100644
--- a/sbin/pfctl/pfctl.c
+++ b/sbin/pfctl/pfctl.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pfctl.c,v 1.268 2007/06/30 18:25:08 henning Exp $ */
+/* $OpenBSD: pfctl.c,v 1.269 2007/10/13 16:35:18 deraadt Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@@ -119,8 +119,6 @@ int dev = -1;
int first_title = 1;
int labels = 0;
-const char *infile;
-
#define INDENT(d, o) do { \
if (o) { \
int i; \
@@ -1337,7 +1335,7 @@ pfctl_add_altq(struct pfctl *pf, struct pf_altq *a)
}
int
-pfctl_rules(int dev, char *filename, FILE *fin, int opts, int optimize,
+pfctl_rules(int dev, char *filename, int opts, int optimize,
char *anchorname, struct pfr_buffer *trans)
{
#define ERR(x) do { warn(x); goto _error; } while(0)
@@ -1373,7 +1371,6 @@ pfctl_rules(int dev, char *filename, FILE *fin, int opts, int optimize,
if (strlcpy(trs.pfrt_anchor, anchorname,
sizeof(trs.pfrt_anchor)) >= sizeof(trs.pfrt_anchor))
ERRX("pfctl_rules: strlcpy");
- infile = filename;
pf.dev = dev;
pf.opts = opts;
pf.optimize = optimize;
@@ -1417,7 +1414,7 @@ pfctl_rules(int dev, char *filename, FILE *fin, int opts, int optimize,
pfctl_get_ticket(t, PF_RULESET_TABLE, anchorname);
}
- if (parse_rules(fin, &pf) < 0) {
+ if (parse_config(filename, &pf) < 0) {
if ((opts & PF_OPT_NOACTION) == 0)
ERRX("Syntax error in config file: "
"pf rules not loaded");
@@ -1443,11 +1440,6 @@ pfctl_rules(int dev, char *filename, FILE *fin, int opts, int optimize,
if (check_commit_altq(dev, opts) != 0)
ERRX("errors in altq config");
- if (fin != stdin) {
- fclose(fin);
- fin = NULL;
- }
-
/* process "load anchor" directives */
if (!anchorname[0])
if (pfctl_load_anchors(dev, &pf, t) == -1)
@@ -1469,8 +1461,6 @@ _error:
err(1, "DIOCXROLLBACK");
exit(1);
} else { /* sub ruleset */
- if (fin != NULL && fin != stdin)
- fclose(fin);
return (-1);
}
@@ -1957,7 +1947,6 @@ main(int argc, char *argv[])
int optimize = PF_OPTIMIZE_BASIC;
char anchorname[MAXPATHLEN];
char *path;
- FILE *fin = NULL;
if (argc < 2)
usage();
@@ -2292,15 +2281,6 @@ main(int argc, char *argv[])
}
}
- if (rulesopt != NULL) {
- if (strcmp(rulesopt, "-") == 0) {
- fin = stdin;
- rulesopt = "stdin";
- } else {
- if ((fin = pfctl_fopen(rulesopt, "r")) == NULL)
- err(1, "%s", rulesopt);
- }
- }
if ((rulesopt != NULL) && (loadopt & PFCTL_FLAG_OPTION) &&
!anchorname[0])
if (pfctl_clear_interface_flags(dev, opts | PF_OPT_QUIET))
@@ -2315,7 +2295,7 @@ main(int argc, char *argv[])
if (anchorname[0] == '_' || strstr(anchorname, "/_") != NULL)
errx(1, "anchor names beginning with '_' cannot "
"be modified from the command line");
- if (pfctl_rules(dev, rulesopt, fin, opts, optimize,
+ if (pfctl_rules(dev, rulesopt, opts, optimize,
anchorname, NULL))
error = 1;
else if (!(opts & PF_OPT_NOACTION) &&
diff --git a/sbin/pfctl/pfctl_parser.h b/sbin/pfctl/pfctl_parser.h
index b901fb906ec..97b0325ddc7 100644
--- a/sbin/pfctl/pfctl_parser.h
+++ b/sbin/pfctl/pfctl_parser.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: pfctl_parser.h,v 1.86 2006/10/31 23:46:25 mcbride Exp $ */
+/* $OpenBSD: pfctl_parser.h,v 1.87 2007/10/13 16:35:18 deraadt Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@@ -187,7 +187,7 @@ struct pf_opt_rule {
TAILQ_HEAD(pf_opt_queue, pf_opt_rule);
-int pfctl_rules(int, char *, FILE *, int, int, char *, struct pfr_buffer *);
+int pfctl_rules(int, char *, int, int, char *, struct pfr_buffer *);
int pfctl_optimize_ruleset(struct pfctl *, struct pf_ruleset *);
int pfctl_add_rule(struct pfctl *, struct pf_rule *, const char *);
@@ -204,7 +204,7 @@ int pfctl_set_hostid(struct pfctl *, u_int32_t);
int pfctl_set_debug(struct pfctl *, char *);
int pfctl_set_interface_flags(struct pfctl *, char *, int, int);
-int parse_rules(FILE *, struct pfctl *);
+int parse_config(char *, struct pfctl *);
int parse_flags(char *);
int pfctl_load_anchors(int, struct pfctl *, struct pfr_buffer *);
diff --git a/usr.sbin/bgpd/bgpd.h b/usr.sbin/bgpd/bgpd.h
index 6d0160646bc..1a9dbf9ce4b 100644
--- a/usr.sbin/bgpd/bgpd.h
+++ b/usr.sbin/bgpd/bgpd.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: bgpd.h,v 1.219 2007/09/11 17:07:59 henning Exp $ */
+/* $OpenBSD: bgpd.h,v 1.220 2007/10/13 16:35:19 deraadt Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -738,7 +738,6 @@ void fatalx(const char *) __dead;
int cmdline_symset(char *);
/* config.c */
-int check_file_secrecy(int, const char *);
int host(const char *, struct bgpd_addr *, u_int8_t *);
/* imsg.c */
diff --git a/usr.sbin/bgpd/config.c b/usr.sbin/bgpd/config.c
index fd87cbfe4fe..49888fbd7a2 100644
--- a/usr.sbin/bgpd/config.c
+++ b/usr.sbin/bgpd/config.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: config.c,v 1.49 2007/01/31 13:04:21 claudio Exp $ */
+/* $OpenBSD: config.c,v 1.50 2007/10/13 16:35:20 deraadt Exp $ */
/*
* Copyright (c) 2003, 2004, 2005 Henning Brauer <henning@openbsd.org>
@@ -154,29 +154,6 @@ get_bgpid(void)
}
int
-check_file_secrecy(int fd, const char *fname)
-{
- struct stat st;
-
- if (fstat(fd, &st)) {
- log_warn("cannot stat %s", fname);
- return (-1);
- }
-
- if (st.st_uid != 0 && st.st_uid != getuid()) {
- log_warnx("%s: owner not root or current user", fname);
- return (-1);
- }
-
- if (st.st_mode & (S_IRWXG | S_IRWXO)) {
- log_warnx("%s: group/world readable/writeable", fname);
- return (-1);
- }
-
- return (0);
-}
-
-int
host(const char *s, struct bgpd_addr *h, u_int8_t *len)
{
int done = 0;
diff --git a/usr.sbin/bgpd/parse.y b/usr.sbin/bgpd/parse.y
index 88a7280bbe4..888f7b7bc97 100644
--- a/usr.sbin/bgpd/parse.y
+++ b/usr.sbin/bgpd/parse.y
@@ -1,4 +1,4 @@
-/* $OpenBSD: parse.y,v 1.209 2007/10/11 14:39:17 deraadt Exp $ */
+/* $OpenBSD: parse.y,v 1.210 2007/10/13 16:35:20 deraadt Exp $ */
/*
* Copyright (c) 2002, 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -22,11 +22,13 @@
%{
#include <sys/types.h>
#include <sys/socket.h>
+#include <sys/stat.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <ctype.h>
#include <err.h>
+#include <unistd.h>
#include <errno.h>
#include <limits.h>
#include <stdarg.h>
@@ -38,6 +40,37 @@
#include "mrt.h"
#include "session.h"
+TAILQ_HEAD(files, file) files = TAILQ_HEAD_INITIALIZER(files);
+static struct file {
+ TAILQ_ENTRY(file) entry;
+ FILE *stream;
+ char *name;
+ int lineno;
+ int errors;
+} *file;
+struct file *pushfile(const char *, int);
+int popfile(void);
+int check_file_secrecy(int, const char *);
+int yyparse(void);
+int yylex(void);
+int yyerror(const char *, ...);
+int kw_cmp(const void *, const void *);
+int lookup(char *);
+int lgetc(int);
+int lungetc(int);
+int findeol(void);
+
+TAILQ_HEAD(symhead, sym) symhead = TAILQ_HEAD_INITIALIZER(symhead);
+struct sym {
+ TAILQ_ENTRY(sym) entry;
+ int used;
+ int persist;
+ char *nam;
+ char *val;
+};
+int symset(const char *, const char *, int);
+char *symget(const char *);
+
static struct bgpd_config *conf;
static struct mrt_head *mrtconf;
static struct network_head *netconf;
@@ -52,24 +85,6 @@ static struct filter_rule *curgroup_filter[2];
static struct listen_addrs *listen_addrs;
static u_int32_t id;
-TAILQ_HEAD(files, file) files = TAILQ_HEAD_INITIALIZER(files);
-static struct file {
- TAILQ_ENTRY(file) entry;
- FILE *stream;
- char *name;
- int lineno;
- int errors;
-} *file;
-
-int yyerror(const char *, ...);
-int yyparse(void);
-int kw_cmp(const void *, const void *);
-int lookup(char *);
-int lgetc(int);
-int lungetc(int);
-int findeol(void);
-int yylex(void);
-
struct filter_peers_l {
struct filter_peers_l *next;
struct filter_peers p;
@@ -92,7 +107,6 @@ struct filter_match_l {
sa_family_t af;
} fmopts;
-struct file *include_file(const char *);
struct peer *alloc_peer(void);
struct peer *new_peer(void);
struct peer *new_group(void);
@@ -109,19 +123,8 @@ void move_filterset(struct filter_set_head *,
struct filter_set_head *);
struct filter_rule *get_rule(enum action_types);
-TAILQ_HEAD(symhead, sym) symhead = TAILQ_HEAD_INITIALIZER(symhead);
-struct sym {
- TAILQ_ENTRY(sym) entry;
- int used;
- int persist;
- char *nam;
- char *val;
-};
-
-int symset(const char *, const char *, int);
-char *symget(const char *);
-int getcommunity(char *);
-int parsecommunity(char *, int *, int *);
+int getcommunity(char *);
+int parsecommunity(char *, int *, int *);
typedef struct {
union {
@@ -287,7 +290,7 @@ varset : STRING '=' string {
include : INCLUDE STRING {
struct file *nfile;
- if ((nfile = include_file($2)) == NULL) {
+ if ((nfile = pushfile($2, 1)) == NULL) {
yyerror("failed to include file %s", $2);
free($2);
YYERROR;
@@ -1861,10 +1864,8 @@ char pushback_buffer[MAXPUSHBACK];
int pushback_index = 0;
int
-lgetc(int inquot)
+lgetc(int quotec)
{
- FILE *f = file->stream;
- struct file *prevfile;
int c, next;
if (parsebuf) {
@@ -1881,13 +1882,18 @@ lgetc(int inquot)
if (pushback_index)
return (pushback_buffer[--pushback_index]);
- if (inquot) {
- c = getc(f);
+ if (quotec) {
+ if ((c = getc(file->stream)) == EOF) {
+ yyerror("reached end of file while parsing quoted string");
+ if (popfile() == EOF)
+ return (EOF);
+ return (quotec);
+ }
return (c);
}
- while ((c = getc(f)) == '\\') {
- next = getc(f);
+ while ((c = getc(file->stream)) == '\\') {
+ next = getc(file->stream);
if (next != '\n') {
c = next;
break;
@@ -1898,24 +1904,17 @@ lgetc(int inquot)
if (c == '\t' || c == ' ') {
/* Compress blanks to a single space. */
do {
- c = getc(f);
+ c = getc(file->stream);
} while (c == '\t' || c == ' ');
- ungetc(c, f);
+ ungetc(c, file->stream);
c = ' ';
}
- while (c == EOF &&
- (prevfile = TAILQ_PREV(file, files, entry)) != NULL) {
- prevfile->errors += file->errors;
- TAILQ_REMOVE(&files, file, entry);
- fclose(f);
- free(file->name);
- free(file);
- file = prevfile;
- f = file->stream;
- c = getc(f);
+ while (c == EOF) {
+ if (popfile() == EOF)
+ return (EOF);
+ c = getc(file->stream);
}
-
return (c);
}
@@ -1961,7 +1960,7 @@ yylex(void)
{
char buf[8096];
char *p, *val;
- int endc, next, c;
+ int quotec, next, c;
int token;
top:
@@ -2003,21 +2002,21 @@ top:
switch (c) {
case '\'':
case '"':
- endc = c;
+ quotec = c;
while (1) {
- if ((c = lgetc(1)) == EOF)
+ if ((c = lgetc(quotec)) == EOF)
return (0);
if (c == '\n') {
file->lineno++;
continue;
} else if (c == '\\') {
- if ((next = lgetc(1)) == EOF)
+ if ((next = lgetc(quotec)) == EOF)
return (0);
- if (next == endc)
+ if (next == quotec)
c = next;
else
lungetc(next);
- } else if (c == endc) {
+ } else if (c == quotec) {
*p = '\0';
break;
}
@@ -2099,34 +2098,69 @@ nodigits:
return (c);
}
+int
+check_file_secrecy(int fd, const char *fname)
+{
+ struct stat st;
+
+ if (fstat(fd, &st)) {
+ log_warn("cannot stat %s", fname);
+ return (-1);
+ }
+ if (st.st_uid != 0 && st.st_uid != getuid()) {
+ log_warnx("%s: owner not root or current user", fname);
+ return (-1);
+ }
+ if (st.st_mode & (S_IRWXG | S_IRWXO)) {
+ log_warnx("%s: group/world readable/writeable", fname);
+ return (-1);
+ }
+ return (0);
+}
+
struct file *
-include_file(const char *name)
+pushfile(const char *name, int secret)
{
struct file *nfile;
if ((nfile = calloc(1, sizeof(struct file))) == NULL ||
(nfile->name = strdup(name)) == NULL)
return (NULL);
-
if ((nfile->stream = fopen(nfile->name, "r")) == NULL) {
- log_warn("%s", nfile->name);
+ free(nfile->name);
+ free(nfile);
return (NULL);
}
-
- if (check_file_secrecy(fileno(nfile->stream), nfile->name)) {
+ if (secret &&
+ check_file_secrecy(fileno(nfile->stream), nfile->name)) {
fclose(nfile->stream);
free(nfile->name);
free(nfile);
return (NULL);
}
-
nfile->lineno = 1;
TAILQ_INSERT_TAIL(&files, nfile, entry);
-
return (nfile);
}
int
+popfile(void)
+{
+ struct file *prev;
+
+ if ((prev = TAILQ_PREV(file, files, entry)) != NULL) {
+ prev->errors += file->errors;
+ TAILQ_REMOVE(&files, file, entry);
+ fclose(file->stream);
+ free(file->name);
+ free(file);
+ file = prev;
+ return (0);
+ }
+ return (EOF);
+}
+
+int
parse_config(char *filename, struct bgpd_config *xconf,
struct mrt_head *xmconf, struct peer **xpeers, struct network_head *nc,
struct filter_head *xfilter_l)
@@ -2138,13 +2172,16 @@ parse_config(char *filename, struct bgpd_config *xconf,
struct filter_rule *r;
int errors = 0;
- if ((file = include_file(filename)) == NULL) {
+ if ((conf = calloc(1, sizeof(struct bgpd_config))) == NULL)
+ fatal(NULL);
+ conf->opts = xconf->opts;
+
+ if ((file = pushfile(filename, 1)) == NULL) {
+ free(conf);
log_warnx("cannot open the main config file!");
return (-1);
}
- if ((conf = calloc(1, sizeof(struct bgpd_config))) == NULL)
- fatal(NULL);
if ((mrtconf = calloc(1, sizeof(struct mrt_head))) == NULL)
fatal(NULL);
if ((listen_addrs = calloc(1, sizeof(struct listen_addrs))) == NULL)
@@ -2166,7 +2203,6 @@ parse_config(char *filename, struct bgpd_config *xconf,
curpeer = NULL;
curgroup = NULL;
id = 1;
- conf->opts = xconf->opts;
/* network list is always empty in the parent */
netconf = nc;
@@ -2176,6 +2212,7 @@ parse_config(char *filename, struct bgpd_config *xconf,
yyparse();
errors = file->errors;
+ popfile();
/* Free macros and check which have not been used. */
for (sym = TAILQ_FIRST(&symhead); sym != NULL; sym = next) {
@@ -2258,11 +2295,6 @@ parse_config(char *filename, struct bgpd_config *xconf,
free(peerfilter_l);
free(groupfilter_l);
- TAILQ_REMOVE(&files, file, entry);
- fclose(file->stream);
- free(file->name);
- free(file);
-
return (errors ? -1 : 0);
}
diff --git a/usr.sbin/dvmrpd/dvmrpd.c b/usr.sbin/dvmrpd/dvmrpd.c
index 01671d1aea9..cf8cb6f7819 100644
--- a/usr.sbin/dvmrpd/dvmrpd.c
+++ b/usr.sbin/dvmrpd/dvmrpd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: dvmrpd.c,v 1.3 2007/01/24 09:57:51 norby Exp $ */
+/* $OpenBSD: dvmrpd.c,v 1.4 2007/10/13 16:35:20 deraadt Exp $ */
/*
* Copyright (c) 2005 Claudio Jeker <claudio@openbsd.org>
@@ -59,8 +59,6 @@ void main_dispatch_rde(int, short, void *);
void main_imsg_compose_dvmrpe(int, pid_t, void *, u_int16_t);
void main_imsg_compose_rde(int, pid_t, void *, u_int16_t);
-int check_file_secrecy(int, const char *);
-
int pipe_parent2dvmrpe[2];
int pipe_parent2rde[2];
int pipe_dvmrpe2rde[2];
@@ -463,29 +461,6 @@ main_imsg_compose_rde(int type, pid_t pid, void *data, u_int16_t datalen)
imsg_compose(ibuf_rde, type, 0, pid, data, datalen);
}
-int
-check_file_secrecy(int fd, const char *fname)
-{
- struct stat st;
-
- if (fstat(fd, &st)) {
- log_warn("cannot stat %s", fname);
- return (-1);
- }
-
- if (st.st_uid != 0 && st.st_uid != getuid()) {
- log_warnx("%s: owner not root or current user", fname);
- return (-1);
- }
-
- if (st.st_mode & (S_IRWXG | S_IRWXO)) {
- log_warnx("%s: group/world readable/writeable", fname);
- return (-1);
- }
-
- return (0);
-}
-
/* this needs to be added here so that dvmrpctl can be used without libevent */
void
imsg_event_add(struct imsgbuf *ibuf)
diff --git a/usr.sbin/dvmrpd/parse.y b/usr.sbin/dvmrpd/parse.y
index fddbd797a29..51ddb0dbc6e 100644
--- a/usr.sbin/dvmrpd/parse.y
+++ b/usr.sbin/dvmrpd/parse.y
@@ -1,4 +1,4 @@
-/* $OpenBSD: parse.y,v 1.8 2007/10/11 14:39:17 deraadt Exp $ */
+/* $OpenBSD: parse.y,v 1.9 2007/10/13 16:35:20 deraadt Exp $ */
/*
* Copyright (c) 2004, 2005, 2006 Esben Norby <norby@openbsd.org>
@@ -24,12 +24,14 @@
%{
#include <sys/types.h>
#include <sys/time.h>
+#include <sys/stat.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <net/if.h>
#include <ctype.h>
#include <err.h>
+#include <unistd.h>
#include <errno.h>
#include <stdarg.h>
#include <stdio.h>
@@ -42,25 +44,40 @@
#include "dvmrpe.h"
#include "log.h"
-static struct dvmrpd_conf *conf;
-static FILE *fin = NULL;
-static int lineno = 1;
-static int errors = 0;
-char *infile;
-char *start_state;
+TAILQ_HEAD(files, file) files = TAILQ_HEAD_INITIALIZER(files);
+static struct file {
+ TAILQ_ENTRY(file) entry;
+ FILE *stream;
+ char *name;
+ int lineno;
+ int errors;
+} *file;
+struct file *pushfile(const char *, int);
+int popfile(void);
+int check_file_secrecy(int, const char *);
+int yyparse(void);
+int yylex(void);
+int yyerror(const char *, ...);
+int kw_cmp(const void *, const void *);
+int lookup(char *);
+int lgetc(int);
+int lungetc(int);
+int findeol(void);
-struct iface *iface = NULL;
+TAILQ_HEAD(symhead, sym) symhead = TAILQ_HEAD_INITIALIZER(symhead);
+struct sym {
+ TAILQ_ENTRY(sym) entry;
+ int used;
+ int persist;
+ char *nam;
+ char *val;
+};
+int symset(const char *, const char *, int);
+char *symget(const char *);
-int yyerror(const char *, ...);
-int yyparse(void);
-int kw_cmp(const void *, const void *);
-int lookup(char *);
-int lgetc(int);
-int lungetc(int);
-int findeol(void);
-int yylex(void);
-void clear_config(struct dvmrpd_conf *xconf);
-int check_file_secrecy(int fd, const char *fname);
+static struct dvmrpd_conf *conf;
+char *start_state;
+struct iface *iface = NULL;
static struct {
u_int32_t probe_interval;
@@ -76,19 +93,9 @@ static struct {
u_int8_t igmp_version;
} *defs, *grdefs, globaldefs, groupdefs, ifacedefs;
-TAILQ_HEAD(symhead, sym) symhead = TAILQ_HEAD_INITIALIZER(symhead);
-struct sym {
- TAILQ_ENTRY(sym) entries;
- int used;
- int persist;
- char *nam;
- char *val;
-};
-
-int symset(const char *, const char *, int);
-char *symget(const char *);
-struct iface *conf_get_if(struct kif *);
-struct iface *new_group(void);
+void clear_config(struct dvmrpd_conf *xconf);
+struct iface *conf_get_if(struct kif *);
+struct iface *new_group(void);
typedef struct {
union {
@@ -121,10 +128,10 @@ grammar : /* empty */
| grammar varset '\n'
| grammar interface '\n'
| grammar group '\n'
- | grammar error '\n' { errors++; }
+ | grammar error '\n' { file->errors++; }
;
-string : string STRING {
+string : string STRING {
if (asprintf(&$$, "%s %s", $1, $2) == -1) {
free($1);
free($2);
@@ -350,9 +357,9 @@ yyerror(const char *fmt, ...)
{
va_list ap;
- errors = 1;
+ file->errors++;
va_start(ap, fmt);
- fprintf(stderr, "%s:%d: ", infile, yylval.lineno);
+ fprintf(stderr, "%s:%d: ", file->name, yylval.lineno);
vfprintf(stderr, fmt, ap);
fprintf(stderr, "\n");
va_end(ap);
@@ -403,10 +410,9 @@ char pushback_buffer[MAXPUSHBACK];
int pushback_index = 0;
int
-lgetc(int inquot)
+lgetc(int quotec)
{
- int c, next;
- FILE *f = fin;
+ int c, next;
if (parsebuf) {
/* Read character from the parsebuffer instead of input. */
@@ -422,29 +428,39 @@ lgetc(int inquot)
if (pushback_index)
return (pushback_buffer[--pushback_index]);
- if (inquot) {
- c = getc(f);
+ if (quotec) {
+ if ((c = getc(file->stream)) == EOF) {
+ yyerror("reached end of file while parsing quoted string");
+ if (popfile() == EOF)
+ return (EOF);
+ return (quotec);
+ }
return (c);
}
- while ((c = getc(f)) == '\\') {
- next = getc(f);
+ while ((c = getc(file->stream)) == '\\') {
+ next = getc(file->stream);
if (next != '\n') {
c = next;
break;
}
- yylval.lineno = lineno;
- lineno++;
+ yylval.lineno = file->lineno;
+ file->lineno++;
}
if (c == '\t' || c == ' ') {
/* Compress blanks to a single space. */
do {
- c = getc(f);
+ c = getc(file->stream);
} while (c == '\t' || c == ' ');
- ungetc(c, f);
+ ungetc(c, file->stream);
c = ' ';
}
+ while (c == EOF) {
+ if (popfile() == EOF)
+ return (EOF);
+ c = getc(file->stream);
+ }
return (c);
}
@@ -476,7 +492,7 @@ findeol(void)
while (1) {
c = lgetc(0);
if (c == '\n') {
- lineno++;
+ file->lineno++;
break;
}
if (c == EOF)
@@ -490,7 +506,7 @@ yylex(void)
{
char buf[8096];
char *p, *val;
- int endc, next, c;
+ int quotec, next, c;
int token;
top:
@@ -498,7 +514,7 @@ top:
while ((c = lgetc(0)) == ' ')
; /* nothing */
- yylval.lineno = lineno;
+ yylval.lineno = file->lineno;
if (c == '#')
while ((c = lgetc(0)) != '\n' && c != EOF)
; /* nothing */
@@ -532,21 +548,21 @@ top:
switch (c) {
case '\'':
case '"':
- endc = c;
+ quotec = c;
while (1) {
- if ((c = lgetc(1)) == EOF)
+ if ((c = lgetc(quotec)) == EOF)
return (0);
if (c == '\n') {
- lineno++;
+ file->lineno++;
continue;
} else if (c == '\\') {
- if ((next = lgetc(1)) == EOF)
+ if ((next = lgetc(quotec)) == EOF)
return (0);
- if (next == endc)
+ if (next == quotec)
c = next;
else
lungetc(next);
- } else if (c == endc) {
+ } else if (c == quotec) {
*p = '\0';
break;
}
@@ -620,17 +636,79 @@ nodigits:
return (token);
}
if (c == '\n') {
- yylval.lineno = lineno;
- lineno++;
+ yylval.lineno = file->lineno;
+ file->lineno++;
}
if (c == EOF)
return (0);
return (c);
}
+int
+check_file_secrecy(int fd, const char *fname)
+{
+ struct stat st;
+
+ if (fstat(fd, &st)) {
+ log_warn("cannot stat %s", fname);
+ return (-1);
+ }
+ if (st.st_uid != 0 && st.st_uid != getuid()) {
+ log_warnx("%s: owner not root or current user", fname);
+ return (-1);
+ }
+ if (st.st_mode & (S_IRWXG | S_IRWXO)) {
+ log_warnx("%s: group/world readable/writeable", fname);
+ return (-1);
+ }
+ return (0);
+}
+
+struct file *
+pushfile(const char *name, int secret)
+{
+ struct file *nfile;
+
+ if ((nfile = calloc(1, sizeof(struct file))) == NULL ||
+ (nfile->name = strdup(name)) == NULL)
+ return (NULL);
+ if ((nfile->stream = fopen(nfile->name, "r")) == NULL) {
+ free(nfile->name);
+ free(nfile);
+ return (NULL);
+ } else if (secret &&
+ check_file_secrecy(fileno(nfile->stream), nfile->name)) {
+ fclose(nfile->stream);
+ free(nfile->name);
+ free(nfile);
+ return (NULL);
+ }
+ nfile->lineno = 1;
+ TAILQ_INSERT_TAIL(&files, nfile, entry);
+ return (nfile);
+}
+
+int
+popfile(void)
+{
+ struct file *prev;
+
+ if ((prev = TAILQ_PREV(file, files, entry)) != NULL) {
+ prev->errors += file->errors;
+ TAILQ_REMOVE(&files, file, entry);
+ fclose(file->stream);
+ free(file->name);
+ free(file);
+ file = prev;
+ return (0);
+ }
+ return (EOF);
+}
+
struct dvmrpd_conf *
parse_config(char *filename, int opts)
{
+ int errors = 0;
struct sym *sym, *next;
struct timeval now;
@@ -652,12 +730,11 @@ parse_config(char *filename, int opts)
defs->igmp_version = DEFAULT_IGMP_VERSION;
defs->dead_interval = NBR_TMOUT;
- if ((fin = fopen(filename, "r")) == NULL) {
+ if ((file = pushfile(filename, 1)) == NULL) {
warn("%s", filename);
free(conf);
return (NULL);
}
- infile = filename;
/* Generation ID must be non decreasing */
gettimeofday(&now, NULL);
@@ -665,26 +742,20 @@ parse_config(char *filename, int opts)
conf->opts = opts;
RB_INIT(&conf->src_list);
- if (check_file_secrecy(fileno(fin), filename)) {
- fclose(fin);
- free(conf);
- return (NULL);
- }
-
yyparse();
-
- fclose(fin);
+ errors = file->errors;
+ popfile();
/* Free macros and check which have not been used. */
for (sym = TAILQ_FIRST(&symhead); sym != NULL; sym = next) {
- next = TAILQ_NEXT(sym, entries);
+ next = TAILQ_NEXT(sym, entry);
if ((conf->opts & DVMRPD_OPT_VERBOSE2) && !sym->used)
fprintf(stderr, "warning: macro '%s' not "
"used\n", sym->nam);
if (!sym->persist) {
free(sym->nam);
free(sym->val);
- TAILQ_REMOVE(&symhead, sym, entries);
+ TAILQ_REMOVE(&symhead, sym, entry);
free(sym);
}
}
@@ -703,7 +774,7 @@ symset(const char *nam, const char *val, int persist)
struct sym *sym;
for (sym = TAILQ_FIRST(&symhead); sym && strcmp(nam, sym->nam);
- sym = TAILQ_NEXT(sym, entries))
+ sym = TAILQ_NEXT(sym, entry))
; /* nothing */
if (sym != NULL) {
@@ -712,7 +783,7 @@ symset(const char *nam, const char *val, int persist)
else {
free(sym->nam);
free(sym->val);
- TAILQ_REMOVE(&symhead, sym, entries);
+ TAILQ_REMOVE(&symhead, sym, entry);
free(sym);
}
}
@@ -732,7 +803,7 @@ symset(const char *nam, const char *val, int persist)
}
sym->used = 0;
sym->persist = persist;
- TAILQ_INSERT_TAIL(&symhead, sym, entries);
+ TAILQ_INSERT_TAIL(&symhead, sym, entry);
return (0);
}
@@ -763,7 +834,7 @@ symget(const char *nam)
{
struct sym *sym;
- TAILQ_FOREACH(sym, &symhead, entries)
+ TAILQ_FOREACH(sym, &symhead, entry)
if (strcmp(nam, sym->nam) == 0) {
sym->used = 1;
return (sym->val);
diff --git a/usr.sbin/hostapd/parse.y b/usr.sbin/hostapd/parse.y
index fdbc297616e..793c25bd3a0 100644
--- a/usr.sbin/hostapd/parse.y
+++ b/usr.sbin/hostapd/parse.y
@@ -1,4 +1,4 @@
-/* $OpenBSD: parse.y,v 1.31 2007/10/11 14:39:17 deraadt Exp $ */
+/* $OpenBSD: parse.y,v 1.32 2007/10/13 16:35:20 deraadt Exp $ */
/*
* Copyright (c) 2004, 2005, 2006 Reyk Floeter <reyk@openbsd.org>
@@ -53,21 +53,29 @@
#include <string.h>
#include <unistd.h>
#include <stdint.h>
+#include <err.h>
#include "hostapd.h"
-extern struct hostapd_config hostapd_cfg;
-static int errors = 0;
-
-TAILQ_HEAD(filehead, file) filehead = TAILQ_HEAD_INITIALIZER(filehead);
-struct file {
+TAILQ_HEAD(files, file) files = TAILQ_HEAD_INITIALIZER(files);
+static struct file {
TAILQ_ENTRY(file) entry;
-
- char *name;
FILE *stream;
+ char *name;
int lineno;
-};
-static struct file *file;
+ int errors;
+} *file;
+struct file *pushfile(const char *, int);
+int popfile(void);
+int check_file_secrecy(int, const char *);
+int yyparse(void);
+int yylex(void);
+int yyerror(const char *, ...);
+int kw_cmp(const void *, const void *);
+int lookup(char *);
+int lgetc(int);
+int lungetc(int);
+int findeol(void);
TAILQ_HEAD(symhead, sym) symhead = TAILQ_HEAD_INITIALIZER(symhead);
struct sym {
@@ -77,18 +85,10 @@ struct sym {
char *nam;
char *val;
};
-
-int yyerror(const char *, ...);
-int yyparse(void);
-int kw_cmp(const void *, const void *);
-int lookup(char *);
-int lgetc(int);
-int lungetc(int);
-int findeol(void);
-int yylex(void);
int symset(const char *, const char *, int);
char *symget(const char *);
-struct file *hostapd_add_file(struct hostapd_config *, const char *);
+
+extern struct hostapd_config hostapd_cfg;
typedef struct {
union {
@@ -181,7 +181,7 @@ grammar : /* empty */
| grammar option '\n'
| grammar event '\n'
| grammar varset '\n'
- | grammar error '\n' { errors++; }
+ | grammar error '\n' { file->errors++; }
;
include : INCLUDE STRING
@@ -189,7 +189,7 @@ include : INCLUDE STRING
struct file *nfile;
if ((nfile =
- hostapd_add_file(&hostapd_cfg, $2)) == NULL) {
+ pushfile($2, 1)) == NULL) {
yyerror("failed to include file %s", $2);
free($2);
YYERROR;
@@ -1331,10 +1331,9 @@ char pushback_buffer[MAXPUSHBACK];
int pushback_index = 0;
int
-lgetc(int inquot)
+lgetc(int quotec)
{
- int c, next;
- struct file *pfile;
+ int c, next;
if (parsebuf) {
/* Read character from the parsebuffer instead of input. */
@@ -1350,8 +1349,13 @@ lgetc(int inquot)
if (pushback_index)
return (pushback_buffer[--pushback_index]);
- if (inquot) {
- c = getc(file->stream);
+ if (quotec) {
+ if ((c = getc(file->stream)) == EOF) {
+ yyerror("reached end of file while parsing quoted string");
+ if (popfile() == EOF)
+ return (EOF);
+ return (quotec);
+ }
return (c);
}
@@ -1369,22 +1373,15 @@ lgetc(int inquot)
do {
c = getc(file->stream);
} while (c == '\t' || c == ' ');
- if (ungetc(c, file->stream) == EOF)
- hostapd_fatal("lgetc: ungetc");
+ ungetc(c, file->stream);
c = ' ';
}
- while (c == EOF &&
- (pfile = TAILQ_PREV(file, filehead, entry)) != NULL) {
- fclose(file->stream);
- free(file->name);
- TAILQ_REMOVE(&filehead, file, entry);
- free(file);
-
- file = pfile;
+ while (c == EOF) {
+ if (popfile() == EOF)
+ return (EOF);
c = getc(file->stream);
}
-
return (c);
}
@@ -1430,7 +1427,7 @@ yylex(void)
{
char buf[8096];
char *p, *val;
- int endc, c;
+ int quotec, next, c;
int token;
top:
@@ -1472,17 +1469,23 @@ top:
switch (c) {
case '\'':
case '"':
- endc = c;
+ quotec = c;
while (1) {
- if ((c = lgetc(1)) == EOF)
+ if ((c = lgetc(quotec)) == EOF)
return (0);
- if (c == endc) {
- *p = '\0';
- break;
- }
if (c == '\n') {
file->lineno++;
continue;
+ } else if (c == '\\') {
+ if ((next = lgetc(quotec)) == EOF)
+ return (0);
+ if (next == quotec)
+ c = next;
+ else
+ lungetc(next);
+ } else if (c == quotec) {
+ *p = '\0';
+ break;
}
if (p + 1 >= buf + sizeof(buf) - 1) {
yyerror("string too long");
@@ -1640,50 +1643,75 @@ symget(const char *nam)
return (NULL);
}
-struct file *
-hostapd_add_file(struct hostapd_config *cfg, const char *name)
+int
+check_file_secrecy(int fd, const char *fname)
{
- struct file *nfile = NULL;
+ struct stat st;
- if ((nfile = calloc(1, sizeof(struct file))) == NULL)
- return (NULL);
-
- if ((nfile->name = strdup(name)) == NULL)
- goto err;
-
- if ((nfile->stream = fopen(name, "rb")) == NULL) {
- hostapd_log(HOSTAPD_LOG, "failed to open %s", name);
- goto err;
+ if (fstat(fd, &st)) {
+ warn("cannot stat %s", fname);
+ return (-1);
}
-
- if (hostapd_check_file_secrecy(fileno(nfile->stream), name)) {
- hostapd_log(HOSTAPD_LOG, "invalid permissions for %s", name);
- goto err;
+ if (st.st_uid != 0 && st.st_uid != getuid()) {
+ warnx("%s: owner not root or current user", fname);
+ return (-1);
}
+ if (st.st_mode & (S_IRWXG | S_IRWXO)) {
+ warnx("%s: group/world readable/writeable", fname);
+ return (-1);
+ }
+ return (0);
+}
- nfile->lineno = 1;
- TAILQ_INSERT_TAIL(&filehead, nfile, entry);
-
- return (nfile);
+struct file *
+pushfile(const char *name, int secret)
+{
+ struct file *nfile;
- err:
- if (nfile->name != NULL)
+ if ((nfile = calloc(1, sizeof(struct file))) == NULL ||
+ (nfile->name = strdup(name)) == NULL)
+ return (NULL);
+ if ((nfile->stream = fopen(nfile->name, "r")) == NULL) {
free(nfile->name);
- if (nfile->stream != NULL)
+ free(nfile);
+ return (NULL);
+ } else if (secret &&
+ check_file_secrecy(fileno(nfile->stream), nfile->name)) {
fclose(nfile->stream);
- free(nfile);
+ free(nfile->name);
+ free(nfile);
+ return (NULL);
+ }
+ nfile->lineno = 1;
+ TAILQ_INSERT_TAIL(&files, nfile, entry);
+ return (nfile);
+}
- return (NULL);
+int
+popfile(void)
+{
+ struct file *prev;
+
+ if ((prev = TAILQ_PREV(file, files, entry)) != NULL) {
+ prev->errors += file->errors;
+ TAILQ_REMOVE(&files, file, entry);
+ fclose(file->stream);
+ free(file->name);
+ free(file);
+ file = prev;
+ return (0);
+ }
+ return (EOF);
}
int
hostapd_parse_file(struct hostapd_config *cfg)
{
struct sym *sym, *next;
- struct file *nfile;
+ int errors = 0;
int ret;
- if ((file = hostapd_add_file(cfg, cfg->c_config)) == NULL)
+ if ((file = pushfile(cfg->c_config, 1)) == NULL)
hostapd_fatal("failed to open the main config file: %s\n",
cfg->c_config);
@@ -1697,17 +1725,9 @@ hostapd_parse_file(struct hostapd_config *cfg)
cfg->c_apme_hopdelay.tv_sec = HOSTAPD_HOPPER_MDELAY / 1000;
cfg->c_apme_hopdelay.tv_usec = (HOSTAPD_HOPPER_MDELAY % 1000) * 1000;
- errors = 0;
-
ret = yyparse();
-
- for (file = TAILQ_FIRST(&filehead); file != NULL; file = nfile) {
- nfile = TAILQ_NEXT(file, entry);
- fclose(file->stream);
- free(file->name);
- TAILQ_REMOVE(&filehead, file, entry);
- free(file);
- }
+ errors = file->errors;
+ popfile();
/* Free macros and check which have not been used. */
for (sym = TAILQ_FIRST(&symhead); sym != NULL; sym = next) {
@@ -1729,10 +1749,10 @@ hostapd_parse_file(struct hostapd_config *cfg)
int
yyerror(const char *fmt, ...)
{
- va_list ap;
- char *nfmt;
+ va_list ap;
+ char *nfmt;
- errors = 1;
+ file->errors++;
va_start(ap, fmt);
if (asprintf(&nfmt, "%s:%d: %s\n", file->name, yylval.lineno,
diff --git a/usr.sbin/hoststated/parse.y b/usr.sbin/hoststated/parse.y
index 1b995e11516..0a09a74ce0f 100644
--- a/usr.sbin/hoststated/parse.y
+++ b/usr.sbin/hoststated/parse.y
@@ -1,4 +1,4 @@
-/* $OpenBSD: parse.y,v 1.62 2007/10/11 14:39:17 deraadt Exp $ */
+/* $OpenBSD: parse.y,v 1.63 2007/10/13 16:35:21 deraadt Exp $ */
/*
* Copyright (c) 2006 Pierre-Yves Ritschard <pyr@openbsd.org>
@@ -25,6 +25,7 @@
%{
#include <sys/types.h>
#include <sys/socket.h>
+#include <sys/stat.h>
#include <sys/queue.h>
#include <netinet/in.h>
#include <net/if.h>
@@ -32,6 +33,7 @@
#include <arpa/nameser.h>
#include <ctype.h>
+#include <unistd.h>
#include <err.h>
#include <errno.h>
#include <event.h>
@@ -46,44 +48,51 @@
#include "hoststated.h"
-struct hoststated *conf = NULL;
-static FILE *fin = NULL;
-static int lineno = 1;
-static int errors = 0;
-const char *infile;
-objid_t last_service_id = 0;
-objid_t last_table_id = 0;
-objid_t last_host_id = 0;
-objid_t last_relay_id = 0;
-objid_t last_proto_id = 0;
-
-static struct service *service = NULL;
-static struct table *table = NULL;
-static struct relay *rlay = NULL;
-static struct protocol *proto = NULL;
-static struct protonode node;
-
-int yyerror(const char *, ...);
-int yyparse(void);
-int kw_cmp(const void *, const void *);
-int lookup(char *);
-int lgetc(int);
-int lungetc(int);
-int findeol(void);
-int yylex(void);
+TAILQ_HEAD(files, file) files = TAILQ_HEAD_INITIALIZER(files);
+static struct file {
+ TAILQ_ENTRY(file) entry;
+ FILE *stream;
+ char *name;
+ int lineno;
+ int errors;
+} *file;
+struct file *pushfile(const char *, int);
+int popfile(void);
+int check_file_secrecy(int, const char *);
+int yyparse(void);
+int yylex(void);
+int yyerror(const char *, ...);
+int kw_cmp(const void *, const void *);
+int lookup(char *);
+int lgetc(int);
+int lungetc(int);
+int findeol(void);
TAILQ_HEAD(symhead, sym) symhead = TAILQ_HEAD_INITIALIZER(symhead);
struct sym {
- TAILQ_ENTRY(sym) entries;
+ TAILQ_ENTRY(sym) entry;
int used;
int persist;
char *nam;
char *val;
};
-
int symset(const char *, const char *, int);
char *symget(const char *);
+struct hoststated *conf = NULL;
+static int errors = 0;
+objid_t last_service_id = 0;
+objid_t last_table_id = 0;
+objid_t last_host_id = 0;
+objid_t last_relay_id = 0;
+objid_t last_proto_id = 0;
+
+static struct service *service = NULL;
+static struct table *table = NULL;
+static struct relay *rlay = NULL;
+static struct protocol *proto = NULL;
+static struct protonode node;
+
struct address *host_v4(const char *);
struct address *host_v6(const char *);
int host_dns(const char *, struct addresslist *,
@@ -132,7 +141,7 @@ grammar : /* empty */
| grammar table '\n'
| grammar relay '\n'
| grammar proto '\n'
- | grammar error '\n' { errors++; }
+ | grammar error '\n' { file->errors++; }
;
optssl : /*empty*/ { $$ = 0; }
@@ -1151,11 +1160,11 @@ struct keywords {
int
yyerror(const char *fmt, ...)
{
- va_list ap;
+ va_list ap;
- errors = 1;
+ file->errors++;
va_start(ap, fmt);
- fprintf(stderr, "%s:%d: ", infile, yylval.lineno);
+ fprintf(stderr, "%s:%d: ", file->name, yylval.lineno);
vfprintf(stderr, fmt, ap);
fprintf(stderr, "\n");
va_end(ap);
@@ -1165,7 +1174,6 @@ yyerror(const char *fmt, ...)
int
kw_cmp(const void *k, const void *e)
{
-
return (strcmp(k, ((const struct keywords *)e)->k_name));
}
@@ -1258,10 +1266,9 @@ char pushback_buffer[MAXPUSHBACK];
int pushback_index = 0;
int
-lgetc(int inquot)
+lgetc(int quotec)
{
- int c, next;
- FILE *f = fin;
+ int c, next;
if (parsebuf) {
/* Read character from the parsebuffer instead of input. */
@@ -1277,29 +1284,39 @@ lgetc(int inquot)
if (pushback_index)
return (pushback_buffer[--pushback_index]);
- if (inquot) {
- c = getc(f);
+ if (quotec) {
+ if ((c = getc(file->stream)) == EOF) {
+ yyerror("reached end of file while parsing quoted string");
+ if (popfile() == EOF)
+ return (EOF);
+ return (quotec);
+ }
return (c);
}
- while ((c = getc(f)) == '\\') {
- next = getc(f);
+ while ((c = getc(file->stream)) == '\\') {
+ next = getc(file->stream);
if (next != '\n') {
c = next;
break;
}
- yylval.lineno = lineno;
- lineno++;
+ yylval.lineno = file->lineno;
+ file->lineno++;
}
if (c == '\t' || c == ' ') {
/* Compress blanks to a single space. */
do {
- c = getc(f);
+ c = getc(file->stream);
} while (c == '\t' || c == ' ');
- ungetc(c, f);
+ ungetc(c, file->stream);
c = ' ';
}
+ while (c == EOF) {
+ if (popfile() == EOF)
+ return (EOF);
+ c = getc(file->stream);
+ }
return (c);
}
@@ -1331,7 +1348,7 @@ findeol(void)
while (1) {
c = lgetc(0);
if (c == '\n') {
- lineno++;
+ file->lineno++;
break;
}
if (c == EOF)
@@ -1345,7 +1362,7 @@ yylex(void)
{
char buf[8096];
char *p, *val;
- int endc, next, c;
+ int quotec, next, c;
int token;
top:
@@ -1353,7 +1370,7 @@ top:
while ((c = lgetc(0)) == ' ')
; /* nothing */
- yylval.lineno = lineno;
+ yylval.lineno = file->lineno;
if (c == '#')
while ((c = lgetc(0)) != '\n' && c != EOF)
; /* nothing */
@@ -1387,21 +1404,21 @@ top:
switch (c) {
case '\'':
case '"':
- endc = c;
+ quotec = c;
while (1) {
- if ((c = lgetc(1)) == EOF)
+ if ((c = lgetc(quotec)) == EOF)
return (0);
if (c == '\n') {
- lineno++;
+ file->lineno++;
continue;
} else if (c == '\\') {
- if ((next = lgetc(1)) == EOF)
+ if ((next = lgetc(quotec)) == EOF)
return (0);
- if (next == endc)
+ if (next == quotec)
c = next;
else
lungetc(next);
- } else if (c == endc) {
+ } else if (c == quotec) {
*p = '\0';
break;
}
@@ -1475,14 +1492,75 @@ nodigits:
return (token);
}
if (c == '\n') {
- yylval.lineno = lineno;
- lineno++;
+ yylval.lineno = file->lineno;
+ file->lineno++;
}
if (c == EOF)
return (0);
return (c);
}
+int
+check_file_secrecy(int fd, const char *fname)
+{
+ struct stat st;
+
+ if (fstat(fd, &st)) {
+ log_warn("cannot stat %s", fname);
+ return (-1);
+ }
+ if (st.st_uid != 0 && st.st_uid != getuid()) {
+ log_warnx("%s: owner not root or current user", fname);
+ return (-1);
+ }
+ if (st.st_mode & (S_IRWXG | S_IRWXO)) {
+ log_warnx("%s: group/world readable/writeable", fname);
+ return (-1);
+ }
+ return (0);
+}
+
+struct file *
+pushfile(const char *name, int secret)
+{
+ struct file *nfile;
+
+ if ((nfile = calloc(1, sizeof(struct file))) == NULL ||
+ (nfile->name = strdup(name)) == NULL)
+ return (NULL);
+ if ((nfile->stream = fopen(nfile->name, "r")) == NULL) {
+ free(nfile->name);
+ free(nfile);
+ return (NULL);
+ } else if (secret &&
+ check_file_secrecy(fileno(nfile->stream), nfile->name)) {
+ fclose(nfile->stream);
+ free(nfile->name);
+ free(nfile);
+ return (NULL);
+ }
+ nfile->lineno = 1;
+ TAILQ_INSERT_TAIL(&files, nfile, entry);
+ return (nfile);
+}
+
+int
+popfile(void)
+{
+ struct file *prev;
+
+ if ((prev = TAILQ_PREV(file, files, entry)) != NULL) {
+ prev->errors += file->errors;
+ TAILQ_REMOVE(&files, file, entry);
+ fclose(file->stream);
+ free(file->name);
+ free(file);
+ file = prev;
+ return (0);
+ }
+ return (EOF);
+}
+
struct hoststated *
parse_config(const char *filename, int opts)
{
@@ -1530,27 +1608,29 @@ parse_config(const char *filename, int opts)
conf->opts = opts;
conf->confpath = filename;
- if ((fin = fopen(filename, "r")) == NULL) {
+ if ((file = pushfile(filename, 1)) == NULL) {
warn("%s", filename);
free(conf);
return (NULL);
}
- infile = filename;
setservent(1);
+
yyparse();
+ errors = file->errors;
+ popfile();
+
endservent();
- fclose(fin);
/* Free macros and check which have not been used. */
for (sym = TAILQ_FIRST(&symhead); sym != NULL; sym = next) {
- next = TAILQ_NEXT(sym, entries);
+ next = TAILQ_NEXT(sym, entry);
if ((conf->opts & HOSTSTATED_OPT_VERBOSE) && !sym->used)
fprintf(stderr, "warning: macro '%s' not "
"used\n", sym->nam);
if (!sym->persist) {
free(sym->nam);
free(sym->val);
- TAILQ_REMOVE(&symhead, sym, entries);
+ TAILQ_REMOVE(&symhead, sym, entry);
free(sym);
}
}
@@ -1616,7 +1696,7 @@ symset(const char *nam, const char *val, int persist)
struct sym *sym;
for (sym = TAILQ_FIRST(&symhead); sym && strcmp(nam, sym->nam);
- sym = TAILQ_NEXT(sym, entries))
+ sym = TAILQ_NEXT(sym, entry))
; /* nothing */
if (sym != NULL) {
@@ -1625,7 +1705,7 @@ symset(const char *nam, const char *val, int persist)
else {
free(sym->nam);
free(sym->val);
- TAILQ_REMOVE(&symhead, sym, entries);
+ TAILQ_REMOVE(&symhead, sym, entry);
free(sym);
}
}
@@ -1645,7 +1725,7 @@ symset(const char *nam, const char *val, int persist)
}
sym->used = 0;
sym->persist = persist;
- TAILQ_INSERT_TAIL(&symhead, sym, entries);
+ TAILQ_INSERT_TAIL(&symhead, sym, entry);
return (0);
}
@@ -1676,7 +1756,7 @@ symget(const char *nam)
{
struct sym *sym;
- TAILQ_FOREACH(sym, &symhead, entries)
+ TAILQ_FOREACH(sym, &symhead, entry)
if (strcmp(nam, sym->nam) == 0) {
sym->used = 1;
return (sym->val);
diff --git a/usr.sbin/ifstated/parse.y b/usr.sbin/ifstated/parse.y
index 6b80338df66..af32be14a49 100644
--- a/usr.sbin/ifstated/parse.y
+++ b/usr.sbin/ifstated/parse.y
@@ -1,4 +1,4 @@
-/* $OpenBSD: parse.y,v 1.19 2007/10/11 14:39:17 deraadt Exp $ */
+/* $OpenBSD: parse.y,v 1.20 2007/10/13 16:35:21 deraadt Exp $ */
/*
* Copyright (c) 2004 Ryan McBride <mcbride@openbsd.org>
@@ -24,54 +24,62 @@
#include <sys/types.h>
#include <sys/time.h>
#include <sys/socket.h>
+#include <sys/stat.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <net/if.h>
#include <ctype.h>
+#include <unistd.h>
#include <err.h>
#include <errno.h>
+#include <limits.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include <syslog.h>
#include <event.h>
-#include <limits.h>
#include "ifstated.h"
-static struct ifsd_config *conf;
-static FILE *fin = NULL;
-static int lineno = 1;
-static int errors = 0;
-char *infile;
-char *start_state;
-
-struct ifsd_action *curaction;
-struct ifsd_state *curstate = NULL;
-
-int yyerror(const char *, ...);
-int yyparse(void);
-int kw_cmp(const void *, const void *);
-int lookup(char *);
-int lgetc(int);
-int lungetc(int);
-int findeol(void);
-int yylex(void);
-
+TAILQ_HEAD(files, file) files = TAILQ_HEAD_INITIALIZER(files);
+static struct file {
+ TAILQ_ENTRY(file) entry;
+ FILE *stream;
+ char *name;
+ int lineno;
+ int errors;
+} *file;
+struct file *pushfile(const char *, int);
+int popfile(void);
+int check_file_secrecy(int, const char *);
+int yyparse(void);
+int yylex(void);
+int yyerror(const char *, ...);
+int kw_cmp(const void *, const void *);
+int lookup(char *);
+int lgetc(int);
+int lungetc(int);
+int findeol(void);
TAILQ_HEAD(symhead, sym) symhead = TAILQ_HEAD_INITIALIZER(symhead);
struct sym {
- TAILQ_ENTRY(sym) entries;
+ TAILQ_ENTRY(sym) entry;
int used;
int persist;
char *nam;
char *val;
};
+int symset(const char *, const char *, int);
+char *symget(const char *);
+
+static struct ifsd_config *conf;
+char *start_state;
+
+struct ifsd_action *curaction;
+struct ifsd_state *curstate = NULL;
void link_states(struct ifsd_action *);
-int symset(const char *, const char *, int);
-char *symget(const char *);
void set_expression_depth(struct ifsd_expression *, int);
void init_state(struct ifsd_state *);
struct ifsd_ifstate *new_ifstate(u_short, int);
@@ -115,7 +123,7 @@ grammar : /* empty */
| grammar varset '\n'
| grammar action '\n'
| grammar state '\n'
- | grammar error '\n' { errors++; }
+ | grammar error '\n' { file->errors++; }
;
string : string STRING {
@@ -359,11 +367,11 @@ struct keywords {
int
yyerror(const char *fmt, ...)
{
- va_list ap;
+ va_list ap;
- errors = 1;
+ file->errors++;
va_start(ap, fmt);
- fprintf(stderr, "%s:%d: ", infile, yylval.lineno);
+ fprintf(stderr, "%s:%d: ", file->name, yylval.lineno);
vfprintf(stderr, fmt, ap);
fprintf(stderr, "\n");
va_end(ap);
@@ -417,10 +425,9 @@ char pushback_buffer[MAXPUSHBACK];
int pushback_index = 0;
int
-lgetc(int inquot)
+lgetc(int quotec)
{
- int c, next;
- FILE *f = fin;
+ int c, next;
if (parsebuf) {
/* Read character from the parsebuffer instead of input. */
@@ -436,29 +443,39 @@ lgetc(int inquot)
if (pushback_index)
return (pushback_buffer[--pushback_index]);
- if (inquot) {
- c = getc(f);
+ if (quotec) {
+ if ((c = getc(file->stream)) == EOF) {
+ yyerror("reached end of file while parsing quoted string");
+ if (popfile() == EOF)
+ return (EOF);
+ return (quotec);
+ }
return (c);
}
- while ((c = getc(f)) == '\\') {
- next = getc(f);
+ while ((c = getc(file->stream)) == '\\') {
+ next = getc(file->stream);
if (next != '\n') {
c = next;
break;
}
- yylval.lineno = lineno;
- lineno++;
+ yylval.lineno = file->lineno;
+ file->lineno++;
}
if (c == '\t' || c == ' ') {
/* Compress blanks to a single space. */
do {
- c = getc(f);
+ c = getc(file->stream);
} while (c == '\t' || c == ' ');
- ungetc(c, f);
+ ungetc(c, file->stream);
c = ' ';
}
+ while (c == EOF) {
+ if (popfile() == EOF)
+ return (EOF);
+ c = getc(file->stream);
+ }
return (c);
}
@@ -490,7 +507,7 @@ findeol(void)
while (1) {
c = lgetc(0);
if (c == '\n') {
- lineno++;
+ file->lineno++;
break;
}
if (c == EOF)
@@ -504,7 +521,7 @@ yylex(void)
{
char buf[8096];
char *p, *val;
- int endc, next, c;
+ int quotec, next, c;
int token;
top:
@@ -512,7 +529,7 @@ top:
while ((c = lgetc(0)) == ' ')
; /* nothing */
- yylval.lineno = lineno;
+ yylval.lineno = file->lineno;
if (c == '#')
while ((c = lgetc(0)) != '\n' && c != EOF)
; /* nothing */
@@ -546,21 +563,21 @@ top:
switch (c) {
case '\'':
case '"':
- endc = c;
+ quotec = c;
while (1) {
- if ((c = lgetc(1)) == EOF)
+ if ((c = lgetc(quotec)) == EOF)
return (0);
if (c == '\n') {
- lineno++;
+ file->lineno++;
continue;
} else if (c == '\\') {
- if ((next = lgetc(1)) == EOF)
+ if ((next = lgetc(quotec)) == EOF)
return (0);
- if (next == endc)
+ if (next == quotec)
c = next;
else
lungetc(next);
- } else if (c == endc) {
+ } else if (c == quotec) {
*p = '\0';
break;
}
@@ -634,17 +651,79 @@ nodigits:
return (token);
}
if (c == '\n') {
- yylval.lineno = lineno;
- lineno++;
+ yylval.lineno = file->lineno;
+ file->lineno++;
}
if (c == EOF)
return (0);
return (c);
}
+int
+check_file_secrecy(int fd, const char *fname)
+{
+ struct stat st;
+
+ if (fstat(fd, &st)) {
+ warn("cannot stat %s", fname);
+ return (-1);
+ }
+ if (st.st_uid != 0 && st.st_uid != getuid()) {
+ warnx("%s: owner not root or current user", fname);
+ return (-1);
+ }
+ if (st.st_mode & (S_IRWXG | S_IRWXO)) {
+ warnx("%s: group/world readable/writeable", fname);
+ return (-1);
+ }
+ return (0);
+}
+
+struct file *
+pushfile(const char *name, int secret)
+{
+ struct file *nfile;
+
+ if ((nfile = calloc(1, sizeof(struct file))) == NULL ||
+ (nfile->name = strdup(name)) == NULL)
+ return (NULL);
+ if ((nfile->stream = fopen(nfile->name, "r")) == NULL) {
+ free(nfile->name);
+ free(nfile);
+ return (NULL);
+ } else if (secret &&
+ check_file_secrecy(fileno(nfile->stream), nfile->name)) {
+ fclose(nfile->stream);
+ free(nfile->name);
+ free(nfile);
+ return (NULL);
+ }
+ nfile->lineno = 1;
+ TAILQ_INSERT_TAIL(&files, nfile, entry);
+ return (nfile);
+}
+
+int
+popfile(void)
+{
+ struct file *prev;
+
+ if ((prev = TAILQ_PREV(file, files, entry)) != NULL) {
+ prev->errors += file->errors;
+ TAILQ_REMOVE(&files, file, entry);
+ fclose(file->stream);
+ free(file->name);
+ free(file);
+ file = prev;
+ return (0);
+ }
+ return (EOF);
+}
+
struct ifsd_config *
parse_config(char *filename, int opts)
{
+ int errors = 0;
struct sym *sym, *next;
struct ifsd_state *state;
@@ -653,12 +732,11 @@ parse_config(char *filename, int opts)
return (NULL);
}
- if ((fin = fopen(filename, "r")) == NULL) {
+ if ((file = pushfile(filename, 0)) == NULL) {
warn("%s", filename);
free(conf);
return (NULL);
}
- infile = filename;
TAILQ_INIT(&conf->states);
@@ -668,8 +746,8 @@ parse_config(char *filename, int opts)
conf->opts = opts;
yyparse();
-
- fclose(fin);
+ errors = file->errors;
+ popfile();
/* Link states */
TAILQ_FOREACH(state, &conf->states, entries) {
@@ -692,14 +770,14 @@ parse_config(char *filename, int opts)
/* Free macros and check which have not been used. */
for (sym = TAILQ_FIRST(&symhead); sym != NULL; sym = next) {
- next = TAILQ_NEXT(sym, entries);
+ next = TAILQ_NEXT(sym, entry);
if ((conf->opts & IFSD_OPT_VERBOSE2) && !sym->used)
fprintf(stderr, "warning: macro '%s' not "
"used\n", sym->nam);
if (!sym->persist) {
free(sym->nam);
free(sym->val);
- TAILQ_REMOVE(&symhead, sym, entries);
+ TAILQ_REMOVE(&symhead, sym, entry);
free(sym);
}
}
@@ -735,7 +813,7 @@ link_states(struct ifsd_action *action)
if (state == NULL) {
fprintf(stderr, "error: state '%s' not declared\n",
action->act.statename);
- errors++;
+ file->errors++;
}
break;
}
@@ -752,7 +830,7 @@ symset(const char *nam, const char *val, int persist)
struct sym *sym;
for (sym = TAILQ_FIRST(&symhead); sym && strcmp(nam, sym->nam);
- sym = TAILQ_NEXT(sym, entries))
+ sym = TAILQ_NEXT(sym, entry))
; /* nothing */
if (sym != NULL) {
@@ -761,7 +839,7 @@ symset(const char *nam, const char *val, int persist)
else {
free(sym->nam);
free(sym->val);
- TAILQ_REMOVE(&symhead, sym, entries);
+ TAILQ_REMOVE(&symhead, sym, entry);
free(sym);
}
}
@@ -781,7 +859,7 @@ symset(const char *nam, const char *val, int persist)
}
sym->used = 0;
sym->persist = persist;
- TAILQ_INSERT_TAIL(&symhead, sym, entries);
+ TAILQ_INSERT_TAIL(&symhead, sym, entry);
return (0);
}
@@ -812,7 +890,7 @@ symget(const char *nam)
{
struct sym *sym;
- TAILQ_FOREACH(sym, &symhead, entries)
+ TAILQ_FOREACH(sym, &symhead, entry)
if (strcmp(nam, sym->nam) == 0) {
sym->used = 1;
return (sym->val);
diff --git a/usr.sbin/ntpd/parse.y b/usr.sbin/ntpd/parse.y
index cbaaa3cd334..f81341ebed0 100644
--- a/usr.sbin/ntpd/parse.y
+++ b/usr.sbin/ntpd/parse.y
@@ -1,4 +1,4 @@
-/* $OpenBSD: parse.y,v 1.36 2007/10/11 14:39:17 deraadt Exp $ */
+/* $OpenBSD: parse.y,v 1.37 2007/10/13 16:35:21 deraadt Exp $ */
/*
* Copyright (c) 2002, 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -36,20 +36,26 @@
#include "ntpd.h"
-static struct ntpd_conf *conf;
-static FILE *fin = NULL;
-static int lineno = 1;
-static int errors = 0;
-const char *infile;
-
-int yyerror(const char *, ...);
-int yyparse(void);
-int kw_cmp(const void *, const void *);
-int lookup(char *);
-int lgetc(int);
-int lungetc(int);
-int findeol(void);
-int yylex(void);
+TAILQ_HEAD(files, file) files = TAILQ_HEAD_INITIALIZER(files);
+static struct file {
+ TAILQ_ENTRY(file) entry;
+ FILE *stream;
+ char *name;
+ int lineno;
+ int errors;
+} *file;
+struct file *pushfile(const char *);
+int popfile(void);
+int yyparse(void);
+int yylex(void);
+int yyerror(const char *, ...);
+int kw_cmp(const void *, const void *);
+int lookup(char *);
+int lgetc(int);
+int lungetc(int);
+int findeol(void);
+
+struct ntpd_conf *conf;
struct opts {
int weight;
@@ -59,10 +65,10 @@ void opts_default(void);
typedef struct {
union {
- int64_t number;
+ int64_t number;
char *string;
struct ntp_addr_wrap *addr;
- struct opts opts;
+ struct opts opts;
} v;
int lineno;
} YYSTYPE;
@@ -83,11 +89,11 @@ typedef struct {
grammar : /* empty */
| grammar '\n'
- | grammar conf_main '\n'
- | grammar error '\n' { errors++; }
+ | grammar main '\n'
+ | grammar error '\n' { file->errors++; }
;
-conf_main : LISTEN ON address {
+main : LISTEN ON address {
struct listen_addr *la;
struct ntp_addr *h, *next;
@@ -279,9 +285,9 @@ yyerror(const char *fmt, ...)
va_list ap;
char *nfmt;
- errors = 1;
+ file->errors++;
va_start(ap, fmt);
- if (asprintf(&nfmt, "%s:%d: %s", infile, yylval.lineno, fmt) == -1)
+ if (asprintf(&nfmt, "%s:%d: %s", file->name, yylval.lineno, fmt) == -1)
fatalx("yyerror asprintf");
vlog(LOG_CRIT, nfmt, ap);
va_end(ap);
@@ -327,10 +333,9 @@ char pushback_buffer[MAXPUSHBACK];
int pushback_index = 0;
int
-lgetc(int inquot)
+lgetc(int quotec)
{
- int c, next;
- FILE *f = fin;
+ int c, next;
if (parsebuf) {
/* Read character from the parsebuffer instead of input. */
@@ -346,29 +351,39 @@ lgetc(int inquot)
if (pushback_index)
return (pushback_buffer[--pushback_index]);
- if (inquot) {
- c = getc(f);
+ if (quotec) {
+ if ((c = getc(file->stream)) == EOF) {
+ yyerror("reached end of file while parsing quoted string");
+ if (popfile() == EOF)
+ return (EOF);
+ return (quotec);
+ }
return (c);
}
- while ((c = getc(f)) == '\\') {
- next = getc(f);
+ while ((c = getc(file->stream)) == '\\') {
+ next = getc(file->stream);
if (next != '\n') {
c = next;
break;
}
- yylval.lineno = lineno;
- lineno++;
+ yylval.lineno = file->lineno;
+ file->lineno++;
}
if (c == '\t' || c == ' ') {
/* Compress blanks to a single space. */
do {
- c = getc(f);
+ c = getc(file->stream);
} while (c == '\t' || c == ' ');
- ungetc(c, f);
+ ungetc(c, file->stream);
c = ' ';
}
+ while (c == EOF) {
+ if (popfile() == EOF)
+ return (EOF);
+ c = getc(file->stream);
+ }
return (c);
}
@@ -400,7 +415,7 @@ findeol(void)
while (1) {
c = lgetc(0);
if (c == '\n') {
- lineno++;
+ file->lineno++;
break;
}
if (c == EOF)
@@ -414,14 +429,14 @@ yylex(void)
{
char buf[8096];
char *p;
- int endc, next, c;
+ int quotec, next, c;
int token;
p = buf;
while ((c = lgetc(0)) == ' ')
; /* nothing */
- yylval.lineno = lineno;
+ yylval.lineno = file->lineno;
if (c == '#')
while ((c = lgetc(0)) != '\n' && c != EOF)
; /* nothing */
@@ -429,21 +444,21 @@ yylex(void)
switch (c) {
case '\'':
case '"':
- endc = c;
+ quotec = c;
while (1) {
- if ((c = lgetc(1)) == EOF)
+ if ((c = lgetc(quotec)) == EOF)
return (0);
if (c == '\n') {
- lineno++;
+ file->lineno++;
continue;
} else if (c == '\\') {
- if ((next = lgetc(1)) == EOF)
+ if ((next = lgetc(quotec)) == EOF)
return (0);
- if (next == endc)
+ if (next == quotec)
c = next;
else
lungetc(next);
- } else if (c == endc) {
+ } else if (c == quotec) {
*p = '\0';
break;
}
@@ -517,33 +532,67 @@ nodigits:
return (token);
}
if (c == '\n') {
- yylval.lineno = lineno;
- lineno++;
+ yylval.lineno = file->lineno;
+ file->lineno++;
}
if (c == EOF)
return (0);
return (c);
}
+struct file *
+pushfile(const char *name)
+{
+ struct file *nfile;
+
+ if ((nfile = calloc(1, sizeof(struct file))) == NULL ||
+ (nfile->name = strdup(name)) == NULL)
+ return (NULL);
+ if ((nfile->stream = fopen(nfile->name, "r")) == NULL) {
+ free(nfile->name);
+ free(nfile);
+ return (NULL);
+ }
+ nfile->lineno = 1;
+ TAILQ_INSERT_TAIL(&files, nfile, entry);
+ return (nfile);
+}
+
+int
+popfile(void)
+{
+ struct file *prev;
+
+ if ((prev = TAILQ_PREV(file, files, entry)) != NULL) {
+ prev->errors += file->errors;
+ TAILQ_REMOVE(&files, file, entry);
+ fclose(file->stream);
+ free(file->name);
+ free(file);
+ file = prev;
+ return (0);
+ }
+ return (EOF);
+}
+
int
parse_config(const char *filename, struct ntpd_conf *xconf)
{
+ int errors = 0;
+
conf = xconf;
- lineno = 1;
- errors = 0;
TAILQ_INIT(&conf->listen_addrs);
TAILQ_INIT(&conf->ntp_peers);
TAILQ_INIT(&conf->ntp_conf_sensors);
- if ((fin = fopen(filename, "r")) == NULL) {
+ if ((file = pushfile(filename)) == NULL) {
log_warn("%s", filename);
return (-1);
}
- infile = filename;
yyparse();
-
- fclose(fin);
+ errors = file->errors;
+ popfile();
return (errors ? -1 : 0);
}
diff --git a/usr.sbin/ospf6d/ospf6d.c b/usr.sbin/ospf6d/ospf6d.c
index fd128cbe3af..0a70a3f44ae 100644
--- a/usr.sbin/ospf6d/ospf6d.c
+++ b/usr.sbin/ospf6d/ospf6d.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ospf6d.c,v 1.3 2007/10/11 21:25:37 claudio Exp $ */
+/* $OpenBSD: ospf6d.c,v 1.4 2007/10/13 16:35:22 deraadt Exp $ */
/*
* Copyright (c) 2005 Claudio Jeker <claudio@openbsd.org>
@@ -55,7 +55,6 @@ int check_child(pid_t, const char *);
void main_dispatch_ospfe(int, short, void *);
void main_dispatch_rde(int, short, void *);
-int check_file_secrecy(int, const char *);
void ospf_redistribute_default(int);
int ospf_reload(void);
@@ -489,29 +488,6 @@ main_imsg_compose_rde(int type, pid_t pid, void *data, u_int16_t datalen)
imsg_compose(ibuf_rde, type, 0, pid, data, datalen);
}
-int
-check_file_secrecy(int fd, const char *fname)
-{
- struct stat st;
-
- if (fstat(fd, &st)) {
- warn("cannot stat %s", fname);
- return (-1);
- }
-
- if (st.st_uid != 0 && st.st_uid != getuid()) {
- warnx("%s: owner not root or current user", fname);
- return (-1);
- }
-
- if (st.st_mode & (S_IRWXG | S_IRWXO)) {
- warnx("%s: group/world readable/writeable", fname);
- return (-1);
- }
-
- return (0);
-}
-
/* this needs to be added here so that ospfctl can be used without libevent */
void
imsg_event_add(struct imsgbuf *ibuf)
diff --git a/usr.sbin/ospf6d/parse.y b/usr.sbin/ospf6d/parse.y
index 1a0b409dff0..eb3cf9830e6 100644
--- a/usr.sbin/ospf6d/parse.y
+++ b/usr.sbin/ospf6d/parse.y
@@ -1,4 +1,4 @@
-/* $OpenBSD: parse.y,v 1.5 2007/10/11 21:29:53 claudio Exp $ */
+/* $OpenBSD: parse.y,v 1.6 2007/10/13 16:35:22 deraadt Exp $ */
/*
* Copyright (c) 2004, 2005 Esben Norby <norby@openbsd.org>
@@ -24,11 +24,14 @@
%{
#include <sys/types.h>
#include <sys/socket.h>
+#include <sys/stat.h>
#include <netinet/in.h>
#include <arpa/inet.h>
+
#include <ctype.h>
#include <err.h>
#include <errno.h>
+#include <unistd.h>
#include <ifaddrs.h>
#include <limits.h>
#include <stdarg.h>
@@ -40,28 +43,47 @@
#include "ospfe.h"
#include "log.h"
+TAILQ_HEAD(files, file) files = TAILQ_HEAD_INITIALIZER(files);
+static struct file {
+ TAILQ_ENTRY(file) entry;
+ FILE *stream;
+ char *name;
+ int lineno;
+ int errors;
+} *file;
+struct file *pushfile(const char *, int);
+int popfile(void);
+int check_file_secrecy(int, const char *);
+int yyparse(void);
+int yylex(void);
+int yyerror(const char *, ...);
+int kw_cmp(const void *, const void *);
+int lookup(char *);
+int lgetc(int);
+int lungetc(int);
+int findeol(void);
+
+TAILQ_HEAD(symhead, sym) symhead = TAILQ_HEAD_INITIALIZER(symhead);
+struct sym {
+ TAILQ_ENTRY(sym) entry;
+ int used;
+ int persist;
+ char *nam;
+ char *val;
+};
+int symset(const char *, const char *, int);
+char *symget(const char *);
+
+void clear_config(struct ospfd_conf *xconf);
+u_int32_t get_rtr_id(void);
+int host(const char *, struct in_addr *, struct in_addr *);
+
static struct ospfd_conf *conf;
-static FILE *fin = NULL;
-static int lineno = 1;
static int errors = 0;
-char *infile;
struct area *area = NULL;
struct iface *iface = NULL;
-int yyerror(const char *, ...);
-int yyparse(void);
-int kw_cmp(const void *, const void *);
-int lookup(char *);
-int lgetc(int);
-int lungetc(int);
-int findeol(void);
-int yylex(void);
-void clear_config(struct ospfd_conf *xconf);
-int check_file_secrecy(int fd, const char *fname);
-u_int32_t get_rtr_id(void);
-int host(const char *, struct in_addr *, struct in_addr *);
-
struct config_defaults {
u_int16_t dead_interval;
u_int16_t transmit_delay;
@@ -76,19 +98,8 @@ struct config_defaults areadefs;
struct config_defaults ifacedefs;
struct config_defaults *defs;
-TAILQ_HEAD(symhead, sym) symhead = TAILQ_HEAD_INITIALIZER(symhead);
-struct sym {
- TAILQ_ENTRY(sym) entries;
- int used;
- int persist;
- char *nam;
- char *val;
-};
-
-int symset(const char *, const char *, int);
-char *symget(const char *);
-struct area *conf_get_area(struct in_addr);
-struct iface *conf_get_if(struct kif *, struct kif_addr *);
+struct area *conf_get_area(struct in_addr);
+struct iface *conf_get_if(struct kif *, struct kif_addr *);
typedef struct {
union {
@@ -121,7 +132,7 @@ grammar : /* empty */
| grammar conf_main '\n'
| grammar varset '\n'
| grammar area '\n'
- | grammar error '\n' { errors++; }
+ | grammar error '\n' { file->errors++; }
;
string : string STRING {
@@ -520,9 +531,9 @@ yyerror(const char *fmt, ...)
{
va_list ap;
- errors = 1;
+ file->errors++;
va_start(ap, fmt);
- fprintf(stderr, "%s:%d: ", infile, yylval.lineno);
+ fprintf(stderr, "%s:%d: ", file->name, yylval.lineno);
vfprintf(stderr, fmt, ap);
fprintf(stderr, "\n");
va_end(ap);
@@ -532,7 +543,6 @@ yyerror(const char *fmt, ...)
int
kw_cmp(const void *k, const void *e)
{
-
return (strcmp(k, ((const struct keywords *)e)->k_name));
}
@@ -584,10 +594,9 @@ char pushback_buffer[MAXPUSHBACK];
int pushback_index = 0;
int
-lgetc(int inquot)
+lgetc(int quotec)
{
- int c, next;
- FILE *f = fin;
+ int c, next;
if (parsebuf) {
/* Read character from the parsebuffer instead of input. */
@@ -603,29 +612,39 @@ lgetc(int inquot)
if (pushback_index)
return (pushback_buffer[--pushback_index]);
- if (inquot) {
- c = getc(f);
+ if (quotec) {
+ if ((c = getc(file->stream)) == EOF) {
+ yyerror("reached end of file while parsing quoted string");
+ if (popfile() == EOF)
+ return (EOF);
+ return (quotec);
+ }
return (c);
}
- while ((c = getc(f)) == '\\') {
- next = getc(f);
+ while ((c = getc(file->stream)) == '\\') {
+ next = getc(file->stream);
if (next != '\n') {
c = next;
break;
}
- yylval.lineno = lineno;
- lineno++;
+ yylval.lineno = file->lineno;
+ file->lineno++;
}
if (c == '\t' || c == ' ') {
/* Compress blanks to a single space. */
do {
- c = getc(f);
+ c = getc(file->stream);
} while (c == '\t' || c == ' ');
- ungetc(c, f);
+ ungetc(c, file->stream);
c = ' ';
}
+ while (c == EOF) {
+ if (popfile() == EOF)
+ return (EOF);
+ c = getc(file->stream);
+ }
return (c);
}
@@ -657,7 +676,7 @@ findeol(void)
while (1) {
c = lgetc(0);
if (c == '\n') {
- lineno++;
+ file->lineno++;
break;
}
if (c == EOF)
@@ -671,7 +690,7 @@ yylex(void)
{
char buf[8096];
char *p, *val;
- int endc, next, c;
+ int quotec, next, c;
int token;
top:
@@ -679,7 +698,7 @@ top:
while ((c = lgetc(0)) == ' ')
; /* nothing */
- yylval.lineno = lineno;
+ yylval.lineno = file->lineno;
if (c == '#')
while ((c = lgetc(0)) != '\n' && c != EOF)
; /* nothing */
@@ -713,21 +732,21 @@ top:
switch (c) {
case '\'':
case '"':
- endc = c;
+ quotec = c;
while (1) {
- if ((c = lgetc(1)) == EOF)
+ if ((c = lgetc(quotec)) == EOF)
return (0);
if (c == '\n') {
- lineno++;
+ file->lineno++;
continue;
} else if (c == '\\') {
- if ((next = lgetc(1)) == EOF)
+ if ((next = lgetc(quotec)) == EOF)
return (0);
- if (next == endc)
+ if (next == quotec)
c = next;
else
lungetc(next);
- } else if (c == endc) {
+ } else if (c == quotec) {
*p = '\0';
break;
}
@@ -801,14 +820,75 @@ nodigits:
return (token);
}
if (c == '\n') {
- yylval.lineno = lineno;
- lineno++;
+ yylval.lineno = file->lineno;
+ file->lineno++;
}
if (c == EOF)
return (0);
return (c);
}
+int
+check_file_secrecy(int fd, const char *fname)
+{
+ struct stat st;
+
+ if (fstat(fd, &st)) {
+ log_warn("cannot stat %s", fname);
+ return (-1);
+ }
+ if (st.st_uid != 0 && st.st_uid != getuid()) {
+ log_warnx("%s: owner not root or current user", fname);
+ return (-1);
+ }
+ if (st.st_mode & (S_IRWXG | S_IRWXO)) {
+ log_warnx("%s: group/world readable/writeable", fname);
+ return (-1);
+ }
+ return (0);
+}
+
+struct file *
+pushfile(const char *name, int secret)
+{
+ struct file *nfile;
+
+ if ((nfile = calloc(1, sizeof(struct file))) == NULL ||
+ (nfile->name = strdup(name)) == NULL)
+ return (NULL);
+ if ((nfile->stream = fopen(nfile->name, "r")) == NULL) {
+ free(nfile->name);
+ free(nfile);
+ return (NULL);
+ } else if (secret &&
+ check_file_secrecy(fileno(nfile->stream), nfile->name)) {
+ fclose(nfile->stream);
+ free(nfile->name);
+ free(nfile);
+ return (NULL);
+ }
+ nfile->lineno = 1;
+ TAILQ_INSERT_TAIL(&files, nfile, entry);
+ return (nfile);
+}
+
+int
+popfile(void)
+{
+ struct file *prev;
+
+ if ((prev = TAILQ_PREV(file, files, entry)) != NULL) {
+ prev->errors += file->errors;
+ TAILQ_REMOVE(&files, file, entry);
+ fclose(file->stream);
+ free(file->name);
+ free(file);
+ file = prev;
+ return (0);
+ }
+ return (EOF);
+}
+
struct ospfd_conf *
parse_config(char *filename, int opts)
{
@@ -816,6 +896,9 @@ parse_config(char *filename, int opts)
if ((conf = calloc(1, sizeof(struct ospfd_conf))) == NULL)
fatal("parse_config");
+ conf->opts = opts;
+ if (conf->opts & OSPFD_OPT_STUB_ROUTER)
+ conf->flags |= OSPFD_FLAG_STUB_ROUTER;
bzero(&globaldefs, sizeof(globaldefs));
defs = &globaldefs;
@@ -830,41 +913,30 @@ parse_config(char *filename, int opts)
conf->spf_hold_time = DEFAULT_SPF_HOLDTIME;
conf->spf_state = SPF_IDLE;
- if ((fin = fopen(filename, "r")) == NULL) {
+ if ((file = pushfile(filename, !(conf->opts & OSPFD_OPT_NOACTION))) == NULL) {
warn("%s", filename);
free(conf);
return (NULL);
}
- infile = filename;
- conf->opts = opts;
- if (conf->opts & OSPFD_OPT_STUB_ROUTER)
- conf->flags |= OSPFD_FLAG_STUB_ROUTER;
LIST_INIT(&conf->area_list);
LIST_INIT(&conf->cand_list);
SIMPLEQ_INIT(&conf->redist_list);
- if (!(conf->opts & OSPFD_OPT_NOACTION))
- if (check_file_secrecy(fileno(fin), filename)) {
- fclose(fin);
- free(conf);
- return (NULL);
- }
-
yyparse();
-
- fclose(fin);
+ errors = file->errors;
+ popfile();
/* Free macros and check which have not been used. */
for (sym = TAILQ_FIRST(&symhead); sym != NULL; sym = next) {
- next = TAILQ_NEXT(sym, entries);
+ next = TAILQ_NEXT(sym, entry);
if ((conf->opts & OSPFD_OPT_VERBOSE2) && !sym->used)
fprintf(stderr, "warning: macro '%s' not "
"used\n", sym->nam);
if (!sym->persist) {
free(sym->nam);
free(sym->val);
- TAILQ_REMOVE(&symhead, sym, entries);
+ TAILQ_REMOVE(&symhead, sym, entry);
free(sym);
}
}
@@ -887,7 +959,7 @@ symset(const char *nam, const char *val, int persist)
struct sym *sym;
for (sym = TAILQ_FIRST(&symhead); sym && strcmp(nam, sym->nam);
- sym = TAILQ_NEXT(sym, entries))
+ sym = TAILQ_NEXT(sym, entry))
; /* nothing */
if (sym != NULL) {
@@ -896,7 +968,7 @@ symset(const char *nam, const char *val, int persist)
else {
free(sym->nam);
free(sym->val);
- TAILQ_REMOVE(&symhead, sym, entries);
+ TAILQ_REMOVE(&symhead, sym, entry);
free(sym);
}
}
@@ -916,7 +988,7 @@ symset(const char *nam, const char *val, int persist)
}
sym->used = 0;
sym->persist = persist;
- TAILQ_INSERT_TAIL(&symhead, sym, entries);
+ TAILQ_INSERT_TAIL(&symhead, sym, entry);
return (0);
}
@@ -947,7 +1019,7 @@ symget(const char *nam)
{
struct sym *sym;
- TAILQ_FOREACH(sym, &symhead, entries)
+ TAILQ_FOREACH(sym, &symhead, entry)
if (strcmp(nam, sym->nam) == 0) {
sym->used = 1;
return (sym->val);
diff --git a/usr.sbin/ospfd/ospfd.c b/usr.sbin/ospfd/ospfd.c
index 480f9146511..eac5bdd48d4 100644
--- a/usr.sbin/ospfd/ospfd.c
+++ b/usr.sbin/ospfd/ospfd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ospfd.c,v 1.52 2007/10/11 12:16:45 claudio Exp $ */
+/* $OpenBSD: ospfd.c,v 1.53 2007/10/13 16:35:22 deraadt Exp $ */
/*
* Copyright (c) 2005 Claudio Jeker <claudio@openbsd.org>
@@ -55,7 +55,6 @@ int check_child(pid_t, const char *);
void main_dispatch_ospfe(int, short, void *);
void main_dispatch_rde(int, short, void *);
-int check_file_secrecy(int, const char *);
void ospf_redistribute_default(int);
int ospf_reload(void);
@@ -492,29 +491,6 @@ main_imsg_compose_rde(int type, pid_t pid, void *data, u_int16_t datalen)
imsg_compose(ibuf_rde, type, 0, pid, data, datalen);
}
-int
-check_file_secrecy(int fd, const char *fname)
-{
- struct stat st;
-
- if (fstat(fd, &st)) {
- warn("cannot stat %s", fname);
- return (-1);
- }
-
- if (st.st_uid != 0 && st.st_uid != getuid()) {
- warnx("%s: owner not root or current user", fname);
- return (-1);
- }
-
- if (st.st_mode & (S_IRWXG | S_IRWXO)) {
- warnx("%s: group/world readable/writeable", fname);
- return (-1);
- }
-
- return (0);
-}
-
/* this needs to be added here so that ospfctl can be used without libevent */
void
imsg_event_add(struct imsgbuf *ibuf)
diff --git a/usr.sbin/ospfd/parse.y b/usr.sbin/ospfd/parse.y
index 2a8df3e22f9..2951cadf3c2 100644
--- a/usr.sbin/ospfd/parse.y
+++ b/usr.sbin/ospfd/parse.y
@@ -1,4 +1,4 @@
-/* $OpenBSD: parse.y,v 1.54 2007/10/11 14:39:17 deraadt Exp $ */
+/* $OpenBSD: parse.y,v 1.55 2007/10/13 16:35:22 deraadt Exp $ */
/*
* Copyright (c) 2004, 2005 Esben Norby <norby@openbsd.org>
@@ -24,11 +24,13 @@
%{
#include <sys/types.h>
#include <sys/socket.h>
+#include <sys/stat.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <ctype.h>
#include <err.h>
#include <errno.h>
+#include <unistd.h>
#include <ifaddrs.h>
#include <limits.h>
#include <stdarg.h>
@@ -40,28 +42,47 @@
#include "ospfe.h"
#include "log.h"
+TAILQ_HEAD(files, file) files = TAILQ_HEAD_INITIALIZER(files);
+static struct file {
+ TAILQ_ENTRY(file) entry;
+ FILE *stream;
+ char *name;
+ int lineno;
+ int errors;
+} *file;
+struct file *pushfile(const char *, int);
+int popfile(void);
+int check_file_secrecy(int, const char *);
+int yyparse(void);
+int yylex(void);
+int yyerror(const char *, ...);
+int kw_cmp(const void *, const void *);
+int lookup(char *);
+int lgetc(int);
+int lungetc(int);
+int findeol(void);
+
+TAILQ_HEAD(symhead, sym) symhead = TAILQ_HEAD_INITIALIZER(symhead);
+struct sym {
+ TAILQ_ENTRY(sym) entry;
+ int used;
+ int persist;
+ char *nam;
+ char *val;
+};
+int symset(const char *, const char *, int);
+char *symget(const char *);
+
+void clear_config(struct ospfd_conf *xconf);
+u_int32_t get_rtr_id(void);
+int host(const char *, struct in_addr *, struct in_addr *);
+
static struct ospfd_conf *conf;
-static FILE *fin = NULL;
-static int lineno = 1;
static int errors = 0;
-char *infile;
struct area *area = NULL;
struct iface *iface = NULL;
-int yyerror(const char *, ...);
-int yyparse(void);
-int kw_cmp(const void *, const void *);
-int lookup(char *);
-int lgetc(int);
-int lungetc(int);
-int findeol(void);
-int yylex(void);
-void clear_config(struct ospfd_conf *xconf);
-int check_file_secrecy(int fd, const char *fname);
-u_int32_t get_rtr_id(void);
-int host(const char *, struct in_addr *, struct in_addr *);
-
struct config_defaults {
char auth_key[MAX_SIMPLE_AUTH_LEN];
struct auth_md_head md_list;
@@ -80,19 +101,8 @@ struct config_defaults areadefs;
struct config_defaults ifacedefs;
struct config_defaults *defs;
-TAILQ_HEAD(symhead, sym) symhead = TAILQ_HEAD_INITIALIZER(symhead);
-struct sym {
- TAILQ_ENTRY(sym) entries;
- int used;
- int persist;
- char *nam;
- char *val;
-};
-
-int symset(const char *, const char *, int);
-char *symget(const char *);
-struct area *conf_get_area(struct in_addr);
-struct iface *conf_get_if(struct kif *, struct kif_addr *);
+struct area *conf_get_area(struct in_addr);
+struct iface *conf_get_if(struct kif *, struct kif_addr *);
typedef struct {
union {
@@ -126,7 +136,7 @@ grammar : /* empty */
| grammar conf_main '\n'
| grammar varset '\n'
| grammar area '\n'
- | grammar error '\n' { errors++; }
+ | grammar error '\n' { file->errors++; }
;
string : string STRING {
@@ -618,9 +628,9 @@ yyerror(const char *fmt, ...)
{
va_list ap;
- errors = 1;
+ file->errors++;
va_start(ap, fmt);
- fprintf(stderr, "%s:%d: ", infile, yylval.lineno);
+ fprintf(stderr, "%s:%d: ", file->name, yylval.lineno);
vfprintf(stderr, fmt, ap);
fprintf(stderr, "\n");
va_end(ap);
@@ -630,7 +640,6 @@ yyerror(const char *fmt, ...)
int
kw_cmp(const void *k, const void *e)
{
-
return (strcmp(k, ((const struct keywords *)e)->k_name));
}
@@ -687,10 +696,9 @@ char pushback_buffer[MAXPUSHBACK];
int pushback_index = 0;
int
-lgetc(int inquot)
+lgetc(int quotec)
{
- int c, next;
- FILE *f = fin;
+ int c, next;
if (parsebuf) {
/* Read character from the parsebuffer instead of input. */
@@ -706,29 +714,39 @@ lgetc(int inquot)
if (pushback_index)
return (pushback_buffer[--pushback_index]);
- if (inquot) {
- c = getc(f);
+ if (quotec) {
+ if ((c = getc(file->stream)) == EOF) {
+ yyerror("reached end of file while parsing quoted string");
+ if (popfile() == EOF)
+ return (EOF);
+ return (quotec);
+ }
return (c);
}
- while ((c = getc(f)) == '\\') {
- next = getc(f);
+ while ((c = getc(file->stream)) == '\\') {
+ next = getc(file->stream);
if (next != '\n') {
c = next;
break;
}
- yylval.lineno = lineno;
- lineno++;
+ yylval.lineno = file->lineno;
+ file->lineno++;
}
if (c == '\t' || c == ' ') {
/* Compress blanks to a single space. */
do {
- c = getc(f);
+ c = getc(file->stream);
} while (c == '\t' || c == ' ');
- ungetc(c, f);
+ ungetc(c, file->stream);
c = ' ';
}
+ while (c == EOF) {
+ if (popfile() == EOF)
+ return (EOF);
+ c = getc(file->stream);
+ }
return (c);
}
@@ -760,7 +778,7 @@ findeol(void)
while (1) {
c = lgetc(0);
if (c == '\n') {
- lineno++;
+ file->lineno++;
break;
}
if (c == EOF)
@@ -774,7 +792,7 @@ yylex(void)
{
char buf[8096];
char *p, *val;
- int endc, next, c;
+ int quotec, next, c;
int token;
top:
@@ -782,7 +800,7 @@ top:
while ((c = lgetc(0)) == ' ')
; /* nothing */
- yylval.lineno = lineno;
+ yylval.lineno = file->lineno;
if (c == '#')
while ((c = lgetc(0)) != '\n' && c != EOF)
; /* nothing */
@@ -816,21 +834,21 @@ top:
switch (c) {
case '\'':
case '"':
- endc = c;
+ quotec = c;
while (1) {
- if ((c = lgetc(1)) == EOF)
+ if ((c = lgetc(quotec)) == EOF)
return (0);
if (c == '\n') {
- lineno++;
+ file->lineno++;
continue;
} else if (c == '\\') {
- if ((next = lgetc(1)) == EOF)
+ if ((next = lgetc(quotec)) == EOF)
return (0);
- if (next == endc)
+ if (next == quotec)
c = next;
else
lungetc(next);
- } else if (c == endc) {
+ } else if (c == quotec) {
*p = '\0';
break;
}
@@ -904,14 +922,75 @@ nodigits:
return (token);
}
if (c == '\n') {
- yylval.lineno = lineno;
- lineno++;
+ yylval.lineno = file->lineno;
+ file->lineno++;
}
if (c == EOF)
return (0);
return (c);
}
+int
+check_file_secrecy(int fd, const char *fname)
+{
+ struct stat st;
+
+ if (fstat(fd, &st)) {
+ log_warn("cannot stat %s", fname);
+ return (-1);
+ }
+ if (st.st_uid != 0 && st.st_uid != getuid()) {
+ log_warnx("%s: owner not root or current user", fname);
+ return (-1);
+ }
+ if (st.st_mode & (S_IRWXG | S_IRWXO)) {
+ log_warnx("%s: group/world readable/writeable", fname);
+ return (-1);
+ }
+ return (0);
+}
+
+struct file *
+pushfile(const char *name, int secret)
+{
+ struct file *nfile;
+
+ if ((nfile = calloc(1, sizeof(struct file))) == NULL ||
+ (nfile->name = strdup(name)) == NULL)
+ return (NULL);
+ if ((nfile->stream = fopen(nfile->name, "r")) == NULL) {
+ free(nfile->name);
+ free(nfile);
+ return (NULL);
+ } else if (secret &&
+ check_file_secrecy(fileno(nfile->stream), nfile->name)) {
+ fclose(nfile->stream);
+ free(nfile->name);
+ free(nfile);
+ return (NULL);
+ }
+ nfile->lineno = 1;
+ TAILQ_INSERT_TAIL(&files, nfile, entry);
+ return (nfile);
+}
+
+int
+popfile(void)
+{
+ struct file *prev;
+
+ if ((prev = TAILQ_PREV(file, files, entry)) != NULL) {
+ prev->errors += file->errors;
+ TAILQ_REMOVE(&files, file, entry);
+ fclose(file->stream);
+ free(file->name);
+ free(file);
+ file = prev;
+ return (0);
+ }
+ return (EOF);
+}
+
struct ospfd_conf *
parse_config(char *filename, int opts)
{
@@ -919,6 +998,9 @@ parse_config(char *filename, int opts)
if ((conf = calloc(1, sizeof(struct ospfd_conf))) == NULL)
fatal("parse_config");
+ conf->opts = opts;
+ if (conf->opts & OSPFD_OPT_STUB_ROUTER)
+ conf->flags |= OSPFD_FLAG_STUB_ROUTER;
bzero(&globaldefs, sizeof(globaldefs));
defs = &globaldefs;
@@ -934,41 +1016,30 @@ parse_config(char *filename, int opts)
conf->spf_hold_time = DEFAULT_SPF_HOLDTIME;
conf->spf_state = SPF_IDLE;
- if ((fin = fopen(filename, "r")) == NULL) {
+ if ((file = pushfile(filename, !(conf->opts & OSPFD_OPT_NOACTION))) == NULL) {
warn("%s", filename);
free(conf);
return (NULL);
}
- infile = filename;
- conf->opts = opts;
- if (conf->opts & OSPFD_OPT_STUB_ROUTER)
- conf->flags |= OSPFD_FLAG_STUB_ROUTER;
LIST_INIT(&conf->area_list);
LIST_INIT(&conf->cand_list);
SIMPLEQ_INIT(&conf->redist_list);
- if (!(conf->opts & OSPFD_OPT_NOACTION))
- if (check_file_secrecy(fileno(fin), filename)) {
- fclose(fin);
- free(conf);
- return (NULL);
- }
-
yyparse();
-
- fclose(fin);
+ errors = file->errors;
+ popfile();
/* Free macros and check which have not been used. */
for (sym = TAILQ_FIRST(&symhead); sym != NULL; sym = next) {
- next = TAILQ_NEXT(sym, entries);
+ next = TAILQ_NEXT(sym, entry);
if ((conf->opts & OSPFD_OPT_VERBOSE2) && !sym->used)
fprintf(stderr, "warning: macro '%s' not "
"used\n", sym->nam);
if (!sym->persist) {
free(sym->nam);
free(sym->val);
- TAILQ_REMOVE(&symhead, sym, entries);
+ TAILQ_REMOVE(&symhead, sym, entry);
free(sym);
}
}
@@ -993,7 +1064,7 @@ symset(const char *nam, const char *val, int persist)
struct sym *sym;
for (sym = TAILQ_FIRST(&symhead); sym && strcmp(nam, sym->nam);
- sym = TAILQ_NEXT(sym, entries))
+ sym = TAILQ_NEXT(sym, entry))
; /* nothing */
if (sym != NULL) {
@@ -1002,7 +1073,7 @@ symset(const char *nam, const char *val, int persist)
else {
free(sym->nam);
free(sym->val);
- TAILQ_REMOVE(&symhead, sym, entries);
+ TAILQ_REMOVE(&symhead, sym, entry);
free(sym);
}
}
@@ -1022,7 +1093,7 @@ symset(const char *nam, const char *val, int persist)
}
sym->used = 0;
sym->persist = persist;
- TAILQ_INSERT_TAIL(&symhead, sym, entries);
+ TAILQ_INSERT_TAIL(&symhead, sym, entry);
return (0);
}
@@ -1053,7 +1124,7 @@ symget(const char *nam)
{
struct sym *sym;
- TAILQ_FOREACH(sym, &symhead, entries)
+ TAILQ_FOREACH(sym, &symhead, entry)
if (strcmp(nam, sym->nam) == 0) {
sym->used = 1;
return (sym->val);
diff --git a/usr.sbin/relayd/parse.y b/usr.sbin/relayd/parse.y
index 1b995e11516..0a09a74ce0f 100644
--- a/usr.sbin/relayd/parse.y
+++ b/usr.sbin/relayd/parse.y
@@ -1,4 +1,4 @@
-/* $OpenBSD: parse.y,v 1.62 2007/10/11 14:39:17 deraadt Exp $ */
+/* $OpenBSD: parse.y,v 1.63 2007/10/13 16:35:21 deraadt Exp $ */
/*
* Copyright (c) 2006 Pierre-Yves Ritschard <pyr@openbsd.org>
@@ -25,6 +25,7 @@
%{
#include <sys/types.h>
#include <sys/socket.h>
+#include <sys/stat.h>
#include <sys/queue.h>
#include <netinet/in.h>
#include <net/if.h>
@@ -32,6 +33,7 @@
#include <arpa/nameser.h>
#include <ctype.h>
+#include <unistd.h>
#include <err.h>
#include <errno.h>
#include <event.h>
@@ -46,44 +48,51 @@
#include "hoststated.h"
-struct hoststated *conf = NULL;
-static FILE *fin = NULL;
-static int lineno = 1;
-static int errors = 0;
-const char *infile;
-objid_t last_service_id = 0;
-objid_t last_table_id = 0;
-objid_t last_host_id = 0;
-objid_t last_relay_id = 0;
-objid_t last_proto_id = 0;
-
-static struct service *service = NULL;
-static struct table *table = NULL;
-static struct relay *rlay = NULL;
-static struct protocol *proto = NULL;
-static struct protonode node;
-
-int yyerror(const char *, ...);
-int yyparse(void);
-int kw_cmp(const void *, const void *);
-int lookup(char *);
-int lgetc(int);
-int lungetc(int);
-int findeol(void);
-int yylex(void);
+TAILQ_HEAD(files, file) files = TAILQ_HEAD_INITIALIZER(files);
+static struct file {
+ TAILQ_ENTRY(file) entry;
+ FILE *stream;
+ char *name;
+ int lineno;
+ int errors;
+} *file;
+struct file *pushfile(const char *, int);
+int popfile(void);
+int check_file_secrecy(int, const char *);
+int yyparse(void);
+int yylex(void);
+int yyerror(const char *, ...);
+int kw_cmp(const void *, const void *);
+int lookup(char *);
+int lgetc(int);
+int lungetc(int);
+int findeol(void);
TAILQ_HEAD(symhead, sym) symhead = TAILQ_HEAD_INITIALIZER(symhead);
struct sym {
- TAILQ_ENTRY(sym) entries;
+ TAILQ_ENTRY(sym) entry;
int used;
int persist;
char *nam;
char *val;
};
-
int symset(const char *, const char *, int);
char *symget(const char *);
+struct hoststated *conf = NULL;
+static int errors = 0;
+objid_t last_service_id = 0;
+objid_t last_table_id = 0;
+objid_t last_host_id = 0;
+objid_t last_relay_id = 0;
+objid_t last_proto_id = 0;
+
+static struct service *service = NULL;
+static struct table *table = NULL;
+static struct relay *rlay = NULL;
+static struct protocol *proto = NULL;
+static struct protonode node;
+
struct address *host_v4(const char *);
struct address *host_v6(const char *);
int host_dns(const char *, struct addresslist *,
@@ -132,7 +141,7 @@ grammar : /* empty */
| grammar table '\n'
| grammar relay '\n'
| grammar proto '\n'
- | grammar error '\n' { errors++; }
+ | grammar error '\n' { file->errors++; }
;
optssl : /*empty*/ { $$ = 0; }
@@ -1151,11 +1160,11 @@ struct keywords {
int
yyerror(const char *fmt, ...)
{
- va_list ap;
+ va_list ap;
- errors = 1;
+ file->errors++;
va_start(ap, fmt);
- fprintf(stderr, "%s:%d: ", infile, yylval.lineno);
+ fprintf(stderr, "%s:%d: ", file->name, yylval.lineno);
vfprintf(stderr, fmt, ap);
fprintf(stderr, "\n");
va_end(ap);
@@ -1165,7 +1174,6 @@ yyerror(const char *fmt, ...)
int
kw_cmp(const void *k, const void *e)
{
-
return (strcmp(k, ((const struct keywords *)e)->k_name));
}
@@ -1258,10 +1266,9 @@ char pushback_buffer[MAXPUSHBACK];
int pushback_index = 0;
int
-lgetc(int inquot)
+lgetc(int quotec)
{
- int c, next;
- FILE *f = fin;
+ int c, next;
if (parsebuf) {
/* Read character from the parsebuffer instead of input. */
@@ -1277,29 +1284,39 @@ lgetc(int inquot)
if (pushback_index)
return (pushback_buffer[--pushback_index]);
- if (inquot) {
- c = getc(f);
+ if (quotec) {
+ if ((c = getc(file->stream)) == EOF) {
+ yyerror("reached end of file while parsing quoted string");
+ if (popfile() == EOF)
+ return (EOF);
+ return (quotec);
+ }
return (c);
}
- while ((c = getc(f)) == '\\') {
- next = getc(f);
+ while ((c = getc(file->stream)) == '\\') {
+ next = getc(file->stream);
if (next != '\n') {
c = next;
break;
}
- yylval.lineno = lineno;
- lineno++;
+ yylval.lineno = file->lineno;
+ file->lineno++;
}
if (c == '\t' || c == ' ') {
/* Compress blanks to a single space. */
do {
- c = getc(f);
+ c = getc(file->stream);
} while (c == '\t' || c == ' ');
- ungetc(c, f);
+ ungetc(c, file->stream);
c = ' ';
}
+ while (c == EOF) {
+ if (popfile() == EOF)
+ return (EOF);
+ c = getc(file->stream);
+ }
return (c);
}
@@ -1331,7 +1348,7 @@ findeol(void)
while (1) {
c = lgetc(0);
if (c == '\n') {
- lineno++;
+ file->lineno++;
break;
}
if (c == EOF)
@@ -1345,7 +1362,7 @@ yylex(void)
{
char buf[8096];
char *p, *val;
- int endc, next, c;
+ int quotec, next, c;
int token;
top:
@@ -1353,7 +1370,7 @@ top:
while ((c = lgetc(0)) == ' ')
; /* nothing */
- yylval.lineno = lineno;
+ yylval.lineno = file->lineno;
if (c == '#')
while ((c = lgetc(0)) != '\n' && c != EOF)
; /* nothing */
@@ -1387,21 +1404,21 @@ top:
switch (c) {
case '\'':
case '"':
- endc = c;
+ quotec = c;
while (1) {
- if ((c = lgetc(1)) == EOF)
+ if ((c = lgetc(quotec)) == EOF)
return (0);
if (c == '\n') {
- lineno++;
+ file->lineno++;
continue;
} else if (c == '\\') {
- if ((next = lgetc(1)) == EOF)
+ if ((next = lgetc(quotec)) == EOF)
return (0);
- if (next == endc)
+ if (next == quotec)
c = next;
else
lungetc(next);
- } else if (c == endc) {
+ } else if (c == quotec) {
*p = '\0';
break;
}
@@ -1475,14 +1492,75 @@ nodigits:
return (token);
}
if (c == '\n') {
- yylval.lineno = lineno;
- lineno++;
+ yylval.lineno = file->lineno;
+ file->lineno++;
}
if (c == EOF)
return (0);
return (c);
}
+int
+check_file_secrecy(int fd, const char *fname)
+{
+ struct stat st;
+
+ if (fstat(fd, &st)) {
+ log_warn("cannot stat %s", fname);
+ return (-1);
+ }
+ if (st.st_uid != 0 && st.st_uid != getuid()) {
+ log_warnx("%s: owner not root or current user", fname);
+ return (-1);
+ }
+ if (st.st_mode & (S_IRWXG | S_IRWXO)) {
+ log_warnx("%s: group/world readable/writeable", fname);
+ return (-1);
+ }
+ return (0);
+}
+
+struct file *
+pushfile(const char *name, int secret)
+{
+ struct file *nfile;
+
+ if ((nfile = calloc(1, sizeof(struct file))) == NULL ||
+ (nfile->name = strdup(name)) == NULL)
+ return (NULL);
+ if ((nfile->stream = fopen(nfile->name, "r")) == NULL) {
+ free(nfile->name);
+ free(nfile);
+ return (NULL);
+ } else if (secret &&
+ check_file_secrecy(fileno(nfile->stream), nfile->name)) {
+ fclose(nfile->stream);
+ free(nfile->name);
+ free(nfile);
+ return (NULL);
+ }
+ nfile->lineno = 1;
+ TAILQ_INSERT_TAIL(&files, nfile, entry);
+ return (nfile);
+}
+
+int
+popfile(void)
+{
+ struct file *prev;
+
+ if ((prev = TAILQ_PREV(file, files, entry)) != NULL) {
+ prev->errors += file->errors;
+ TAILQ_REMOVE(&files, file, entry);
+ fclose(file->stream);
+ free(file->name);
+ free(file);
+ file = prev;
+ return (0);
+ }
+ return (EOF);
+}
+
struct hoststated *
parse_config(const char *filename, int opts)
{
@@ -1530,27 +1608,29 @@ parse_config(const char *filename, int opts)
conf->opts = opts;
conf->confpath = filename;
- if ((fin = fopen(filename, "r")) == NULL) {
+ if ((file = pushfile(filename, 1)) == NULL) {
warn("%s", filename);
free(conf);
return (NULL);
}
- infile = filename;
setservent(1);
+
yyparse();
+ errors = file->errors;
+ popfile();
+
endservent();
- fclose(fin);
/* Free macros and check which have not been used. */
for (sym = TAILQ_FIRST(&symhead); sym != NULL; sym = next) {
- next = TAILQ_NEXT(sym, entries);
+ next = TAILQ_NEXT(sym, entry);
if ((conf->opts & HOSTSTATED_OPT_VERBOSE) && !sym->used)
fprintf(stderr, "warning: macro '%s' not "
"used\n", sym->nam);
if (!sym->persist) {
free(sym->nam);
free(sym->val);
- TAILQ_REMOVE(&symhead, sym, entries);
+ TAILQ_REMOVE(&symhead, sym, entry);
free(sym);
}
}
@@ -1616,7 +1696,7 @@ symset(const char *nam, const char *val, int persist)
struct sym *sym;
for (sym = TAILQ_FIRST(&symhead); sym && strcmp(nam, sym->nam);
- sym = TAILQ_NEXT(sym, entries))
+ sym = TAILQ_NEXT(sym, entry))
; /* nothing */
if (sym != NULL) {
@@ -1625,7 +1705,7 @@ symset(const char *nam, const char *val, int persist)
else {
free(sym->nam);
free(sym->val);
- TAILQ_REMOVE(&symhead, sym, entries);
+ TAILQ_REMOVE(&symhead, sym, entry);
free(sym);
}
}
@@ -1645,7 +1725,7 @@ symset(const char *nam, const char *val, int persist)
}
sym->used = 0;
sym->persist = persist;
- TAILQ_INSERT_TAIL(&symhead, sym, entries);
+ TAILQ_INSERT_TAIL(&symhead, sym, entry);
return (0);
}
@@ -1676,7 +1756,7 @@ symget(const char *nam)
{
struct sym *sym;
- TAILQ_FOREACH(sym, &symhead, entries)
+ TAILQ_FOREACH(sym, &symhead, entry)
if (strcmp(nam, sym->nam) == 0) {
sym->used = 1;
return (sym->val);
diff --git a/usr.sbin/ripd/parse.y b/usr.sbin/ripd/parse.y
index 8ccac2102ad..cf8192e7b29 100644
--- a/usr.sbin/ripd/parse.y
+++ b/usr.sbin/ripd/parse.y
@@ -1,4 +1,4 @@
-/* $OpenBSD: parse.y,v 1.9 2007/10/11 14:39:17 deraadt Exp $ */
+/* $OpenBSD: parse.y,v 1.10 2007/10/13 16:35:22 deraadt Exp $ */
/*
* Copyright (c) 2006 Michele Marchetto <mydecay@openbeer.it>
@@ -25,11 +25,13 @@
%{
#include <sys/types.h>
#include <sys/socket.h>
+#include <sys/stat.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <ctype.h>
#include <err.h>
#include <errno.h>
+#include <unistd.h>
#include <ifaddrs.h>
#include <limits.h>
#include <stdarg.h>
@@ -41,27 +43,35 @@
#include "ripe.h"
#include "log.h"
-static struct ripd_conf *conf;
-static FILE *fin = NULL;
-static int lineno = 1;
-static int errors = 0;
-char *infile;
-char *start_state;
+TAILQ_HEAD(files, file) files = TAILQ_HEAD_INITIALIZER(files);
+static struct file {
+ TAILQ_ENTRY(file) entry;
+ FILE *stream;
+ char *name;
+ int lineno;
+ int errors;
+} *file;
+struct file *pushfile(const char *, int);
+int popfile(void);
+int yyparse(void);
+int yylex(void);
+int yyerror(const char *, ...);
+int kw_cmp(const void *, const void *);
+int lookup(char *);
+int lgetc(int);
+int lungetc(int);
+int findeol(void);
-struct iface *iface = NULL;
-
-int yyerror(const char *, ...);
-int yyparse(void);
-int kw_cmp(const void *, const void *);
-int lookup(char *);
-int lgetc(int);
-int lungetc(int);
-int findeol(void);
-int yylex(void);
-void clear_config(struct ripd_conf *);
-int check_file_secrecy(int, const char *);
-u_int32_t get_rtr_id(void);
-int host(const char *, struct in_addr *, struct in_addr *);
+TAILQ_HEAD(symhead, sym) symhead = TAILQ_HEAD_INITIALIZER(symhead);
+struct sym {
+ TAILQ_ENTRY(sym) entry;
+ int used;
+ int persist;
+ char *nam;
+ char *val;
+};
+int symset(const char *, const char *, int);
+char *symget(const char *);
static struct {
char auth_key[MAX_SIMPLE_AUTH_LEN];
@@ -71,18 +81,16 @@ static struct {
u_int8_t cost;
} *defs, globaldefs, ifacedefs;
-TAILQ_HEAD(symhead, sym) symhead = TAILQ_HEAD_INITIALIZER(symhead);
-struct sym {
- TAILQ_ENTRY(sym) entries;
- int used;
- int persist;
- char *nam;
- char *val;
-};
+struct iface *iface = NULL;
+static struct ripd_conf *conf;
+static int errors = 0;
+char *start_state;
-int symset(const char *, const char *, int);
-char *symget(const char *);
-struct iface *conf_get_if(struct kif *);
+struct iface *conf_get_if(struct kif *);
+void clear_config(struct ripd_conf *);
+int check_file_secrecy(int, const char *);
+u_int32_t get_rtr_id(void);
+int host(const char *, struct in_addr *, struct in_addr *);
typedef struct {
union {
@@ -112,6 +120,7 @@ grammar : /* empty */
| grammar conf_main '\n'
| grammar varset '\n'
| grammar interface '\n'
+ | grammar error '\n' { file->errors++; }
;
string : string STRING {
@@ -305,7 +314,7 @@ optnl : '\n' optnl
nl : '\n' optnl
;
-interface : INTERFACE STRING {
+interface : INTERFACE STRING {
struct kif *kif;
if ((kif = kif_findname($2)) == NULL) {
@@ -333,11 +342,11 @@ interface : INTERFACE STRING {
}
;
-interface_block : '{' optnl interfaceopts_l '}'
+interface_block : '{' optnl interfaceopts_l '}'
| '{' optnl '}'
;
-interfaceopts_l : interfaceopts_l interfaceoptsl
+interfaceopts_l : interfaceopts_l interfaceoptsl
| interfaceoptsl
;
@@ -356,9 +365,9 @@ yyerror(const char *fmt, ...)
{
va_list ap;
- errors = 1;
+ file->errors++;
va_start(ap, fmt);
- fprintf(stderr, "%s:%d: ", infile, yylval.lineno);
+ fprintf(stderr, "%s:%d: ", file->name, yylval.lineno);
vfprintf(stderr, fmt, ap);
fprintf(stderr, "\n");
va_end(ap);
@@ -410,10 +419,9 @@ char pushback_buffer[MAXPUSHBACK];
int pushback_index = 0;
int
-lgetc(int inquot)
+lgetc(int quotec)
{
- int c, next;
- FILE *f = fin;
+ int c, next;
if (parsebuf) {
/* Read character from the parsebuffer instead of input. */
@@ -429,29 +437,39 @@ lgetc(int inquot)
if (pushback_index)
return (pushback_buffer[--pushback_index]);
- if (inquot) {
- c = getc(f);
+ if (quotec) {
+ if ((c = getc(file->stream)) == EOF) {
+ yyerror("reached end of file while parsing quoted string");
+ if (popfile() == EOF)
+ return (EOF);
+ return (quotec);
+ }
return (c);
}
- while ((c = getc(f)) == '\\') {
- next = getc(f);
+ while ((c = getc(file->stream)) == '\\') {
+ next = getc(file->stream);
if (next != '\n') {
c = next;
break;
}
- yylval.lineno = lineno;
- lineno++;
+ yylval.lineno = file->lineno;
+ file->lineno++;
}
if (c == '\t' || c == ' ') {
/* Compress blanks to a single space. */
do {
- c = getc(f);
+ c = getc(file->stream);
} while (c == '\t' || c == ' ');
- ungetc(c, f);
+ ungetc(c, file->stream);
c = ' ';
}
+ while (c == EOF) {
+ if (popfile() == EOF)
+ return (EOF);
+ c = getc(file->stream);
+ }
return (c);
}
@@ -483,7 +501,7 @@ findeol(void)
while (1) {
c = lgetc(0);
if (c == '\n') {
- lineno++;
+ file->lineno++;
break;
}
if (c == EOF)
@@ -497,7 +515,7 @@ yylex(void)
{
char buf[8096];
char *p, *val;
- int endc, next, c;
+ int quotec, next, c;
int token;
top:
@@ -505,7 +523,7 @@ top:
while ((c = lgetc(0)) == ' ')
; /* nothing */
- yylval.lineno = lineno;
+ yylval.lineno = file->lineno;
if (c == '#')
while ((c = lgetc(0)) != '\n' && c != EOF)
; /* nothing */
@@ -539,21 +557,21 @@ top:
switch (c) {
case '\'':
case '"':
- endc = c;
+ quotec = c;
while (1) {
- if ((c = lgetc(1)) == EOF)
+ if ((c = lgetc(quotec)) == EOF)
return (0);
if (c == '\n') {
- lineno++;
+ file->lineno++;
continue;
} else if (c == '\\') {
- if ((next = lgetc(1)) == EOF)
+ if ((next = lgetc(quotec)) == EOF)
return (0);
- if (next == endc)
+ if (next == quotec)
c = next;
else
lungetc(next);
- } else if (c == endc) {
+ } else if (c == quotec) {
*p = '\0';
break;
}
@@ -627,14 +645,75 @@ nodigits:
return (token);
}
if (c == '\n') {
- yylval.lineno = lineno;
- lineno++;
+ yylval.lineno = file->lineno;
+ file->lineno++;
}
if (c == EOF)
return (0);
return (c);
}
+int
+check_file_secrecy(int fd, const char *fname)
+{
+ struct stat st;
+
+ if (fstat(fd, &st)) {
+ log_warn("cannot stat %s", fname);
+ return (-1);
+ }
+ if (st.st_uid != 0 && st.st_uid != getuid()) {
+ log_warnx("%s: owner not root or current user", fname);
+ return (-1);
+ }
+ if (st.st_mode & (S_IRWXG | S_IRWXO)) {
+ log_warnx("%s: group/world readable/writeable", fname);
+ return (-1);
+ }
+ return (0);
+}
+
+struct file *
+pushfile(const char *name, int secret)
+{
+ struct file *nfile;
+
+ if ((nfile = calloc(1, sizeof(struct file))) == NULL ||
+ (nfile->name = strdup(name)) == NULL)
+ return (NULL);
+ if ((nfile->stream = fopen(nfile->name, "r")) == NULL) {
+ free(nfile->name);
+ free(nfile);
+ return (NULL);
+ } else if (secret &&
+ check_file_secrecy(fileno(nfile->stream), nfile->name)) {
+ fclose(nfile->stream);
+ free(nfile->name);
+ free(nfile);
+ return (NULL);
+ }
+ nfile->lineno = 1;
+ TAILQ_INSERT_TAIL(&files, nfile, entry);
+ return (nfile);
+}
+
+int
+popfile(void)
+{
+ struct file *prev;
+
+ if ((prev = TAILQ_PREV(file, files, entry)) != NULL) {
+ prev->errors += file->errors;
+ TAILQ_REMOVE(&files, file, entry);
+ fclose(file->stream);
+ free(file->name);
+ free(file);
+ file = prev;
+ return (0);
+ }
+ return (EOF);
+}
+
struct ripd_conf *
parse_config(char *filename, int opts)
{
@@ -648,38 +727,29 @@ parse_config(char *filename, int opts)
TAILQ_INIT(&defs->md_list);
defs->cost = DEFAULT_COST;
defs->auth_type = AUTH_NONE;
+ conf->opts = opts;
+ SIMPLEQ_INIT(&conf->redist_list);
- if ((fin = fopen(filename, "r")) == NULL) {
+ if ((file = pushfile(filename, !(conf->opts & RIPD_OPT_NOACTION))) == NULL) {
warn("%s", filename);
free(conf);
return (NULL);
}
- infile = filename;
-
- conf->opts = opts;
- SIMPLEQ_INIT(&conf->redist_list);
-
- if (!(conf->opts & RIPD_OPT_NOACTION))
- if (check_file_secrecy(fileno(fin), filename)) {
- fclose(fin);
- free(conf);
- return (NULL);
- }
yyparse();
-
- fclose(fin);
+ errors = file->errors;
+ popfile();
/* Free macros and check which have not been used. */
for (sym = TAILQ_FIRST(&symhead); sym != NULL; sym = next) {
- next = TAILQ_NEXT(sym, entries);
+ next = TAILQ_NEXT(sym, entry);
if ((conf->opts & RIPD_OPT_VERBOSE2) && !sym->used)
fprintf(stderr, "warning: macro '%s' not "
"used\n", sym->nam);
if (!sym->persist) {
free(sym->nam);
free(sym->val);
- TAILQ_REMOVE(&symhead, sym, entries);
+ TAILQ_REMOVE(&symhead, sym, entry);
free(sym);
}
}
@@ -701,7 +771,7 @@ symset(const char *nam, const char *val, int persist)
struct sym *sym;
for (sym = TAILQ_FIRST(&symhead); sym && strcmp(nam, sym->nam);
- sym = TAILQ_NEXT(sym, entries))
+ sym = TAILQ_NEXT(sym, entry))
; /* nothing */
if (sym != NULL) {
@@ -710,7 +780,7 @@ symset(const char *nam, const char *val, int persist)
else {
free(sym->nam);
free(sym->val);
- TAILQ_REMOVE(&symhead, sym, entries);
+ TAILQ_REMOVE(&symhead, sym, entry);
free(sym);
}
}
@@ -730,7 +800,7 @@ symset(const char *nam, const char *val, int persist)
}
sym->used = 0;
sym->persist = persist;
- TAILQ_INSERT_TAIL(&symhead, sym, entries);
+ TAILQ_INSERT_TAIL(&symhead, sym, entry);
return (0);
}
@@ -761,7 +831,7 @@ symget(const char *nam)
{
struct sym *sym;
- TAILQ_FOREACH(sym, &symhead, entries)
+ TAILQ_FOREACH(sym, &symhead, entry)
if (strcmp(nam, sym->nam) == 0) {
sym->used = 1;
return (sym->val);
@@ -772,7 +842,7 @@ symget(const char *nam)
struct iface *
conf_get_if(struct kif *kif)
{
- struct iface *i;
+ struct iface *i;
LIST_FOREACH(i, &conf->iface_list, entry)
if (i->ifindex == kif->ifindex) {
diff --git a/usr.sbin/ripd/ripd.c b/usr.sbin/ripd/ripd.c
index c9576f0572b..0ff9f2b4741 100644
--- a/usr.sbin/ripd/ripd.c
+++ b/usr.sbin/ripd/ripd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ripd.c,v 1.3 2007/01/24 10:14:17 claudio Exp $ */
+/* $OpenBSD: ripd.c,v 1.4 2007/10/13 16:35:22 deraadt Exp $ */
/*
* Copyright (c) 2006 Michele Marchetto <mydecay@openbeer.it>
@@ -54,7 +54,6 @@ void main_sig_handler(int, short, void *);
void ripd_shutdown(void);
void main_dispatch_ripe(int, short, void *);
void main_dispatch_rde(int, short, void *);
-int check_file_secrecy(int, const char *);
void ripd_redistribute_default(int);
int pipe_parent2ripe[2];
@@ -448,29 +447,6 @@ main_imsg_compose_rde(int type, pid_t pid, void *data, u_int16_t datalen)
}
int
-check_file_secrecy(int fd, const char *fname)
-{
- struct stat st;
-
- if (fstat(fd, &st)) {
- log_warn("cannot stat %s", fname);
- return (-1);
- }
-
- if (st.st_uid != 0 && st.st_uid != getuid()) {
- log_warnx("%s: owner not root or current user", fname);
- return (-1);
- }
-
- if (st.st_mode & (S_IRWXG | S_IRWXO)) {
- log_warnx("%s: group/world readable/writeable", fname);
- return (-1);
- }
-
- return (0);
-}
-
-int
rip_redistribute(struct kroute *kr)
{
struct redistribute *r;