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

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