net-snmp  5.4.1
default_store.c
00001 /*
00002  * default_store.c: storage space for defaults 
00003  */
00004 /* Portions of this file are subject to the following copyright(s).  See
00005  * the Net-SNMP's COPYING file for more details and other copyrights
00006  * that may apply:
00007  */
00008 /*
00009  * Portions of this file are copyrighted by:
00010  * Copyright © 2003 Sun Microsystems, Inc. All rights reserved.
00011  * Use is subject to license terms specified in the COPYING file
00012  * distributed with the Net-SNMP package.
00013  */
00128 #include <net-snmp/net-snmp-config.h>
00129 #include <sys/types.h>
00130 #if HAVE_STDLIB_H
00131 #include <stdlib.h>
00132 #endif
00133 #if HAVE_NETINET_IN_H
00134 #include <netinet/in.h>
00135 #endif
00136 #if HAVE_STDLIB_H
00137 #include <stdlib.h>
00138 #endif
00139 #if HAVE_STRING_H
00140 #include <string.h>
00141 #else
00142 #include <strings.h>
00143 #endif
00144 #if HAVE_WINSOCK_H
00145 #include <winsock.h>
00146 #endif
00147 
00148 #if HAVE_DMALLOC_H
00149 #include <dmalloc.h>
00150 #endif
00151 
00152 #include <net-snmp/types.h>
00153 #include <net-snmp/output_api.h>
00154 #include <net-snmp/config_api.h>
00155 #include <net-snmp/library/default_store.h>    /* for "internal" definitions */
00156 #include <net-snmp/utilities.h>
00157 
00158 #include <net-snmp/library/snmp_api.h>
00159 
00160 static const char * stores [NETSNMP_DS_MAX_IDS] = { "LIB", "APP", "TOK" };
00161 
00162 typedef struct netsnmp_ds_read_config_s {
00163   u_char          type;
00164   char           *token;
00165   char           *ftype;
00166   int             storeid;
00167   int             which;
00168   struct netsnmp_ds_read_config_s *next;
00169 } netsnmp_ds_read_config;
00170 
00171 static netsnmp_ds_read_config *netsnmp_ds_configs = NULL;
00172 
00173 static int   netsnmp_ds_integers[NETSNMP_DS_MAX_IDS][NETSNMP_DS_MAX_SUBIDS];
00174 static char  netsnmp_ds_booleans[NETSNMP_DS_MAX_IDS][NETSNMP_DS_MAX_SUBIDS/8];
00175 static char *netsnmp_ds_strings[NETSNMP_DS_MAX_IDS][NETSNMP_DS_MAX_SUBIDS];
00176 static void *netsnmp_ds_voids[NETSNMP_DS_MAX_IDS][NETSNMP_DS_MAX_SUBIDS];
00177 
00178 /*
00179  * Prototype definitions 
00180  */
00181 void            netsnmp_ds_handle_config(const char *token, char *line);
00182 
00196 int
00197 netsnmp_ds_set_boolean(int storeid, int which, int value)
00198 {
00199     if (storeid < 0 || storeid >= NETSNMP_DS_MAX_IDS || 
00200         which   < 0 || which   >= NETSNMP_DS_MAX_SUBIDS) {
00201         return SNMPERR_GENERR;
00202     }
00203 
00204     DEBUGMSGTL(("netsnmp_ds_set_boolean", "Setting %s:%d = %d/%s\n",
00205                 stores[storeid], which, value, ((value) ? "True" : "False")));
00206 
00207     if (value > 0) {
00208         netsnmp_ds_booleans[storeid][which/8] |= (1 << (which % 8));
00209     } else {
00210         netsnmp_ds_booleans[storeid][which/8] &= (0xff7f >> (7 - (which % 8)));
00211     }
00212 
00213     return SNMPERR_SUCCESS;
00214 }
00215 
00216 int
00217 netsnmp_ds_toggle_boolean(int storeid, int which)
00218 {
00219     if (storeid < 0 || storeid >= NETSNMP_DS_MAX_IDS || 
00220         which   < 0 || which   >= NETSNMP_DS_MAX_SUBIDS) {
00221         return SNMPERR_GENERR;
00222     }
00223 
00224     if ((netsnmp_ds_booleans[storeid][which/8] & (1 << (which % 8))) == 0) {
00225         netsnmp_ds_booleans[storeid][which/8] |= (1 << (which % 8));
00226     } else {
00227         netsnmp_ds_booleans[storeid][which/8] &= (0xff7f >> (7 - (which % 8)));
00228     }
00229 
00230     DEBUGMSGTL(("netsnmp_ds_toggle_boolean", "Setting %s:%d = %d/%s\n",
00231                 stores[storeid], which, netsnmp_ds_booleans[storeid][which/8],
00232                 ((netsnmp_ds_booleans[storeid][which/8]) ? "True" : "False")));
00233 
00234     return SNMPERR_SUCCESS;
00235 }
00236 
00237 int
00238 netsnmp_ds_get_boolean(int storeid, int which)
00239 {
00240     if (storeid < 0 || storeid >= NETSNMP_DS_MAX_IDS || 
00241         which   < 0 || which   >= NETSNMP_DS_MAX_SUBIDS) {
00242         return SNMPERR_GENERR;
00243     }
00244 
00245     return (netsnmp_ds_booleans[storeid][which/8] & (1 << (which % 8))) ? 1:0;
00246 }
00247 
00248 int
00249 netsnmp_ds_set_int(int storeid, int which, int value)
00250 {
00251     if (storeid < 0 || storeid >= NETSNMP_DS_MAX_IDS || 
00252         which   < 0 || which   >= NETSNMP_DS_MAX_SUBIDS) {
00253         return SNMPERR_GENERR;
00254     }
00255 
00256     DEBUGMSGTL(("netsnmp_ds_set_int", "Setting %s:%d = %d\n",
00257                 stores[storeid], which, value));
00258 
00259     netsnmp_ds_integers[storeid][which] = value;
00260     return SNMPERR_SUCCESS;
00261 }
00262 
00263 int
00264 netsnmp_ds_get_int(int storeid, int which)
00265 {
00266     if (storeid < 0 || storeid >= NETSNMP_DS_MAX_IDS || 
00267         which   < 0 || which   >= NETSNMP_DS_MAX_SUBIDS) {
00268         return SNMPERR_GENERR;
00269     }
00270 
00271     return netsnmp_ds_integers[storeid][which];
00272 }
00273 
00274 int
00275 netsnmp_ds_set_string(int storeid, int which, const char *value)
00276 {
00277     if (storeid < 0 || storeid >= NETSNMP_DS_MAX_IDS || 
00278         which   < 0 || which   >= NETSNMP_DS_MAX_SUBIDS) {
00279         return SNMPERR_GENERR;
00280     }
00281 
00282     DEBUGMSGTL(("netsnmp_ds_set_string", "Setting %s:%d = \"%s\"\n",
00283                 stores[storeid], which, (value ? value : "(null)")));
00284 
00285     /*
00286      * is some silly person is calling us with our own pointer?
00287      */
00288     if (netsnmp_ds_strings[storeid][which] == value)
00289         return SNMPERR_SUCCESS;
00290     
00291     if (netsnmp_ds_strings[storeid][which] != NULL) {
00292         free(netsnmp_ds_strings[storeid][which]);
00293         netsnmp_ds_strings[storeid][which] = NULL;
00294     }
00295 
00296     if (value) {
00297         netsnmp_ds_strings[storeid][which] = strdup(value);
00298     } else {
00299         netsnmp_ds_strings[storeid][which] = NULL;
00300     }
00301 
00302     return SNMPERR_SUCCESS;
00303 }
00304 
00305 char *
00306 netsnmp_ds_get_string(int storeid, int which)
00307 {
00308     if (storeid < 0 || storeid >= NETSNMP_DS_MAX_IDS || 
00309         which   < 0 || which   >= NETSNMP_DS_MAX_SUBIDS) {
00310         return NULL;
00311     }
00312 
00313     return netsnmp_ds_strings[storeid][which];
00314 }
00315 
00316 int
00317 netsnmp_ds_set_void(int storeid, int which, void *value)
00318 {
00319     if (storeid < 0 || storeid >= NETSNMP_DS_MAX_IDS || 
00320         which   < 0 || which   >= NETSNMP_DS_MAX_SUBIDS) {
00321         return SNMPERR_GENERR;
00322     }
00323 
00324     DEBUGMSGTL(("netsnmp_ds_set_void", "Setting %s:%d = %x\n",
00325                 stores[storeid], which, value));
00326 
00327     netsnmp_ds_voids[storeid][which] = value;
00328 
00329     return SNMPERR_SUCCESS;
00330 }
00331 
00332 void *
00333 netsnmp_ds_get_void(int storeid, int which)
00334 {
00335     if (storeid < 0 || storeid >= NETSNMP_DS_MAX_IDS || 
00336         which   < 0 || which   >= NETSNMP_DS_MAX_SUBIDS) {
00337         return NULL;
00338     }
00339 
00340     return netsnmp_ds_voids[storeid][which];
00341 }
00342 
00343 int
00344 netsnmp_ds_parse_boolean(char *line)
00345 {
00346     char           *value, *endptr;
00347     int             itmp;
00348     char           *st;
00349 
00350     value = strtok_r(line, " \t\n", &st);
00351     if (strcasecmp(value, "yes") == 0 || 
00352         strcasecmp(value, "true") == 0) {
00353         return 1;
00354     } else if (strcasecmp(value, "no") == 0 ||
00355                strcasecmp(value, "false") == 0) {
00356         return 0;
00357     } else {
00358         itmp = strtol(value, &endptr, 10);
00359         if (*endptr != 0 || itmp < 0 || itmp > 1) {
00360             config_perror("Should be yes|no|true|false|0|1");
00361             return -1;
00362         }
00363         return itmp;
00364     }
00365 }
00366 
00367 void
00368 netsnmp_ds_handle_config(const char *token, char *line)
00369 {
00370     netsnmp_ds_read_config *drsp;
00371     char            buf[SNMP_MAXBUF];
00372     char           *value, *endptr;
00373     int             itmp;
00374     char           *st;
00375 
00376     DEBUGMSGTL(("netsnmp_ds_handle_config", "handling %s\n", token));
00377 
00378     for (drsp = netsnmp_ds_configs;
00379          drsp != NULL && strcasecmp(token, drsp->token) != 0;
00380          drsp = drsp->next);
00381 
00382     if (drsp != NULL) {
00383         DEBUGMSGTL(("netsnmp_ds_handle_config",
00384                     "setting: token=%s, type=%d, id=%s, which=%d\n",
00385                     drsp->token, drsp->type, stores[drsp->storeid],
00386                     drsp->which));
00387 
00388         switch (drsp->type) {
00389         case ASN_BOOLEAN:
00390             itmp = netsnmp_ds_parse_boolean(line);
00391             if ( itmp != -1 )
00392                 netsnmp_ds_set_boolean(drsp->storeid, drsp->which, itmp);
00393             DEBUGMSGTL(("netsnmp_ds_handle_config", "bool: %d\n", itmp));
00394             break;
00395 
00396         case ASN_INTEGER:
00397             value = strtok_r(line, " \t\n", &st);
00398             itmp = strtol(value, &endptr, 10);
00399             if (*endptr != 0) {
00400                 config_perror("Bad integer value");
00401             } else {
00402                 netsnmp_ds_set_int(drsp->storeid, drsp->which, itmp);
00403             }
00404             DEBUGMSGTL(("netsnmp_ds_handle_config", "int: %d\n", itmp));
00405             break;
00406 
00407         case ASN_OCTET_STR:
00408             if (*line == '"') {
00409                 copy_nword(line, buf, sizeof(buf));
00410                 netsnmp_ds_set_string(drsp->storeid, drsp->which, buf);
00411             } else {
00412                 netsnmp_ds_set_string(drsp->storeid, drsp->which, line);
00413             }
00414             DEBUGMSGTL(("netsnmp_ds_handle_config", "string: %s\n", line));
00415             break;
00416 
00417         default:
00418             snmp_log(LOG_ERR, "netsnmp_ds_handle_config: type %d (0x%02x)\n",
00419                      drsp->type, drsp->type);
00420             break;
00421         }
00422     } else {
00423         snmp_log(LOG_ERR, "netsnmp_ds_handle_config: no registration for %s\n",
00424                  token);
00425     }
00426 }
00427 
00428 
00429 int
00430 netsnmp_ds_register_config(u_char type, const char *ftype, const char *token,
00431                            int storeid, int which)
00432 {
00433     netsnmp_ds_read_config *drsp;
00434 
00435     if (storeid < 0 || storeid >= NETSNMP_DS_MAX_IDS    || 
00436         which   < 0 || which   >= NETSNMP_DS_MAX_SUBIDS || token == NULL) {
00437         return SNMPERR_GENERR;
00438     }
00439 
00440     if (netsnmp_ds_configs == NULL) {
00441         netsnmp_ds_configs = SNMP_MALLOC_TYPEDEF(netsnmp_ds_read_config);
00442         drsp = netsnmp_ds_configs;
00443     } else {
00444         for (drsp = netsnmp_ds_configs; drsp->next != NULL; drsp = drsp->next);
00445         drsp->next = SNMP_MALLOC_TYPEDEF(netsnmp_ds_read_config);
00446         drsp = drsp->next;
00447     }
00448 
00449     drsp->type    = type;
00450     drsp->ftype   = strdup(ftype);
00451     drsp->token   = strdup(token);
00452     drsp->storeid = storeid;
00453     drsp->which   = which;
00454 
00455     switch (type) {
00456     case ASN_BOOLEAN:
00457         register_config_handler(ftype, token, netsnmp_ds_handle_config, NULL,
00458                                 "(1|yes|true|0|no|false)");
00459         break;
00460 
00461     case ASN_INTEGER:
00462         register_config_handler(ftype, token, netsnmp_ds_handle_config, NULL,
00463                                 "integerValue");
00464         break;
00465 
00466     case ASN_OCTET_STR:
00467         register_config_handler(ftype, token, netsnmp_ds_handle_config, NULL,
00468                                 "string");
00469         break;
00470 
00471     }
00472     return SNMPERR_SUCCESS;
00473 }
00474 
00475 int
00476 netsnmp_ds_register_premib(u_char type, const char *ftype, const char *token,
00477                            int storeid, int which)
00478 {
00479     netsnmp_ds_read_config *drsp;
00480 
00481     if (storeid < 0 || storeid >= NETSNMP_DS_MAX_IDS    || 
00482         which   < 0 || which   >= NETSNMP_DS_MAX_SUBIDS || token == NULL) {
00483         return SNMPERR_GENERR;
00484     }
00485 
00486     if (netsnmp_ds_configs == NULL) {
00487         netsnmp_ds_configs = SNMP_MALLOC_TYPEDEF(netsnmp_ds_read_config);
00488         drsp = netsnmp_ds_configs;
00489     } else {
00490         for (drsp = netsnmp_ds_configs; drsp->next != NULL; drsp = drsp->next);
00491         drsp->next = SNMP_MALLOC_TYPEDEF(netsnmp_ds_read_config);
00492         drsp = drsp->next;
00493     }
00494 
00495     drsp->type    = type;
00496     drsp->ftype   = strdup(ftype);
00497     drsp->token   = strdup(token);
00498     drsp->storeid = storeid;
00499     drsp->which   = which;
00500 
00501     switch (type) {
00502     case ASN_BOOLEAN:
00503         register_prenetsnmp_mib_handler(ftype, token, netsnmp_ds_handle_config,
00504                                         NULL, "(1|yes|true|0|no|false)");
00505         break;
00506 
00507     case ASN_INTEGER:
00508         register_prenetsnmp_mib_handler(ftype, token, netsnmp_ds_handle_config,
00509                                         NULL, "integerValue");
00510         break;
00511 
00512     case ASN_OCTET_STR:
00513         register_prenetsnmp_mib_handler(ftype, token, netsnmp_ds_handle_config,
00514                                         NULL, "string");
00515         break;
00516 
00517     }
00518     return SNMPERR_SUCCESS;
00519 }
00520 
00521 void
00522 netsnmp_ds_shutdown()
00523 {
00524     netsnmp_ds_read_config *drsp;
00525     int             i, j;
00526 
00527     for (drsp = netsnmp_ds_configs; drsp; drsp = netsnmp_ds_configs) {
00528         netsnmp_ds_configs = drsp->next;
00529 
00530         unregister_config_handler(drsp->ftype, drsp->token);
00531         if (drsp->ftype != NULL) {
00532             free(drsp->ftype);
00533         }
00534         if (drsp->token != NULL) {
00535             free(drsp->token);
00536         }
00537         free(drsp);
00538     }
00539 
00540     for (i = 0; i < NETSNMP_DS_MAX_IDS; i++) {
00541         for (j = 0; j < NETSNMP_DS_MAX_SUBIDS; j++) {
00542             if (netsnmp_ds_strings[i][j] != NULL) {
00543                 free(netsnmp_ds_strings[i][j]);
00544                 netsnmp_ds_strings[i][j] = NULL;
00545             }
00546         }
00547     }
00548 }