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) 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) 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 ) 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 ) 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) 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 ) 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 ) 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 ) 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) 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 ) 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 ) 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 |