modules/er/er_macro.c
/* [<][>][^][v][top][bottom][index][help] */
FUNCTIONS
This source file includes following functions.
- ER_process_split
- ER_macro_spec
- ER_make_macro
- ER_macro_predef
- er_macro_list_hook
- ER_macro_list
- ER_proc_ca_macro
- ER_proc_ca_err
1 /***************************************
2 $Revision: 1.5 $
3
4 Error reporting (er) er_macro.c - simple macro processor
5
6 Status: NOT REVUED, PARTLY TESTED
7
8 Design and implementation by: Marek Bukowy
9
10 ******************/ /******************
11 Copyright (c) 1999,2000 RIPE NCC
12
13 All Rights Reserved
14
15 Permission to use, copy, modify, and distribute this software and its
16 documentation for any purpose and without fee is hereby granted,
17 provided that the above copyright notice appear in all copies and that
18 both that copyright notice and this permission notice appear in
19 supporting documentation, and that the name of the author not be
20 used in advertising or publicity pertaining to distribution of the
21 software without specific, written prior permission.
22
23 THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
24 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS; IN NO EVENT SHALL
25 AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
26 DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
27 AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
28 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
29 ***************************************/
30
31 #include <string.h>
32 #include <glib.h>
33 #include "stubs.h"
34 #include "sk.h"
35 #include "er_macro.h"
36 #include "er_paths.h"
37 #include "er_yacc_helper.h"
38 #include "memwrap.h"
39
40 #include "ca_configFns.h"
41 #include "ca_dictSyms.h"
42 #include "ca_macros.h"
43
44 GHashTable *er_macro_hash = NULL;
45
46 /* process a macro call, i.e. execute one of the predefined macros
47 selected by the 0th argument, using other arguments.
48
49 Uses the er_macro_array[] to find the macro definition.
50
51 Allocates the result string and stores the pointer to it in **output.
52
53 returns 0 on success, non-0 on failure.
54 */
55
56 int
57 ER_process_split(int argc, char **argv, char **output)
/* [<][>][^][v][top][bottom][index][help] */
58 {
59 char *pattern, *ch;
60 GString *result = g_string_new("");
61
62 dieif( argc == 0 ); /* may not be called without the macro name */
63
64 /* find macro, error if not found */
65 if( (pattern = g_hash_table_lookup(er_macro_hash, argv[0])) == NULL ) {
66 return -1;
67 }
68
69 /* copy the macro definition by portions, substituting the $([0-9])
70 entries with arguments. Error if not enough arguments.
71 */
72 do {
73
74 if( (ch = strstr( pattern, "$(" )) == NULL ) {
75 /* no more entries. copy the rest */
76 g_string_append ( result, pattern );
77 break;
78 }
79 else {
80 /* pass the string between here and ch */
81 while( pattern != ch ) {
82 g_string_append_c ( result, *pattern );
83 pattern++;
84 }
85 /* check the next 3 characters exist, break the look if not */
86 if( *(ch+2) == '\0' || *(ch+3) == '\0') {
87 break;
88 }
89
90 /* look for the digit and ")", pass the $( through if not present */
91 if( ! isdigit(*(ch+2)) || *(ch+3) != ')' ) {
92 /* not need to do anything to make it pass through */
93 ;
94 }
95 else {
96 /* substitute the $(?) with the appropriate argument.
97 error if not enough arguments or $(0) is used.*/
98 int a = *(ch+2) - '0';
99
100 if( argc < a || a==0) {
101 return -1;
102 }
103 g_string_append( result, argv[a]);
104 /* advance the pattern pointer */
105 pattern += strlen("$(1)");
106 }
107 }
108 } while(1);
109
110 /* copy the pointer, free the orig structure, keep the text */
111
112 *output = (result->str);
113
114 g_string_free( result, FALSE );
115
116 return 0;
117 }
118
119
120 /* wrapper around the above that splits the string into argv
121 and calls the ER_parse.
122
123 sets the errbuf to the ER_parse_spec result
124
125 returns 0 on success, non-0 on failure.
126 */
127 int
128 ER_macro_spec(char *input, char **errbuf)
/* [<][>][^][v][top][bottom][index][help] */
129 {
130 char **argv = g_strsplit(input, " ", 0);
131 int argc = 0, ret;
132 char *fullspec;
133
134 while( argv[argc] != NULL ) {
135 argc++;
136 }
137
138
139 if( ER_process_split(argc, argv, &fullspec) != 0 ) {
140 /* macro unknown. That's OK, just parse that text now */
141
142 fullspec = strdup(input);
143 }
144
145 ret = ER_parse_spec(fullspec, errbuf);
146
147 free(fullspec);
148 g_strfreev(argv);
149 return ret;
150
151 }
152
153
154 void
155 ER_make_macro(char *name, char *def)
/* [<][>][^][v][top][bottom][index][help] */
156 {
157 char *cp_name = wr_string(name);
158 char *cp_def = wr_string(def);
159
160 void *oldkey, *oldval;
161
162 /* cleanup on redefinition */
163 if( g_hash_table_lookup_extended(er_macro_hash, name,
164 &oldkey, &oldval) == TRUE ) {
165 g_hash_table_remove(er_macro_hash, name);
166 wr_free(oldkey);
167 wr_free(oldval);
168 }
169
170 g_hash_table_insert(er_macro_hash, cp_name, cp_def);
171 }
172
173
174 /* predefine some macros */
175 void
176 ER_macro_predef(void)
/* [<][>][^][v][top][bottom][index][help] */
177 {
178 /* create the hash with hashing and equality testing functions
179 specific for strings
180 */
181 er_macro_hash = g_hash_table_new(g_str_hash, g_str_equal);
182
183 #define DBUPDLOG_FORMAT " FORMAT SEVCHAR|FACSYMB|TEXTLONG|DATETIME|PIDFULL|PROGNAME|MNEMONIC "
184 #define RIPLOG_FORMAT " FORMAT SEVCHAR|FACSYMB|TEXTLONG|DATETIME|PIDFULL|PROGNAME|THR_ID|MNEMONIC "
185
186 /* catch-all for dbupdate */
187 ER_make_macro("DBUPERR", "CREATE dbuperr {"
188 DBUPDLOG_FORMAT "NAME $(1) DATE}"
189 " ( FAC MM|UP SEV W- )");
190
191 /* catch-all for rip */
192 ER_make_macro("ALLRIPERR", "CREATE allriperr { "
193 RIPLOG_FORMAT "NAME $(1) DATE}"
194 " (FAC ALL SEV W- )");
195
196 /* selected: errors in ripupdate */
197 ER_make_macro("RIPUPERR", "CREATE ripuperr {"
198 RIPLOG_FORMAT "NAME $(1) DATE}"
199 " (FAC UD SEV W- )");
200
201 /* querylog: logs all rip queries */
202 ER_make_macro("QRYLOG", "CREATE qrylog {"
203 RIPLOG_FORMAT "NAME $(1) DATE}"
204 " (FAC PW ASP PW_I_QRYLOG SEV I )");
205
206 /* audit: any security related messages from RIP */
207 ER_make_macro("RIPAUDIT", "CREATE ripaudit {"
208 RIPLOG_FORMAT "NAME $(1) DATE}"
209 "( FAC PW ASP PW_I_PASSUN SEV i )"
210 " ( FAC AC ASP AC_I_PERMBAN SEV I )");
211
212 /* ripupdlog: logs all update transactions */
213 ER_make_macro("RIPUPDLOG", "CREATE ripupdlog_$(2) {"
214 RIPLOG_FORMAT "NAME $(1)_$(2) DATE}"
215 " ( FAC UD ASP 0xffffffff SEV I THR self)");
216
217 /* ripmirlog */
218 ER_make_macro("RIPMIRLOG", "CREATE ripmirlog {"
219 RIPLOG_FORMAT "NAME $(1) DATE }"
220 "( FAC PM ASP 0xffffffff SEV I )");
221
222 /* server log: all administration by SV (startup, shutdown, etc) and errors */
223 ER_make_macro("RIPSVRLOG", "CREATE ripsvrlog {"
224 RIPLOG_FORMAT "NAME $(1) DATE}"
225 " ( FAC SV ASP 0xffffffff SEV I-F )");
226 /* dbase log: all errors of SQ */
227 ER_make_macro("SQLOG", " CREATE sqlog {"
228 RIPLOG_FORMAT "NAME $(1) DATE}"
229 " ( FAC SQ SEV W- )");
230
231 }
232
233 static
234 void er_macro_list_hook (void* key, void * value, void *condat)
/* [<][>][^][v][top][bottom][index][help] */
235 {
236 SK_cd_printf(condat, "%s: %s\n", (char *) key, (char *) value);
237 }
238
239 void
240 ER_macro_list(sk_conn_st *condat)
/* [<][>][^][v][top][bottom][index][help] */
241 {
242 g_hash_table_foreach(er_macro_hash, er_macro_list_hook, condat );
243 }
244
245 /* override macros with the definitions from the config file */
246 void
247 ER_proc_ca_macro(void)
/* [<][>][^][v][top][bottom][index][help] */
248 {
249 char *alldef = ca_get_er_macro ;
250 char *this_line = alldef;
251 char *defname, *defbody, *end_line;
252
253 /* alldef is a copy of the configured value. so we can modify it
254 if it helps us to do it line by line */
255
256 /* ER_MACRO may not be present in the configuration, in which case
257 ca_get_er_macro returns NULL */
258
259 if( alldef != NULL ) {
260
261 while( *this_line != '\0' ) {
262 /* separate the line */
263 end_line = strchr(this_line, '\n');
264 *end_line = '\0';
265
266 /* advance to non-whitespace */
267 while( isspace(*this_line) ) {
268 this_line++;
269 }
270
271 /* find the name and body of the definition */
272 defname = strsep(&this_line, " \t");
273 defbody = this_line;
274
275 /* fire */
276 dieif( defname == NULL || defbody == NULL );
277 ER_make_macro( defname, defbody );
278
279 this_line = end_line + 1;
280 }
281
282 free(alldef);
283 }
284 }
285
286
287 /* process the error definitions from the config file */
288 void
289 ER_proc_ca_err(void)
/* [<][>][^][v][top][bottom][index][help] */
290 {
291 char *alldef = ca_get_er_def ;
292 char *this_line = alldef;
293 char *defname, *defbody, *end_line;
294 char *erret = NULL;
295 int res;
296
297 /* alldef is a copy of the configured value. so we can modify it
298 if it helps us to do it line by line */
299
300 /* ER_DEF may not be present in the configuration, in which case
301 ca_get_er_def returns NULL */
302 if( alldef != NULL ) {
303
304 while( *this_line != '\0' ) {
305 /* separate the line */
306 end_line = strchr(this_line, '\n');
307 *end_line = '\0';
308
309 /* fire */
310 if( (res = ER_macro_spec(this_line, &erret)) != 0 ) {
311 fputs(erret, stderr);
312 die;
313 }
314
315 free(erret);
316
317 this_line = end_line + 1;
318 }
319
320 free(alldef);
321 }
322 }