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