aboutsummaryrefslogtreecommitdiff
path: root/src/rcfile.h
blob: 99d3679f9ec2c6224c499c8b895782818e42415d (plain)
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
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
/*
   rcfile.h

   This file is part of GNU Anubis.
   Copyright (C) 2003-2014 The Anubis Team.

   GNU Anubis 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 3 of the License, or (at your
   option) any later version.

   GNU Anubis 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 GNU Anubis.  If not, see <http://www.gnu.org/licenses/>.
*/

/* Types describing the basic syntax of an anubis rc file */
typedef struct rc_section RC_SECTION;
typedef struct rc_stmt RC_STMT;
typedef struct rc_rule RC_RULE;
typedef struct rc_cond RC_COND;
typedef struct rc_asgn RC_ASGN;
typedef struct rc_node RC_NODE;
typedef struct rc_bool RC_BOOL;
typedef struct rc_expr RC_EXPR;
typedef struct rc_inst RC_INST;
typedef struct rc_loc RC_LOC;

struct rc_loc
{
  char *file;
  size_t line;
  size_t column;
};

/* Input location for the parser */
struct rc_yyltype
{
  struct rc_loc beg;
  struct rc_loc end;
};

#define YYLTYPE struct rc_yyltype

#define RC_LOCUS_FILE_EQ(a,b)						\
  (((a)->file == (b)->file) ||						\
   ((a)->file && (b)->file && strcmp ((a)->file, (b)->file) == 0))

#define RC_LOCUS_EQ(a,b)				\
  (RC_LOCUS_FILE_EQ(a,b) && (a)->line == (b)->line)

struct rc_section
{				/* RC Section */
  RC_LOC loc;			/* Location in the config file */
  RC_SECTION *next;		/* Link to the next section */
  char *name;			/* Section name */
  RC_STMT *stmt;		/* List of parsed statements */
};

enum rc_stmt_type
{				/* Statement type: */
  rc_stmt_asgn,			/* Assignment */
  rc_stmt_rule,			/* Rule definition */
  rc_stmt_cond,			/* Conditional expression */
  rc_stmt_inst			/* Instruction */
};

struct rc_asgn
{				/* Assignment */
  char *lhs;			/* Left-hand side: A keyword */
  ANUBIS_LIST rhs;		/* Right-hand side: A list of character strings */
  int flags;			/* Flags control various aspects of assignment
				   functionality */
};

enum bool_op
{				/* Boolean operator */
  bool_not,
  bool_and,
  bool_or
};

struct rc_bool
{				/* Boolean expression */
  enum bool_op op;		/* Opcode */
  RC_NODE *left;		/* Left operand */
  RC_NODE *right;		/* Right operand (NULL for bool_not) */
};

enum rc_node_type
{				/* Executable node type */
  rc_node_bool,			/* Boolean instruction */
  rc_node_expr			/* Regular expression */
};

struct rc_expr
{
  int part;			/* HEADER, COMMAND or BODY */
  char *sep;                    /* If not-null, concatenate all values of
				   a same key, using this string as a separator
				   before matching */
  char *key;
  RC_REGEX *re;
};

struct rc_node
{				/* Executable node */
  RC_LOC loc;			/* Location in the config file */
  enum rc_node_type type;	/* Node type */
  union
  {
    RC_EXPR expr;
    RC_BOOL bool;
  }
  v;
};

struct rc_cond
{				/* Conditional expression */
  RC_NODE *node;		/* Condition node */
  RC_STMT *iftrue;		/* Branch to follow when the condition is true */
  RC_STMT *iffalse;		/* Branch to follow when the condition is false */
};

struct rc_rule
{				/* Rule definition */
  RC_NODE *node;		/* Compiled regular expression */
  RC_STMT *stmt;		/* Body of the rule */
};

enum rc_inst_opcode
{				/* Operation code */
  inst_add,
  inst_remove,
  inst_modify,
  inst_stop,
  inst_call
};

struct rc_inst
{				/* Instruction definition */
  enum rc_inst_opcode opcode;
  int part;			/* Message part to operate upon */
  RC_REGEX *key;		/* Key */
  char *key2;			/* New key value (for modify) */
  char *arg;			/* Argument */
};

struct rc_stmt
{				/* General statement representation */
  RC_LOC loc;			/* Location in the config file */
  RC_STMT *next;		/* Link to the next statement */
  enum rc_stmt_type type;	/* Statement type */
  union
  {				/* Actual data */
    RC_ASGN asgn;		/* type == rc_stmt_asgn */
    RC_RULE rule;		/* type == rc_stmt_rule */
    RC_COND cond;		/* type == rc_stmt_cond */
    RC_INST inst;		/* type == rc_stmt_inst */
  }
  v;
};

/* Semantic handler tables */

typedef void (*rc_kw_parser_t) (EVAL_ENV env, int key, ANUBIS_LIST arg,
				void *inv_data);

/* Keyword flags */
#define KWF_HIDDEN 0x0001	/* Replace RHS with stars in debugging output */

struct rc_kwdef
{
  char *name;			/* Keyword name */
  int tok;			/* Assigned token number */
  int flags;			/* Flags controlling debugging output, etc. */
};

struct rc_secdef_child
{
  struct rc_secdef_child *next;
  int method;
  struct rc_kwdef *kwdef;
  rc_kw_parser_t parser;
  void *data;
};

/* Section priorities affect linking the user-defined sections to
   the parse tree left from parsing the system configuration file. */
enum section_prio
{
  prio_user_only,		/* Only user-defined section is taken into account */
  prio_system_only,		/* Only system-defined section */
  prio_system,			/* System-defined section first, user-defined next */
  prio_user			/* User-defined section first, system-defined next */
};

struct rc_secdef
{
  char *name;			/* Section name */
  enum section_prio prio;	/* Execution priority */
  int allow_prog;		/* Are rules allowed in this section? */
  struct rc_secdef_child *child;
};

typedef void (*RC_ERROR_PRINTER) (void *data,
				  struct rc_loc *loc,
				  const char *pfx,
				  const char *fmt, va_list ap);

/* Global data */
struct rc_loc rc_locus;

/* Function declarations */
void verbatim (void);
void lex_clear_state (void);

int error_sync_begin ();

RC_SECTION *rc_section_lookup (RC_SECTION *, char *);
void rc_section_link (RC_SECTION **, RC_SECTION *);
void rc_secdef_add_child (struct rc_secdef *, struct rc_secdef_child *);
RC_SECTION *rc_parse (char *);
RC_SECTION *rc_parse_ep (char *name, RC_ERROR_PRINTER errprn, void *data);
void rc_section_list_destroy (RC_SECTION **);
int rc_run_cond (char *, int, char *);
void rc_run_section (int, RC_SECTION *, struct rc_secdef *, const char *,
		     void *, MESSAGE);
void rc_set_debug_level (char *);
int rc_open (char *);
struct rc_secdef *anubis_add_section (char *);
struct rc_secdef *anubis_find_section (char *);

void parse_error (struct rc_loc *loc, const char *fmt, ...)
  ANUBIS_PRINTFLIKE(2,3);
void tracefile (RC_LOC *, const char *fmt, ...)
  ANUBIS_PRINTFLIKE(2,3);

extern int yy_flex_debug;
/* EOF */

Return to:

Send suggestions and report system problems to the System administrator.