## 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] */