ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/i-scream/projects/libstatgrab/src/libstatgrab/os_info.c
Revision: 1.24
Committed: Mon Oct 9 14:09:38 2006 UTC (17 years, 7 months ago) by tdb
Content type: text/plain
Branch: MAIN
CVS Tags: LIBSTATGRAB_0_17, LIBSTATGRAB_0_16, LIBSTATGRAB_0_15, LIBSTATGRAB_0_14
Changes since 1.23: +4 -1 lines
Log Message:
Make sure we always close kstat.

Spotted by: "Javier Donaire" <jyuyu@fraguel.org> (in load_stats.c)

File Contents

# User Rev Content
1 tdb 1.12 /*
2 tdb 1.16 * i-scream libstatgrab
3 tdb 1.6 * http://www.i-scream.org
4 tdb 1.12 * Copyright (C) 2000-2004 i-scream
5 pajs 1.1 *
6 tdb 1.12 * This library is free software; you can redistribute it and/or
7     * modify it under the terms of the GNU Lesser General Public
8     * License as published by the Free Software Foundation; either
9     * version 2.1 of the License, or (at your option) any later version.
10 pajs 1.1 *
11 tdb 1.12 * This library is distributed in the hope that it will be useful,
12 pajs 1.1 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 tdb 1.12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14     * Lesser General Public License for more details.
15 pajs 1.1 *
16 tdb 1.12 * You should have received a copy of the GNU Lesser General Public
17     * License along with this library; if not, write to the Free Software
18     * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19     * 02111-1307 USA
20 tdb 1.13 *
21 tdb 1.24 * $Id: os_info.c,v 1.23 2005/09/24 13:29:22 tdb Exp $
22 pajs 1.1 */
23    
24     #ifdef HAVE_CONFIG_H
25     #include "config.h"
26     #endif
27    
28 tdb 1.23 #ifndef WIN32
29 tdb 1.3 #include <sys/utsname.h>
30 tdb 1.23 #endif
31 pajs 1.1 #include "statgrab.h"
32 ats 1.9 #include <stdlib.h>
33 pajs 1.1 #ifdef SOLARIS
34     #include <kstat.h>
35     #include <time.h>
36     #endif
37 ats 1.11 #if defined(LINUX) || defined(CYGWIN)
38 pajs 1.4 #include <stdio.h>
39     #endif
40 ats 1.9 #ifdef ALLBSD
41 tdb 1.14 #if defined(FREEBSD) || defined(DFBSD)
42 pajs 1.5 #include <sys/types.h>
43     #include <sys/sysctl.h>
44 ats 1.9 #else
45     #include <sys/param.h>
46     #include <sys/sysctl.h>
47     #endif
48 pajs 1.5 #include <time.h>
49     #include <sys/time.h>
50     #endif
51 tdb 1.20 #ifdef HPUX
52     #include <sys/param.h>
53     #include <sys/pstat.h>
54     #include <time.h>
55     #endif
56 tdb 1.23 #ifdef WIN32
57     #include <windows.h>
58     #include "win32.h"
59     #define WINDOWS2000 "Windows 2000"
60     #define WINDOWSXP "Windows XP"
61     #define WINDOWS2003 "Windows Server 2003"
62     #define BUFSIZE 12
63     static int runonce = 0;
64     #endif
65 ats 1.22
66     #include "tools.h"
67 pajs 1.1
68 tdb 1.23 #ifdef WIN32
69     static int home_or_pro(const OSVERSIONINFOEX osinfo, char **name)
70     {
71     int r;
72    
73     if (osinfo.wSuiteMask & VER_SUITE_PERSONAL) {
74     r = sg_concat_string(name, " Home Edition");
75     } else {
76     r = sg_concat_string(name, " Professional");
77     }
78     return r;
79     }
80    
81     static char *get_os_name(const OSVERSIONINFOEX osinfo)
82     {
83     char *name;
84     char tmp[10];
85     int r = 0;
86    
87     /* we only compile on 2k or newer, which is version 5
88     * Covers 2000, XP and 2003 */
89     if (osinfo.dwMajorVersion != 5) {
90     return "Unknown";
91     }
92     switch(osinfo.dwMinorVersion) {
93     case 0: /* Windows 2000 */
94     name = strdup(WINDOWS2000);
95     if(name == NULL) {
96     goto out;
97     }
98     if (osinfo.wProductType == VER_NT_WORKSTATION) {
99     r = home_or_pro(osinfo, &name);
100     } else if (osinfo.wSuiteMask & VER_SUITE_DATACENTER) {
101     r = sg_concat_string(&name, " Datacenter Server");
102     } else if (osinfo.wSuiteMask & VER_SUITE_ENTERPRISE) {
103     r = sg_concat_string(&name, " Advanced Server");
104     } else {
105     r = sg_concat_string(&name, " Server");
106     }
107     break;
108     case 1: /* Windows XP */
109     name = strdup(WINDOWSXP);
110     if(name == NULL) {
111     goto out;
112     }
113     r = home_or_pro(osinfo, &name);
114     break;
115     case 2: /* Windows 2003 */
116     name = strdup(WINDOWS2003);
117     if(name == NULL) {
118     goto out;
119     }
120     if (osinfo.wSuiteMask & VER_SUITE_DATACENTER) {
121     r = sg_concat_string(&name, " Datacenter Edition");
122     } else if (osinfo.wSuiteMask & VER_SUITE_ENTERPRISE) {
123     r = sg_concat_string(&name, " Enterprise Edition");
124     } else if (osinfo.wSuiteMask & VER_SUITE_BLADE) {
125     r = sg_concat_string(&name, " Web Edition");
126     } else {
127     r = sg_concat_string(&name, " Standard Edition");
128     }
129     break;
130     default:
131     name = strdup("Windows 2000 based");
132     break;
133     }
134     if(r != 0) {
135     free (name);
136     return NULL;
137     }
138     /* Add on service pack version */
139     if (osinfo.wServicePackMajor != 0) {
140     if(osinfo.wServicePackMinor == 0) {
141     if(snprintf(tmp, sizeof(tmp), " SP%d", osinfo.wServicePackMajor) != -1) {
142     r = sg_concat_string(&name, tmp);
143     }
144     } else {
145     if(snprintf(tmp, sizeof(tmp), " SP%d.%d", osinfo.wServicePackMajor,
146     osinfo.wServicePackMinor) != -1) {
147     r = sg_concat_string(&name, tmp);
148     }
149     }
150     if(r) {
151     free(name);
152     return NULL;
153     }
154     }
155     return name;
156    
157     out:
158     /* strdup failed */
159     sg_set_error_with_errno(SG_ERROR_MALLOC, NULL);
160     return NULL;
161     }
162     #endif
163 pajs 1.1
164 tdb 1.23 sg_host_info *sg_get_host_info()
165     {
166 tdb 1.20 static sg_host_info general_stat;
167 tdb 1.23 #ifndef WIN32
168 pajs 1.4 static struct utsname os;
169 tdb 1.23 #endif
170 pajs 1.1
171 tdb 1.20 #ifdef HPUX
172 ats 1.21 struct pst_static *pstat_static;
173 tdb 1.20 time_t currtime;
174     long boottime;
175     #endif
176 pajs 1.4 #ifdef SOLARIS
177 pajs 1.1 time_t boottime,curtime;
178     kstat_ctl_t *kc;
179     kstat_t *ksp;
180     kstat_named_t *kn;
181 pajs 1.4 #endif
182 ats 1.11 #if defined(LINUX) || defined(CYGWIN)
183 pajs 1.4 FILE *f;
184     #endif
185 ats 1.9 #ifdef ALLBSD
186     int mib[2];
187 pajs 1.5 struct timeval boottime;
188     time_t curtime;
189     size_t size;
190     #endif
191 tdb 1.23 #ifdef WIN32
192     unsigned long nameln;
193     char *name;
194     long long result;
195     OSVERSIONINFOEX osinfo;
196     SYSTEM_INFO sysinfo;
197     char *tmp_name;
198     char tmp[10];
199     #endif
200 pajs 1.1
201 tdb 1.23 #ifndef WIN32 /* Trust windows to be different */
202 pajs 1.1 if((uname(&os)) < 0){
203 ats 1.19 sg_set_error_with_errno(SG_ERROR_UNAME, NULL);
204 pajs 1.1 return NULL;
205     }
206 tdb 1.23
207 pajs 1.1 general_stat.os_name = os.sysname;
208 tdb 1.17 general_stat.os_release = os.release;
209     general_stat.os_version = os.version;
210     general_stat.platform = os.machine;
211     general_stat.hostname = os.nodename;
212 tdb 1.23 #else /* WIN32 */
213     if (!runonce) {
214     /* these settings are static after boot, so why get them
215     * constantly? */
216    
217     /* get system name */
218     nameln = MAX_COMPUTERNAME_LENGTH + 1;
219     name = sg_malloc(nameln);
220     if(name == NULL) {
221     return NULL;
222     }
223     if(GetComputerName(name, &nameln) == 0) {
224     free(name);
225     sg_set_error(SG_ERROR_HOST, "GetComputerName");
226     return NULL;
227     }
228     if(sg_update_string(&general_stat.hostname, name)) {
229     free(name);
230     return NULL;
231     }
232     free(name);
233    
234     /* get OS name, version and build */
235     ZeroMemory(&osinfo, sizeof(OSVERSIONINFOEX));
236     osinfo.dwOSVersionInfoSize = sizeof(osinfo);
237     if(!GetVersionEx(&osinfo)) {
238     sg_set_error(SG_ERROR_HOST, "GetVersionEx");
239     return NULL;
240     }
241    
242     /* Release - single number */
243     if(snprintf(tmp, sizeof(tmp), "%ld", osinfo.dwBuildNumber) == -1) {
244     free(tmp);
245     return NULL;
246     }
247     if(sg_update_string(&general_stat.os_release, tmp)) {
248     free(tmp);
249     return NULL;
250     }
251    
252     /* Version */
253     /* usually a single digit . single digit, eg 5.0 */
254     if(snprintf(tmp, sizeof(tmp), "%ld.%ld", osinfo.dwMajorVersion,
255     osinfo.dwMinorVersion) == -1) {
256     free(tmp);
257     return NULL;
258     }
259     if(sg_update_string(&general_stat.os_version, tmp)) {
260     free(tmp);
261     return NULL;
262     }
263    
264     /* OS name */
265     tmp_name = get_os_name(osinfo);
266     if(tmp_name == NULL) {
267     return NULL;
268     }
269     if(sg_update_string(&general_stat.os_name, tmp_name)) {
270     free(tmp_name);
271     return NULL;
272     }
273     free(tmp_name);
274     runonce = 1;
275    
276     /* Platform */
277     GetSystemInfo(&sysinfo);
278     switch(sysinfo.wProcessorArchitecture) {
279     case PROCESSOR_ARCHITECTURE_INTEL:
280     if(sg_update_string(&general_stat.platform,
281     "Intel")) {
282     return NULL;
283     }
284     break;
285     case PROCESSOR_ARCHITECTURE_IA64:
286     if(sg_update_string(&general_stat.platform,
287     "IA64")) {
288     return NULL;
289     }
290     break;
291     case PROCESSOR_ARCHITECTURE_AMD64:
292     if(sg_update_string(&general_stat.platform,
293     "AMD64")) {
294     return NULL;
295     }
296     break;
297     default:
298     if(sg_update_string(&general_stat.platform,
299     "Unknown")){
300     return NULL;
301     }
302     break;
303     }
304     }
305     #endif /* WIN32 */
306 pajs 1.1
307     /* get uptime */
308 tdb 1.20 #ifdef HPUX
309 ats 1.21 pstat_static = sg_get_pstat_static();
310     if (pstat_static == NULL) {
311 tdb 1.20 return NULL;
312     }
313    
314     currtime = time(NULL);
315    
316 ats 1.21 boottime = pstat_static->boot_time;
317 tdb 1.20
318     general_stat.uptime = currtime - boottime;
319     #endif
320 pajs 1.4 #ifdef SOLARIS
321 pajs 1.1 if ((kc = kstat_open()) == NULL) {
322 tdb 1.18 sg_set_error(SG_ERROR_KSTAT_OPEN, NULL);
323 pajs 1.1 return NULL;
324     }
325     if((ksp=kstat_lookup(kc, "unix", -1, "system_misc"))==NULL){
326 tdb 1.18 sg_set_error(SG_ERROR_KSTAT_LOOKUP, "unix,-1,system_misc");
327 tdb 1.24 kstat_close(kc);
328 pajs 1.1 return NULL;
329     }
330     if (kstat_read(kc, ksp, 0) == -1) {
331 tdb 1.18 sg_set_error(SG_ERROR_KSTAT_READ, NULL);
332 tdb 1.24 kstat_close(kc);
333 pajs 1.1 return NULL;
334     }
335     if((kn=kstat_data_lookup(ksp, "boot_time")) == NULL){
336 tdb 1.18 sg_set_error(SG_ERROR_KSTAT_DATA_LOOKUP, "boot_time");
337 tdb 1.24 kstat_close(kc);
338 pajs 1.1 return NULL;
339     }
340     boottime=(kn->value.ui32);
341 pajs 1.2
342     kstat_close(kc);
343 pajs 1.1
344     time(&curtime);
345     general_stat.uptime = curtime - boottime;
346 pajs 1.4 #endif
347 ats 1.11 #if defined(LINUX) || defined(CYGWIN)
348 pajs 1.4 if ((f=fopen("/proc/uptime", "r")) == NULL) {
349 ats 1.19 sg_set_error_with_errno(SG_ERROR_OPEN, "/proc/uptime");
350 pajs 1.4 return NULL;
351     }
352     if((fscanf(f,"%lu %*d",&general_stat.uptime)) != 1){
353 tdb 1.18 sg_set_error(SG_ERROR_PARSE, NULL);
354 pajs 1.4 return NULL;
355     }
356     fclose(f);
357 pajs 1.5 #endif
358 ats 1.9 #ifdef ALLBSD
359     mib[0] = CTL_KERN;
360     mib[1] = KERN_BOOTTIME;
361 ats 1.8 size = sizeof boottime;
362 ats 1.9 if (sysctl(mib, 2, &boottime, &size, NULL, 0) < 0){
363 ats 1.19 sg_set_error_with_errno(SG_ERROR_SYSCTL,
364     "CTL_KERN.KERN_BOOTTIME");
365 pajs 1.5 return NULL;
366     }
367     time(&curtime);
368     general_stat.uptime=curtime-boottime.tv_sec;
369 tdb 1.23 #endif
370     #ifdef WIN32
371     if(read_counter_large(SG_WIN32_UPTIME, &result)) {
372     sg_set_error(SG_ERROR_PDHREAD, PDH_UPTIME);
373     return NULL;
374     }
375     general_stat.uptime = (time_t) result;
376 pajs 1.4 #endif
377 pajs 1.1
378     return &general_stat;
379    
380     }