auto_nlist.c

00001 #include <net-snmp/net-snmp-config.h>
00002 
00003 #ifdef CAN_USE_NLIST
00004 #if HAVE_STRING_H
00005 #include <string.h>
00006 #else
00007 #include <strings.h>
00008 #endif
00009 
00010 #if HAVE_STDLIB_H
00011 #include <stdlib.h>
00012 #endif
00013 #include <stdio.h>
00014 #include <errno.h>
00015 #include <fcntl.h>
00016 #include <netinet/in.h>
00017 #ifdef HAVE_NLIST_H
00018 #include <nlist.h>
00019 #endif
00020 #if HAVE_KVM_H
00021 #include <kvm.h>
00022 #endif
00023 
00024 #include <net-snmp/agent/auto_nlist.h>
00025 #include "autonlist.h"
00026 #include "kernel.h"
00027 
00028 #include <net-snmp/net-snmp-includes.h>
00029 #include <net-snmp/agent/ds_agent.h>
00030 
00031 struct autonlist *nlists = 0;
00032 static void     init_nlist(struct nlist *);
00033 
00034 long
00035 auto_nlist_value(const char *string)
00036 {
00037     struct autonlist **ptr, *it = 0;
00038     int             cmp;
00039 
00040     if (string == 0)
00041         return 0;
00042 
00043     ptr = &nlists;
00044     while (*ptr != 0 && it == 0) {
00045         cmp = strcmp((*ptr)->symbol, string);
00046         if (cmp == 0)
00047             it = *ptr;
00048         else if (cmp < 0) {
00049             ptr = &((*ptr)->left);
00050         } else {
00051             ptr = &((*ptr)->right);
00052         }
00053     }
00054     if (*ptr == 0) {
00055         *ptr = (struct autonlist *) malloc(sizeof(struct autonlist));
00056         it = *ptr;
00057         it->left = 0;
00058         it->right = 0;
00059         it->symbol = (char *) malloc(strlen(string) + 1);
00060         strcpy(it->symbol, string);
00061         /*
00062          * allocate an extra byte for inclusion of a preceding '_' later 
00063          */
00064         it->nl[0].n_name = (char *) malloc(strlen(string) + 2);
00065 #ifdef aix4
00066         strcpy(it->nl[0].n_name, string);
00067 #else
00068         sprintf(it->nl[0].n_name, "_%s", string);
00069 #endif
00070         it->nl[1].n_name = 0;
00071         init_nlist(it->nl);
00072 #ifndef aix4
00073         if (it->nl[0].n_type == 0) {
00074             strcpy(it->nl[0].n_name, string);
00075             init_nlist(it->nl);
00076         }
00077 #endif
00078         if (it->nl[0].n_type == 0) {
00079             if (!netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, 
00080                                         NETSNMP_DS_AGENT_NO_ROOT_ACCESS)) {
00081                 snmp_log(LOG_ERR, "nlist err: neither %s nor _%s found.\n",
00082                          string, string);
00083             }
00084             return (-1);
00085         } else {
00086             DEBUGMSGTL(("auto_nlist", "nlist:  found symbol %s at %x.\n",
00087                         it->symbol, it->nl[0].n_value));
00088             return (it->nl[0].n_value);
00089         }
00090     } else
00091         return (it->nl[0].n_value);
00092 }
00093 
00094 int
00095 auto_nlist(const char *string, char *var, int size)
00096 {
00097     long            result;
00098     int             ret;
00099     result = auto_nlist_value(string);
00100     if (result != -1) {
00101         if (var != NULL) {
00102             ret = klookup(result, var, size);
00103             if (!ret)
00104                 snmp_log(LOG_ERR,
00105                          "auto_nlist failed on %s at location %lx\n",
00106                          string, result);
00107             return ret;
00108         } else
00109             return 1;
00110     }
00111     return 0;
00112 }
00113 
00114 static void
00115 init_nlist(struct nlist nl[])
00116 {
00117 #ifdef CAN_USE_NLIST
00118     int             ret;
00119 #if HAVE_KVM_OPENFILES
00120     kvm_t          *kernel;
00121     char            kvm_errbuf[4096];
00122 
00123     if ((kernel = kvm_openfiles(KERNEL_LOC, NULL, NULL, O_RDONLY, kvm_errbuf))
00124         == NULL) {
00125         if (netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, 
00126                                    NETSNMP_DS_AGENT_NO_ROOT_ACCESS)) {
00127             return;
00128         } else {
00129             snmp_log_perror("kvm_openfiles");
00130             snmp_log(LOG_ERR, "kvm_openfiles: %s\n", kvm_errbuf);
00131             exit(1);
00132         }
00133     }
00134     if ((ret = kvm_nlist(kernel, nl)) == -1) {
00135         if (netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, 
00136                                    NETSNMP_DS_AGENT_NO_ROOT_ACCESS)) {
00137             return;
00138         } else {
00139             snmp_log_perror("kvm_nlist");
00140             exit(1);
00141         }
00142     }
00143     kvm_close(kernel);
00144 #else                           /* ! HAVE_KVM_OPENFILES */
00145 #if defined(aix4) && defined(HAVE_KNLIST)
00146     if (knlist(nl, 1, sizeof(struct nlist)) == -1) {
00147         DEBUGMSGTL(("auto_nlist", "knlist failed on symbol:  %s\n",
00148                     nl[0].n_name));
00149         if (errno == EFAULT) {
00150             nl[0].n_type = 0;
00151             nl[0].n_value = 0;
00152         } else {
00153             snmp_log_perror("knlist");
00154             if (netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, 
00155                                        NETSNMP_DS_AGENT_NO_ROOT_ACCESS)) {
00156                 return;
00157             } else {
00158                 exit(1);
00159             }
00160         }
00161     }
00162 #else
00163     if ((ret = nlist(KERNEL_LOC, nl)) == -1) {
00164         if (netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, 
00165                                    NETSNMP_DS_AGENT_NO_ROOT_ACCESS)) {
00166             return;
00167         } else {
00168             snmp_log_perror("nlist");
00169             exit(1);
00170         }
00171     }
00172 #endif                          /*aix4 */
00173 #endif                          /* ! HAVE_KVM_OPENFILES */
00174     for (ret = 0; nl[ret].n_name != NULL; ret++) {
00175 #ifdef aix4
00176         if (nl[ret].n_type == 0 && nl[ret].n_value != 0)
00177             nl[ret].n_type = 1;
00178 #endif
00179         if (nl[ret].n_type == 0) {
00180             if (!netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, 
00181                                         NETSNMP_DS_AGENT_NO_ROOT_ACCESS)) {
00182                 DEBUGMSGTL(("auto_nlist", "nlist err:  %s not found\n",
00183                             nl[ret].n_name));
00184             }
00185         } else {
00186             DEBUGMSGTL(("auto_nlist", "nlist: %s 0x%X\n", nl[ret].n_name,
00187                         (unsigned int) nl[ret].n_value));
00188         }
00189     }
00190 #endif                          /* CAN_USE_NLIST */
00191 }
00192 
00193 int
00194 KNLookup(struct nlist nl[], int nl_which, char *buf, int s)
00195 {
00196     struct nlist   *nlp = &nl[nl_which];
00197 
00198     if (nlp->n_value == 0) {
00199         snmp_log(LOG_ERR, "Accessing non-nlisted variable: %s\n",
00200                  nlp->n_name);
00201         nlp->n_value = -1;      /* only one error message ... */
00202         return 0;
00203     }
00204     if (nlp->n_value == -1)
00205         return 0;
00206 
00207     return klookup(nlp->n_value, buf, s);
00208 }
00209 
00210 #ifdef TESTING
00211 void
00212 auto_nlist_print_tree(int indent, struct autonlist *ptr)
00213 {
00214     char            buf[1024];
00215     if (indent == -2) {
00216         snmp_log(LOG_ERR, "nlist tree:\n");
00217         auto_nlist_print_tree(12, nlists);
00218     } else {
00219         if (ptr == 0)
00220             return;
00221         sprintf(buf, "%%%ds\n", indent);
00222         /*
00223          * DEBUGMSGTL(("auto_nlist", "buf: %s\n",buf)); 
00224          */
00225         DEBUGMSGTL(("auto_nlist", buf, ptr->symbol));
00226         auto_nlist_print_tree(indent + 2, ptr->left);
00227         auto_nlist_print_tree(indent + 2, ptr->right);
00228     }
00229 }
00230 #endif
00231 #else                           /* !CAN_USE_NLIST */
00232 #include <net-snmp/agent/auto_nlist.h>
00233 int
00234 auto_nlist_noop(void)
00235 {
00236     return 0;
00237 }
00238 #endif                          /* CAN_USE_NLIST */

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