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