From owner-freebsd-audit Wed Jun 27 23: 0:36 2001 Delivered-To: freebsd-audit@freebsd.org Received: from bazooka.unixfreak.org (bazooka.unixfreak.org [63.198.170.138]) by hub.freebsd.org (Postfix) with ESMTP id 20FBE37B403; Wed, 27 Jun 2001 23:00:20 -0700 (PDT) (envelope-from dima@unixfreak.org) Received: from hornet.unixfreak.org (hornet [63.198.170.140]) by bazooka.unixfreak.org (Postfix) with ESMTP id C14C13E32; Wed, 27 Jun 2001 23:00:19 -0700 (PDT) To: audit@freebsd.org Cc: peter@freebsd.org Subject: config(8) 'include' patch Date: Wed, 27 Jun 2001 23:00:19 -0700 From: Dima Dorfman Message-Id: <20010628060019.C14C13E32@bazooka.unixfreak.org> Sender: owner-freebsd-audit@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.ORG The attached patch, mostly ported from OpenBSD, adds an 'include' directive to config(8). As discussed on -hackers, this can be used to split up kernel config files into a machine-dependent and machine-independent parts. In relation to this, some people also asked for unoption/undevice directives; it looks like those would be easy to implement, but I'd like to commit this first since these changes ('include' vs. 'unoption') are technically unrelated. Please review and comment. Thanks, Dima Dorfman dima@unixfreak.org Index: config.h =================================================================== RCS file: /stl/src/FreeBSD/src/usr.sbin/config/config.h,v retrieving revision 1.48 diff -u -r1.48 config.h --- config.h 2001/02/28 02:55:15 1.48 +++ config.h 2001/06/28 05:51:11 @@ -142,6 +142,7 @@ extern char errbuf[80]; extern int yyline; +extern const char *yyfile; extern struct file_list *ftab; Index: config.y =================================================================== RCS file: /stl/src/FreeBSD/src/usr.sbin/config/config.y,v retrieving revision 1.54 diff -u -r1.54 config.y --- config.y 2001/02/22 04:00:29 1.54 +++ config.y 2001/06/28 05:51:11 @@ -17,6 +17,7 @@ %token OPTIONS %token MAKEOPTIONS %token SEMICOLON +%token INCLUDE %token ID %token NUMBER @@ -77,14 +78,15 @@ char *hints; int hintmode; int yyline; +const char *yyfile; struct file_list *ftab; char errbuf[80]; int maxusers; #define ns(s) strdup(s) +int include(const char *, int); +void yyerror(const char *s); -static void yyerror(const char *s); - static char * devopt(char *dev) { @@ -147,11 +149,14 @@ = { hints = $2; hintmode = 1; - }; + } | + INCLUDE ID + = { include($2, 0); }; System_spec: CONFIG System_id System_parameter_list - = { errx(1, "line %d: root/dump/swap specifications obsolete", yyline);} + = { errx(1, "%s:%d: root/dump/swap specifications obsolete", + yyfile, yyline);} | CONFIG System_id ; @@ -178,7 +183,8 @@ newopt(&opt, $1, NULL); if ((s = strchr($1, '='))) - errx(1, "line %d: The `=' in options should not be quoted", yyline); + errx(1, "%s:%d: The `=' in options should not be " + "quoted", yyfile, yyline); } | Save_id EQUALS Opt_value = { @@ -229,16 +235,17 @@ /* and the device part */ newdev($2, $3); if ($3 == 0) - errx(1, "line %d: devices with zero units are not likely to be correct", yyline); + errx(1, "%s:%d: devices with zero units are not " + "likely to be correct", yyfile, yyline); } ; %% -static void +void yyerror(const char *s) { - errx(1, "line %d: %s", yyline + 1, s); + errx(1, "%s:%d: %s", yyfile, yyline + 1, s); } /* Index: lang.l =================================================================== RCS file: /stl/src/FreeBSD/src/usr.sbin/config/lang.l,v retrieving revision 1.30 diff -u -r1.30 lang.l --- lang.l 2001/02/19 04:43:21 1.30 +++ lang.l 2001/06/28 05:51:11 @@ -35,6 +35,7 @@ * $FreeBSD: src/usr.sbin/config/lang.l,v 1.30 2001/02/19 04:43:21 peter Exp $ */ +#include #include #include #include "y.tab.h" @@ -43,6 +44,19 @@ #define YY_NO_UNPUT /* + * Data for returning to previous files from include files. + */ +struct incl { + struct incl *in_prev; /* previous includes in effect, if any */ + YY_BUFFER_STATE in_buf; /* previous lex state */ + const char *in_fname; /* previous file name */ + int in_lineno; /* previous line number */ + int in_ateof; /* token to insert at EOF */ +}; +static struct incl *inclp; +static const char *lastfile; + +/* * Key word table */ @@ -61,13 +75,17 @@ { "profile", PROFILE }, { "option", OPTIONS }, { "options", OPTIONS }, + { "include", INCLUDE }, { 0, 0 }, }; +static int endinclude(void); +int include(const char *, int); int kw_lookup(char *); int octal(char *); int hex(char *); +int yyerror(const char *); %} WORD [A-Za-z_][-A-Za-z_]* @@ -145,6 +163,16 @@ ";" { return SEMICOLON; } "," { return COMMA; } "=" { BEGIN TOEOL; return EQUALS; } +<> { + int tok; + + if (inclp == NULL) + return YY_NULL; + tok = endinclude(); + if (tok != 0) + return tok; + /* otherwise continue scanning */ + } . { return yytext[0]; } %% @@ -185,4 +213,61 @@ (void) sscanf(str+2, "%x", &num); return num; +} + + +/* + * Open the named file for inclusion at the current point. Returns 0 on + * success (file opened and previous state pushed), nonzero on failure + * (fopen failed, complaint made). The `ateof' parameter controls the + * token to be inserted at the end of the include file. If ateof == 0, + * then nothing is inserted. + */ +int +include(const char *fname, int ateof) +{ + FILE *fp; + struct incl *in; + + fp = fopen(fname, "r"); + if (fp == NULL) { + yyerror("cannot open file"); + return (-1); + } + in = malloc(sizeof(*in)); + assert(in != NULL); + in->in_prev = inclp; + in->in_buf = YY_CURRENT_BUFFER; + in->in_fname = yyfile; + in->in_lineno = yyline; + in->in_ateof = ateof; + inclp = in; + yy_switch_to_buffer(yy_create_buffer(fp, YY_BUF_SIZE)); + yyfile = fname; + yyline = 0; + return (0); +} + +/* + * Terminate the most recent inclusion. + */ +static int +endinclude() +{ + struct incl *in; + int ateof; + + in = inclp; + assert(in != NULL); + inclp = in->in_prev; + lastfile = yyfile; + yy_delete_buffer(YY_CURRENT_BUFFER); + (void)fclose(yyin); + yy_switch_to_buffer(in->in_buf); + yyfile = in->in_fname; + yyline = in->in_lineno; + ateof = in->in_ateof; + free(in); + + return (ateof); } Index: main.c =================================================================== RCS file: /stl/src/FreeBSD/src/usr.sbin/config/main.c,v retrieving revision 1.50 diff -u -r1.50 main.c --- main.c 2001/02/23 00:22:04 1.50 +++ main.c 2001/06/28 05:51:11 @@ -144,6 +144,7 @@ errx(2, "%s isn't a directory", p); dtab = NULL; + yyfile = *argv; if (yyparse()) exit(3); if (machinename == NULL) { To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-audit" in the body of the message