modules/er/er_paths.c
/* [<][>][^][v][top][bottom][index][help] */
FUNCTIONS
This source file includes following functions.
- er_find_path_byname
- er_upd_asparray
- er_add_filter
- er_attach_filter_chain
- er_register_path
- er_modify_path
- er_delete_filter
- er_add_exec_arg
- er_free_dynadescr
- er_delete_path
- er_print_format
- er_print_one_path_descr
- er_print_aspmask
- er_print_facmask
- er_print_one_filter
- er_print_one_path
- er_print_paths
1 /***************************************
2 $Revision: 1.3 $
3
4 Error reporting (er) er_paths.c - parser callback functions for path
5 & filter creation/modification/deletion
6
7 Status: NOT REVUED, PARTLY TESTED
8
9 Design and implementation by: Marek Bukowy
10
11 ******************/ /******************
12 Copyright (c) 1999,2000 RIPE NCC
13
14 All Rights Reserved
15
16 Permission to use, copy, modify, and distribute this software and its
17 documentation for any purpose and without fee is hereby granted,
18 provided that the above copyright notice appear in all copies and that
19 both that copyright notice and this permission notice appear in
20 supporting documentation, and that the name of the author not be
21 used in advertising or publicity pertaining to distribution of the
22 software without specific, written prior permission.
23
24 THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
25 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS; IN NO EVENT SHALL
26 AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
27 DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
28 AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
29 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
30 ***************************************/
31
32
33
34 #include "erroutines.h"
35 #include "memwrap.h"
36
37
38 /* find path by name, returns the pointer to it if found or NULL. */
39 static
40 er_path_t *
41 er_find_path_byname(char *key)
/* [<][>][^][v][top][bottom][index][help] */
42 {
43 GList *pitem;
44 er_path_t *pathptr;
45
46 /* foreach path */
47 for( pitem = g_list_first(er_pathlist);
48 pitem != NULL;
49 pitem = g_list_next(pitem)) {
50
51 pathptr = (er_path_t *)pitem->data;
52
53 if( strcmp(pathptr->name, key) == 0 ) {
54 return pathptr;
55 }
56 }
57
58 return NULL;
59 }
60
61 /* the "asp" array describes the "OR" of all filters' aspects. This is to allow
62 fast dropping of messages that would be dropped anyway
63
64 when invoked, clears the array and then goes through all filters
65 setting appropriate bits of aspects per facility
66 */
67 void
68 er_upd_asparray(void)
/* [<][>][^][v][top][bottom][index][help] */
69 {
70 GList *pitem, *fitem;
71 er_fac_code_t f;
72
73 /* clear */
74 for(f=0; f<FAC_LAST; f++) {
75 er_asparray[f] = 0;
76 }
77
78 /* foreach path */
79 for( pitem = g_list_first(er_pathlist);
80 pitem != NULL;
81 pitem = g_list_next(pitem)) {
82
83 er_path_t *pathptr = (er_path_t *)pitem->data;
84
85 /* active paths only */
86 if( pathptr->active ) {
87
88 /* foreach filter on that path */
89 for( fitem = g_list_first(pathptr->filters);
90 fitem != NULL;
91 fitem = g_list_next(fitem)) {
92
93 er_filter_t *filtptr = (er_filter_t *) fitem->data;
94
95 /* foreach facility in that filter */
96 for(f=0; f<FAC_LAST; f++) {
97 if( MA_isset( filtptr->fac_mask, f ) ) {
98 er_asparray[f] |= filtptr->asp_mask;
99 }
100 }
101 }
102 }
103 }
104 }
105
106
107
108 er_ret_t
109 er_add_filter( er_path_t *pathptr, er_filter_t *filter )
/* [<][>][^][v][top][bottom][index][help] */
110 {
111 er_filter_t *ft = malloc(sizeof(er_filter_t));
112
113 memcpy(ft, filter, sizeof(er_filter_t));
114 pathptr->filters = g_list_append(pathptr->filters, ft);
115
116 return ER_OK;
117 }
118
119
120 er_ret_t
121 er_attach_filter_chain( char *key, GList *filterlist )
/* [<][>][^][v][top][bottom][index][help] */
122 {
123 er_path_t *pathptr;
124 er_ret_t err;
125
126 if( (pathptr=er_find_path_byname(key)) == NULL ) {
127 return ER_INVKEY;
128 }
129 else {
130 GList *fitem;
131 for( fitem = g_list_first(filterlist);
132 fitem != NULL;
133 fitem = g_list_next(fitem)) {
134
135 er_filter_t *filtptr = (er_filter_t *) fitem->data;
136
137 if( !NOERR(err=er_add_filter( pathptr, filtptr)) ) {
138 return err;
139 }
140 }
141 }
142
143 return ER_OK;
144 }
145
146
147 er_ret_t
148 er_register_path( er_path_t *path, char *key )
/* [<][>][^][v][top][bottom][index][help] */
149 {
150 er_path_t *ft;
151 er_path_t *pathptr;
152
153 if( (pathptr=er_find_path_byname(key)) != NULL ) {
154 return ER_DUPENT; /* duplicate !!! */
155 }
156
157 ft = calloc(sizeof(er_path_t),1);
158 memcpy(ft, path, sizeof(er_path_t));
159 strncpy(ft->name, key, 31);
160 er_pathlist = g_list_append(er_pathlist, ft);
161
162 er_upd_asparray();
163
164 return ER_OK;
165 }
166
167 /* find the path by name and replace its definition without touching
168 the filters
169 */
170 er_ret_t
171 er_modify_path( er_path_t *newpath, char *key )
/* [<][>][^][v][top][bottom][index][help] */
172 {
173 er_path_t *pathptr;
174
175 if( (pathptr=er_find_path_byname(key)) == NULL ) {
176 return ER_INVKEY;
177 }
178 else {
179 /* name stays the same */
180 pathptr->active = newpath->active;
181 pathptr->format = newpath->format;
182 pathptr->mutex = newpath->mutex;
183 pathptr->type = newpath->type;
184 pathptr->descr = newpath->descr;
185 /* filters stay the same */
186
187 er_upd_asparray();
188
189 return ER_OK;
190 }
191 }
192
193 er_ret_t
194 er_delete_filter( char *key, unsigned int filterid )
/* [<][>][^][v][top][bottom][index][help] */
195 {
196 er_path_t *pathptr;
197 er_filter_t *filtptr;
198
199 if( (pathptr=er_find_path_byname(key)) == NULL ) {
200 return ER_INVKEY;
201 }
202 else {
203 int numfilters = g_list_length(pathptr->filters);
204
205 if( filterid >= numfilters ) {
206 return ER_INVKEY;
207 }
208
209 filtptr = g_list_nth_data(pathptr->filters, filterid);
210 /* free filter structure */
211 free(filtptr);
212 /* remove filter link from list */
213 pathptr->filters = g_list_remove(pathptr->filters, filtptr);
214 /* update arrays */
215 er_upd_asparray();
216
217 return ER_OK;
218 }
219 }
220
221
222 void
223 er_add_exec_arg(er_path_t *pathptr, char *arg)
/* [<][>][^][v][top][bottom][index][help] */
224 {
225 int len = 0;
226 char **argv = pathptr->descr.exec.argv;
227 char **newargv;
228
229 if( argv != NULL ) {
230 while( argv[len] != NULL ) {
231 len++;
232 }
233 }
234
235 newargv = calloc( sizeof(char **) * (len+2), 1 );
236 if( len > 0 ) {
237 memcpy( newargv, argv, sizeof(char **) * len);
238 }
239 newargv[len] = strdup(arg);
240
241 pathptr->descr.exec.argv = newargv;
242
243 if( argv != NULL ) {
244 free(argv);
245 }
246 }
247
248 /* free dynamic elements of the path description */
249 void er_free_dynadescr( er_path_t *pathptr )
/* [<][>][^][v][top][bottom][index][help] */
250 {
251 char **argv = pathptr->descr.exec.argv;
252 int len=0;
253
254 if( argv != NULL ) {
255 while( argv[len] != NULL ) {
256 free( argv[len] );
257 len++;
258 }
259 }
260
261 if( argv != NULL ) {
262 free(argv);
263 }
264 }
265
266
267 /* finds and removes a path identified by the key (name).
268 Also removes all associated filters.
269
270 returns:
271 ER_OK on success
272
273 */
274 er_ret_t
275 er_delete_path(char *key )
/* [<][>][^][v][top][bottom][index][help] */
276 {
277 er_path_t *pathptr;
278
279 if( (pathptr=er_find_path_byname(key)) == NULL ) {
280 return ER_INVKEY;
281 }
282 else {
283 /* remove filters */
284 wr_clear_list( &(pathptr->filters) );
285 /* delete dynamic elements */
286 er_free_dynadescr( pathptr );
287 /* free path structure */
288 free(pathptr);
289 /* remove path link from list */
290 er_pathlist = g_list_remove(er_pathlist, pathptr);
291
292 /* update arrays */
293 er_upd_asparray();
294
295 return ER_OK;
296 }
297 }
298
299
300 /************************************************************/
301 static
302 void er_print_format(int format, GString *g_reply )
/* [<][>][^][v][top][bottom][index][help] */
303 {
304 int i;
305
306 for(i=0; er_formarr[i].n != NULL; i++) {
307 if( format & er_formarr[i].v ) {
308 g_string_sprintfa(g_reply, "%s|",er_formarr[i].n);
309 }
310 }
311 /* cut the last "|" */
312 g_string_truncate(g_reply, strlen(g_reply->str)-1);
313 }
314
315
316 static
317 void er_print_one_path_descr(er_path_t *pathptr, GString *g_reply )
/* [<][>][^][v][top][bottom][index][help] */
318 {
319 er_path_descr_t *d = &(pathptr->descr);
320
321 switch(pathptr->type) {
322 case ER_PATH_NAME:
323 g_string_sprintfa(g_reply, "NAME %s%s", d->name.filename,
324 d->name.date ? " DATE" : ""
325 );
326 break;
327 case ER_PATH_SOCK:
328 g_string_sprintfa(g_reply, "SOCK %d", d->sock.fd );
329
330 break;
331
332 case ER_PATH_EXEC:
333 g_string_sprintfa(g_reply, "EXEC ");
334 if( d->exec.usepath ) {
335 g_string_sprintfa(g_reply, "PATH ");
336 }
337 {
338 char **argv = d->exec.argv;
339 int len=0;
340
341 if( argv != NULL ) {
342 while( argv[len] != NULL ) {
343 g_string_sprintfa(g_reply, "%s ", argv[len]);
344 len++;
345 }
346 }
347 }
348 break;
349
350 default:
351 /* XXX other path descriptions missing */
352 break;
353 }
354 }
355
356 static
357 void er_print_aspmask(mask_t facmask, unsigned aspmask, GString *g_reply)
/* [<][>][^][v][top][bottom][index][help] */
358 {
359 int i = 31;
360
361 while(i >= 0) {
362 if( aspmask & (1<<i) ) {
363 er_getaspsym(facmask, 1<<i, g_reply);
364 g_string_append(g_reply, "|");
365 }
366
367 i--;
368 }
369 /* cut the last "|" */
370 g_string_truncate(g_reply, strlen(g_reply->str)-1);
371 }
372
373 static
374 void er_print_facmask(mask_t facmask, GString *g_reply)
/* [<][>][^][v][top][bottom][index][help] */
375 {
376 int i = FAC_NONE;
377
378 while( ++i != FAC_LAST ) {
379 if( MA_isset(facmask, er_fac_err[i].code) ) {
380 g_string_sprintfa(g_reply, "%s|", er_fac_err[i].name);
381 }
382 }
383 /* cut the last "|" */
384 g_string_truncate(g_reply, strlen(g_reply->str)-1);
385
386 }
387
388 static
389 void er_print_one_filter(er_filter_t *filtptr, GString *g_reply )
/* [<][>][^][v][top][bottom][index][help] */
390 {
391 g_string_sprintfa(g_reply, "( FAC ");
392 er_print_facmask( filtptr->fac_mask, g_reply);
393
394 if( filtptr->asp_mask != 0 ) {
395 g_string_sprintfa(g_reply, " ASP ");
396 er_print_aspmask( filtptr->fac_mask, filtptr->asp_mask, g_reply);
397 }
398
399 g_string_sprintfa(g_reply, " SEV %s-%s ",
400 er_getsevsym( filtptr->sev_min, ER_M_SEVCHAR),
401 er_getsevsym( filtptr->sev_max, ER_M_SEVCHAR)
402 );
403 if( filtptr->thr_id != 0 ) {
404 g_string_sprintfa(g_reply, " THR %u ", filtptr->thr_id);
405 }
406 g_string_sprintfa(g_reply, " )" );
407 }
408
409 static
410 void er_print_one_path(er_path_t *pathptr, GString *g_reply )
/* [<][>][^][v][top][bottom][index][help] */
411 {
412 GList *qitem;
413 int f=1;
414
415 g_string_sprintfa(g_reply,"%s { ", pathptr->name );
416 g_string_sprintfa(g_reply," FORMAT ");
417 er_print_format(pathptr->format, g_reply );
418 g_string_sprintfa(g_reply," ");
419
420 er_print_one_path_descr(pathptr, g_reply);
421 g_string_sprintfa(g_reply," }\n");
422
423 for(qitem = g_list_first(pathptr->filters);
424 qitem != NULL;
425 qitem = g_list_next(qitem)) {
426 er_filter_t *filtptr = (er_filter_t *) qitem -> data;
427
428 g_string_sprintfa(g_reply,"\t");
429 er_print_one_filter(filtptr, g_reply) ;
430 g_string_sprintfa(g_reply,"\n");
431 f++;
432 }
433
434 }
435
436 void er_print_paths(char **retbuf)
/* [<][>][^][v][top][bottom][index][help] */
437 {
438 GList *qitem;
439 GString *g_reply = g_string_sized_new(2048); /* initial size */
440
441 for( qitem = g_list_first(er_pathlist);
442 qitem != NULL;
443 qitem = g_list_next(qitem)) {
444 er_path_t *pathptr = qitem -> data;
445
446 /* g_string_sprintfa(g_reply, "path type %d (%s) with %d filters\n",
447 pathptr->type, er_pathtypes[pathptr->type],
448 g_list_length(pathptr->filters));
449 */
450 er_print_one_path(pathptr, g_reply);
451
452 }
453
454 *retbuf = g_reply->str;
455
456 /* we must duplicate the string allocated by glib - it can be freed
457 only by glib internal free function :-( */
458 g_string_free( g_reply, /* CONSTCOND */ FALSE);
459 }