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