Module: sip-router
Branch: master
Commit: d20565193c1176312a29d75710d494707abdf6a5
URL:
http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=d205651…
Author: Daniel-Constantin Mierla <miconda(a)gmail.com>
Committer: Daniel-Constantin Mierla <miconda(a)gmail.com>
Date: Tue Aug 25 19:27:01 2009 +0300
core: support for include file in cfg
- syntax:
include path/to/file
- example:
include checks.cfg
- path can be absolute or relative
- if path is relative:
- first attempt is to open the file relative to current directory
- second attempt is to open the file relative to the directory
of the file including it
- if include file fails, then print error and exit
- cfg syntax error messages print file name
- there is no restriction where 'include' can be used, can have
global parameters, module configs or entire/parts of route blocks
---
cfg.lex | 159 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-
cfg.y | 29 ++++++-----
route_struct.h | 1 +
3 files changed, 174 insertions(+), 15 deletions(-)
diff --git a/cfg.lex b/cfg.lex
index ebe2b6d..079613d 100644
--- a/cfg.lex
+++ b/cfg.lex
@@ -122,6 +122,7 @@
int column=1;
int startcolumn=1;
int startline=1;
+ char *finame = 0;
static int ign_lines=0;
static int ign_columns=0;
char* yy_number_str=0; /* str correspondent for the current NUMBER token */
@@ -132,12 +133,30 @@
static void count_more();
static void count_ignore();
+ #define MAX_INCLUDE_DEPTH 10
+ static struct sr_yy_state {
+ YY_BUFFER_STATE state;
+ int line;
+ int column;
+ int startcolumn;
+ int startline;
+ char *finame;
+ } include_stack[MAX_INCLUDE_DEPTH];
+ static int include_stack_ptr = 0;
+
+ static int sr_push_yy_state(char *fin);
+ static int sr_pop_yy_state();
+
+ static struct sr_yy_fname {
+ char *fname;
+ struct sr_yy_fname *next;
+ } *sr_yy_fname_list = 0;
%}
/* start conditions */
%x STRING1 STRING2 STR_BETWEEN COMMENT COMMENT_LN ATTR SELECT AVP_PVAR PVAR_P
-%x PVARID
+%x PVARID INCL
/* config script types : #!SER or #!KAMAILIO or #!MAX_COMPAT */
SER_CFG SER
@@ -201,6 +220,8 @@ CASE "case"
DEFAULT "default"
WHILE "while"
+INCLUDE "include"
+
/*ACTION LVALUES*/
URIHOST "uri:host"
URIPORT "uri:port"
@@ -556,6 +577,8 @@ EAT_ABLE [\ \t\b\r]
<INITIAL>{DEFAULT} { count(); yylval.strval=yytext; return DEFAULT; }
<INITIAL>{WHILE} { count(); yylval.strval=yytext; return WHILE; }
+<INITIAL>{INCLUDE} { BEGIN(INCL); }
+
<INITIAL>{URIHOST} { count(); yylval.strval=yytext; return URIHOST; }
<INITIAL>{URIPORT} { count(); yylval.strval=yytext; return URIPORT; }
@@ -1097,6 +1120,13 @@ EAT_ABLE [\ \t\b\r]
<SELECT>. { unput(yytext[0]); state = INITIAL_S; BEGIN(INITIAL); } /*
Rescan the token in INITIAL state */
+<INCL>[ \t]* /* eat the whitespace */
+<INCL>[^ \t\n]+ { /* get the include file name */
+ if(sr_push_yy_state(yytext)<0)
+ exit(-1);
+ BEGIN(INITIAL);
+}
+
<<EOF>> {
switch(state){
@@ -1141,7 +1171,8 @@ EAT_ABLE [\ \t\b\r]
" while parsing"
" avp or pvar name\n");
}
- return 0;
+ if(sr_pop_yy_state()<0)
+ return 0;
}
%%
@@ -1253,3 +1284,127 @@ int yywrap()
{
return 1;
}
+
+static int sr_push_yy_state(char *fin)
+{
+ struct sr_yy_fname *fn = NULL;
+ char *x = NULL;
+ char *newf = NULL;
+
+ if ( include_stack_ptr >= MAX_INCLUDE_DEPTH )
+ {
+ LOG(L_CRIT, "too many includes\n");
+ return -1;
+ }
+
+ include_stack[include_stack_ptr].state = YY_CURRENT_BUFFER;
+ include_stack[include_stack_ptr].line = line;
+ include_stack[include_stack_ptr].column = column;
+ include_stack[include_stack_ptr].startline = startline;
+ include_stack[include_stack_ptr].startcolumn = startcolumn;
+ include_stack[include_stack_ptr].finame = finame;
+ include_stack_ptr++;
+
+ line=1;
+ column=1;
+ startline=1;
+ startcolumn=1;
+
+ yyin = fopen(fin, "r" );
+
+ if ( ! yyin )
+ {
+ finame = (finame==0)?cfg_file:finame;
+ if(finame==0 || fin[0]=='/')
+ {
+ LOG(L_CRIT, "cannot open included file: %s\n", fin);
+ return -1;
+ }
+ x = strrchr(finame, '/');
+ if(x)
+ {
+ newf = (char*)pkg_malloc(x-finame+strlen(fin)+2);
+ if(newf==0)
+ {
+ LOG(L_CRIT, "no more pkg\n");
+ return -1;
+ }
+ newf[0] = '\0';
+ strncat(newf, finame, x-finame);
+ strcat(newf, "/");
+ strcat(newf, fin);
+ }
+ yyin = fopen(newf, "r" );
+ if ( ! yyin )
+ {
+ LOG(L_CRIT, "cannot open included file: %s (%s)\n", fin, newf);
+ return -1;
+ }
+ LOG(L_DBG, "including file: %s (%s)\n", fin, newf);
+ } else {
+ newf = fin;
+ }
+
+ fn = sr_yy_fname_list;
+ while(fn!=0)
+ {
+ if(strcmp(fn->fname, newf)==0)
+ {
+ if(newf!=fin)
+ pkg_free(newf);
+ newf = fin;
+ break;
+ }
+ fn = fn->next;
+ }
+ if(fn==0)
+ {
+ fn = (struct sr_yy_fname*)pkg_malloc(sizeof(struct sr_yy_fname));
+ if(fn==0)
+ {
+ if(newf!=fin)
+ pkg_free(newf);
+ LOG(L_CRIT, "no more pkg\n");
+ return -1;
+ }
+ if(newf==fin)
+ {
+ fn->fname = (char*)pkg_malloc(strlen(fin)+1);
+ if(fn->fname==0)
+ {
+ pkg_free(fn);
+ LOG(L_CRIT, "no more pkg!\n");
+ return -1;
+ }
+ strcpy(fn->fname, fin);
+ } else {
+ fn->fname = newf;
+ }
+ fn->next = sr_yy_fname_list;
+ sr_yy_fname_list = fn;
+ }
+
+ finame = fn->fname;
+
+ yy_switch_to_buffer( yy_create_buffer(yyin, YY_BUF_SIZE ) );
+
+ return 0;
+
+}
+
+static int sr_pop_yy_state()
+{
+ include_stack_ptr--;
+ if (include_stack_ptr<0 )
+ return -1;
+
+ yy_delete_buffer( YY_CURRENT_BUFFER );
+ yy_switch_to_buffer(include_stack[include_stack_ptr].state);
+ line=include_stack[include_stack_ptr].line;
+ column=include_stack[include_stack_ptr].column;
+ startline=include_stack[include_stack_ptr].startline;
+ startcolumn=include_stack[include_stack_ptr].startcolumn;
+ finame = include_stack[include_stack_ptr].finame;
+ return 0;
+}
+
diff --git a/cfg.y b/cfg.y
index 6950d88..25dd635 100644
--- a/cfg.y
+++ b/cfg.y
@@ -3070,7 +3070,7 @@ extern int line;
extern int column;
extern int startcolumn;
extern int startline;
-
+extern char *finame;
static void get_cpos(struct cfg_pos* pos)
{
@@ -3078,6 +3078,9 @@ static void get_cpos(struct cfg_pos* pos)
pos->e_line=line;
pos->s_col=startcolumn;
pos->e_col=column-1;
+ if(finame==0)
+ finame = (cfg_file!=0)?cfg_file:"default";
+ pos->fname=finame;
}
@@ -3090,15 +3093,15 @@ static void warn_at(struct cfg_pos* p, char* format, ...)
vsnprintf(s, sizeof(s), format, ap);
va_end(ap);
if (p->e_line!=p->s_line)
- LOG(L_WARN, "warning in config file, from line %d, column %d to"
+ LOG(L_WARN, "warning in config file %s, from line %d, column %d to"
" line %d, column %d: %s\n",
- p->s_line, p->s_col, p->e_line, p->e_col, s);
+ p->fname, p->s_line, p->s_col, p->e_line, p->e_col, s);
else if (p->s_col!=p->e_col)
- LOG(L_WARN, "warning in config file, line %d, column %d-%d: %s\n",
- p->s_line, p->s_col, p->e_col, s);
+ LOG(L_WARN, "warning in config file %s, line %d, column %d-%d: %s\n",
+ p->fname, p->s_line, p->s_col, p->e_col, s);
else
- LOG(L_WARN, "warning in config file, line %d, column %d: %s\n",
- p->s_line, p->s_col, s);
+ LOG(L_WARN, "warning in config file %s, line %d, column %d: %s\n",
+ p->fname, p->s_line, p->s_col, s);
cfg_warnings++;
}
@@ -3113,15 +3116,15 @@ static void yyerror_at(struct cfg_pos* p, char* format, ...)
vsnprintf(s, sizeof(s), format, ap);
va_end(ap);
if (p->e_line!=p->s_line)
- LOG(L_CRIT, "parse error in config file, from line %d, column %d"
+ LOG(L_CRIT, "parse error in config file %s, from line %d, column %d"
" to line %d, column %d: %s\n",
- p->s_line, p->s_col, p->e_line, p->e_col, s);
+ p->fname, p->s_line, p->s_col, p->e_line, p->e_col, s);
else if (p->s_col!=p->e_col)
- LOG(L_CRIT, "parse error in config file, line %d, column %d-%d: %s\n",
- p->s_line, p->s_col, p->e_col, s);
+ LOG(L_CRIT,"parse error in config file %s, line %d, column %d-%d: %s\n",
+ p->fname, p->s_line, p->s_col, p->e_col, s);
else
- LOG(L_CRIT, "parse error in config file, line %d, column %d: %s\n",
- p->s_line, p->s_col, s);
+ LOG(L_CRIT, "parse error in config file %s, line %d, column %d: %s\n",
+ p->fname, p->s_line, p->s_col, s);
cfg_errors++;
}
diff --git a/route_struct.h b/route_struct.h
index 9274340..fcc475e 100644
--- a/route_struct.h
+++ b/route_struct.h
@@ -136,6 +136,7 @@ struct cfg_pos{
int e_line;
unsigned short s_col;
unsigned short e_col;
+ char *fname;
};