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