cfg.lex
3c1a8ef8
 /*
  * $Id$
  *
  * scanner for cfg files
  */
 
 
 %{
 	#include "cfg.tab.h"
7268726e
 	#include "dprint.h"
3c1a8ef8
 	#include <string.h>
03150098
 	#include <stdlib.h>
 
 #ifdef DEBUG_DMALLOC
 #include <dmalloc.h>
 #endif
3c1a8ef8
 
 	/* states */
 	#define INITIAL_S		0
 	#define COMMENT_S		1
 	#define COMMENT_LN_S	2
 	#define STRING_S		3
 
 	
 	static int comment_nest=0;
 	static int state=0;
 	static char* str=0;
09e52ebb
 	int line=1;
 	int column=1;
 	int startcolumn=1;
3c1a8ef8
 
 	static char* addstr(char*, char**);
 	static void count();
 
 
 %}
 
 /* start conditions */
 %x STRING1 STRING2 COMMENT COMMENT_LN
 
 /* action keywords */
 FORWARD	forward
f20a56a2
 DROP	"drop"|"break"
3c1a8ef8
 SEND	send
 LOG		log
 ERROR	error
 ROUTE	route
09e52ebb
 EXEC	exec
7268726e
 SET_HOST		"rewritehost"|"sethost"|"seth"
 SET_HOSTPORT	"rewritehostport"|"sethostport"|"sethp"
 SET_USER		"rewriteuser"|"setuser"|"setu"
 SET_USERPASS	"rewriteuserpass"|"setuserpass"|"setup"
 SET_PORT		"rewriteport"|"setport"|"setp"
 SET_URI			"rewriteuri"|"seturi"
f20a56a2
 IF				"if"
 ELSE			"else"
7268726e
 
5ada8f8a
 /*ACTION LVALUES*/
 URIHOST			"uri:host"
 URIPORT			"uri:port"
 
7268726e
 
3c1a8ef8
 /* condition keywords */
 METHOD	method
 URI		uri
 SRCIP	src_ip
 DSTIP	dst_ip
 /* operators */
 EQUAL	=
 EQUAL_T	==
7268726e
 MATCH	=~
09e52ebb
 NOT		!|"not"
3c1a8ef8
 AND		"and"|"&&"|"&"
 OR		"or"|"||"|"|"
 
 /* config vars. */
 DEBUG	debug
 FORK	fork
 LOGSTDERROR	log_stderror
 LISTEN		listen
 DNS		 dns
 REV_DNS	 rev_dns
7268726e
 PORT	port
f571aa35
 STAT	statistics
c3ce2841
 MAXBUFFER maxbuffer
7268726e
 CHILDREN children
 CHECK_VIA	check_via
676eb608
 LOOP_CHECKS	loop_checks
3c1a8ef8
 
3bf76e49
 LOADMODULE	loadmodule
 
3c1a8ef8
 /* values */
 YES			"yes"|"true"|"on"|"enable"
 NO			"no"|"false"|"off"|"disable"
 
 LETTER		[a-zA-Z]
 DIGIT		[0-9]
3bf76e49
 ALPHANUM	{LETTER}|{DIGIT}|[_]
3c1a8ef8
 NUMBER		{DIGIT}+
 ID			{LETTER}{ALPHANUM}*
 QUOTES		\"
 TICK		\'
 SLASH		"/"
 SEMICOLON	;
 RPAREN		\)
 LPAREN		\(
 LBRACE		\{
 RBRACE		\}
 LBRACK		\[
 RBRACK		\]
f539ba9c
 COMMA		","
3c1a8ef8
 DOT			\.
 CR			\n
 
 
 
 COM_LINE	#
 COM_START	"/\*"
 COM_END		"\*/"
 
 EAT_ABLE	[\ \t\b\r]
 
 %%
 
 
 <INITIAL>{EAT_ABLE}	{ count(); }
 
 <INITIAL>{FORWARD}	{count(); yylval.strval=yytext; return FORWARD; }
 <INITIAL>{DROP}	{ count(); yylval.strval=yytext; return DROP; }
 <INITIAL>{SEND}	{ count(); yylval.strval=yytext; return SEND; }
7268726e
 <INITIAL>{LOG}	{ count(); yylval.strval=yytext; return LOG_TOK; }
3c1a8ef8
 <INITIAL>{ERROR}	{ count(); yylval.strval=yytext; return ERROR; }
 <INITIAL>{ROUTE}	{ count(); yylval.strval=yytext; return ROUTE; }
09e52ebb
 <INITIAL>{EXEC}	{ count(); yylval.strval=yytext; return EXEC; }
7268726e
 <INITIAL>{SET_HOST}	{ count(); yylval.strval=yytext; return SET_HOST; }
 <INITIAL>{SET_HOSTPORT}	{ count(); yylval.strval=yytext; return SET_HOSTPORT; }
 <INITIAL>{SET_USER}	{ count(); yylval.strval=yytext; return SET_USER; }
 <INITIAL>{SET_USERPASS}	{ count(); yylval.strval=yytext; return SET_USERPASS; }
 <INITIAL>{SET_PORT}	{ count(); yylval.strval=yytext; return SET_PORT; }
 <INITIAL>{SET_URI}	{ count(); yylval.strval=yytext; return SET_URI; }
f20a56a2
 <INITIAL>{IF}	{ count(); yylval.strval=yytext; return IF; }
 <INITIAL>{ELSE}	{ count(); yylval.strval=yytext; return ELSE; }
3c1a8ef8
 
5ada8f8a
 <INITIAL>{URIHOST}	{ count(); yylval.strval=yytext; return URIHOST; }
 <INITIAL>{URIPORT}	{ count(); yylval.strval=yytext; return URIPORT; }
 
3c1a8ef8
 <INITIAL>{METHOD}	{ count(); yylval.strval=yytext; return METHOD; }
 <INITIAL>{URI}	{ count(); yylval.strval=yytext; return URI; }
 <INITIAL>{SRCIP}	{ count(); yylval.strval=yytext; return SRCIP; }
 <INITIAL>{DSTIP}	{ count(); yylval.strval=yytext; return DSTIP; }
 
 <INITIAL>{DEBUG}	{ count(); yylval.strval=yytext; return DEBUG; }
 <INITIAL>{FORK}		{ count(); yylval.strval=yytext; return FORK; }
 <INITIAL>{LOGSTDERROR}	{ yylval.strval=yytext; return LOGSTDERROR; }
 <INITIAL>{LISTEN}	{ count(); yylval.strval=yytext; return LISTEN; }
 <INITIAL>{DNS}	{ count(); yylval.strval=yytext; return DNS; }
 <INITIAL>{REV_DNS}	{ count(); yylval.strval=yytext; return REV_DNS; }
7268726e
 <INITIAL>{PORT}	{ count(); yylval.strval=yytext; return PORT; }
f571aa35
 <INITIAL>{STAT}	{ count(); yylval.strval=yytext; return STAT; }
c3ce2841
 <INITIAL>{MAXBUFFER}	{ count(); yylval.strval=yytext; return MAXBUFFER; }
7268726e
 <INITIAL>{CHILDREN}	{ count(); yylval.strval=yytext; return CHILDREN; }
 <INITIAL>{CHECK_VIA}	{ count(); yylval.strval=yytext; return CHECK_VIA; }
676eb608
 <INITIAL>{LOOP_CHECKS}	{ count(); yylval.strval=yytext; return LOOP_CHECKS; }
3bf76e49
 <INITIAL>{LOADMODULE}	{ count(); yylval.strval=yytext; return LOADMODULE; }
3c1a8ef8
 
 <INITIAL>{EQUAL}	{ count(); return EQUAL; }
 <INITIAL>{EQUAL_T}	{ count(); return EQUAL_T; }
 <INITIAL>{MATCH}	{ count(); return MATCH; }
 <INITIAL>{NOT}		{ count(); return NOT; }
 <INITIAL>{AND}		{ count(); return AND; }
 <INITIAL>{OR}		{ count(); return OR;  }
 
 <INITIAL>{NUMBER}		{ count(); yylval.intval=atoi(yytext);
 							return NUMBER; }
 <INITIAL>{YES}			{ count(); yylval.intval=1; return NUMBER; }
 <INITIAL>{NO}			{ count(); yylval.intval=0; return NUMBER; }
 
 <INITIAL>{COMMA}		{ count(); return COMMA; }
 <INITIAL>{SEMICOLON}	{ count(); return SEMICOLON; }
 <INITIAL>{RPAREN}	{ count(); return RPAREN; }
 <INITIAL>{LPAREN}	{ count(); return LPAREN; }
 <INITIAL>{LBRACE}	{ count(); return LBRACE; }
 <INITIAL>{RBRACE}	{ count(); return RBRACE; }
 <INITIAL>{LBRACK}	{ count(); return LBRACK; }
 <INITIAL>{RBRACK}	{ count(); return RBRACK; }
 <INITIAL>{SLASH}	{ count(); return SLASH; }
 <INITIAL>{DOT}		{ count(); return DOT; }
 <INITIAL>\\{CR}		{count(); } /* eat the escaped CR */
f20a56a2
 <INITIAL>{CR}		{ count();/* return CR;*/ }
3c1a8ef8
 
 
 <INITIAL>{QUOTES} { count(); state=STRING_S; BEGIN(STRING1); }
 <INITIAL>{TICK} { count(); state=STRING_S; BEGIN(STRING2); }
 
 
 <STRING1>{QUOTES} { count(); state=INITIAL_S; BEGIN(INITIAL); 
 						yytext[yyleng-1]=0; yyleng--;
 						addstr(yytext, &str);
c07508e2
 						yylval.strval=str; str=0;
 						return STRING;
3c1a8ef8
 					}
 <STRING2>{TICK}  { count(); state=INITIAL_S; BEGIN(INITIAL); 
 						yytext[yyleng-1]=0; yyleng--;
c07508e2
 						addstr(yytext, &str);
 						yylval.strval=str;
 						str=0;
 						return STRING;
3c1a8ef8
 					}
 <STRING2>.|{EAT_ABLE}|{CR}	{ yymore(); }
 
 <STRING1>\\n		{ count(); yytext[yyleng-2]='\n';yytext[yyleng-1]=0; 
 						yyleng--; addstr(yytext, &str); }
34fd2612
 <STRING1>\\r		{ count(); yytext[yyleng-2]='\r';yytext[yyleng-1]=0; 
 						yyleng--; addstr(yytext, &str); }
5ada8f8a
 <STRING1>\\a		{ count(); yytext[yyleng-2]='\a';yytext[yyleng-1]=0; 
34fd2612
 						yyleng--; addstr(yytext, &str); }
3c1a8ef8
 <STRING1>\\t		{ count(); yytext[yyleng-2]='\t';yytext[yyleng-1]=0; 
 						yyleng--; addstr(yytext, &str); }
 <STRING1>\\\\		{ count(); yytext[yyleng-2]='\\';yytext[yyleng-1]=0; 
 						yyleng--; addstr(yytext, &str); } 
 <STRING1>.|{EAT_ABLE}|{CR}	{ yymore(); }
 
 
 <INITIAL,COMMENT>{COM_START}	{ count(); comment_nest++; state=COMMENT_S;
 										BEGIN(COMMENT); }
 <COMMENT>{COM_END}				{ count(); comment_nest--;
 										if (comment_nest==0){
 											state=INITIAL_S;
 											BEGIN(INITIAL);
 										}
 								}
 <COMMENT>.|{EAT_ABLE}|{CR}				{ count(); };
 
 <INITIAL>{COM_LINE}.*{CR}	{ count(); } 
 
09e52ebb
 <INITIAL>{ID}			{ count(); addstr(yytext, &str);
 						  yylval.strval=str; str=0; return ID; }
3c1a8ef8
 
 
 <<EOF>>							{
 									switch(state){
 										case STRING_S: 
7268726e
 											LOG(L_CRIT, "ERROR: cfg. parser: unexpected EOF in"
 														" unclosed string\n");
3c1a8ef8
 											if (str) {free(str); str=0;}
 											break;
 										case COMMENT_S:
7268726e
 											LOG(L_CRIT, "ERROR: cfg. parser: unexpected EOF:"
 														" %d comments open\n", comment_nest);
3c1a8ef8
 											break;
 										case COMMENT_LN_S:
7268726e
 											LOG(L_CRIT, "ERROR: unexpected EOF:"
 														"comment line open\n");
3c1a8ef8
 											break;
 									}
 									return 0;
 								}
 			
 %%
 
 static char* addstr(char * src, char ** dest)
 {
 	char *tmp;
3e429f5c
 	unsigned len1, len2;
3c1a8ef8
 	
 	if (*dest==0){
 		*dest=strdup(src);
 	}else{
 		len1=strlen(*dest);
 		len2=strlen(src);
 		tmp=malloc(len1+len2+1);
 		if (tmp==0) goto error;
 		memcpy(tmp, *dest, len1);
 		memcpy(tmp+len1, src, len2);
 		tmp[len1+len2]=0;
 		free(*dest);
 		*dest=tmp;
 	}
 	return *dest;
 error:
7268726e
 	LOG(L_CRIT, "ERROR:lex:addstr: memory allocation error\n");
3c1a8ef8
 	return 0;
 }
 
 
 
 static void count()
 {
 	int i;
 	
09e52ebb
 	startcolumn=column;
3c1a8ef8
 	for (i=0; i<yyleng;i++){
 		if (yytext[i]=='\n'){
 			line++;
09e52ebb
 			column=startcolumn=1;
3c1a8ef8
 		}else if (yytext[i]=='\t'){
09e52ebb
 			column++;
 			/*column+=8 -(column%8);*/
3c1a8ef8
 		}else{
 			column++;
 		}
 	}
 }