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