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_register_path
  6. er_modify_path
  7. er_delete_filter
  8. er_add_exec_arg
  9. er_free_dynadescr
  10. er_delete_path
  11. er_print_format
  12. er_print_one_path_descr
  13. er_print_aspmask
  14. er_print_facmask
  15. er_print_one_filter
  16. er_print_one_path
  17. er_print_paths

   1 /***************************************
   2   $Revision: 1.3 $
   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 
  34 #include "erroutines.h"
  35 #include "memwrap.h"
  36 
  37 
  38 /* find path by name, returns the pointer to it if found or NULL. */
  39 static
  40 er_path_t *
  41 er_find_path_byname(char *key)
     /* [<][>][^][v][top][bottom][index][help] */
  42 {
  43   GList *pitem;
  44   er_path_t *pathptr;
  45 
  46   /* foreach path */
  47   for( pitem = g_list_first(er_pathlist);
  48        pitem != NULL;
  49        pitem = g_list_next(pitem)) {
  50     
  51     pathptr = (er_path_t *)pitem->data;
  52     
  53     if( strcmp(pathptr->name, key) == 0 ) {
  54       return pathptr;
  55     }
  56   } 
  57 
  58   return NULL;
  59 }
  60 
  61 /* the "asp" array describes the "OR" of all filters' aspects. This is to allow
  62    fast dropping of messages that would be dropped anyway 
  63    
  64    when invoked, clears the array and then goes through all filters
  65    setting appropriate bits of aspects per facility
  66 */
  67 void
  68 er_upd_asparray(void)
     /* [<][>][^][v][top][bottom][index][help] */
  69 {
  70   GList *pitem, *fitem;
  71   er_fac_code_t f;
  72 
  73   /* clear */
  74   for(f=0; f<FAC_LAST; f++) {
  75     er_asparray[f] = 0;
  76   }
  77 
  78   /* foreach path */
  79   for( pitem = g_list_first(er_pathlist);
  80        pitem != NULL;
  81        pitem = g_list_next(pitem)) {
  82     
  83     er_path_t *pathptr = (er_path_t *)pitem->data;
  84     
  85     /* active paths only */
  86     if( pathptr->active ) {
  87       
  88       /* foreach filter on that path */
  89       for( fitem = g_list_first(pathptr->filters);
  90            fitem != NULL;
  91            fitem = g_list_next(fitem)) {
  92         
  93         er_filter_t *filtptr = (er_filter_t *) fitem->data;
  94 
  95         /* foreach facility in that filter */
  96         for(f=0; f<FAC_LAST; f++) {
  97           if( MA_isset( filtptr->fac_mask, f ) ) {
  98             er_asparray[f] |= filtptr->asp_mask;
  99           }
 100         }
 101       }
 102     }
 103   }
 104 }
 105 
 106 
 107 
 108 er_ret_t 
 109 er_add_filter( er_path_t *pathptr, er_filter_t *filter )
     /* [<][>][^][v][top][bottom][index][help] */
 110 {
 111   er_filter_t *ft = malloc(sizeof(er_filter_t));
 112   
 113   memcpy(ft, filter, sizeof(er_filter_t));
 114   pathptr->filters =  g_list_append(pathptr->filters, ft);
 115  
 116   return ER_OK;
 117 }
 118 
 119 
 120 er_ret_t 
 121 er_attach_filter_chain( char *key, GList *filterlist )
     /* [<][>][^][v][top][bottom][index][help] */
 122 { 
 123   er_path_t *pathptr;
 124   er_ret_t err;
 125   
 126   if( (pathptr=er_find_path_byname(key)) == NULL ) {
 127      return ER_INVKEY;
 128   }
 129   else {     
 130     GList  *fitem;
 131     for( fitem = g_list_first(filterlist);
 132          fitem != NULL;
 133          fitem = g_list_next(fitem)) {
 134         
 135       er_filter_t *filtptr = (er_filter_t *) fitem->data;
 136       
 137       if( !NOERR(err=er_add_filter( pathptr, filtptr)) ) {
 138         return err;
 139       }
 140     }
 141   }
 142 
 143   return ER_OK;
 144 }
 145 
 146 
 147 er_ret_t
 148 er_register_path(  er_path_t *path, char *key )
     /* [<][>][^][v][top][bottom][index][help] */
 149 {
 150   er_path_t *ft;
 151   er_path_t *pathptr;
 152   
 153   if( (pathptr=er_find_path_byname(key)) != NULL ) {
 154     return ER_DUPENT; /* duplicate !!! */
 155   }
 156   
 157   ft = calloc(sizeof(er_path_t),1);
 158   memcpy(ft, path, sizeof(er_path_t));
 159   strncpy(ft->name, key, 31);
 160   er_pathlist = g_list_append(er_pathlist, ft);
 161 
 162   er_upd_asparray();
 163   
 164   return ER_OK;
 165 }
 166 
 167 /* find the path by name and replace its definition without touching
 168    the filters
 169 */
 170 er_ret_t
 171 er_modify_path(  er_path_t *newpath, char *key )
     /* [<][>][^][v][top][bottom][index][help] */
 172 {
 173   er_path_t *pathptr;
 174 
 175   if( (pathptr=er_find_path_byname(key)) == NULL ) {
 176      return ER_INVKEY;
 177   }
 178   else {
 179     /* name stays the same */
 180     pathptr->active = newpath->active;
 181     pathptr->format = newpath->format;
 182     pathptr->mutex  = newpath->mutex;
 183     pathptr->type   = newpath->type;
 184     pathptr->descr  = newpath->descr;
 185     /* filters stay the same */
 186     
 187     er_upd_asparray();
 188   
 189     return ER_OK;
 190   }
 191 }
 192 
 193 er_ret_t
 194 er_delete_filter( char *key, unsigned int filterid ) 
     /* [<][>][^][v][top][bottom][index][help] */
 195 {
 196   er_path_t *pathptr;
 197   er_filter_t *filtptr;
 198 
 199   if( (pathptr=er_find_path_byname(key)) == NULL ) {
 200      return ER_INVKEY;
 201   }
 202   else {
 203     int numfilters = g_list_length(pathptr->filters);
 204     
 205     if( filterid >= numfilters ) {
 206       return ER_INVKEY;
 207     }
 208     
 209     filtptr = g_list_nth_data(pathptr->filters, filterid);
 210     /* free filter structure */
 211     free(filtptr);
 212     /* remove filter link from list */
 213     pathptr->filters = g_list_remove(pathptr->filters, filtptr);
 214     /* update arrays */
 215     er_upd_asparray();  
 216 
 217     return ER_OK;
 218   }
 219 }
 220 
 221 
 222 void
 223 er_add_exec_arg(er_path_t *pathptr, char *arg)
     /* [<][>][^][v][top][bottom][index][help] */
 224 {
 225   int len = 0;
 226   char **argv = pathptr->descr.exec.argv;
 227   char **newargv;
 228 
 229   if( argv != NULL ) {
 230     while( argv[len] != NULL ) {
 231       len++;
 232     }
 233   }
 234 
 235   newargv = calloc( sizeof(char **) * (len+2), 1 );
 236   if( len > 0 ) {
 237     memcpy( newargv, argv, sizeof(char **) * len);
 238   }
 239   newargv[len] = strdup(arg);
 240   
 241   pathptr->descr.exec.argv = newargv;
 242 
 243   if( argv != NULL ) {
 244     free(argv);
 245   }
 246 }
 247  
 248 /* free dynamic elements of the path description */ 
 249 void er_free_dynadescr( er_path_t *pathptr )
     /* [<][>][^][v][top][bottom][index][help] */
 250 {
 251   char **argv = pathptr->descr.exec.argv;
 252   int len=0;
 253   
 254   if( argv != NULL ) {
 255     while( argv[len] != NULL ) {
 256       free( argv[len] );
 257       len++;
 258     }
 259   }
 260 
 261   if( argv != NULL ) {
 262     free(argv);
 263   }
 264 }
 265 
 266 
 267 /* finds and removes a path identified by the key (name).
 268    Also removes all associated filters.
 269 
 270    returns:
 271    ER_OK on success 
 272    
 273 */
 274 er_ret_t
 275 er_delete_path(char *key )
     /* [<][>][^][v][top][bottom][index][help] */
 276 {
 277   er_path_t *pathptr;
 278 
 279   if( (pathptr=er_find_path_byname(key)) == NULL ) {
 280      return ER_INVKEY;
 281   }
 282   else {
 283     /* remove filters */
 284     wr_clear_list( &(pathptr->filters) );
 285     /* delete dynamic elements */
 286     er_free_dynadescr( pathptr );
 287     /* free path structure */
 288     free(pathptr);
 289     /* remove path link from list */
 290     er_pathlist = g_list_remove(er_pathlist, pathptr);
 291     
 292     /* update arrays */
 293     er_upd_asparray();  
 294 
 295     return ER_OK;
 296   }
 297 }
 298 
 299 
 300 /************************************************************/
 301 static
 302 void er_print_format(int format, GString *g_reply )
     /* [<][>][^][v][top][bottom][index][help] */
 303 {
 304   int i;
 305 
 306   for(i=0;  er_formarr[i].n != NULL; i++) {
 307     if( format & er_formarr[i].v ) {
 308       g_string_sprintfa(g_reply, "%s|",er_formarr[i].n);
 309     }
 310   }
 311   /* cut the last "|" */
 312   g_string_truncate(g_reply, strlen(g_reply->str)-1);
 313 }
 314 
 315 
 316 static
 317 void er_print_one_path_descr(er_path_t *pathptr, GString *g_reply )
     /* [<][>][^][v][top][bottom][index][help] */
 318 {
 319   er_path_descr_t *d = &(pathptr->descr);
 320 
 321   switch(pathptr->type) {
 322   case  ER_PATH_NAME:
 323     g_string_sprintfa(g_reply, "NAME %s%s", d->name.filename, 
 324                       d->name.date ? " DATE" : ""
 325                       );
 326     break;
 327   case  ER_PATH_SOCK:
 328     g_string_sprintfa(g_reply, "SOCK %d", d->sock.fd );
 329 
 330     break;
 331 
 332   case  ER_PATH_EXEC:
 333     g_string_sprintfa(g_reply, "EXEC ");
 334     if( d->exec.usepath ) {
 335       g_string_sprintfa(g_reply, "PATH ");
 336     }
 337     {
 338       char **argv = d->exec.argv;
 339       int len=0;
 340   
 341       if( argv != NULL ) {
 342         while( argv[len] != NULL ) {
 343           g_string_sprintfa(g_reply, "%s ", argv[len]);
 344           len++;
 345         }
 346       }
 347     }
 348     break;
 349 
 350   default:
 351     /* XXX other path descriptions missing */
 352     break;
 353   }
 354 }
 355 
 356 static
 357 void er_print_aspmask(mask_t facmask, unsigned aspmask, GString *g_reply)
     /* [<][>][^][v][top][bottom][index][help] */
 358 {
 359   int i = 31;
 360 
 361   while(i >= 0) {
 362     if( aspmask & (1<<i) ) {
 363       er_getaspsym(facmask, 1<<i, g_reply);
 364       g_string_append(g_reply, "|");
 365     }
 366     
 367     i--;
 368   }
 369   /* cut the last "|" */
 370   g_string_truncate(g_reply, strlen(g_reply->str)-1);
 371 }
 372 
 373 static
 374 void er_print_facmask(mask_t facmask, GString *g_reply)
     /* [<][>][^][v][top][bottom][index][help] */
 375 {
 376   int i = FAC_NONE;
 377   
 378   while( ++i != FAC_LAST ) {
 379     if( MA_isset(facmask, er_fac_err[i].code) ) {
 380       g_string_sprintfa(g_reply, "%s|", er_fac_err[i].name);
 381     }
 382   }
 383   /* cut the last "|" */
 384   g_string_truncate(g_reply, strlen(g_reply->str)-1);
 385 
 386 }
 387 
 388 static
 389 void er_print_one_filter(er_filter_t *filtptr, GString *g_reply )
     /* [<][>][^][v][top][bottom][index][help] */
 390 { 
 391   g_string_sprintfa(g_reply, "( FAC ");
 392   er_print_facmask( filtptr->fac_mask, g_reply);
 393   
 394   if( filtptr->asp_mask != 0 ) {
 395     g_string_sprintfa(g_reply, "  ASP ");
 396     er_print_aspmask(  filtptr->fac_mask, filtptr->asp_mask, g_reply);
 397   }
 398 
 399   g_string_sprintfa(g_reply, "  SEV %s-%s ",
 400                     er_getsevsym( filtptr->sev_min, ER_M_SEVCHAR),
 401                     er_getsevsym( filtptr->sev_max, ER_M_SEVCHAR)
 402                     );
 403   if( filtptr->thr_id != 0 ) {
 404     g_string_sprintfa(g_reply, "   THR %u ", filtptr->thr_id);
 405   }
 406   g_string_sprintfa(g_reply, " )" );
 407 }
 408 
 409 static
 410 void er_print_one_path(er_path_t *pathptr, GString *g_reply )
     /* [<][>][^][v][top][bottom][index][help] */
 411 {
 412   GList   *qitem;
 413   int f=1;
 414   
 415   g_string_sprintfa(g_reply,"%s { ", pathptr->name );
 416   g_string_sprintfa(g_reply," FORMAT ");
 417   er_print_format(pathptr->format, g_reply ); 
 418   g_string_sprintfa(g_reply,"  ");
 419 
 420   er_print_one_path_descr(pathptr, g_reply);
 421   g_string_sprintfa(g_reply," }\n");
 422 
 423   for(qitem = g_list_first(pathptr->filters);
 424       qitem != NULL;
 425       qitem = g_list_next(qitem)) {
 426     er_filter_t *filtptr = (er_filter_t *) qitem -> data;
 427     
 428     g_string_sprintfa(g_reply,"\t");
 429     er_print_one_filter(filtptr, g_reply) ;
 430     g_string_sprintfa(g_reply,"\n");
 431     f++;
 432   }
 433 
 434 }
 435 
 436 void er_print_paths(char **retbuf)
     /* [<][>][^][v][top][bottom][index][help] */
 437 {
 438   GList   *qitem;
 439   GString *g_reply = g_string_sized_new(2048); /* initial size */
 440 
 441   for( qitem = g_list_first(er_pathlist);
 442        qitem != NULL;
 443        qitem = g_list_next(qitem)) {
 444     er_path_t *pathptr = qitem -> data;
 445 
 446     /*   g_string_sprintfa(g_reply, "path type %d (%s) with %d filters\n",
 447            pathptr->type, er_pathtypes[pathptr->type],
 448            g_list_length(pathptr->filters));
 449     */
 450     er_print_one_path(pathptr, g_reply);
 451 
 452   }
 453 
 454   *retbuf = g_reply->str;  
 455 
 456   /* we must duplicate the string allocated by glib - it can be freed 
 457      only by glib internal free function :-( */
 458   g_string_free( g_reply, /* CONSTCOND */ FALSE);
 459 }

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