chiark / gitweb /
Internal code review complete.
[userv.git] / lexer.l.m4
1 dnl  userv - lexer.l.m4
2 dnl  lexer, passed through m4 with defs from langauge.i4
3 /*
4  *   Copyright (C)1996-1997 Ian Jackson
5  *  
6  *   This is free software; you can redistribute it and/or modify it
7  *   under the terms of the GNU General Public License as published by
8  *   the Free Software Foundation; either version 2 of the License, or
9  *   (at your option) any later version.
10  *  
11  *   This program is distributed in the hope that it will be useful, but
12  *   WITHOUT ANY WARRANTY; without even the implied warranty of
13  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  *   General Public License for more details.
15  *  
16  *   You should have received a copy of the GNU General Public License
17  *   along with userv; if not, write to the Free Software
18  *   Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19  */
20
21 %{
22 include(language.i4)
23
24 #include <syslog.h>
25 #include <assert.h>
26 #include <stdio.h>
27 #include <stdarg.h>
28 #include <ctype.h>
29 #include <string.h>
30 #include <unistd.h>
31 #include <pwd.h>
32 #include <grp.h>
33 #include <fnmatch.h>
34 #include <limits.h>
35 #include <dirent.h>
36 #include <sys/stat.h>
37 #include <time.h>
38
39 #include "config.h"
40 #include "common.h"
41 #include "daemon.h"
42 #include "lib.h"
43 #include "tokens.h"
44
45 #define HYPHEN '-'
46
47 typedef int directive_fnt(int dtoken);
48 static directive_fnt df_reject, df_execute, df_executefrompath;
49 static directive_fnt df_executefromdirectory, df_executebuiltin;
50 static directive_fnt df_errorstostderr, df_errorstosyslog, df_errorstofile;
51 static directive_fnt dfg_fdwant, dfg_setflag;
52 static directive_fnt df_reset, df_cd, df_userrcfile, df_include;
53 static directive_fnt df_includelookup, df_includedirectory;
54 static directive_fnt df_message, df_error, df_quit, df_eof;
55 static directive_fnt df_if, df_catchquit, df_errorspush;
56 static directive_fnt dfi_includeuserrcfile, dfi_includeclientconfig;
57 /* directive functions return:
58  *  0 for success having scanned up to and including end of line but not beyond,
59  *  or tokv_error or tokv_quit.
60  * They expect to parse the whitespace before their parameters (if any).
61  */
62
63 typedef int parmcondition_fnt(int ctoken, char *const *parmvalues, int *rtrue);
64 static parmcondition_fnt pcf_glob, pcf_range, pcf_grep;
65 /* all conditional functions return tokv_error for failure or 0 for success
66  *  at parsing and testing, in which case *rtrue is set to 0 or 1.
67  *  On success they have scanned up to and including the condition's
68  *  terminating newline; the pcf_... functions expect to parse the whitespace
69  *  between the parameter name and the condition's arguments.
70  * Otherwise they return tokv_error.
71  * The parameter-based conditionals take a list of parameter values
72  * as obtained from the parameter functions and pa_parameter,
73  * and do _not_ free it.
74  */
75
76 typedef int parameter_fnt(int ptoken, char ***rvalues);
77 static parameter_fnt pf_service;
78 static parameter_fnt pf_callinguser, pf_serviceuser;
79 static parameter_fnt pf_callinggroup, pf_servicegroup;
80 static parameter_fnt pf_callingusershell, pf_serviceusershell;
81 /* Parameter functions return tokv_error or 0 for success at parsing
82  * and determining the value, in which case *rvalues is made to be
83  * a mallocd null-terminated array of pointers to mallocd strings.
84  * freeparm can be used to free such an array.
85  */
86
87 typedef int builtinserviceparse_fnt(char ***rnewargs);
88 static builtinserviceparse_fnt bispa_none, bispa_parameter;
89 /* These parse the arguments to a builtin service, including the
90  * newline at the end of the line.  *rnewargs will initially be
91  * null, indicating that no arguments are to be set; the function
92  * may store a mallocd array of mallocd strings in it,
93  * containing the arguments it wishes to have set (null-pointer
94  * terminated).
95  */
96
97 static int yylex(void);
98 /* Returns a token (which may be an eof or error exception) */
99
100 static directive_fnt *lr_dir;
101 static parmcondition_fnt *lr_parmcond;
102 static builtinserviceparse_fnt *lr_bispa;
103 static builtinserviceexec_fnt *lr_bisexec;
104 static parameter_fnt *lr_parameter;
105 static int lr_loglevel, lr_logfacility, lr_min, lr_max, *lr_flag;
106 static int lr_flagval, lr_controlend;
107 static int lr_fdwant_readwrite; /* -1=never, 0=opt, 1=always */
108
109 /* Forward declarations of things used in lexer and parser */
110
111 struct parser_state {
112   int lineno, reportlineno, notedreferer, isinternal;
113   const char *filename;
114   struct stat filestab;
115   YY_BUFFER_STATE ybuf;
116   struct parser_state *upstate;
117 };
118
119 static struct parser_state *cstate;
120
121 struct error_handling {
122   int handling; /* One of the error handling modes tokt_ehandlemode */
123   int logfacility, loglevel;
124   int filekeep; /* File is in use by higher-level errors-push, leave it open */
125   FILE *file;
126   char *filename;
127 };
128
129 static struct error_handling eh = { tokv_word_errorstostderr, 0,0,0,0,0 };
130
131 static int dequote(char *inplace);
132
133 #define YY_NO_UNPUT
134
135 %}
136
137 %option noyywrap
138
139 %%
140
141 dnl simple words
142 undivert(3)
143 changequote({*,*})
144 {*
145 [0-9]{1,8}              {
146                           char *ep;
147                           lr_min=lr_max= (int)strtoul(yytext,&ep,10);
148                           assert(!*ep);
149                           return tokv_ordinal;
150                         }
151 [0-9]{1,8}-[0-9]{1,8}   {
152                           char *ep;
153                           lr_min= (int)strtoul(yytext,&ep,10);
154                           assert(*ep == HYPHEN);
155                           assert(*++ep);
156                           lr_max= (int)strtoul(ep,&ep,10);
157                           assert(!*ep);
158                           if (lr_max < lr_min) {
159                             parseerrprint("fd range has min > max");
160                             return tokv_error;
161                           }
162                           return tokv_fdrange;
163                         }
164 [0-9]{1,8}-             {
165                           char *ep;
166                           lr_min= (int)strtoul(yytext,&ep,10);
167                           assert(*ep == HYPHEN);
168                           assert(!*++ep);
169                           lr_max=-1;
170                           return tokv_fdstoend;
171                         }
172 [\ \t]+                 return tokv_lwsp;
173 [\ \t]*\n               cstate->lineno++; return tokv_newline;
174 [\ \t]*\#[^\n]*\n       cstate->lineno++; return tokv_newline;
175 [\ \t]*\#[^\n]*         {
176                           parseerrprint("missing newline at eof after comment");
177                           return tokv_error;
178                         }
179 [^\ \t\n]+              return tokv_barestring;
180 \"([^\\\"\n]|\\[a-z]|\\[0-9]{3}|\\x[0-9A-Fa-f]{2}|\\[:punct:]|\\[ \t]*\n)*\" {
181                           return dequote(yytext);
182                         }
183 \".*                    {
184                           parseerrprint("misquoted or unterminated string");
185                           return tokv_error;
186                         }
187 <<EOF>>                 return tokv_eof;
188 *}
189 changequote(`,')
190 %%
191 `
192 #include "parser.c"
193 '
194 divert(-1)
195 undivert