and added files
[bcm963xx.git] / userapps / opensource / net-snmp / agent / mibgroup / host / hr_system.c
1 /*
2  *  Host Resources MIB - system group implementation - hr_system.c
3  *
4  */
5
6 #include <net-snmp/net-snmp-config.h>
7 #if HAVE_STRING_H
8 #include <string.h>
9 #else
10 #include <strings.h>
11 #endif
12
13 #include <net-snmp/net-snmp-includes.h>
14 #include <net-snmp/agent/net-snmp-agent-includes.h>
15
16 #include "host.h"
17 #include "host_res.h"
18 #include "hr_system.h"
19 #include <net-snmp/agent/auto_nlist.h>
20
21 #ifdef HAVE_SYS_PROC_H
22 #include <sys/param.h>
23 #include "sys/proc.h"
24 #endif
25 #if HAVE_UTMPX_H
26 #include <utmpx.h>
27 #else
28 #include <utmp.h>
29 #endif
30
31 #ifdef linux
32 #ifdef HAVE_LINUX_TASKS_H
33 #include <linux/tasks.h>
34 #else
35 /*
36  * If this file doesn't exist, then there is no hard limit on the number
37  * of processes, so return 0 for hrSystemMaxProcesses.  
38  */
39 #define NR_TASKS        0
40 #endif
41 #endif
42
43 #if defined(hpux10) || defined(hpux11)
44 #include <sys/pstat.h>
45 #endif
46
47 #ifdef HAVE_SYS_SYSCTL_H
48 #include <sys/sysctl.h>
49 #endif
50
51 #if !defined(UTMP_FILE) && defined(_PATH_UTMP)
52 #define UTMP_FILE _PATH_UTMP
53 #endif
54
55 #if defined(UTMP_FILE) && !HAVE_UTMPX_H
56 void            setutent(void);
57 void            endutent(void);
58 struct utmp    *getutent(void);
59 #endif                          /* UTMP_FILE */
60
61
62         /*********************
63          *
64          *  Kernel & interface information,
65          *   and internal forward declarations
66          *
67          *********************/
68
69 static int      get_load_dev(void);
70 static int      count_users(void);
71 extern int      count_processes(void);
72
73
74         /*********************
75          *
76          *  Initialisation & common implementation functions
77          *
78          *********************/
79
80 #define HRSYS_UPTIME            1
81 #define HRSYS_DATE              2
82 #define HRSYS_LOAD_DEV          3
83 #define HRSYS_LOAD_PARAM        4
84 #define HRSYS_USERS             5
85 #define HRSYS_PROCS             6
86 #define HRSYS_MAXPROCS          7
87
88 struct variable2 hrsystem_variables[] = {
89     {HRSYS_UPTIME, ASN_TIMETICKS, RONLY, var_hrsys, 1, {1}},
90     {HRSYS_DATE, ASN_OCTET_STR, RONLY, var_hrsys, 1, {2}},
91     {HRSYS_LOAD_DEV, ASN_INTEGER, RONLY, var_hrsys, 1, {3}},
92     {HRSYS_LOAD_PARAM, ASN_OCTET_STR, RONLY, var_hrsys, 1, {4}},
93     {HRSYS_USERS, ASN_GAUGE, RONLY, var_hrsys, 1, {5}},
94     {HRSYS_PROCS, ASN_GAUGE, RONLY, var_hrsys, 1, {6}},
95     {HRSYS_MAXPROCS, ASN_INTEGER, RONLY, var_hrsys, 1, {7}}
96 };
97 oid             hrsystem_variables_oid[] = { 1, 3, 6, 1, 2, 1, 25, 1 };
98
99
100 void
101 init_hr_system(void)
102 {
103 #ifdef NPROC_SYMBOL
104     auto_nlist(NPROC_SYMBOL, 0, 0);
105 #endif
106
107     REGISTER_MIB("host/hr_system", hrsystem_variables, variable2,
108                  hrsystem_variables_oid);
109 }
110
111 /*
112  * header_hrsys(...
113  * Arguments:
114  * vp     IN      - pointer to variable entry that points here
115  * name    IN/OUT  - IN/name requested, OUT/name found
116  * length  IN/OUT  - length of IN/OUT oid's 
117  * exact   IN      - TRUE if an exact match was requested
118  * var_len OUT     - length of variable or 0 if function returned
119  * write_method
120  */
121
122 int
123 header_hrsys(struct variable *vp,
124              oid * name,
125              size_t * length,
126              int exact, size_t * var_len, WriteMethod ** write_method)
127 {
128 #define HRSYS_NAME_LENGTH       9
129     oid             newname[MAX_OID_LEN];
130     int             result;
131
132     DEBUGMSGTL(("host/hr_system", "var_hrsys: "));
133     DEBUGMSGOID(("host/hr_system", name, *length));
134     DEBUGMSG(("host/hr_system", " %d\n", exact));
135
136     memcpy((char *) newname, (char *) vp->name, vp->namelen * sizeof(oid));
137     newname[HRSYS_NAME_LENGTH] = 0;
138     result = snmp_oid_compare(name, *length, newname, vp->namelen + 1);
139     if ((exact && (result != 0)) || (!exact && (result >= 0)))
140         return (MATCH_FAILED);
141     memcpy((char *) name, (char *) newname,
142            (vp->namelen + 1) * sizeof(oid));
143     *length = vp->namelen + 1;
144
145     *write_method = 0;
146     *var_len = sizeof(long);    /* default to 'long' results */
147     return (MATCH_SUCCEEDED);
148 }
149
150
151         /*********************
152          *
153          *  System specific implementation functions
154          *
155          *********************/
156
157 u_char         *
158 var_hrsys(struct variable * vp,
159           oid * name,
160           size_t * length,
161           int exact, size_t * var_len, WriteMethod ** write_method)
162 {
163     static char     string[100];
164     time_t          now;
165 #ifndef NR_TASKS
166     int             nproc = 0;
167 #endif
168 #ifdef linux
169     FILE           *fp;
170 #endif
171 #if CAN_USE_SYSCTL && defined(CTL_KERN) && defined(KERN_MAXPROC)
172     static int      maxproc_mib[] = { CTL_KERN, KERN_MAXPROC };
173     int             buf_size;
174 #endif
175 #if defined(hpux10) || defined(hpux11)
176     struct pst_static pst_buf;
177 #endif
178
179     if (header_hrsys(vp, name, length, exact, var_len, write_method) ==
180         MATCH_FAILED)
181         return NULL;
182
183     switch (vp->magic) {
184     case HRSYS_UPTIME:
185         long_return = get_uptime();
186         return (u_char *) & long_return;
187     case HRSYS_DATE:
188         (void *) time(&now);
189         return (u_char *) date_n_time(&now, var_len);
190     case HRSYS_LOAD_DEV:
191         long_return = get_load_dev();
192         return (u_char *) & long_return;
193     case HRSYS_LOAD_PARAM:
194 #ifdef linux
195         fp = fopen("/proc/cmdline", "r");
196         fgets(string, sizeof(string), fp);
197         fclose(fp);
198 #else
199 #if NO_DUMMY_VALUES
200         return NULL;
201 #endif
202         sprintf(string, "ask Dave");    /* XXX */
203 #endif
204         *var_len = strlen(string);
205         return (u_char *) string;
206     case HRSYS_USERS:
207         long_return = count_users();
208         return (u_char *) & long_return;
209     case HRSYS_PROCS:
210 #if USING_HOST_HR_SWRUN_MODULE
211         long_return = count_processes();
212 #else
213 #if NO_DUMMY_VALUES
214         return NULL;
215 #endif
216         long_return = 0;
217 #endif
218         return (u_char *) & long_return;
219     case HRSYS_MAXPROCS:
220 #if defined(NR_TASKS)
221         long_return = NR_TASKS; /* <linux/tasks.h> */
222 #elif CAN_USE_SYSCTL && defined(CTL_KERN) && defined(KERN_MAXPROC)
223         buf_size = sizeof(nproc);
224         if (sysctl(maxproc_mib, 2, &nproc, &buf_size, NULL, 0) < 0)
225             return NULL;
226         long_return = nproc;
227 #elif defined(hpux10) || defined(hpux11)
228         pstat_getstatic(&pst_buf, sizeof(struct pst_static), 1, 0);
229         long_return = pst_buf.max_proc;
230 #elif defined(NPROC_SYMBOL)
231         auto_nlist(NPROC_SYMBOL, (char *) &nproc, sizeof(int));
232         long_return = nproc;
233 #else
234 #if NO_DUMMY_VALUES
235         return NULL;
236 #endif
237         long_return = 0;
238 #endif
239         return (u_char *) & long_return;
240     default:
241         DEBUGMSGTL(("snmpd", "unknown sub-id %d in var_hrsys\n",
242                     vp->magic));
243     }
244     return NULL;
245 }
246
247
248         /*********************
249          *
250          *  Internal implementation functions
251          *
252          *********************/
253
254                 /*
255                  *  Return the DeviceIndex corresponding
256                  *   to the boot device
257                  */
258 static int
259 get_load_dev(void)
260 {
261     return (HRDEV_DISK << HRDEV_TYPE_SHIFT);    /* XXX */
262 }
263
264 static int
265 count_users(void)
266 {
267     int             total = 0;
268 #if HAVE_UTMPX_H
269 #define setutent setutxent
270 #define getutent getutxent
271 #define endutent endutxent
272     struct utmpx   *utmp_p;
273 #else
274     struct utmp    *utmp_p;
275 #endif
276
277     setutent();
278     while ((utmp_p = getutent()) != NULL) {
279 #ifndef UTMP_HAS_NO_TYPE
280         if (utmp_p->ut_type == USER_PROCESS)
281 #endif
282             ++total;
283     }
284     endutent();
285     return total;
286 }
287
288 #if defined(UTMP_FILE) && !HAVE_UTMPX_H
289
290 static FILE    *utmp_file;
291 static struct utmp utmp_rec;
292
293 void
294 setutent(void)
295 {
296     if (utmp_file)
297         fclose(utmp_file);
298     utmp_file = fopen(UTMP_FILE, "r");
299 }
300
301 void
302 endutent(void)
303 {
304     if (utmp_file) {
305         fclose(utmp_file);
306         utmp_file = NULL;
307     }
308 }
309
310 struct utmp    *
311 getutent(void)
312 {
313     if (!utmp_file)
314         return NULL;
315     while (fread(&utmp_rec, sizeof(utmp_rec), 1, utmp_file) == 1)
316         if (*utmp_rec.ut_name && *utmp_rec.ut_line)
317             return &utmp_rec;
318     return NULL;
319 }
320
321 #endif                          /* UTMP_FILE */