aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSUZUKI, Shinsuke <suz@kame.net>2006-04-26 09:32:46 +0000
committerSUZUKI, Shinsuke <suz@kame.net>2006-04-26 09:32:46 +0000
commitc8548ef8ee768d64e1f30ea720990297a4889968 (patch)
tree38a2ef51f3b61567d15f237371e109857a358442
parentdc17a7a9bd72e5bef9e31653708df355fc6666d9 (diff)
supported 'include' statement (contributed by Bruno STEVANT)
-rw-r--r--CHANGES4
-rw-r--r--cfparse.y14
-rw-r--r--cftoken.l67
-rw-r--r--config.c3
-rw-r--r--config.h1
-rw-r--r--dhcp6s.conf.512
6 files changed, 99 insertions, 2 deletions
diff --git a/CHANGES b/CHANGES
index 9bf0a28..cd1f3b7 100644
--- a/CHANGES
+++ b/CHANGES
@@ -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
diff --git a/cfparse.y b/cfparse.y
index 9d8857f..5b6b8a4 100644
--- a/cfparse.y
+++ b/cfparse.y
@@ -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
{
diff --git a/cftoken.l b/cftoken.l
index 337a6cc..f932cb8 100644
--- a/cftoken.l
+++ b/cftoken.l
@@ -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;
{
diff --git a/config.c b/config.c
index bdb17f2..70185c9 100644
--- a/config.c
+++ b/config.c
@@ -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;
{
diff --git a/config.h b/config.h
index fe56b3b..04c8785 100644
--- a/config.h
+++ b/config.h
@@ -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.