snmp_enum.c

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
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  * remember a list of enums based on a lookup name.
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                          /* TESTING */

net-snmpに対してSat Sep 5 13:14:25 2009に生成されました。  doxygen 1.4.7