|
net-snmp
5.4.1
|
00001 #include <net-snmp/net-snmp-config.h> 00002 00003 #ifdef HAVE_STDLIB_H 00004 #include <stdlib.h> 00005 #endif 00006 #include <stdio.h> 00007 #if HAVE_STRING_H 00008 #include <string.h> 00009 #else 00010 #include <strings.h> 00011 #endif 00012 00013 #if HAVE_DMALLOC_H 00014 #include <dmalloc.h> 00015 #endif 00016 #include <sys/types.h> 00017 00018 #include <net-snmp/types.h> 00019 #include <net-snmp/config_api.h> 00020 00021 #include <net-snmp/library/snmp_enum.h> 00022 #include <net-snmp/library/tools.h> 00023 00024 struct snmp_enum_list_str { 00025 char *name; 00026 struct snmp_enum_list *list; 00027 struct snmp_enum_list_str *next; 00028 }; 00029 00030 static struct snmp_enum_list ***snmp_enum_lists; 00031 unsigned int current_maj_num; 00032 unsigned int current_min_num; 00033 struct snmp_enum_list_str *sliststorage; 00034 00035 int 00036 init_snmp_enum(const char *type) 00037 { 00038 int i; 00039 00040 if (!snmp_enum_lists) 00041 snmp_enum_lists = (struct snmp_enum_list ***) 00042 calloc(1, sizeof(struct snmp_enum_list **) * SE_MAX_IDS); 00043 if (!snmp_enum_lists) 00044 return SE_NOMEM; 00045 current_maj_num = SE_MAX_IDS; 00046 00047 for (i = 0; i < SE_MAX_IDS; i++) { 00048 if (!snmp_enum_lists[i]) 00049 snmp_enum_lists[i] = (struct snmp_enum_list **) 00050 calloc(1, sizeof(struct snmp_enum_list *) * SE_MAX_SUBIDS); 00051 if (!snmp_enum_lists[i]) 00052 return SE_NOMEM; 00053 } 00054 current_min_num = SE_MAX_SUBIDS; 00055 00056 if (!sliststorage) 00057 sliststorage = NULL; 00058 00059 register_config_handler(type, "enum", se_read_conf, NULL, NULL); 00060 return SE_OK; 00061 } 00062 00063 int 00064 se_store_in_list(struct snmp_enum_list *new_list, 00065 unsigned int major, unsigned int minor) 00066 { 00067 int ret = SE_OK; 00068 00069 if (major > current_maj_num || minor > current_min_num) { 00070 /* 00071 * XXX: realloc 00072 */ 00073 return SE_NOMEM; 00074 } 00075 00076 00077 if (snmp_enum_lists[major][minor] != NULL) 00078 ret = SE_ALREADY_THERE; 00079 00080 snmp_enum_lists[major][minor] = new_list; 00081 00082 return ret; 00083 } 00084 00085 void 00086 se_read_conf(const char *word, char *cptr) 00087 { 00088 int major, minor; 00089 int value; 00090 char *cp, *cp2; 00091 char e_name[BUFSIZ]; 00092 char e_enum[ BUFSIZ]; 00093 00094 if (!cptr || *cptr=='\0') 00095 return; 00096 00097 /* 00098 * Extract the first token 00099 * (which should be the name of the list) 00100 */ 00101 cp = copy_nword(cptr, e_name, sizeof(e_name)); 00102 cp = skip_white(cp); 00103 if (!cp || *cp=='\0') 00104 return; 00105 00106 00107 /* 00108 * Add each remaining enumeration to the list, 00109 * using the appropriate style interface 00110 */ 00111 if (sscanf(e_name, "%d:%d", &major, &minor) == 2) { 00112 /* 00113 * Numeric major/minor style 00114 */ 00115 while (1) { 00116 cp = copy_nword(cp, e_enum, sizeof(e_enum)); 00117 if (sscanf(e_enum, "%d:", &value) != 1) { 00118 break; 00119 } 00120 cp2 = e_enum; 00121 while (*(cp2++) != ':') 00122 ; 00123 se_add_pair(major, minor, cp2, value); 00124 if (!cp) 00125 break; 00126 } 00127 } else { 00128 /* 00129 * Named enumeration 00130 */ 00131 while (1) { 00132 cp = copy_nword(cp, e_enum, sizeof(e_enum)); 00133 if (sscanf(e_enum, "%d:", &value) != 1) { 00134 break; 00135 } 00136 cp2 = e_enum; 00137 while (*(cp2++) != ':') 00138 ; 00139 se_add_pair_to_slist(e_name, cp2, value); 00140 if (!cp) 00141 break; 00142 } 00143 } 00144 } 00145 00146 void 00147 se_store_enum_list(struct snmp_enum_list *new_list, 00148 const char *token, char *type) 00149 { 00150 struct snmp_enum_list *listp = new_list; 00151 char line[2048]; 00152 char buf[512]; 00153 int len = 0; 00154 00155 snprintf(line, sizeof(line), "enum %s", token); 00156 while (listp) { 00157 snprintf(buf, sizeof(buf), " %d:%s", listp->value, listp->label); 00158 /* 00159 * Calculate the space left in the buffer. 00160 * If this is not sufficient to include the next enum, 00161 * then save the line so far, and start again. 00162 */ 00163 len = sizeof(line) - strlen(line); 00164 if ((int)strlen(buf) > len) { 00165 read_config_store(type, line); 00166 snprintf(line, sizeof(line), "enum %s", token); 00167 len = sizeof(line); 00168 } 00169 00170 strncat(line, buf, len); 00171 listp = listp->next; 00172 } 00173 00174 /* 00175 * If there's anything left, then save that. 00176 * But don't bother saving an empty 'overflow' line. 00177 */ 00178 if (len != sizeof(line)) 00179 read_config_store(type, line); 00180 00181 return; 00182 } 00183 00184 void 00185 se_store_list(unsigned int major, unsigned int minor, char *type) 00186 { 00187 char token[32]; 00188 00189 snprintf(token, sizeof(token), "%d:%d", major, minor); 00190 se_store_enum_list(se_find_list(major, minor), token, type); 00191 } 00192 00193 struct snmp_enum_list * 00194 se_find_list(unsigned int major, unsigned int minor) 00195 { 00196 if (major > current_maj_num || minor > current_min_num) 00197 return NULL; 00198 00199 return snmp_enum_lists[major][minor]; 00200 } 00201 00202 int 00203 se_find_value_in_list(struct snmp_enum_list *list, const char *label) 00204 { 00205 if (!list) 00206 return SE_DNE; /* XXX: um, no good solution here */ 00207 while (list) { 00208 if (strcmp(list->label, label) == 0) 00209 return (list->value); 00210 list = list->next; 00211 } 00212 00213 return SE_DNE; /* XXX: um, no good solution here */ 00214 } 00215 00216 int se_remove_value_from_list(struct snmp_enum_list **list, const char *label) 00217 { 00218 struct snmp_enum_list *lastlist; 00219 if(!list) 00220 return SE_DNE; 00221 00222 lastlist = NULL; 00223 while(*list) { 00224 if(strcmp((*list)->label, label) == 0) { 00225 free((*list)->label); 00226 if(lastlist) 00227 lastlist->next = (*list)->next; 00228 free(*list); 00229 *list = NULL; 00230 return 0; 00231 } 00232 lastlist = *list; 00233 (*list) = (*list)->next; 00234 } 00235 00236 } 00237 00238 int 00239 se_find_free_value_in_list(struct snmp_enum_list *list) 00240 { 00241 int max_value = 0; 00242 if (!list) 00243 return SE_DNE; 00244 00245 for (;list; list=list->next) { 00246 if (max_value < list->value) 00247 max_value = list->value; 00248 } 00249 return max_value+1; 00250 } 00251 00252 int 00253 se_find_value(unsigned int major, unsigned int minor, const char *label) 00254 { 00255 return se_find_value_in_list(se_find_list(major, minor), label); 00256 } 00257 00258 int 00259 se_find_free_value(unsigned int major, unsigned int minor) 00260 { 00261 return se_find_free_value_in_list(se_find_list(major, minor)); 00262 } 00263 00264 char * 00265 se_find_label_in_list(struct snmp_enum_list *list, int value) 00266 { 00267 if (!list) 00268 return NULL; 00269 while (list) { 00270 if (list->value == value) 00271 return (list->label); 00272 list = list->next; 00273 } 00274 return NULL; 00275 } 00276 00277 char * 00278 se_find_label(unsigned int major, unsigned int minor, int value) 00279 { 00280 return se_find_label_in_list(se_find_list(major, minor), value); 00281 } 00282 00283 int 00284 se_add_pair_to_list(struct snmp_enum_list **list, char *label, int value) 00285 { 00286 struct snmp_enum_list *lastnode = NULL; 00287 00288 if (!list) 00289 return SE_DNE; 00290 00291 while (*list) { 00292 if ((*list)->value == value) 00293 return (SE_ALREADY_THERE); 00294 lastnode = (*list); 00295 (*list) = (*list)->next; 00296 } 00297 00298 if (lastnode) { 00299 lastnode->next = SNMP_MALLOC_STRUCT(snmp_enum_list); 00300 lastnode = lastnode->next; 00301 } else { 00302 (*list) = SNMP_MALLOC_STRUCT(snmp_enum_list); 00303 lastnode = (*list); 00304 } 00305 if (!lastnode) 00306 return (SE_NOMEM); 00307 lastnode->label = label; 00308 lastnode->value = value; 00309 lastnode->next = NULL; 00310 return (SE_OK); 00311 } 00312 00313 int 00314 se_add_pair(unsigned int major, unsigned int minor, char *label, int value) 00315 { 00316 struct snmp_enum_list *list = se_find_list(major, minor); 00317 int created = (list) ? 1 : 0; 00318 int ret = se_add_pair_to_list(&list, label, value); 00319 if (!created) 00320 se_store_in_list(list, major, minor); 00321 return ret; 00322 } 00323 00324 /* 00325 * remember a list of enums based on a lookup name. 00326 */ 00327 struct snmp_enum_list * 00328 se_find_slist(const char *listname) 00329 { 00330 struct snmp_enum_list_str *sptr, *lastp = NULL; 00331 if (!listname) 00332 return NULL; 00333 00334 for (sptr = sliststorage; 00335 sptr != NULL; lastp = sptr, sptr = sptr->next) 00336 if (sptr->name && strcmp(sptr->name, listname) == 0) 00337 return sptr->list; 00338 00339 return NULL; 00340 } 00341 00342 00343 char * 00344 se_find_label_in_slist(const char *listname, int value) 00345 { 00346 return (se_find_label_in_list(se_find_slist(listname), value)); 00347 } 00348 00349 00350 int 00351 se_find_value_in_slist(const char *listname, const char *label) 00352 { 00353 return (se_find_value_in_list(se_find_slist(listname), label)); 00354 } 00355 00356 int 00357 se_find_free_value_in_slist(const char *listname) 00358 { 00359 return (se_find_free_value_in_list(se_find_slist(listname))); 00360 } 00361 00362 void se_remove_value_from_slist(const char *listname, const char *label) 00363 { 00364 struct snmp_enum_list_str *sptr, *lastp = NULL; 00365 struct snmp_enum_list *list; 00366 if (!listname) 00367 return; 00368 00369 for (sptr = sliststorage; 00370 sptr != NULL; lastp = sptr, sptr = sptr->next) 00371 if (sptr->name && strcmp(sptr->name, listname) == 0) 00372 se_remove_value_from_list(&sptr->list, label); 00373 } 00374 00375 int 00376 se_add_pair_to_slist(const char *listname, char *label, int value) 00377 { 00378 struct snmp_enum_list *list = se_find_slist(listname); 00379 int created = (list) ? 1 : 0; 00380 int ret = se_add_pair_to_list(&list, label, value); 00381 00382 if (!created) { 00383 struct snmp_enum_list_str *sptr = 00384 SNMP_MALLOC_STRUCT(snmp_enum_list_str); 00385 if (!sptr) 00386 return SE_NOMEM; 00387 sptr->next = sliststorage; 00388 sptr->name = strdup(listname); 00389 sptr->list = list; 00390 sliststorage = sptr; 00391 } 00392 return ret; 00393 } 00394 00395 void 00396 clear_snmp_enum(void) 00397 { 00398 struct snmp_enum_list_str *sptr = sliststorage, *next = NULL; 00399 struct snmp_enum_list *list = NULL, *nextlist = NULL; 00400 int i; 00401 00402 while (sptr != NULL) { 00403 next = sptr->next; 00404 list = sptr->list; 00405 while (list != NULL) { 00406 nextlist = list->next; 00407 SNMP_FREE(list->label); 00408 SNMP_FREE(list); 00409 list = nextlist; 00410 } 00411 SNMP_FREE(sptr->name); 00412 SNMP_FREE(sptr); 00413 sptr = next; 00414 } 00415 sliststorage = NULL; 00416 00417 if (snmp_enum_lists) { 00418 for (i = 0; i < SE_MAX_IDS; i++) { 00419 if (snmp_enum_lists[i]) 00420 SNMP_FREE(snmp_enum_lists[i]); 00421 } 00422 SNMP_FREE(snmp_enum_lists); 00423 } 00424 } 00425 00426 void 00427 se_clear_list(struct snmp_enum_list **list) 00428 { 00429 struct snmp_enum_list *this_entry, *next_entry; 00430 00431 if (!list) 00432 return; 00433 00434 this_entry = *list; 00435 while (this_entry) { 00436 next_entry = this_entry->next; 00437 SNMP_FREE(this_entry->label); 00438 SNMP_FREE(this_entry); 00439 this_entry = next_entry; 00440 } 00441 *list = NULL; 00442 return; 00443 } 00444 00445 void 00446 se_clear_slist(const char *listname) 00447 { 00448 struct snmp_enum_list *list = se_find_slist(listname); 00449 se_clear_list(&list); 00450 } 00451 00452 void 00453 se_store_slist(const char *listname, char *type) 00454 { 00455 struct snmp_enum_list *list = se_find_slist(listname); 00456 se_store_enum_list(list, listname, type); 00457 } 00458 00459 int 00460 se_store_slist_callback(int majorID, int minorID, 00461 void *serverargs, void *clientargs) 00462 { 00463 char *appname = netsnmp_ds_get_string(NETSNMP_DS_LIBRARY_ID, 00464 NETSNMP_DS_LIB_APPTYPE); 00465 se_store_slist((char *)clientargs, appname); 00466 return SNMPERR_SUCCESS; 00467 } 00468 00469 void 00470 se_clear_all_lists(void) 00471 { 00472 struct snmp_enum_list_str *sptr = NULL; 00473 00474 for (sptr = sliststorage; sptr != NULL; sptr = sptr->next) 00475 se_clear_list(&(sptr->list)); 00476 } 00477 00478 #ifdef TESTING 00479 main() 00480 { 00481 init_snmp_enum(); 00482 se_add_pair(1, 1, "hi", 1); 00483 se_add_pair(1, 1, "there", 2); 00484 printf("hi: %d\n", se_find_value(1, 1, "hi")); 00485 printf("2: %s\n", se_find_label(1, 1, 2)); 00486 00487 se_add_pair_to_slist("testing", "life, and everything", 42); 00488 se_add_pair_to_slist("testing", "resturant at the end of the universe", 00489 2); 00490 00491 printf("life, and everything: %d\n", 00492 se_find_value_in_slist("testing", "life, and everything")); 00493 printf("2: %s\n", se_find_label_in_slist("testing", 2)); 00494 } 00495 #endif /* TESTING */
1.7.6.1