1 /*
2    rcfile.h
3 
4    This file is part of GNU Anubis.
5    Copyright (C) 2003-2014 The Anubis Team.
6 
7    GNU Anubis is free software; you can redistribute it and/or modify it
8    under the terms of the GNU General Public License as published by the
9    Free Software Foundation; either version 3 of the License, or (at your
10    option) any later version.
11 
12    GNU Anubis is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16 
17    You should have received a copy of the GNU General Public License along
18    with GNU Anubis.  If not, see <http://www.gnu.org/licenses/>.
19 */
20 
21 /* Types describing the basic syntax of an anubis rc file */
22 typedef struct rc_section RC_SECTION;
23 typedef struct rc_stmt RC_STMT;
24 typedef struct rc_rule RC_RULE;
25 typedef struct rc_cond RC_COND;
26 typedef struct rc_asgn RC_ASGN;
27 typedef struct rc_node RC_NODE;
28 typedef struct rc_bool RC_BOOL;
29 typedef struct rc_expr RC_EXPR;
30 typedef struct rc_inst RC_INST;
31 typedef struct rc_loc RC_LOC;
32 
33 struct rc_loc
34 {
35   char *file;
36   size_t line;
37   size_t column;
38 };
39 
40 /* Input location for the parser */
41 struct rc_yyltype
42 {
43   struct rc_loc beg;
44   struct rc_loc end;
45 };
46 
47 #define YYLTYPE struct rc_yyltype
48 
49 #define RC_LOCUS_FILE_EQ(a,b)						\
50   (((a)->file == (b)->file) ||						\
51    ((a)->file && (b)->file && strcmp ((a)->file, (b)->file) == 0))
52 
53 #define RC_LOCUS_EQ(a,b)				\
54   (RC_LOCUS_FILE_EQ(a,b) && (a)->line == (b)->line)
55 
56 struct rc_section
57 {				/* RC Section */
58   RC_LOC loc;			/* Location in the config file */
59   RC_SECTION *next;		/* Link to the next section */
60   char *name;			/* Section name */
61   RC_STMT *stmt;		/* List of parsed statements */
62 };
63 
64 enum rc_stmt_type
65 {				/* Statement type: */
66   rc_stmt_asgn,			/* Assignment */
67   rc_stmt_rule,			/* Rule definition */
68   rc_stmt_cond,			/* Conditional expression */
69   rc_stmt_inst			/* Instruction */
70 };
71 
72 struct rc_asgn
73 {				/* Assignment */
74   char *lhs;			/* Left-hand side: A keyword */
75   ANUBIS_LIST rhs;		/* Right-hand side: A list of character strings */
76   int flags;			/* Flags control various aspects of assignment
77 				   functionality */
78 };
79 
80 enum bool_op
81 {				/* Boolean operator */
82   bool_not,
83   bool_and,
84   bool_or
85 };
86 
87 struct rc_bool
88 {				/* Boolean expression */
89   enum bool_op op;		/* Opcode */
90   RC_NODE *left;		/* Left operand */
91   RC_NODE *right;		/* Right operand (NULL for bool_not) */
92 };
93 
94 enum rc_node_type
95 {				/* Executable node type */
96   rc_node_bool,			/* Boolean instruction */
97   rc_node_expr			/* Regular expression */
98 };
99 
100 struct rc_expr
101 {
102   int part;			/* HEADER, COMMAND or BODY */
103   char *sep;                    /* If not-null, concatenate all values of
104 				   a same key, using this string as a separator
105 				   before matching */
106   char *key;
107   RC_REGEX *re;
108 };
109 
110 struct rc_node
111 {				/* Executable node */
112   RC_LOC loc;			/* Location in the config file */
113   enum rc_node_type type;	/* Node type */
114   union
115   {
116     RC_EXPR expr;
117     RC_BOOL bool;
118   }
119   v;
120 };
121 
122 struct rc_cond
123 {				/* Conditional expression */
124   RC_NODE *node;		/* Condition node */
125   RC_STMT *iftrue;		/* Branch to follow when the condition is true */
126   RC_STMT *iffalse;		/* Branch to follow when the condition is false */
127 };
128 
129 struct rc_rule
130 {				/* Rule definition */
131   RC_NODE *node;		/* Compiled regular expression */
132   RC_STMT *stmt;		/* Body of the rule */
133 };
134 
135 enum rc_inst_opcode
136 {				/* Operation code */
137   inst_add,
138   inst_remove,
139   inst_modify,
140   inst_stop,
141   inst_call
142 };
143 
144 struct rc_inst
145 {				/* Instruction definition */
146   enum rc_inst_opcode opcode;
147   int part;			/* Message part to operate upon */
148   RC_REGEX *key;		/* Key */
149   char *key2;			/* New key value (for modify) */
150   char *arg;			/* Argument */
151 };
152 
153 struct rc_stmt
154 {				/* General statement representation */
155   RC_LOC loc;			/* Location in the config file */
156   RC_STMT *next;		/* Link to the next statement */
157   enum rc_stmt_type type;	/* Statement type */
158   union
159   {				/* Actual data */
160     RC_ASGN asgn;		/* type == rc_stmt_asgn */
161     RC_RULE rule;		/* type == rc_stmt_rule */
162     RC_COND cond;		/* type == rc_stmt_cond */
163     RC_INST inst;		/* type == rc_stmt_inst */
164   }
165   v;
166 };
167 
168 /* Semantic handler tables */
169 
170 typedef void (*rc_kw_parser_t) (EVAL_ENV env, int key, ANUBIS_LIST arg,
171 				void *inv_data);
172 
173 /* Keyword flags */
174 #define KWF_HIDDEN 0x0001	/* Replace RHS with stars in debugging output */
175 
176 struct rc_kwdef
177 {
178   char *name;			/* Keyword name */
179   int tok;			/* Assigned token number */
180   int flags;			/* Flags controlling debugging output, etc. */
181 };
182 
183 struct rc_secdef_child
184 {
185   struct rc_secdef_child *next;
186   int method;
187   struct rc_kwdef *kwdef;
188   rc_kw_parser_t parser;
189   void *data;
190 };
191 
192 /* Section priorities affect linking the user-defined sections to
193    the parse tree left from parsing the system configuration file. */
194 enum section_prio
195 {
196   prio_user_only,		/* Only user-defined section is taken into account */
197   prio_system_only,		/* Only system-defined section */
198   prio_system,			/* System-defined section first, user-defined next */
199   prio_user			/* User-defined section first, system-defined next */
200 };
201 
202 struct rc_secdef
203 {
204   char *name;			/* Section name */
205   enum section_prio prio;	/* Execution priority */
206   int allow_prog;		/* Are rules allowed in this section? */
207   struct rc_secdef_child *child;
208 };
209 
210 typedef void (*RC_ERROR_PRINTER) (void *data,
211 				  struct rc_loc *loc,
212 				  const char *pfx,
213 				  const char *fmt, va_list ap);
214 
215 /* Global data */
216 extern struct rc_loc rc_locus;
217 
218 /* Function declarations */
219 void verbatim (void);
220 void lex_clear_state (void);
221 
222 int error_sync_begin ();
223 
224 RC_SECTION *rc_section_lookup (RC_SECTION *, char *);
225 void rc_section_link (RC_SECTION **, RC_SECTION *);
226 void rc_secdef_add_child (struct rc_secdef *, struct rc_secdef_child *);
227 RC_SECTION *rc_parse (char *);
228 RC_SECTION *rc_parse_ep (char *name, RC_ERROR_PRINTER errprn, void *data);
229 void rc_section_list_destroy (RC_SECTION **);
230 int rc_run_cond (char *, int, char *);
231 void rc_run_section (int, RC_SECTION *, struct rc_secdef *, const char *,
232 		     void *, MESSAGE);
233 void rc_set_debug_level (char *);
234 int rc_open (char *);
235 struct rc_secdef *anubis_add_section (char *);
236 struct rc_secdef *anubis_find_section (char *);
237 
238 void parse_error (struct rc_loc *loc, const char *fmt, ...)
239   ANUBIS_PRINTFLIKE(2,3);
240 void tracefile (RC_LOC *, const char *fmt, ...)
241   ANUBIS_PRINTFLIKE(2,3);
242 
243 extern int yy_flex_debug;
244 /* EOF */
245