Source File modules/er/er_paths.c

    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  |