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