ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/i-scream/projects/libstatgrab/src/libstatgrab/os_info.c
Revision: 1.25
Committed: Sun Oct 3 18:35:58 2010 UTC (13 years, 7 months ago) by tdb
Content type: text/plain
Branch: MAIN
CVS Tags: HEAD
Changes since 1.24: +24 -1 lines
Log Message:
Add support for AIX 5.x - 9.x.

Many thanks to Jens Rehsack <rehsack@googlemail.com> for providing the
patch for this work. Thanks!

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.25 * $Id: os_info.c,v 1.24 2006/10/09 14:09:38 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.25 #ifdef AIX
57     #include <utmp.h>
58     #include <libperfstat.h>
59     #endif
60 tdb 1.23 #ifdef WIN32
61     #include <windows.h>
62     #include "win32.h"
63     #define WINDOWS2000 "Windows 2000"
64     #define WINDOWSXP "Windows XP"
65     #define WINDOWS2003 "Windows Server 2003"
66     #define BUFSIZE 12
67     static int runonce = 0;
68     #endif
69 ats 1.22
70     #include "tools.h"
71 pajs 1.1
72 tdb 1.23 #ifdef WIN32
73     static int home_or_pro(const OSVERSIONINFOEX osinfo, char **name)
74     {
75     int r;
76    
77     if (osinfo.wSuiteMask & VER_SUITE_PERSONAL) {
78     r = sg_concat_string(name, " Home Edition");
79     } else {
80     r = sg_concat_string(name, " Professional");
81     }
82     return r;
83     }
84    
85     static char *get_os_name(const OSVERSIONINFOEX osinfo)
86     {
87     char *name;
88     char tmp[10];
89     int r = 0;
90    
91     /* we only compile on 2k or newer, which is version 5
92     * Covers 2000, XP and 2003 */
93     if (osinfo.dwMajorVersion != 5) {
94     return "Unknown";
95     }
96     switch(osinfo.dwMinorVersion) {
97     case 0: /* Windows 2000 */
98     name = strdup(WINDOWS2000);
99     if(name == NULL) {
100     goto out;
101     }
102     if (osinfo.wProductType == VER_NT_WORKSTATION) {
103     r = home_or_pro(osinfo, &name);
104     } else if (osinfo.wSuiteMask & VER_SUITE_DATACENTER) {
105     r = sg_concat_string(&name, " Datacenter Server");
106     } else if (osinfo.wSuiteMask & VER_SUITE_ENTERPRISE) {
107     r = sg_concat_string(&name, " Advanced Server");
108     } else {
109     r = sg_concat_string(&name, " Server");
110     }
111     break;
112     case 1: /* Windows XP */
113     name = strdup(WINDOWSXP);
114     if(name == NULL) {
115     goto out;
116     }
117     r = home_or_pro(osinfo, &name);
118     break;
119     case 2: /* Windows 2003 */
120     name = strdup(WINDOWS2003);
121     if(name == NULL) {
122     goto out;
123     }
124     if (osinfo.wSuiteMask & VER_SUITE_DATACENTER) {
125     r = sg_concat_string(&name, " Datacenter Edition");
126     } else if (osinfo.wSuiteMask & VER_SUITE_ENTERPRISE) {
127     r = sg_concat_string(&name, " Enterprise Edition");
128     } else if (osinfo.wSuiteMask & VER_SUITE_BLADE) {
129     r = sg_concat_string(&name, " Web Edition");
130     } else {
131     r = sg_concat_string(&name, " Standard Edition");
132     }
133     break;
134     default:
135     name = strdup("Windows 2000 based");
136     break;
137     }
138     if(r != 0) {
139     free (name);
140     return NULL;
141     }
142     /* Add on service pack version */
143     if (osinfo.wServicePackMajor != 0) {
144     if(osinfo.wServicePackMinor == 0) {
145     if(snprintf(tmp, sizeof(tmp), " SP%d", osinfo.wServicePackMajor) != -1) {
146     r = sg_concat_string(&name, tmp);
147     }
148     } else {
149     if(snprintf(tmp, sizeof(tmp), " SP%d.%d", osinfo.wServicePackMajor,
150     osinfo.wServicePackMinor) != -1) {
151     r = sg_concat_string(&name, tmp);
152     }
153     }
154     if(r) {
155     free(name);
156     return NULL;
157     }
158     }
159     return name;
160    
161     out:
162     /* strdup failed */
163     sg_set_error_with_errno(SG_ERROR_MALLOC, NULL);
164     return NULL;
165     }
166     #endif
167 pajs 1.1
168 tdb 1.23 sg_host_info *sg_get_host_info()
169     {
170 tdb 1.20 static sg_host_info general_stat;
171 tdb 1.23 #ifndef WIN32
172 pajs 1.4 static struct utsname os;
173 tdb 1.23 #endif
174 pajs 1.1
175 tdb 1.20 #ifdef HPUX
176 ats 1.21 struct pst_static *pstat_static;
177 tdb 1.20 time_t currtime;
178     long boottime;
179     #endif
180 pajs 1.4 #ifdef SOLARIS
181 pajs 1.1 time_t boottime,curtime;
182     kstat_ctl_t *kc;
183     kstat_t *ksp;
184     kstat_named_t *kn;
185 pajs 1.4 #endif
186 ats 1.11 #if defined(LINUX) || defined(CYGWIN)
187 pajs 1.4 FILE *f;
188     #endif
189 ats 1.9 #ifdef ALLBSD
190     int mib[2];
191 pajs 1.5 struct timeval boottime;
192     time_t curtime;
193     size_t size;
194     #endif
195 tdb 1.23 #ifdef WIN32
196     unsigned long nameln;
197     char *name;
198     long long result;
199     OSVERSIONINFOEX osinfo;
200     SYSTEM_INFO sysinfo;
201     char *tmp_name;
202     char tmp[10];
203     #endif
204 tdb 1.25 #ifdef AIX
205     static perfstat_cpu_total_t cpu_total;
206     struct utmp *ut;
207     #endif
208 pajs 1.1
209 tdb 1.23 #ifndef WIN32 /* Trust windows to be different */
210 pajs 1.1 if((uname(&os)) < 0){
211 ats 1.19 sg_set_error_with_errno(SG_ERROR_UNAME, NULL);
212 pajs 1.1 return NULL;
213     }
214 tdb 1.23
215 pajs 1.1 general_stat.os_name = os.sysname;
216 tdb 1.17 general_stat.os_release = os.release;
217     general_stat.os_version = os.version;
218     general_stat.platform = os.machine;
219     general_stat.hostname = os.nodename;
220 tdb 1.23 #else /* WIN32 */
221     if (!runonce) {
222     /* these settings are static after boot, so why get them
223     * constantly? */
224    
225     /* get system name */
226     nameln = MAX_COMPUTERNAME_LENGTH + 1;
227     name = sg_malloc(nameln);
228     if(name == NULL) {
229     return NULL;
230     }
231     if(GetComputerName(name, &nameln) == 0) {
232     free(name);
233     sg_set_error(SG_ERROR_HOST, "GetComputerName");
234     return NULL;
235     }
236     if(sg_update_string(&general_stat.hostname, name)) {
237     free(name);
238     return NULL;
239     }
240     free(name);
241    
242     /* get OS name, version and build */
243     ZeroMemory(&osinfo, sizeof(OSVERSIONINFOEX));
244     osinfo.dwOSVersionInfoSize = sizeof(osinfo);
245     if(!GetVersionEx(&osinfo)) {
246     sg_set_error(SG_ERROR_HOST, "GetVersionEx");
247     return NULL;
248     }
249    
250     /* Release - single number */
251     if(snprintf(tmp, sizeof(tmp), "%ld", osinfo.dwBuildNumber) == -1) {
252     free(tmp);
253     return NULL;
254     }
255     if(sg_update_string(&general_stat.os_release, tmp)) {
256     free(tmp);
257     return NULL;
258     }
259    
260     /* Version */
261     /* usually a single digit . single digit, eg 5.0 */
262     if(snprintf(tmp, sizeof(tmp), "%ld.%ld", osinfo.dwMajorVersion,
263     osinfo.dwMinorVersion) == -1) {
264     free(tmp);
265     return NULL;
266     }
267     if(sg_update_string(&general_stat.os_version, tmp)) {
268     free(tmp);
269     return NULL;
270     }
271    
272     /* OS name */
273     tmp_name = get_os_name(osinfo);
274     if(tmp_name == NULL) {
275     return NULL;
276     }
277     if(sg_update_string(&general_stat.os_name, tmp_name)) {
278     free(tmp_name);
279     return NULL;
280     }
281     free(tmp_name);
282     runonce = 1;
283    
284     /* Platform */
285     GetSystemInfo(&sysinfo);
286     switch(sysinfo.wProcessorArchitecture) {
287     case PROCESSOR_ARCHITECTURE_INTEL:
288     if(sg_update_string(&general_stat.platform,
289     "Intel")) {
290     return NULL;
291     }
292     break;
293     case PROCESSOR_ARCHITECTURE_IA64:
294     if(sg_update_string(&general_stat.platform,
295     "IA64")) {
296     return NULL;
297     }
298     break;
299     case PROCESSOR_ARCHITECTURE_AMD64:
300     if(sg_update_string(&general_stat.platform,
301     "AMD64")) {
302     return NULL;
303     }
304     break;
305     default:
306     if(sg_update_string(&general_stat.platform,
307     "Unknown")){
308     return NULL;
309     }
310     break;
311     }
312     }
313     #endif /* WIN32 */
314 pajs 1.1
315     /* get uptime */
316 tdb 1.20 #ifdef HPUX
317 ats 1.21 pstat_static = sg_get_pstat_static();
318     if (pstat_static == NULL) {
319 tdb 1.20 return NULL;
320     }
321    
322     currtime = time(NULL);
323    
324 ats 1.21 boottime = pstat_static->boot_time;
325 tdb 1.20
326     general_stat.uptime = currtime - boottime;
327     #endif
328 pajs 1.4 #ifdef SOLARIS
329 pajs 1.1 if ((kc = kstat_open()) == NULL) {
330 tdb 1.18 sg_set_error(SG_ERROR_KSTAT_OPEN, NULL);
331 pajs 1.1 return NULL;
332     }
333     if((ksp=kstat_lookup(kc, "unix", -1, "system_misc"))==NULL){
334 tdb 1.18 sg_set_error(SG_ERROR_KSTAT_LOOKUP, "unix,-1,system_misc");
335 tdb 1.24 kstat_close(kc);
336 pajs 1.1 return NULL;
337     }
338     if (kstat_read(kc, ksp, 0) == -1) {
339 tdb 1.18 sg_set_error(SG_ERROR_KSTAT_READ, NULL);
340 tdb 1.24 kstat_close(kc);
341 pajs 1.1 return NULL;
342     }
343     if((kn=kstat_data_lookup(ksp, "boot_time")) == NULL){
344 tdb 1.18 sg_set_error(SG_ERROR_KSTAT_DATA_LOOKUP, "boot_time");
345 tdb 1.24 kstat_close(kc);
346 pajs 1.1 return NULL;
347     }
348     boottime=(kn->value.ui32);
349 pajs 1.2
350     kstat_close(kc);
351 pajs 1.1
352     time(&curtime);
353     general_stat.uptime = curtime - boottime;
354 pajs 1.4 #endif
355 ats 1.11 #if defined(LINUX) || defined(CYGWIN)
356 pajs 1.4 if ((f=fopen("/proc/uptime", "r")) == NULL) {
357 ats 1.19 sg_set_error_with_errno(SG_ERROR_OPEN, "/proc/uptime");
358 pajs 1.4 return NULL;
359     }
360     if((fscanf(f,"%lu %*d",&general_stat.uptime)) != 1){
361 tdb 1.18 sg_set_error(SG_ERROR_PARSE, NULL);
362 pajs 1.4 return NULL;
363     }
364     fclose(f);
365 pajs 1.5 #endif
366 ats 1.9 #ifdef ALLBSD
367     mib[0] = CTL_KERN;
368     mib[1] = KERN_BOOTTIME;
369 ats 1.8 size = sizeof boottime;
370 ats 1.9 if (sysctl(mib, 2, &boottime, &size, NULL, 0) < 0){
371 ats 1.19 sg_set_error_with_errno(SG_ERROR_SYSCTL,
372     "CTL_KERN.KERN_BOOTTIME");
373 pajs 1.5 return NULL;
374     }
375     time(&curtime);
376     general_stat.uptime=curtime-boottime.tv_sec;
377 tdb 1.23 #endif
378     #ifdef WIN32
379     if(read_counter_large(SG_WIN32_UPTIME, &result)) {
380     sg_set_error(SG_ERROR_PDHREAD, PDH_UPTIME);
381     return NULL;
382     }
383     general_stat.uptime = (time_t) result;
384 pajs 1.4 #endif
385 tdb 1.25 #ifdef AIX
386     if(perfstat_cpu_total(NULL, &cpu_total, sizeof(cpu_total), 1) != 1) {
387     sg_set_error_with_errno(SG_ERROR_SYSCTL, "perfstat_cpu_total");
388     return NULL;
389     }
390     general_stat.platform = cpu_total.description;
391    
392     while( ut = getutent() ) {
393     if( ut->ut_type == BOOT_TIME ) {
394     general_stat.uptime = time(NULL) - ut->ut_time;
395     break;
396     }
397     }
398    
399     #endif
400 pajs 1.1
401     return &general_stat;
402    
403     }