modules/er/er_paths.c

/* [<][>]
[^][v][top][bottom][index][help] */

FUNCTIONS

This source file includes following functions.
  1. er_find_path_byname
  2. er_upd_asparray
  3. er_add_filter
  4. er_attach_filter_chain
  5. er_path_safeguard
  6. er_register_path
  7. er_modify_path
  8. er_delete_filter
  9. er_add_exec_arg
  10. er_free_dynadescr
  11. 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 

/* [<][>][^][v][top][bottom][index][help] */