snmp_enum.c
上传用户:wxp200602
上传日期:2007-10-30
资源大小:4028k
文件大小:11k
源码类别:

SNMP编程

开发平台:

Unix_Linux

  1. #include <net-snmp/net-snmp-config.h>
  2. #ifdef HAVE_STDLIB_H
  3. #include <stdlib.h>
  4. #endif
  5. #include <stdio.h>
  6. #if HAVE_STRING_H
  7. #include <string.h>
  8. #else
  9. #include <strings.h>
  10. #endif
  11. #if HAVE_DMALLOC_H
  12. #include <dmalloc.h>
  13. #endif
  14. #include <sys/types.h>
  15. #include <net-snmp/types.h>
  16. #include <net-snmp/config_api.h>
  17. #include <net-snmp/library/snmp_enum.h>
  18. #include <net-snmp/library/tools.h>
  19. struct snmp_enum_list_str {
  20.     char           *name;
  21.     struct snmp_enum_list *list;
  22.     struct snmp_enum_list_str *next;
  23. };
  24. static struct snmp_enum_list ***snmp_enum_lists;
  25. unsigned int    current_maj_num;
  26. unsigned int    current_min_num;
  27. struct snmp_enum_list_str *sliststorage;
  28. int
  29. init_snmp_enum(const char *type)
  30. {
  31.     int             i;
  32.     if (!snmp_enum_lists)
  33.         snmp_enum_lists = (struct snmp_enum_list ***)
  34.             calloc(1, sizeof(struct snmp_enum_list **) * SE_MAX_IDS);
  35.     if (!snmp_enum_lists)
  36.         return SE_NOMEM;
  37.     current_maj_num = SE_MAX_IDS;
  38.     for (i = 0; i < SE_MAX_IDS; i++) {
  39.         if (!snmp_enum_lists[i])
  40.             snmp_enum_lists[i] = (struct snmp_enum_list **)
  41.                 calloc(1, sizeof(struct snmp_enum_list *) * SE_MAX_SUBIDS);
  42.         if (!snmp_enum_lists[i])
  43.             return SE_NOMEM;
  44.     }
  45.     current_min_num = SE_MAX_SUBIDS;
  46.     if (!sliststorage)
  47.         sliststorage = NULL;
  48.     register_config_handler(type, "enum", se_read_conf, NULL, NULL);
  49.     return SE_OK;
  50. }
  51. int
  52. se_store_in_list(struct snmp_enum_list *new_list,
  53.               unsigned int major, unsigned int minor)
  54. {
  55.     int             ret = SE_OK;
  56.     if (major > current_maj_num || minor > current_min_num) {
  57.         /*
  58.          * XXX: realloc 
  59.          */
  60.         return SE_NOMEM;
  61.     }
  62.     if (snmp_enum_lists[major][minor] != NULL)
  63.         ret = SE_ALREADY_THERE;
  64.     snmp_enum_lists[major][minor] = new_list;
  65.     return ret;
  66. }
  67. void
  68. se_read_conf(const char *word, char *cptr)
  69. {
  70.     int major, minor;
  71.     int value;
  72.     char *cp, *cp2;
  73.     char e_name[BUFSIZ];
  74.     char e_enum[  BUFSIZ];
  75.     if (!cptr || *cptr=='')
  76.         return;
  77.     /*
  78.      * Extract the first token
  79.      *   (which should be the name of the list)
  80.      */
  81.     cp = copy_nword(cptr, e_name, sizeof(e_name));
  82.     cp = skip_white(cp);
  83.     if (!cp || *cp=='')
  84.         return;
  85.     /*
  86.      * Add each remaining enumeration to the list,
  87.      *   using the appropriate style interface
  88.      */
  89.     if (sscanf(e_name, "%d:%d", &major, &minor) == 2) {
  90.         /*
  91.          *  Numeric major/minor style
  92.          */
  93.         while (1) {
  94.             cp = copy_nword(cp, e_enum, sizeof(e_enum));
  95.             if (sscanf(e_enum, "%d:", &value) != 1) {
  96.                 break;
  97.             }
  98.             cp2 = e_enum;
  99.             while (*(cp2++) != ':')
  100.                 ;
  101.             se_add_pair(major, minor, cp2, value);
  102.             if (!cp)
  103.                 break;
  104.         }
  105.     } else {
  106.         /*
  107.          *  Named enumeration
  108.          */
  109.         while (1) {
  110.             cp = copy_nword(cp, e_enum, sizeof(e_enum));
  111.             if (sscanf(e_enum, "%d:", &value) != 1) {
  112.                 break;
  113.             }
  114.             cp2 = e_enum;
  115.             while (*(cp2++) != ':')
  116.                 ;
  117.             se_add_pair_to_slist(e_name, cp2, value);
  118.             if (!cp)
  119.                 break;
  120.         }
  121.     }
  122. }
  123. void
  124. se_store_enum_list(struct snmp_enum_list *new_list,
  125.                    const char *token, char *type)
  126. {
  127.     struct snmp_enum_list *listp = new_list;
  128.     char line[2048];
  129.     char buf[512];
  130.     int  len = 0;
  131.     snprintf(line, sizeof(line), "enum %s", token);
  132.     while (listp) {
  133.         snprintf(buf, sizeof(buf), " %d:%s", listp->value, listp->label);
  134.         /*
  135.          * Calculate the space left in the buffer.
  136.          * If this is not sufficient to include the next enum,
  137.          *   then save the line so far, and start again.
  138.          */
  139. len = sizeof(line) - strlen(line);
  140. if ((int)strlen(buf) > len) {
  141.     read_config_store(type, line);
  142.             snprintf(line, sizeof(line), "enum %s", token);
  143.     len = sizeof(line);
  144. }
  145. strncat(line, buf, len);
  146.         listp = listp->next;
  147.     }
  148.     /*
  149.      * If there's anything left, then save that.
  150.      * But don't bother saving an empty 'overflow' line.
  151.      */
  152.     if (len != sizeof(line))
  153. read_config_store(type, line);
  154.     return;
  155. }
  156. void
  157. se_store_list(unsigned int major, unsigned int minor, char *type)
  158. {
  159.     char token[32];
  160.     snprintf(token, sizeof(token), "%d:%d", major, minor);
  161.     se_store_enum_list(se_find_list(major, minor), token, type);
  162. }
  163. struct snmp_enum_list *
  164. se_find_list(unsigned int major, unsigned int minor)
  165. {
  166.     if (major > current_maj_num || minor > current_min_num)
  167.         return NULL;
  168.     return snmp_enum_lists[major][minor];
  169. }
  170. int
  171. se_find_value_in_list(struct snmp_enum_list *list, const char *label)
  172. {
  173.     if (!list)
  174.         return SE_DNE;          /* XXX: um, no good solution here */
  175.     while (list) {
  176.         if (strcmp(list->label, label) == 0)
  177.             return (list->value);
  178.         list = list->next;
  179.     }
  180.     return SE_DNE;              /* XXX: um, no good solution here */
  181. }
  182. int
  183. se_find_free_value_in_list(struct snmp_enum_list *list)
  184. {
  185.     int max_value = 0;
  186.     if (!list)
  187.         return SE_DNE;
  188.     for (;list; list=list->next) {
  189.         if (max_value < list->value)
  190.             max_value = list->value;
  191.     }
  192.     return max_value+1;
  193. }
  194. int
  195. se_find_value(unsigned int major, unsigned int minor, const char *label)
  196. {
  197.     return se_find_value_in_list(se_find_list(major, minor), label);
  198. }
  199. int
  200. se_find_free_value(unsigned int major, unsigned int minor)
  201. {
  202.     return se_find_free_value_in_list(se_find_list(major, minor));
  203. }
  204. char           *
  205. se_find_label_in_list(struct snmp_enum_list *list, int value)
  206. {
  207.     if (!list)
  208.         return NULL;
  209.     while (list) {
  210.         if (list->value == value)
  211.             return (list->label);
  212.         list = list->next;
  213.     }
  214.     return NULL;
  215. }
  216. char           *
  217. se_find_label(unsigned int major, unsigned int minor, int value)
  218. {
  219.     return se_find_label_in_list(se_find_list(major, minor), value);
  220. }
  221. int
  222. se_add_pair_to_list(struct snmp_enum_list **list, char *label, int value)
  223. {
  224.     struct snmp_enum_list *lastnode = NULL;
  225.     if (!list)
  226.         return SE_DNE;
  227.     while (*list) {
  228.         if ((*list)->value == value)
  229.             return (SE_ALREADY_THERE);
  230.         lastnode = (*list);
  231.         (*list) = (*list)->next;
  232.     }
  233.     if (lastnode) {
  234.         lastnode->next = SNMP_MALLOC_STRUCT(snmp_enum_list);
  235.         lastnode = lastnode->next;
  236.     } else {
  237.         (*list) = SNMP_MALLOC_STRUCT(snmp_enum_list);
  238.         lastnode = (*list);
  239.     }
  240.     if (!lastnode)
  241.         return (SE_NOMEM);
  242.     lastnode->label = label;
  243.     lastnode->value = value;
  244.     lastnode->next = NULL;
  245.     return (SE_OK);
  246. }
  247. int
  248. se_add_pair(unsigned int major, unsigned int minor, char *label, int value)
  249. {
  250.     struct snmp_enum_list *list = se_find_list(major, minor);
  251.     int             created = (list) ? 1 : 0;
  252.     int             ret = se_add_pair_to_list(&list, label, value);
  253.     if (!created)
  254.         se_store_in_list(list, major, minor);
  255.     return ret;
  256. }
  257. /*
  258.  * remember a list of enums based on a lookup name.
  259.  */
  260. struct snmp_enum_list *
  261. se_find_slist(const char *listname)
  262. {
  263.     struct snmp_enum_list_str *sptr, *lastp = NULL;
  264.     if (!listname)
  265.         return NULL;
  266.     for (sptr = sliststorage;
  267.          sptr != NULL; lastp = sptr, sptr = sptr->next)
  268.         if (sptr->name && strcmp(sptr->name, listname) == 0)
  269.             return sptr->list;
  270.     return NULL;
  271. }
  272. char           *
  273. se_find_label_in_slist(const char *listname, int value)
  274. {
  275.     return (se_find_label_in_list(se_find_slist(listname), value));
  276. }
  277. int
  278. se_find_value_in_slist(const char *listname, const char *label)
  279. {
  280.     return (se_find_value_in_list(se_find_slist(listname), label));
  281. }
  282. int
  283. se_find_free_value_in_slist(const char *listname)
  284. {
  285.     return (se_find_free_value_in_list(se_find_slist(listname)));
  286. }
  287. int
  288. se_add_pair_to_slist(const char *listname, char *label, int value)
  289. {
  290.     struct snmp_enum_list *list = se_find_slist(listname);
  291.     int             created = (list) ? 1 : 0;
  292.     int             ret = se_add_pair_to_list(&list, label, value);
  293.     if (!created) {
  294.         struct snmp_enum_list_str *sptr =
  295.             SNMP_MALLOC_STRUCT(snmp_enum_list_str);
  296.         if (!sptr)
  297.             return SE_NOMEM;
  298.         sptr->next = sliststorage;
  299.         sptr->name = strdup(listname);
  300.         sptr->list = list;
  301.         sliststorage = sptr;
  302.     }
  303.     return ret;
  304. }
  305. void
  306. clear_snmp_enum(void)
  307. {
  308.     struct snmp_enum_list_str *sptr = sliststorage, *next = NULL;
  309.     struct snmp_enum_list *list = NULL, *nextlist = NULL;
  310.     int i;
  311.     while (sptr != NULL) {
  312. next = sptr->next;
  313. list = sptr->list;
  314. while (list != NULL) {
  315.     nextlist = list->next;
  316.     SNMP_FREE(list->label);
  317.     SNMP_FREE(list);
  318.     list = nextlist;
  319. }
  320. SNMP_FREE(sptr->name);
  321. SNMP_FREE(sptr);
  322. sptr = next;
  323.     }
  324.     sliststorage = NULL;
  325.     if (snmp_enum_lists) {
  326.         for (i = 0; i < SE_MAX_IDS; i++) {
  327.             if (snmp_enum_lists[i])
  328.                 SNMP_FREE(snmp_enum_lists[i]);
  329.         }
  330.         SNMP_FREE(snmp_enum_lists);
  331.     }
  332. }
  333. void
  334. se_clear_list(struct snmp_enum_list **list)
  335. {
  336.     struct snmp_enum_list *this_entry, *next_entry;
  337.     if (!list)
  338.         return;
  339.     this_entry = *list;
  340.     while (this_entry) {
  341.         next_entry = this_entry->next;
  342.         SNMP_FREE(this_entry->label);
  343.         SNMP_FREE(this_entry);
  344.         this_entry = next_entry;
  345.     }
  346.     *list = NULL;
  347.     return;
  348. }
  349. void
  350. se_clear_slist(const char *listname)
  351. {
  352.     struct snmp_enum_list *list = se_find_slist(listname);
  353.     se_clear_list(&list);
  354. }
  355. void
  356. se_store_slist(const char *listname, char *type)
  357. {
  358.     struct snmp_enum_list *list = se_find_slist(listname);
  359.     se_store_enum_list(list, listname, type);
  360. }
  361. int
  362. se_store_slist_callback(int majorID, int minorID,
  363.                         void *serverargs, void *clientargs)
  364. {
  365.     char *appname = netsnmp_ds_get_string(NETSNMP_DS_LIBRARY_ID,
  366.                                           NETSNMP_DS_LIB_APPTYPE);
  367.     se_store_slist((char *)clientargs, appname);
  368.     return SNMPERR_SUCCESS;
  369. }
  370. void
  371. se_clear_all_lists(void)
  372. {
  373.     struct snmp_enum_list_str *sptr = NULL;
  374.     for (sptr = sliststorage; sptr != NULL; sptr = sptr->next)
  375.         se_clear_list(&(sptr->list));
  376. }
  377. #ifdef TESTING
  378. main()
  379. {
  380.     init_snmp_enum();
  381.     se_add_pair(1, 1, "hi", 1);
  382.     se_add_pair(1, 1, "there", 2);
  383.     printf("hi: %dn", se_find_value(1, 1, "hi"));
  384.     printf("2: %sn", se_find_label(1, 1, 2));
  385.     se_add_pair_to_slist("testing", "life, and everything", 42);
  386.     se_add_pair_to_slist("testing", "resturant at the end of the universe",
  387.                          2);
  388.     printf("life, and everything: %dn",
  389.            se_find_value_in_slist("testing", "life, and everything"));
  390.     printf("2: %sn", se_find_label_in_slist("testing", 2));
  391. }
  392. #endif                          /* TESTING */