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

SNMP编程

开发平台:

Unix_Linux

  1. #include <net-snmp/net-snmp-config.h>
  2. #ifdef CAN_USE_NLIST
  3. #if HAVE_STRING_H
  4. #include <string.h>
  5. #else
  6. #include <strings.h>
  7. #endif
  8. #if HAVE_STDLIB_H
  9. #include <stdlib.h>
  10. #endif
  11. #include <stdio.h>
  12. #include <errno.h>
  13. #include <fcntl.h>
  14. #include <netinet/in.h>
  15. #ifdef HAVE_NLIST_H
  16. #include <nlist.h>
  17. #endif
  18. #if HAVE_KVM_H
  19. #include <kvm.h>
  20. #endif
  21. #if HAVE_DMALLOC_H
  22. #include <dmalloc.h>
  23. #endif
  24. #include <net-snmp/agent/auto_nlist.h>
  25. #include "autonlist.h"
  26. #include "kernel.h"
  27. #include <net-snmp/net-snmp-includes.h>
  28. #include <net-snmp/agent/ds_agent.h>
  29. struct autonlist *nlists = 0;
  30. static void     init_nlist(struct nlist *);
  31. long
  32. auto_nlist_value(const char *string)
  33. {
  34.     struct autonlist **ptr, *it = 0;
  35.     int             cmp;
  36.     if (string == 0)
  37.         return 0;
  38.     ptr = &nlists;
  39.     while (*ptr != 0 && it == 0) {
  40.         cmp = strcmp((*ptr)->symbol, string);
  41.         if (cmp == 0)
  42.             it = *ptr;
  43.         else if (cmp < 0) {
  44.             ptr = &((*ptr)->left);
  45.         } else {
  46.             ptr = &((*ptr)->right);
  47.         }
  48.     }
  49.     if (*ptr == 0) {
  50.         *ptr = (struct autonlist *) malloc(sizeof(struct autonlist));
  51.         it = *ptr;
  52.         it->left = 0;
  53.         it->right = 0;
  54.         it->symbol = (char *) malloc(strlen(string) + 1);
  55.         strcpy(it->symbol, string);
  56.         /*
  57.          * allocate an extra byte for inclusion of a preceding '_' later 
  58.          */
  59.         it->nl[0].n_name = (char *) malloc(strlen(string) + 2);
  60. #ifdef aix4
  61.         strcpy(it->nl[0].n_name, string);
  62. #else
  63.         sprintf(it->nl[0].n_name, "_%s", string);
  64. #endif
  65.         it->nl[1].n_name = 0;
  66.         init_nlist(it->nl);
  67. #ifndef aix4
  68.         if (it->nl[0].n_type == 0) {
  69.             strcpy(it->nl[0].n_name, string);
  70.             init_nlist(it->nl);
  71.         }
  72. #endif
  73.         if (it->nl[0].n_type == 0) {
  74.             if (!netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, 
  75. NETSNMP_DS_AGENT_NO_ROOT_ACCESS)) {
  76.                 snmp_log(LOG_ERR, "nlist err: neither %s nor _%s found.n",
  77.                          string, string);
  78.     }
  79.             return (-1);
  80.         } else {
  81.             DEBUGMSGTL(("auto_nlist", "nlist:  found symbol %s at %x.n",
  82.                         it->symbol, it->nl[0].n_value));
  83.             return (it->nl[0].n_value);
  84.         }
  85.     } else
  86.         return (it->nl[0].n_value);
  87. }
  88. int
  89. auto_nlist(const char *string, char *var, int size)
  90. {
  91.     long            result;
  92.     int             ret;
  93.     result = auto_nlist_value(string);
  94.     if (result != -1) {
  95.         if (var != NULL) {
  96.             ret = klookup(result, var, size);
  97.             if (!ret)
  98.                 snmp_log(LOG_ERR,
  99.                          "auto_nlist failed on %s at location %lxn",
  100.                          string, result);
  101.             return ret;
  102.         } else
  103.             return 1;
  104.     }
  105.     return 0;
  106. }
  107. static void
  108. init_nlist(struct nlist nl[])
  109. {
  110. #ifdef CAN_USE_NLIST
  111.     int             ret;
  112. #if HAVE_KVM_OPENFILES
  113.     kvm_t          *kernel;
  114.     char            kvm_errbuf[4096];
  115.     if ((kernel = kvm_openfiles(KERNEL_LOC, NULL, NULL, O_RDONLY, kvm_errbuf))
  116. == NULL) {
  117.         if (netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, 
  118.    NETSNMP_DS_AGENT_NO_ROOT_ACCESS)) {
  119.             return;
  120. } else {
  121.             snmp_log_perror("kvm_openfiles");
  122.             snmp_log(LOG_ERR, "kvm_openfiles: %sn", kvm_errbuf);
  123.             exit(1);
  124.         }
  125.     }
  126.     if ((ret = kvm_nlist(kernel, nl)) == -1) {
  127.         if (netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, 
  128.    NETSNMP_DS_AGENT_NO_ROOT_ACCESS)) {
  129.             return;
  130. } else {
  131.             snmp_log_perror("kvm_nlist");
  132.             exit(1);
  133.         }
  134.     }
  135.     kvm_close(kernel);
  136. #else                           /* ! HAVE_KVM_OPENFILES */
  137. #if defined(aix4) && defined(HAVE_KNLIST)
  138.     if (knlist(nl, 1, sizeof(struct nlist)) == -1) {
  139.         DEBUGMSGTL(("auto_nlist", "knlist failed on symbol:  %sn",
  140.                     nl[0].n_name));
  141.         if (errno == EFAULT) {
  142.             nl[0].n_type = 0;
  143.             nl[0].n_value = 0;
  144.         } else {
  145.             snmp_log_perror("knlist");
  146.             if (netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, 
  147.        NETSNMP_DS_AGENT_NO_ROOT_ACCESS)) {
  148.                 return;
  149.     } else {
  150.                 exit(1);
  151.     }
  152.         }
  153.     }
  154. #else
  155.     if ((ret = nlist(KERNEL_LOC, nl)) == -1) {
  156.         if (netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, 
  157.    NETSNMP_DS_AGENT_NO_ROOT_ACCESS)) {
  158.             return;
  159. } else {
  160.             snmp_log_perror("nlist");
  161.             exit(1);
  162.         }
  163.     }
  164. #endif                          /*aix4 */
  165. #endif                          /* ! HAVE_KVM_OPENFILES */
  166.     for (ret = 0; nl[ret].n_name != NULL; ret++) {
  167. #ifdef aix4
  168.         if (nl[ret].n_type == 0 && nl[ret].n_value != 0)
  169.             nl[ret].n_type = 1;
  170. #endif
  171.         if (nl[ret].n_type == 0) {
  172.             if (!netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, 
  173. NETSNMP_DS_AGENT_NO_ROOT_ACCESS)) {
  174.                 DEBUGMSGTL(("auto_nlist", "nlist err:  %s not foundn",
  175.                             nl[ret].n_name));
  176.     }
  177.         } else {
  178.             DEBUGMSGTL(("auto_nlist", "nlist: %s 0x%Xn", nl[ret].n_name,
  179.                         (unsigned int) nl[ret].n_value));
  180.         }
  181.     }
  182. #endif                          /* CAN_USE_NLIST */
  183. }
  184. int
  185. KNLookup(struct nlist nl[], int nl_which, char *buf, int s)
  186. {
  187.     struct nlist   *nlp = &nl[nl_which];
  188.     if (nlp->n_value == 0) {
  189.         snmp_log(LOG_ERR, "Accessing non-nlisted variable: %sn",
  190.                  nlp->n_name);
  191.         nlp->n_value = -1;      /* only one error message ... */
  192.         return 0;
  193.     }
  194.     if (nlp->n_value == -1)
  195.         return 0;
  196.     return klookup(nlp->n_value, buf, s);
  197. }
  198. #ifdef TESTING
  199. void
  200. auto_nlist_print_tree(int indent, struct autonlist *ptr)
  201. {
  202.     char            buf[1024];
  203.     if (indent == -2) {
  204.         snmp_log(LOG_ERR, "nlist tree:n");
  205.         auto_nlist_print_tree(12, nlists);
  206.     } else {
  207.         if (ptr == 0)
  208.             return;
  209.         sprintf(buf, "%%%dsn", indent);
  210.         /*
  211.          * DEBUGMSGTL(("auto_nlist", "buf: %sn",buf)); 
  212.          */
  213.         DEBUGMSGTL(("auto_nlist", buf, ptr->symbol));
  214.         auto_nlist_print_tree(indent + 2, ptr->left);
  215.         auto_nlist_print_tree(indent + 2, ptr->right);
  216.     }
  217. }
  218. #endif
  219. #else                           /* !CAN_USE_NLIST */
  220. int
  221. auto_nlist_noop(void)
  222. {
  223.     return 0;
  224. }
  225. #endif                          /* CAN_USE_NLIST */