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
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
00099
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
00109
00110
00111 if (sscanf(e_name, "%d:%d", &major, &minor) == 2) {
00112
00113
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
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
00160
00161
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
00176
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;
00207 while (list) {
00208 if (strcmp(list->label, label) == 0)
00209 return (list->value);
00210 list = list->next;
00211 }
00212
00213 return SE_DNE;
00214 }
00215
00216 int
00217 se_find_free_value_in_list(struct snmp_enum_list *list)
00218 {
00219 int max_value = 0;
00220 if (!list)
00221 return SE_DNE;
00222
00223 for (;list; list=list->next) {
00224 if (max_value < list->value)
00225 max_value = list->value;
00226 }
00227 return max_value+1;
00228 }
00229
00230 int
00231 se_find_value(unsigned int major, unsigned int minor, const char *label)
00232 {
00233 return se_find_value_in_list(se_find_list(major, minor), label);
00234 }
00235
00236 int
00237 se_find_free_value(unsigned int major, unsigned int minor)
00238 {
00239 return se_find_free_value_in_list(se_find_list(major, minor));
00240 }
00241
00242 char *
00243 se_find_label_in_list(struct snmp_enum_list *list, int value)
00244 {
00245 if (!list)
00246 return NULL;
00247 while (list) {
00248 if (list->value == value)
00249 return (list->label);
00250 list = list->next;
00251 }
00252 return NULL;
00253 }
00254
00255 char *
00256 se_find_label(unsigned int major, unsigned int minor, int value)
00257 {
00258 return se_find_label_in_list(se_find_list(major, minor), value);
00259 }
00260
00261 int
00262 se_add_pair_to_list(struct snmp_enum_list **list, char *label, int value)
00263 {
00264 struct snmp_enum_list *lastnode = NULL;
00265
00266 if (!list)
00267 return SE_DNE;
00268
00269 while (*list) {
00270 if ((*list)->value == value)
00271 return (SE_ALREADY_THERE);
00272 lastnode = (*list);
00273 (*list) = (*list)->next;
00274 }
00275
00276 if (lastnode) {
00277 lastnode->next = SNMP_MALLOC_STRUCT(snmp_enum_list);
00278 lastnode = lastnode->next;
00279 } else {
00280 (*list) = SNMP_MALLOC_STRUCT(snmp_enum_list);
00281 lastnode = (*list);
00282 }
00283 if (!lastnode)
00284 return (SE_NOMEM);
00285 lastnode->label = label;
00286 lastnode->value = value;
00287 lastnode->next = NULL;
00288 return (SE_OK);
00289 }
00290
00291 int
00292 se_add_pair(unsigned int major, unsigned int minor, char *label, int value)
00293 {
00294 struct snmp_enum_list *list = se_find_list(major, minor);
00295 int created = (list) ? 1 : 0;
00296 int ret = se_add_pair_to_list(&list, label, value);
00297 if (!created)
00298 se_store_in_list(list, major, minor);
00299 return ret;
00300 }
00301
00302
00303
00304
00305 struct snmp_enum_list *
00306 se_find_slist(const char *listname)
00307 {
00308 struct snmp_enum_list_str *sptr, *lastp = NULL;
00309 if (!listname)
00310 return NULL;
00311
00312 for (sptr = sliststorage;
00313 sptr != NULL; lastp = sptr, sptr = sptr->next)
00314 if (sptr->name && strcmp(sptr->name, listname) == 0)
00315 return sptr->list;
00316
00317 return NULL;
00318 }
00319
00320
00321 char *
00322 se_find_label_in_slist(const char *listname, int value)
00323 {
00324 return (se_find_label_in_list(se_find_slist(listname), value));
00325 }
00326
00327
00328 int
00329 se_find_value_in_slist(const char *listname, const char *label)
00330 {
00331 return (se_find_value_in_list(se_find_slist(listname), label));
00332 }
00333
00334 int
00335 se_find_free_value_in_slist(const char *listname)
00336 {
00337 return (se_find_free_value_in_list(se_find_slist(listname)));
00338 }
00339
00340 int
00341 se_add_pair_to_slist(const char *listname, char *label, int value)
00342 {
00343 struct snmp_enum_list *list = se_find_slist(listname);
00344 int created = (list) ? 1 : 0;
00345 int ret = se_add_pair_to_list(&list, label, value);
00346
00347 if (!created) {
00348 struct snmp_enum_list_str *sptr =
00349 SNMP_MALLOC_STRUCT(snmp_enum_list_str);
00350 if (!sptr)
00351 return SE_NOMEM;
00352 sptr->next = sliststorage;
00353 sptr->name = strdup(listname);
00354 sptr->list = list;
00355 sliststorage = sptr;
00356 }
00357 return ret;
00358 }
00359
00360 void
00361 clear_snmp_enum(void)
00362 {
00363 struct snmp_enum_list_str *sptr = sliststorage, *next = NULL;
00364 struct snmp_enum_list *list = NULL, *nextlist = NULL;
00365 int i;
00366
00367 while (sptr != NULL) {
00368 next = sptr->next;
00369 list = sptr->list;
00370 while (list != NULL) {
00371 nextlist = list->next;
00372 SNMP_FREE(list->label);
00373 SNMP_FREE(list);
00374 list = nextlist;
00375 }
00376 SNMP_FREE(sptr->name);
00377 SNMP_FREE(sptr);
00378 sptr = next;
00379 }
00380 sliststorage = NULL;
00381
00382 if (snmp_enum_lists) {
00383 for (i = 0; i < SE_MAX_IDS; i++) {
00384 if (snmp_enum_lists[i])
00385 SNMP_FREE(snmp_enum_lists[i]);
00386 }
00387 SNMP_FREE(snmp_enum_lists);
00388 }
00389 }
00390
00391 void
00392 se_clear_list(struct snmp_enum_list **list)
00393 {
00394 struct snmp_enum_list *this_entry, *next_entry;
00395
00396 if (!list)
00397 return;
00398
00399 this_entry = *list;
00400 while (this_entry) {
00401 next_entry = this_entry->next;
00402 SNMP_FREE(this_entry->label);
00403 SNMP_FREE(this_entry);
00404 this_entry = next_entry;
00405 }
00406 *list = NULL;
00407 return;
00408 }
00409
00410 void
00411 se_clear_slist(const char *listname)
00412 {
00413 struct snmp_enum_list *list = se_find_slist(listname);
00414 se_clear_list(&list);
00415 }
00416
00417 void
00418 se_store_slist(const char *listname, char *type)
00419 {
00420 struct snmp_enum_list *list = se_find_slist(listname);
00421 se_store_enum_list(list, listname, type);
00422 }
00423
00424 int
00425 se_store_slist_callback(int majorID, int minorID,
00426 void *serverargs, void *clientargs)
00427 {
00428 char *appname = netsnmp_ds_get_string(NETSNMP_DS_LIBRARY_ID,
00429 NETSNMP_DS_LIB_APPTYPE);
00430 se_store_slist((char *)clientargs, appname);
00431 return SNMPERR_SUCCESS;
00432 }
00433
00434 void
00435 se_clear_all_lists(void)
00436 {
00437 struct snmp_enum_list_str *sptr = NULL;
00438
00439 for (sptr = sliststorage; sptr != NULL; sptr = sptr->next)
00440 se_clear_list(&(sptr->list));
00441 }
00442
00443 #ifdef TESTING
00444 main()
00445 {
00446 init_snmp_enum();
00447 se_add_pair(1, 1, "hi", 1);
00448 se_add_pair(1, 1, "there", 2);
00449 printf("hi: %d\n", se_find_value(1, 1, "hi"));
00450 printf("2: %s\n", se_find_label(1, 1, 2));
00451
00452 se_add_pair_to_slist("testing", "life, and everything", 42);
00453 se_add_pair_to_slist("testing", "resturant at the end of the universe",
00454 2);
00455
00456 printf("life, and everything: %d\n",
00457 se_find_value_in_slist("testing", "life, and everything"));
00458 printf("2: %s\n", se_find_label_in_slist("testing", 2));
00459 }
00460 #endif