aboutsummaryrefslogtreecommitdiff
path: root/cftoken.l
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 /cftoken.l
parentdc17a7a9bd72e5bef9e31653708df355fc6666d9 (diff)
supported 'include' statement (contributed by Bruno STEVANT)
Diffstat (limited to 'cftoken.l')
-rw-r--r--cftoken.l67
1 files changed, 67 insertions, 0 deletions
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;
{