diff options
author | SUZUKI, Shinsuke <suz@kame.net> | 2006-04-26 09:32:46 +0000 |
---|---|---|
committer | SUZUKI, Shinsuke <suz@kame.net> | 2006-04-26 09:32:46 +0000 |
commit | c8548ef8ee768d64e1f30ea720990297a4889968 (patch) | |
tree | 38a2ef51f3b61567d15f237371e109857a358442 | |
parent | dc17a7a9bd72e5bef9e31653708df355fc6666d9 (diff) |
supported 'include' statement (contributed by Bruno STEVANT)
-rw-r--r-- | CHANGES | 4 | ||||
-rw-r--r-- | cfparse.y | 14 | ||||
-rw-r--r-- | cftoken.l | 67 | ||||
-rw-r--r-- | config.c | 3 | ||||
-rw-r--r-- | config.h | 1 | ||||
-rw-r--r-- | dhcp6s.conf.5 | 12 |
6 files changed, 99 insertions, 2 deletions
@@ -1,3 +1,7 @@ +2006-04-26 SUZUKI, Shinsuke <suz@kame.net> + * supported 'include' statement + (contributed by Bruno STEVANT) + 2006-04-11 SUZUKI, Shinsuke <suz@kame.net> * removed 'ifdef USE_POOL' macros, since it is always ON * rename some pool-related variables to prepare for the support of prefix-pool @@ -91,6 +91,7 @@ struct cf_list *cf_sip_list, *cf_sip_name_list; long long cf_refreshtime = -1; extern int yylex __P((void)); +extern int cfswitch_buffer __P((char *)); static int add_namelist __P((struct cf_namelist *, struct cf_namelist **)); static void cleanup __P((void)); static void cleanup_namelist __P((struct cf_namelist *)); @@ -111,6 +112,7 @@ static void cleanup_cflist __P((struct cf_list *)); %token AUTHNAME RDM KEY %token KEYINFO REALM KEYID SECRET KEYNAME EXPIRE %token ADDRPOOL POOLNAME RANGE TO ADDRESS_POOL +%token INCLUDE %token NUMBER SLASH EOS BCL ECL STRING QSTRING PREFIX INFINITY %token COMMA @@ -151,6 +153,7 @@ statement: | authentication_statement | key_statement | addrpool_statement + | include_statement ; interface_statement: @@ -336,6 +339,17 @@ key_statement: } ; +include_statement: + INCLUDE QSTRING EOS + { + if (cfswitch_buffer($2)) { + free($2); + return (-1); + } + free($2); + } + ; + addrpool_statement: ADDRPOOL POOLNAME BCL declarations ECL EOS { @@ -60,6 +60,18 @@ char *configfilename; int lineno = 1; + +/* Recursion limit for includes */ +#define MAX_INCLUDE_DEPTH 10 + +static struct include_stack { + char *path; + YY_BUFFER_STATE state; + int lineno; +} incstack[MAX_INCLUDE_DEPTH]; +int incstackp = 0; + + static int yy_first_time = 1; static int yyerrorcount = 0; @@ -111,6 +123,7 @@ ecl \} %s S_KEY %s S_SECRET %s S_ADDRPOOL +%s S_INCL %% %{ @@ -267,6 +280,15 @@ ecl \} } <S_CNF>expire { DECHO; return (EXPIRE); } + /* include */ +<S_CNF>include { DECHO; BEGIN S_INCL; return (INCLUDE); } +<S_INCL>{quotedstring} { + DECHO; + yylval.str = strdup(yytext); + BEGIN S_CNF; + return (QSTRING); +} + /* quoted string */ {quotedstring} { DECHO; @@ -296,6 +318,18 @@ ecl \} return (STRING); } +<<EOF>> { + if (--incstackp < 0) + yyterminate(); + else { + yy_delete_buffer(YY_CURRENT_BUFFER); + free(incstack[incstackp + 1].path); + configfilename = incstack[incstackp].path; + lineno = incstack[incstackp].lineno; + yy_switch_to_buffer(incstack[incstackp].state); + } + } + %% static void cfdebug_print(w, t, l) @@ -353,6 +387,39 @@ yywarn(char *s, ...) } int +cfswitch_buffer(incl) + char *incl; +{ + char *path = qstrdup(incl); + FILE *fp; + + if (incstackp >= MAX_INCLUDE_DEPTH) { + dprintf(LOG_ERR, FNAME, "cfparse: includes nested too deeply"); + return (-1); + } + incstack[incstackp].path = configfilename; + incstack[incstackp].state = YY_CURRENT_BUFFER; + incstack[incstackp].lineno = lineno; + + fp = fopen(path, "r"); + if (fp == NULL) { + dprintf(LOG_ERR, FNAME, "cfparse: fopen(%s): %s", + path, strerror(errno)); + if (errno == ENOENT) + return (0); + return (-1); + } + incstackp++; + configfilename = path; + lineno = 1; + yy_switch_to_buffer(yy_create_buffer(fp, YY_BUF_SIZE)); + + BEGIN(S_CNF); + + return (0); +} + +int cfparse(conf) char *conf; { @@ -127,7 +127,6 @@ static void clear_keys __P((struct keyinfo *)); static void clear_authinfo __P((struct authinfo *)); static int configure_duid __P((char *, struct duid *)); static int get_default_ifid __P((struct prefix_ifconf *)); -static char *qstrdup __P((char *)); static void clear_poolconf __P((struct pool_conf *)); static struct pool_conf *create_pool __P((char *, struct dhcp6_range *)); struct host_conf *find_dynamic_hostconf __P((struct duid *)); @@ -1867,7 +1866,7 @@ find_key(realm, realmlen, id) return (NULL); } -static char * +char * qstrdup(qstr) char *qstr; { @@ -318,3 +318,4 @@ extern int get_free_address_from_pool __P((struct pool_conf *, struct in6_addr *)); struct host_conf *create_dynamic_hostconf __P((struct duid *, struct dhcp6_poolspec *)); +extern char *qstrdup __P((char *)); diff --git a/dhcp6s.conf.5 b/dhcp6s.conf.5 index da337da..93727f4 100644 --- a/dhcp6s.conf.5 +++ b/dhcp6s.conf.5 @@ -60,6 +60,18 @@ Interfaces are specified in the form of "name unit", such as and .Ar gif1. .\" +.Sh Include statement +An include statement specifies another configuration file to be included. +The format of an include statement is as follows: +.Bl -tag -width Ds -compact +.It Xo +.Ic include Ar \(dqfilename\(dq ; +.Xc +Where +.Ar \(dqfilename\(dq +is the name (full path) of the file to be included. +.El +.\" .Sh Option statement An option statement specifies configuration parameters provided for every client. |