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