1 %{
2 /*  $Id: configfile.l 10305 2018-12-02 14:21:56Z iulius $
3 **
4 **  A flex input file for the innfeed config file.
5 **
6 **  Written by James Brister <brister@vix.com>
7 */
8 
9 #include "innfeed.h"
10 
11 #include <errno.h>
12 #include <stdlib.h>
13 #include <string.h>
14 #include <syslog.h>
15 
16 #include "inn/libinn.h"
17 
18 #include "configfile.h"
19 #include "config_y.h"
20 #include "misc.h"
21 
22 #if ! defined (FLEX_SCANNER)
23 #error "You must use FLEX to process the lex input file."
24 #endif
25 
26 /* Some versions of flex (such as 2.6.1-1.3 in Debian stretch) declare a
27    variable as int that should be size_t.  We can't really do much about
28    that, and it's fixed in current flex, so just suppress the warning.
29    Same thing for a possible NULL pointer dereference. */
30 #pragma GCC diagnostic ignored "-Wsign-compare"
31 #pragma GCC diagnostic ignored "-Wnull-dereference"
32 
33 #if defined (FLEX_DEBUG)
34 #define YY_USER_INIT yy_flex_debug = (getenv ("YYDEBUG") == NULL ? 0 : 1)
35 #endif
36 
37 /* We never use this function but flex always defines it, so silence the
38    warnings about it. */
39 static void yyunput(int, char *) UNUSED;
40 
41 char *strPtr = 0 ;
42 int strPtrLen = 0 ;
43 int strIdx = 0 ;
44 int sawBsl ;
45 int lineCount = 0 ;
46 int current ;
47 
strAppend(int ch)48 static void strAppend (int ch)
49 {
50   if (strIdx == strPtrLen)
51     {
52       if (strPtr == 0)
53         strPtr = xmalloc (strPtrLen = 50) ;
54       else
55         strPtr = xrealloc (strPtr,strPtrLen += 10) ;
56     }
57   strPtr [strIdx++] = ch ;
58 }
59 
60 #define MAX_INCLUDE_DEPTH 11
61 struct includeFile {
62     YY_BUFFER_STATE state;
63     char *name ;
64 } include_stack[MAX_INCLUDE_DEPTH];
65 int include_stack_ptr = 0;
66 
67 %}
68 
69 %x incl
70 
71 ID	[a-zA-Z][-a-zA-Z0-9._/]+
72 
73 %%
74 
75 \n			lineCount++ ;
76 
77 ":"			{ return (COLON) ; }
78 
79 "{"			{ return (LBRACE) ; }
80 
81 "}"			{ return (RBRACE) ; }
82 
83 [pP][eE][eE][rR]	{ return (PEER) ; }
84 
85 ^"$INCLUDE"		BEGIN(incl);
86 
87 <incl>[ \t]*		/* eat the whitespace before include filename */
88 
89 <incl>[^ \t\n]+		{
90   if (include_stack_ptr == MAX_INCLUDE_DEPTH - 1)
91     {
92       int i ;
93       fprintf( stderr, "Includes nested too deeply:\n" );
94       for (i = 1 ; i <= include_stack_ptr ; i++)
95         fprintf (stderr,"\t%s\n",include_stack[i].name) ;
96 
97       syslog (LOG_ERR, "includes nested to deeply") ;
98       exit( 1 );
99     }
100 
101   if ((yyin = fopen(yytext,"r")) == NULL)
102     {
103       syslog (LOG_CRIT,"include file fopen failed: %s %s",
104               yytext,strerror(errno));
105       fprintf (stderr,"include file fopen failed: %s %s\n",
106                yytext,strerror(errno));
107       exit (1) ;
108     }
109   else
110     {
111       d_printf (1,"Including (%d) from %s\n",
112                include_stack_ptr + 1,yytext) ;
113       include_stack[include_stack_ptr].state = YY_CURRENT_BUFFER;
114       include_stack[++include_stack_ptr].name = xstrdup (yytext) ;
115       yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE));
116     }
117 
118   BEGIN(INITIAL);
119 }
120 
121 <<EOF>> {
122   if ( include_stack_ptr <= 0 )
123     yyterminate();
124   else
125     {
126       free (include_stack[include_stack_ptr].name) ;
127       yy_delete_buffer(YY_CURRENT_BUFFER);
128       yy_switch_to_buffer(include_stack[--include_stack_ptr].state);
129     }
130 }
131 
132 [gG][rR][oO][uU][pP]	{ return (GROUP) ; }
133 
134 #[^\n]*			{ (void) 0 ; }
135 
136 [ \t]+			{ (void) 1 ; }
137 
138 '\\[\\abfnrtv]'		{
139 	switch (yytext[2]) {
140 		case '\\': yylval.chr = '\\' ; break ;
141 		case 'a': yylval.chr = 007 ; break ;
142 		case 'b': yylval.chr = 010 ; break ;
143 		case 'f': yylval.chr = 014 ; break ;
144 		case 'n': yylval.chr = 012 ; break ;
145 		case 'r': yylval.chr = 015 ; break ;
146 		case 't': yylval.chr = 011 ; break ;
147 		case 'v': yylval.chr = 013 ; break ;
148 	}
149 	return (CHAR) ; }
150 
151 '.'			{ yylval.chr = yytext[1] ; return (CHAR) ; }
152 
153 '\\[0-9][0-9][0-9]'	{ yylval.chr = (char)strtol(&yytext[2], (char **)NULL, 8);
154 			  return (CHAR) ;}
155 
156 \"[^\"]*	{{
157 	size_t i ;
158 
159 	for (i = 1, strIdx = 0, sawBsl = 0 ; ; i++)
160           {
161             /* Cast yyleng to size_t because it used to be an int
162              * in flex versions anterior or equal to 2.5.35.
163              * Do not use yyget_leng() here because old flex versions
164              * do not define it. */
165             if (i < (size_t) yyleng)
166               current = yytext [i] ;
167             else
168               current = input() ;
169 
170             if (current != EOF)
171               {
172                 switch (current)
173                   {
174                     case '\\':
175                       if (sawBsl)
176                         {
177                           strAppend (current) ;
178                           sawBsl = 0 ;
179                         }
180                       else
181                         sawBsl = 1 ;
182                       break ;
183 
184                     case '\n':
185                       if (!sawBsl)
186                         strAppend(current) ;
187                       sawBsl = 0 ;
188                       lineCount++ ;
189                       break ;
190 
191                     case '\"':
192                       if (sawBsl)
193                         {
194                           strAppend (current) ;
195                           sawBsl = 0 ;
196                         }
197                       else
198                         {
199                           strAppend ('\0') ;
200                           yylval.string = strPtr ;
201                           strPtr = 0 ;
202                           strPtrLen = strIdx = 0 ;
203                           return (XSTRING) ;
204                         }
205                       break ;
206 
207                     case 'a':
208                     case 'b':
209                     case 'f':
210                     case 'n':
211                     case 'r':
212                     case 't':
213                     case 'v':
214                       if (sawBsl)
215                         {
216                           switch (current)
217                             {
218                               case 'a': strAppend (007) ; break ;
219                               case 'b': strAppend (010) ; break ;
220                               case 'f': strAppend (014) ; break ;
221                               case 'n': strAppend (012) ; break ;
222                               case 'r': strAppend (015) ; break ;
223                               case 't': strAppend (011) ; break ;
224                               case 'v': strAppend (013) ; break ;
225                             }
226                           sawBsl = 0 ;
227                         }
228                       else
229                         strAppend (current) ;
230                       break ;
231 
232                     default:
233                       strAppend (current) ;
234                       sawBsl = 0 ;
235                       break ;
236                   }
237               }
238             else
239               {
240                 return (XSTRING) ;
241               }
242           }
243 }}
244 
245 [-0-9][0-9]*		{ yylval.integer = atoi (yytext) ; return (IVAL) ; }
246 
247 [-0-9][0-9]*\.[0-9]*	{ yylval.real = atof (yytext) ; return (RVAL) ; }
248 
249 [^#:\'\" \t\n]+	{
250   yylval.name = xstrdup (yytext) ;
251   if (strcasecmp (yylval.name,"false") == 0)
252     return (FALSEBVAL) ;
253   else if (strcasecmp (yylval.name,"true") == 0)
254     return (TRUEBVAL) ;
255   else
256   return (WORD) ;
257 }
258 
259 %%
260 
261 
262 
263