modules/er/er_macro.c

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

FUNCTIONS

This source file includes following functions.
  1. ER_process_split
  2. ER_macro_spec
  3. ER_make_macro
  4. ER_macro_predef
  5. er_macro_list_hook
  6. ER_macro_list
  7. ER_proc_ca_macro
  8. ER_proc_ca_err

   1 /***************************************
   2   $Revision: 1.5 $
   3 
   4   Error reporting (er) er_macro.c - simple macro processor
   5 
   6   Status: NOT REVUED, PARTLY TESTED
   7 
   8   Design and implementation by: Marek Bukowy
   9 
  10   ******************/ /******************
  11   Copyright (c) 1999,2000                             RIPE NCC
  12  
  13   All Rights Reserved
  14   
  15   Permission to use, copy, modify, and distribute this software and its
  16   documentation for any purpose and without fee is hereby granted,
  17   provided that the above copyright notice appear in all copies and that
  18   both that copyright notice and this permission notice appear in
  19   supporting documentation, and that the name of the author not be
  20   used in advertising or publicity pertaining to distribution of the
  21   software without specific, written prior permission.
  22   
  23   THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
  24   ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS; IN NO EVENT SHALL
  25   AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
  26   DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
  27   AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  28   OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  29   ***************************************/
  30 
  31 #include <string.h>
  32 #include <glib.h>
  33 #include "stubs.h"
  34 #include "sk.h"
  35 #include "er_macro.h"
  36 #include "er_paths.h"
  37 #include "er_yacc_helper.h" 
  38 #include "memwrap.h"
  39 
  40 #include "ca_configFns.h"
  41 #include "ca_dictSyms.h"
  42 #include "ca_macros.h"
  43 
  44 GHashTable *er_macro_hash = NULL;
  45 
  46 /* process a macro call, i.e. execute one of the predefined macros 
  47    selected by the 0th argument, using other arguments.
  48    
  49    Uses the er_macro_array[] to find the macro definition.
  50    
  51    Allocates the result string and stores the pointer to it in **output.
  52 
  53    returns 0 on success, non-0 on failure.
  54 */
  55 
  56 int
  57 ER_process_split(int argc, char **argv, char **output)
     /* [<][>][^][v][top][bottom][index][help] */
  58 {
  59   char *pattern, *ch;
  60   GString *result = g_string_new("");
  61 
  62   dieif( argc == 0 ); /* may not be called without the macro name */
  63 
  64   /* find macro, error if not found */
  65   if( (pattern = g_hash_table_lookup(er_macro_hash, argv[0])) == NULL ) {
  66     return -1;
  67   }
  68 
  69   /* copy the macro definition by portions, substituting the $([0-9]) 
  70      entries with arguments. Error if not enough arguments.
  71   */
  72   do {
  73 
  74     if( (ch = strstr( pattern, "$(" )) == NULL ) {
  75       /* no more entries. copy the rest */
  76       g_string_append ( result, pattern );
  77       break;
  78     }
  79     else {
  80       /* pass the string between here and ch */
  81       while( pattern != ch ) {
  82         g_string_append_c ( result, *pattern );
  83         pattern++;
  84       }
  85       /* check the next 3 characters exist, break the look if not */
  86       if( *(ch+2) == '\0' ||  *(ch+3) == '\0') {
  87         break;
  88       }
  89 
  90       /* look for the digit and ")", pass the $( through if not present */
  91       if( ! isdigit(*(ch+2)) || *(ch+3) != ')' ) {
  92         /* not need to do anything to make it pass through */
  93         ;
  94       }
  95       else {
  96         /* substitute the $(?) with the appropriate argument.
  97            error if not enough arguments or $(0) is used.*/
  98         int a = *(ch+2) - '0';
  99         
 100         if( argc < a || a==0) {
 101           return -1;
 102         }
 103         g_string_append( result, argv[a]);
 104         /* advance the pattern pointer */
 105         pattern += strlen("$(1)");
 106       }
 107     }
 108   } while(1);
 109 
 110   /* copy the pointer, free the orig structure, keep the text */
 111 
 112   *output = (result->str); 
 113   
 114   g_string_free( result, FALSE );
 115 
 116   return 0;
 117 }
 118 
 119 
 120 /* wrapper around the above that splits the string into argv 
 121    and calls the ER_parse. 
 122 
 123    sets the errbuf to the ER_parse_spec result
 124 
 125    returns 0 on success, non-0 on failure.
 126 */
 127 int
 128 ER_macro_spec(char *input, char **errbuf)
     /* [<][>][^][v][top][bottom][index][help] */
 129 {
 130   char **argv = g_strsplit(input, " ", 0);
 131   int argc = 0, ret;
 132   char *fullspec;
 133 
 134   while( argv[argc] != NULL ) {
 135     argc++;
 136   }
 137   
 138 
 139   if( ER_process_split(argc, argv, &fullspec) != 0 ) {
 140     /* macro unknown. That's OK, just parse that text now */
 141 
 142     fullspec = strdup(input);
 143   }
 144 
 145   ret = ER_parse_spec(fullspec, errbuf);
 146 
 147   free(fullspec);
 148   g_strfreev(argv);
 149   return ret;
 150   
 151 }
 152 
 153 
 154 void
 155 ER_make_macro(char *name, char *def)
     /* [<][>][^][v][top][bottom][index][help] */
 156 {
 157   char *cp_name = wr_string(name);
 158   char *cp_def  = wr_string(def);
 159 
 160   void *oldkey, *oldval;
 161   
 162   /* cleanup on redefinition */
 163   if( g_hash_table_lookup_extended(er_macro_hash, name, 
 164                                    &oldkey, &oldval) == TRUE ) {
 165     g_hash_table_remove(er_macro_hash, name);
 166     wr_free(oldkey);
 167     wr_free(oldval);
 168   }
 169   
 170   g_hash_table_insert(er_macro_hash, cp_name, cp_def);
 171 }
 172 
 173 
 174 /* predefine some macros */
 175 void
 176 ER_macro_predef(void)
     /* [<][>][^][v][top][bottom][index][help] */
 177 {
 178   /* create the hash with hashing and equality testing functions
 179      specific for strings 
 180   */
 181   er_macro_hash = g_hash_table_new(g_str_hash, g_str_equal);
 182   
 183 #define DBUPDLOG_FORMAT "  FORMAT SEVCHAR|FACSYMB|TEXTLONG|DATETIME|PIDFULL|PROGNAME|MNEMONIC  "
 184 #define RIPLOG_FORMAT   "  FORMAT SEVCHAR|FACSYMB|TEXTLONG|DATETIME|PIDFULL|PROGNAME|THR_ID|MNEMONIC  "
 185 
 186   /* catch-all for dbupdate */
 187   ER_make_macro("DBUPERR", "CREATE dbuperr {"
 188                 DBUPDLOG_FORMAT "NAME $(1) DATE}"
 189                 " ( FAC MM|UP SEV W- )");
 190 
 191   /* catch-all for rip */
 192   ER_make_macro("ALLRIPERR", "CREATE allriperr { " 
 193                 RIPLOG_FORMAT "NAME $(1) DATE}" 
 194                 " (FAC ALL SEV W- )");
 195 
 196   /* selected: errors in ripupdate */
 197   ER_make_macro("RIPUPERR", "CREATE ripuperr {" 
 198                 RIPLOG_FORMAT "NAME $(1) DATE}" 
 199                 " (FAC UD SEV W- )");
 200 
 201   /* querylog: logs all rip queries */
 202   ER_make_macro("QRYLOG", "CREATE qrylog {" 
 203                 RIPLOG_FORMAT "NAME $(1) DATE}" 
 204                 " (FAC PW ASP PW_I_QRYLOG SEV I )");
 205 
 206   /* audit: any security related messages from RIP */
 207   ER_make_macro("RIPAUDIT", "CREATE ripaudit {"
 208                 RIPLOG_FORMAT "NAME $(1) DATE}"
 209                 "( FAC PW ASP PW_I_PASSUN SEV i )" 
 210                 " (  FAC AC ASP AC_I_PERMBAN SEV I )");
 211 
 212   /* ripupdlog: logs all update transactions */
 213   ER_make_macro("RIPUPDLOG", "CREATE ripupdlog_$(2) {" 
 214                 RIPLOG_FORMAT "NAME $(1)_$(2) DATE}" 
 215                 " ( FAC UD ASP 0xffffffff SEV I THR self)");
 216 
 217   /* ripmirlog */
 218   ER_make_macro("RIPMIRLOG", "CREATE ripmirlog {"  
 219                 RIPLOG_FORMAT "NAME $(1) DATE }"
 220                 "( FAC PM ASP 0xffffffff SEV I )");
 221 
 222   /* server log: all administration by SV (startup, shutdown, etc) and errors */
 223   ER_make_macro("RIPSVRLOG", "CREATE ripsvrlog {" 
 224                 RIPLOG_FORMAT "NAME $(1) DATE}" 
 225                 " ( FAC SV ASP 0xffffffff SEV I-F )");                                                                                        
 226   /* dbase log: all errors of SQ */
 227   ER_make_macro("SQLOG", " CREATE sqlog {" 
 228                 RIPLOG_FORMAT "NAME $(1) DATE}" 
 229                 " ( FAC SQ SEV W- )");
 230   
 231 }
 232 
 233 static
 234 void er_macro_list_hook (void* key, void * value, void *condat)
     /* [<][>][^][v][top][bottom][index][help] */
 235 {
 236   SK_cd_printf(condat, "%s: %s\n", (char *) key, (char *) value);
 237 }
 238      
 239 void 
 240 ER_macro_list(sk_conn_st *condat)
     /* [<][>][^][v][top][bottom][index][help] */
 241 {
 242   g_hash_table_foreach(er_macro_hash, er_macro_list_hook, condat );
 243 }
 244 
 245 /* override macros with the definitions from the config file */
 246 void 
 247 ER_proc_ca_macro(void)
     /* [<][>][^][v][top][bottom][index][help] */
 248 {
 249   char *alldef = ca_get_er_macro ;
 250   char *this_line = alldef;
 251   char *defname, *defbody, *end_line;
 252   
 253   /* alldef is a copy of the configured value. so we can modify it
 254      if it helps us to do it line by line */
 255   
 256   /* ER_MACRO may not be present in the configuration, in which case 
 257      ca_get_er_macro returns NULL */
 258   
 259   if( alldef != NULL ) {
 260     
 261     while( *this_line != '\0' ) {
 262       /* separate the line */
 263       end_line = strchr(this_line, '\n');
 264       *end_line = '\0';
 265       
 266       /* advance to non-whitespace */
 267       while( isspace(*this_line) ) {
 268         this_line++;
 269       }
 270       
 271       /* find the name and body of the definition */
 272       defname = strsep(&this_line, " \t");
 273       defbody = this_line;
 274       
 275       /* fire */
 276       dieif( defname == NULL || defbody == NULL );
 277       ER_make_macro( defname, defbody );
 278       
 279       this_line = end_line + 1;
 280     }
 281     
 282     free(alldef);
 283   }
 284 }
 285 
 286 
 287 /* process the error definitions from the config file */
 288 void 
 289 ER_proc_ca_err(void)
     /* [<][>][^][v][top][bottom][index][help] */
 290 {
 291   char *alldef = ca_get_er_def ;
 292   char *this_line = alldef;
 293   char *defname, *defbody, *end_line;
 294   char *erret = NULL;
 295   int res;
 296  
 297     /* alldef is a copy of the configured value. so we can modify it
 298        if it helps us to do it line by line */
 299 
 300   /* ER_DEF may not be present in the configuration, in which case 
 301      ca_get_er_def returns NULL */
 302   if( alldef != NULL ) {
 303     
 304     while( *this_line != '\0' ) {
 305       /* separate the line */
 306       end_line = strchr(this_line, '\n');
 307       *end_line = '\0';
 308       
 309       /* fire */      
 310       if( (res = ER_macro_spec(this_line, &erret)) != 0 ) {
 311         fputs(erret, stderr);
 312         die;
 313       }
 314       
 315       free(erret); 
 316       
 317       this_line = end_line + 1;
 318     }
 319     
 320     free(alldef);
 321   }
 322 }

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