00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
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>
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
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
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 }