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_path_safeguard
- er_register_path
- er_modify_path
- er_delete_filter
- er_add_exec_arg
- er_free_dynadescr
- er_delete_path
1 /***************************************
2 $Revision: 1.7 $
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 #include "memwrap.h"
34 #include "erroutines.h"
35
36 #include "er_paths.h"
37 #include "er_arrays.h"
38
39 #include "sk.h"
40
41
42 /*++++++++++++++++++++++++++++++++++++++
43 finds path by identifier
44
45 er_path_t *
46 er_find_path_byname returns the pointer to it if found or NULL if not found
47
48 char *key path identifier
49
50 ++++++++++++++++++++++++++++++++++++++*/
51 static
52 er_path_t *
53 er_find_path_byname(char *key)
/* [<][>][^][v][top][bottom][index][help] */
54 {
55 GList *pitem;
56 er_path_t *pathptr;
57
58 /* foreach path */
59 for( pitem = g_list_first(er_pathlist);
60 pitem != NULL;
61 pitem = g_list_next(pitem)) {
62
63 pathptr = (er_path_t *)pitem->data;
64
65 if( strcmp(pathptr->name, key) == 0 ) {
66 return pathptr;
67 }
68 }
69
70 return NULL;
71 }
72
73
74 /*++++++++++++++++++++++++++++++++++++++
75
76 Updates the array of currently active aspects. Must be used after any change
77 of filters/paths.
78
79 The "asp" array describes the "OR" of all filters' aspects. This is to allow
80 fast dropping of messages that would be dropped anyway
81
82 This function clears the array and regenerates it by going through
83 all filters and setting appropriate bits of aspects per facility.
84
85 ++++++++++++++++++++++++++++++++++++++*/
86 void
87 er_upd_asparray(void)
/* [<][>][^][v][top][bottom][index][help] */
88 {
89 GList *pitem, *fitem;
90 er_fac_code_t f;
91
92 /* clear */
93 for(f=0; f<FAC_LAST; f++) {
94 er_asparray[f] = 0;
95 }
96
97 /* foreach path */
98 for( pitem = g_list_first(er_pathlist);
99 pitem != NULL;
100 pitem = g_list_next(pitem)) {
101
102 er_path_t *pathptr = (er_path_t *)pitem->data;
103
104 /* active paths only */
105 if( pathptr->active ) {
106
107 /* foreach filter on that path */
108 for( fitem = g_list_first(pathptr->filters);
109 fitem != NULL;
110 fitem = g_list_next(fitem)) {
111
112 er_filter_t *filtptr = (er_filter_t *) fitem->data;
113
114 /* foreach facility in that filter */
115 for(f=0; f<FAC_LAST; f++) {
116 if( MA_isset( filtptr->fac_mask, f ) ) {
117 er_asparray[f] |= filtptr->asp_mask;
118 }
119 }
120 }
121 }
122 }
123 }
124
125
126 /*++++++++++++++++++++++++++++++++++++++
127
128 Adds a filter to the filter chain for the given path.
129
130 er_ret_t
131 er_add_filter always returns ER_OK.
132
133 er_path_t *pathptr pointer to path
134
135 er_filter_t *filter pointer to the filter
136 ++++++++++++++++++++++++++++++++++++++*/
137 er_ret_t
138 er_add_filter( er_path_t *pathptr, er_filter_t *filter )
/* [<][>][^][v][top][bottom][index][help] */
139 {
140 er_filter_t *ft = malloc(sizeof(er_filter_t));
141
142 memcpy(ft, filter, sizeof(er_filter_t));
143 pathptr->filters = g_list_append(pathptr->filters, ft);
144
145 return ER_OK;
146 }
147
148
149 /*++++++++++++++++++++++++++++++++++++++
150
151 Finds a path by identifier and adds a list of filters to the filter
152 chain for that path.
153
154 er_ret_t
155 er_attach_filter_chain returns ER_INVKEY if the path cannot be found
156 or ER_OK on success.
157
158 char *key path identifier
159
160 GList *filterlist list of filters
161 ++++++++++++++++++++++++++++++++++++++*/
162 er_ret_t
163 er_attach_filter_chain( char *key, GList *filterlist )
/* [<][>][^][v][top][bottom][index][help] */
164 {
165 er_path_t *pathptr;
166 er_ret_t err;
167
168 if( (pathptr=er_find_path_byname(key)) == NULL ) {
169 return ER_INVKEY;
170 }
171 else {
172 GList *fitem;
173 for( fitem = g_list_first(filterlist);
174 fitem != NULL;
175 fitem = g_list_next(fitem)) {
176
177 er_filter_t *filtptr = (er_filter_t *) fitem->data;
178
179 if( !NOERR(err=er_add_filter( pathptr, filtptr)) ) {
180 return err;
181 }
182 }
183 }
184
185 er_upd_asparray();
186
187 return ER_OK;
188 }
189
190
191 /*++++++++++++++++++++++++++++++++++++++
192
193 basic sanity checks for a path definition. Currently only checking
194 if a specified socket exists.
195
196 int
197 er_path_safeguard Returns 0 on success, -1 on failure
198
199 er_path_t *path new path structure
200 ++++++++++++++++++++++++++++++++++++++*/
201 static
202 int
203 er_path_safeguard(er_path_t *path)
/* [<][>][^][v][top][bottom][index][help] */
204 {
205
206 switch ( path->type ) {
207
208 case ER_PATH_SOCK: /* the socket must exist */
209 {
210 char *n = SK_getpeername(path->descr.sock.fd);
211 if( n == NULL ) {
212 return -1;
213 }
214 else {
215 free(n);
216 }
217 }
218 break;
219 default:
220 break;
221 }
222
223 return 0;
224 }
225
226
227 /*++++++++++++++++++++++++++++++++++++++
228
229 Registers a path in the chain of paths.
230
231 er_ret_t
232 er_register_path returns ER_DUPENT if a path with that identifier
233 already exists, returns ER_INSANE if the sanity check
234 is not passed, or ER_OK on success.
235
236 er_path_t *path new path structure
237
238 char *key path identifier
239 ++++++++++++++++++++++++++++++++++++++*/
240 er_ret_t
241 er_register_path( er_path_t *path, char *key )
/* [<][>][^][v][top][bottom][index][help] */
242 {
243 er_path_t *ft;
244 er_path_t *pathptr;
245
246 if( (pathptr=er_find_path_byname(key)) != NULL ) {
247 return ER_DUPENT; /* duplicate !!! */
248 }
249 if( er_path_safeguard(path) < 0 ) {
250 return ER_INSANE;
251 }
252
253 ft = calloc(sizeof(er_path_t),1);
254 memcpy(ft, path, sizeof(er_path_t));
255 strncpy(ft->name, key, 31);
256 er_pathlist = g_list_append(er_pathlist, ft);
257
258 er_upd_asparray();
259
260 return ER_OK;
261 }
262
263
264 /*++++++++++++++++++++++++++++++++++++++
265
266 Finds the path by identified and replaces its definition without touching
267 the filters
268
269 er_ret_t
270 er_modify_path returns ER_INVKEY if the path cannot be found
271 or ER_OK on success.
272
273 er_path_t *newpath new path structure
274
275 char *key path identifier
276 ++++++++++++++++++++++++++++++++++++++*/
277 er_ret_t
278 er_modify_path( er_path_t *newpath, char *key )
/* [<][>][^][v][top][bottom][index][help] */
279 {
280 er_path_t *pathptr;
281
282 if( (pathptr=er_find_path_byname(key)) == NULL ) {
283 return ER_INVKEY;
284 }
285 else {
286 /* name stays the same */
287 pathptr->active = newpath->active;
288 pathptr->format = newpath->format;
289 pathptr->mutex = newpath->mutex;
290 pathptr->type = newpath->type;
291 pathptr->descr = newpath->descr;
292 /* filters stay the same */
293
294 er_upd_asparray();
295
296 return ER_OK;
297 }
298 }
299
300
301 /*++++++++++++++++++++++++++++++++++++++
302
303 Deletes a filter from the list of filters of the path specified by
304 identifier. The filter is specified by its position in the list,
305 starting with 0.
306
307 er_ret_t
308 er_delete_filter returns ER_INVKEY if the path or filter cannot be found
309
310 char *key path identifier
311
312 unsigned filterid filter position
313 ++++++++++++++++++++++++++++++++++++++*/
314 er_ret_t
315 er_delete_filter( char *key, unsigned filterid )
/* [<][>][^][v][top][bottom][index][help] */
316 {
317 er_path_t *pathptr;
318 er_filter_t *filtptr;
319
320 if( (pathptr=er_find_path_byname(key)) == NULL ) {
321 return ER_INVKEY;
322 }
323 else {
324 int numfilters = g_list_length(pathptr->filters);
325
326 if( filterid >= numfilters ) {
327 return ER_INVKEY;
328 }
329
330 filtptr = g_list_nth_data(pathptr->filters, (unsigned) filterid);
331 /* free filter structure */
332 free(filtptr);
333 /* remove filter link from list */
334 pathptr->filters = g_list_remove(pathptr->filters, filtptr);
335 /* update arrays */
336 er_upd_asparray();
337
338 return ER_OK;
339 }
340 }
341
342
343 /*++++++++++++++++++++++++++++++++++++++
344
345 Adds an argument to a dynamically build argv array of arguments for
346 a path of EXEC type.
347
348 er_path_t *pathptr path structure
349
350 char *arg new argument
351 ++++++++++++++++++++++++++++++++++++++*/
352 void
353 er_add_exec_arg(er_path_t *pathptr, char *arg)
/* [<][>][^][v][top][bottom][index][help] */
354 {
355 int len = 0;
356 char **argv = pathptr->descr.exec.argv;
357 char **newargv;
358
359 if( argv != NULL ) {
360 while( argv[len] != NULL ) {
361 len++;
362 }
363 }
364
365 newargv = calloc( sizeof(char **) * (len+2), 1 );
366 if( len > 0 ) {
367 memcpy( newargv, argv, sizeof(char **) * len);
368 }
369 newargv[len] = strdup(arg);
370
371 pathptr->descr.exec.argv = newargv;
372
373 if( argv != NULL ) {
374 free(argv);
375 }
376 }
377
378
379
380 /*++++++++++++++++++++++++++++++++++++++
381
382 free dynamic elements of the path structure
383
384 er_path_t *pathptr path structure
385
386 ++++++++++++++++++++++++++++++++++++++*/
387 void er_free_dynadescr( er_path_t *pathptr )
/* [<][>][^][v][top][bottom][index][help] */
388 {
389 if(pathptr->type == ER_PATH_EXEC ) {
390 char **argv = pathptr->descr.exec.argv;
391 int len=0;
392
393 if( argv != NULL ) {
394 while( argv[len] != NULL ) {
395 free( argv[len] );
396 len++;
397 }
398 }
399 if( argv != NULL ) {
400 free(argv);
401 }
402 }
403 }
404
405
406
407 /*++++++++++++++++++++++++++++++++++++++
408
409 finds and removes a path identified by identifier
410
411 er_ret_t
412 er_delete_path ER_OK on success, ER_INVKEY if path not found
413
414 char *key path identifier
415 ++++++++++++++++++++++++++++++++++++++*/
416 er_ret_t
417 er_delete_path(char *key )
/* [<][>][^][v][top][bottom][index][help] */
418 {
419 er_path_t *pathptr;
420
421 if( (pathptr=er_find_path_byname(key)) == NULL ) {
422 return ER_INVKEY;
423 }
424 else {
425 /* remove filters */
426 wr_clear_list( &(pathptr->filters) );
427 /* delete dynamic elements */
428 er_free_dynadescr( pathptr );
429 /* free path structure */
430 free(pathptr);
431 /* remove path link from list */
432 er_pathlist = g_list_remove(er_pathlist, pathptr);
433
434 /* update arrays */
435 er_upd_asparray();
436
437 return ER_OK;
438 }
439 }
440