cfg.lex
3c1a8ef8
 /*
  * $Id$
  *
  * scanner for cfg files
2d4b798e
  *
  * Copyright (C) 2001-2003 Fhg Fokus
  *
  * This file is part of ser, a free SIP server.
  *
  * ser is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
  * (at your option) any later version
  *
  * For a license to use the ser software under conditions
  * other than those described here, or to purchase support for this
  * software, please contact iptel.org by e-mail at the following addresses:
  *    info@iptel.org
  *
  * ser is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License 
  * along with this program; if not, write to the Free Software 
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
  * History:
  * -------
049f64c2
  * 2001-01-29 src_port added (jiri)
2d4b798e
  * 2001-01-23 mhomed added (jiri)
3c1a8ef8
  */
 
 
 %{
 	#include "cfg.tab.h"
7268726e
 	#include "dprint.h"
4e2fdd79
 	#include "globals.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;
36ef0329
 	static char* tstr=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
0c5da34b
 FORWARD_TCP	forward_tcp
f2f969dd
 FORWARD_UDP	forward_udp
f20a56a2
 DROP	"drop"|"break"
3c1a8ef8
 SEND	send
0c5da34b
 SEND_TCP	send_tcp
3c1a8ef8
 LOG		log
 ERROR	error
 ROUTE	route
caf80ae6
 REPLY_ROUTE reply_route
09e52ebb
 EXEC	exec
3881f12c
 SETFLAG		setflag
 RESETFLAG	resetflag
 ISFLAGSET	isflagset
1f377e97
 LEN_GT		len_gt
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"
caf80ae6
 REVERT_URI		"revert_uri"
1f377e97
 PREFIX			"prefix"
 STRIP			"strip"
caf80ae6
 APPEND_BRANCH	"append_branch"
f20a56a2
 IF				"if"
 ELSE			"else"
7268726e
 
5ada8f8a
 /*ACTION LVALUES*/
 URIHOST			"uri:host"
 URIPORT			"uri:port"
 
1f377e97
 MAX_LEN			"max_len"
 
7268726e
 
3c1a8ef8
 /* condition keywords */
 METHOD	method
 URI		uri
 SRCIP	src_ip
049f64c2
 SRCPORT	src_port
3c1a8ef8
 DSTIP	dst_ip
855c2e68
 MYSELF	myself
3c1a8ef8
 /* 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
e278821b
 ALIAS		alias
3c1a8ef8
 DNS		 dns
 REV_DNS	 rev_dns
7268726e
 PORT	port
f571aa35
 STAT	statistics
c3ce2841
 MAXBUFFER maxbuffer
7268726e
 CHILDREN children
 CHECK_VIA	check_via
caf80ae6
 SYN_BRANCH syn_branch
843b2927
 MEMLOG	memlog
caf80ae6
 SIP_WARNING sip_warning
 FIFO fifo
 FIFO_MODE fifo_mode
 SERVER_SIGNATURE server_signature
 REPLY_TO_VIA reply_to_via
054cb6cf
 USER		"user"|"uid"
 GROUP		"group"|"gid"
2d4b798e
 MHOMED		mhomed
3c1a8ef8
 
3bf76e49
 LOADMODULE	loadmodule
31309a3a
 MODPARAM        modparam
3bf76e49
 
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}*
4e2fdd79
 HEX			[0-9a-fA-F]
 HEX4		{HEX}{1,4}
 IPV6ADDR	({HEX4}":"){7}{HEX4}|({HEX4}":"){1,7}(":"{HEX4}){1,7}|":"(":"{HEX4}){1,7}|({HEX4}":"){1,7}":"|"::"
3c1a8ef8
 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; }
0c5da34b
 <INITIAL>{FORWARD_TCP}	{count(); yylval.strval=yytext; return FORWARD_TCP; }
f2f969dd
 <INITIAL>{FORWARD_UDP}	{count(); yylval.strval=yytext; return FORWARD_UDP; }
3c1a8ef8
 <INITIAL>{DROP}	{ count(); yylval.strval=yytext; return DROP; }
 <INITIAL>{SEND}	{ count(); yylval.strval=yytext; return SEND; }
0c5da34b
 <INITIAL>{SEND_TCP}	{ count(); yylval.strval=yytext; return SEND_TCP; }
7268726e
 <INITIAL>{LOG}	{ count(); yylval.strval=yytext; return LOG_TOK; }
3c1a8ef8
 <INITIAL>{ERROR}	{ count(); yylval.strval=yytext; return ERROR; }
3881f12c
 <INITIAL>{SETFLAG}	{ count(); yylval.strval=yytext; return SETFLAG; }
 <INITIAL>{RESETFLAG}	{ count(); yylval.strval=yytext; return RESETFLAG; }
 <INITIAL>{ISFLAGSET}	{ count(); yylval.strval=yytext; return ISFLAGSET; }
1f377e97
 <INITIAL>{LEN_GT}	{ count(); yylval.strval=yytext; return LEN_GT; }
3c1a8ef8
 <INITIAL>{ROUTE}	{ count(); yylval.strval=yytext; return ROUTE; }
caf80ae6
 <INITIAL>{REPLY_ROUTE}	{ count(); yylval.strval=yytext; return REPLY_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; }
caf80ae6
 <INITIAL>{REVERT_URI}	{ count(); yylval.strval=yytext; return REVERT_URI; }
1f377e97
 <INITIAL>{PREFIX}	{ count(); yylval.strval=yytext; return PREFIX; }
 <INITIAL>{STRIP}	{ count(); yylval.strval=yytext; return STRIP; }
caf80ae6
 <INITIAL>{APPEND_BRANCH}	{ count(); yylval.strval=yytext; return APPEND_BRANCH; }
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; }
 
1f377e97
 <INITIAL>{MAX_LEN}	{ count(); yylval.strval=yytext; return MAX_LEN; }
 
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; }
049f64c2
 <INITIAL>{SRCPORT}	{ count(); yylval.strval=yytext; return SRCPORT; }
3c1a8ef8
 <INITIAL>{DSTIP}	{ count(); yylval.strval=yytext; return DSTIP; }
855c2e68
 <INITIAL>{MYSELF}	{ count(); yylval.strval=yytext; return MYSELF; }
3c1a8ef8
 
 <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; }
e278821b
 <INITIAL>{ALIAS}	{ count(); yylval.strval=yytext; return ALIAS; }
3c1a8ef8
 <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; }
caf80ae6
 <INITIAL>{SYN_BRANCH}	{ count(); yylval.strval=yytext; return SYN_BRANCH; }
843b2927
 <INITIAL>{MEMLOG}	{ count(); yylval.strval=yytext; return MEMLOG; }
caf80ae6
 <INITIAL>{SIP_WARNING}	{ count(); yylval.strval=yytext; return SIP_WARNING; }
054cb6cf
 <INITIAL>{USER}		{ count(); yylval.strval=yytext; return USER; }
 <INITIAL>{GROUP}	{ count(); yylval.strval=yytext; return GROUP; }
2d4b798e
 <INITIAL>{MHOMED}	{ count(); yylval.strval=yytext; return MHOMED; }
caf80ae6
 <INITIAL>{FIFO}	{ count(); yylval.strval=yytext; return FIFO; }
 <INITIAL>{FIFO_MODE}	{ count(); yylval.strval=yytext; return FIFO_MODE; }
 <INITIAL>{SERVER_SIGNATURE}	{ count(); yylval.strval=yytext; return SERVER_SIGNATURE; }
 <INITIAL>{REPLY_TO_VIA}	{ count(); yylval.strval=yytext; return REPLY_TO_VIA; }
3bf76e49
 <INITIAL>{LOADMODULE}	{ count(); yylval.strval=yytext; return LOADMODULE; }
31309a3a
 <INITIAL>{MODPARAM}     { count(); yylval.strval=yytext; return MODPARAM; }
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;  }
 
4e2fdd79
 
 
 <INITIAL>{IPV6ADDR}		{ count(); yylval.strval=yytext; return IPV6ADDR; }
 <INITIAL>{NUMBER}		{ count(); yylval.intval=atoi(yytext);return NUMBER; }
3c1a8ef8
 <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--;
36ef0329
 						addstr(yytext, &tstr);
 						yylval.strval=tstr; tstr=0;
c07508e2
 						return STRING;
3c1a8ef8
 					}
 <STRING2>{TICK}  { count(); state=INITIAL_S; BEGIN(INITIAL); 
 						yytext[yyleng-1]=0; yyleng--;
36ef0329
 						addstr(yytext, &tstr);
 						yylval.strval=tstr;
 						tstr=0;
c07508e2
 						return STRING;
3c1a8ef8
 					}
 <STRING2>.|{EAT_ABLE}|{CR}	{ yymore(); }
 
 <STRING1>\\n		{ count(); yytext[yyleng-2]='\n';yytext[yyleng-1]=0; 
36ef0329
 						yyleng--; addstr(yytext, &tstr); }
34fd2612
 <STRING1>\\r		{ count(); yytext[yyleng-2]='\r';yytext[yyleng-1]=0; 
36ef0329
 						yyleng--; addstr(yytext, &tstr); }
5ada8f8a
 <STRING1>\\a		{ count(); yytext[yyleng-2]='\a';yytext[yyleng-1]=0; 
36ef0329
 						yyleng--; addstr(yytext, &tstr); }
3c1a8ef8
 <STRING1>\\t		{ count(); yytext[yyleng-2]='\t';yytext[yyleng-1]=0; 
36ef0329
 						yyleng--; addstr(yytext, &tstr); }
3c1a8ef8
 <STRING1>\\\\		{ count(); yytext[yyleng-2]='\\';yytext[yyleng-1]=0; 
36ef0329
 						yyleng--; addstr(yytext, &tstr); } 
3c1a8ef8
 <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(); } 
 
36ef0329
 <INITIAL>{ID}			{ count(); addstr(yytext, &tstr);
 						  yylval.strval=tstr; tstr=0; return ID; }
3c1a8ef8
 
 
 <<EOF>>							{
 									switch(state){
 										case STRING_S: 
7268726e
 											LOG(L_CRIT, "ERROR: cfg. parser: unexpected EOF in"
 														" unclosed string\n");
36ef0329
 											if (tstr) {free(tstr); tstr=0;}
3c1a8ef8
 											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++;
 		}
 	}
 }