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