2005-01-20 23:22:22 +00:00
|
|
|
|
// Berkeley Open Infrastructure for Network Computing
|
|
|
|
|
// http://boinc.berkeley.edu
|
|
|
|
|
// Copyright (C) 2005 University of California
|
2004-07-13 13:54:09 +00:00
|
|
|
|
//
|
2005-01-20 23:22:22 +00:00
|
|
|
|
// This is free software; you can redistribute it and/or
|
|
|
|
|
// modify it under the terms of the GNU Lesser General Public
|
|
|
|
|
// License as published by the Free Software Foundation;
|
|
|
|
|
// either version 2.1 of the License, or (at your option) any later version.
|
2004-07-13 13:54:09 +00:00
|
|
|
|
//
|
2005-01-20 23:22:22 +00:00
|
|
|
|
// This software is distributed in the hope that it will be useful,
|
|
|
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
|
|
|
// See the GNU Lesser General Public License for more details.
|
2002-04-30 22:22:54 +00:00
|
|
|
|
//
|
2005-01-20 23:22:22 +00:00
|
|
|
|
// To view the GNU Lesser General Public License visit
|
|
|
|
|
// http://www.gnu.org/copyleft/lesser.html
|
|
|
|
|
// or write to the Free Software Foundation, Inc.,
|
|
|
|
|
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
2002-04-30 22:22:54 +00:00
|
|
|
|
|
2003-10-16 19:03:49 +00:00
|
|
|
|
#include "cpp.h"
|
2002-07-22 23:07:14 +00:00
|
|
|
|
|
2005-11-21 18:34:44 +00:00
|
|
|
|
#include "config.h"
|
|
|
|
|
|
2004-07-13 13:54:09 +00:00
|
|
|
|
#include <cstdio>
|
|
|
|
|
#include <cstdlib>
|
|
|
|
|
#include <cstring>
|
|
|
|
|
#include <ctime>
|
2002-07-03 22:37:24 +00:00
|
|
|
|
|
2002-10-14 05:52:48 +00:00
|
|
|
|
#include <sys/param.h>
|
|
|
|
|
|
2002-07-03 22:37:24 +00:00
|
|
|
|
#if HAVE_SYS_TYPES_H
|
2002-04-30 22:22:54 +00:00
|
|
|
|
#include <sys/types.h>
|
2002-07-03 22:37:24 +00:00
|
|
|
|
#endif
|
2002-10-14 05:52:48 +00:00
|
|
|
|
#ifdef HAVE_SYS_MOUNT_H
|
|
|
|
|
#include <sys/mount.h>
|
|
|
|
|
#endif
|
|
|
|
|
#ifdef HAVE_SYS_VFS_H
|
|
|
|
|
#include <sys/vfs.h>
|
|
|
|
|
#endif
|
2002-10-14 05:58:33 +00:00
|
|
|
|
#ifdef HAVE_SYS_VMMETER_H
|
2002-10-14 05:52:48 +00:00
|
|
|
|
#include <sys/vmmeter.h>
|
2002-10-14 05:58:33 +00:00
|
|
|
|
#endif
|
2002-10-14 05:52:48 +00:00
|
|
|
|
|
2003-04-08 18:36:03 +00:00
|
|
|
|
#include <sys/stat.h>
|
|
|
|
|
#if HAVE_SYS_SWAP_H
|
|
|
|
|
#include <sys/swap.h>
|
|
|
|
|
#endif
|
2002-10-14 05:52:48 +00:00
|
|
|
|
#if HAVE_SYS_SYSCTL_H
|
|
|
|
|
#include <sys/sysctl.h>
|
|
|
|
|
#endif
|
2002-06-10 06:14:18 +00:00
|
|
|
|
#if HAVE_SYS_SYSTEMINFO_H
|
2002-06-06 22:39:21 +00:00
|
|
|
|
#include <sys/systeminfo.h>
|
2002-06-10 06:14:18 +00:00
|
|
|
|
#endif
|
2002-07-03 22:37:24 +00:00
|
|
|
|
#if HAVE_SYS_UTSNAME_H
|
2002-06-06 18:50:12 +00:00
|
|
|
|
#include <sys/utsname.h>
|
2002-07-03 22:37:24 +00:00
|
|
|
|
#endif
|
|
|
|
|
#if HAVE_UNISTD_H
|
2002-04-30 22:22:54 +00:00
|
|
|
|
#include <unistd.h>
|
2002-07-03 22:37:24 +00:00
|
|
|
|
#endif
|
2004-06-15 00:46:59 +00:00
|
|
|
|
#if HAVE_UTMP_H
|
|
|
|
|
#include <utmp.h>
|
|
|
|
|
#endif
|
2002-07-03 22:37:24 +00:00
|
|
|
|
#if HAVE_NETINET_IN_H
|
2002-04-30 22:22:54 +00:00
|
|
|
|
#include <netinet/in.h>
|
2002-06-06 18:50:12 +00:00
|
|
|
|
#endif
|
2002-04-30 22:22:54 +00:00
|
|
|
|
|
2005-12-02 22:29:35 +00:00
|
|
|
|
#ifdef __EMX__
|
|
|
|
|
#define INCL_DOSMISC
|
|
|
|
|
#include <os2.h>
|
|
|
|
|
#include "win/opt_x86.h"
|
|
|
|
|
#endif
|
|
|
|
|
|
2002-06-01 20:26:21 +00:00
|
|
|
|
#include "client_types.h"
|
2003-06-14 20:24:29 +00:00
|
|
|
|
#include "filesys.h"
|
2002-07-11 01:09:53 +00:00
|
|
|
|
#include "error_numbers.h"
|
2007-02-21 16:26:51 +00:00
|
|
|
|
#include "str_util.h"
|
2004-04-05 20:08:20 +00:00
|
|
|
|
#include "client_state.h"
|
2004-06-16 19:59:07 +00:00
|
|
|
|
#include "hostinfo_network.h"
|
2002-04-30 22:22:54 +00:00
|
|
|
|
|
2004-07-02 02:58:43 +00:00
|
|
|
|
using std::string;
|
|
|
|
|
|
2005-03-11 13:08:52 +00:00
|
|
|
|
#ifdef __APPLE__
|
2007-03-13 00:41:38 +00:00
|
|
|
|
#include "client_msgs.h"
|
|
|
|
|
#include <Carbon/Carbon.h>
|
2005-04-29 08:32:20 +00:00
|
|
|
|
#include <CoreFoundation/CoreFoundation.h>
|
|
|
|
|
#ifdef __cplusplus
|
|
|
|
|
extern "C" {
|
|
|
|
|
#endif
|
|
|
|
|
#include <IOKit/ps/IOPowerSources.h>
|
|
|
|
|
#include <IOKit/ps/IOPSKeys.h>
|
|
|
|
|
#ifdef __cplusplus
|
2007-03-19 20:03:06 +00:00
|
|
|
|
} // extern "C"
|
2005-04-29 08:32:20 +00:00
|
|
|
|
#endif
|
2005-03-11 13:08:52 +00:00
|
|
|
|
#endif // __APPLE__
|
|
|
|
|
|
2005-06-14 20:31:15 +00:00
|
|
|
|
#ifdef _HPUX_SOURCE
|
|
|
|
|
#include <sys/pstat.h>
|
|
|
|
|
#endif
|
|
|
|
|
|
2005-12-29 00:59:53 +00:00
|
|
|
|
// Tru64 UNIX.
|
|
|
|
|
// 2005-12-26 SMS.
|
|
|
|
|
#ifdef __osf__
|
|
|
|
|
#include <sys/sysinfo.h>
|
|
|
|
|
#include <machine/hal_sysinfo.h>
|
|
|
|
|
#include <machine/cpuconf.h>
|
|
|
|
|
#endif
|
|
|
|
|
|
2002-04-30 22:22:54 +00:00
|
|
|
|
// functions to get name/addr of local host
|
|
|
|
|
|
2002-07-15 23:21:20 +00:00
|
|
|
|
// Converts a int ip address to a string representation (i.e. "66.218.71.198")
|
|
|
|
|
//
|
2003-01-13 23:37:56 +00:00
|
|
|
|
#if 0
|
|
|
|
|
char* ip_addr_string(int ip_addr) {
|
2002-04-30 22:22:54 +00:00
|
|
|
|
in_addr ia;
|
|
|
|
|
|
|
|
|
|
ia.s_addr = ip_addr;
|
|
|
|
|
return inet_ntoa(ia);
|
2003-01-13 23:37:56 +00:00
|
|
|
|
}
|
|
|
|
|
#endif
|
2002-04-30 22:22:54 +00:00
|
|
|
|
|
2005-05-05 04:26:52 +00:00
|
|
|
|
// Returns the offset between LOCAL STANDARD TIME and UTC.
|
|
|
|
|
// LOCAL_STANDARD_TIME = UTC_TIME + get_timezone().
|
2002-07-15 23:21:20 +00:00
|
|
|
|
//
|
2003-06-14 20:24:29 +00:00
|
|
|
|
int get_timezone() {
|
2002-07-18 21:21:37 +00:00
|
|
|
|
tzset();
|
|
|
|
|
// TODO: take daylight savings time into account
|
2003-08-13 21:35:26 +00:00
|
|
|
|
#ifdef HAVE_STRUCT_TM_TM_ZONE
|
2003-01-13 23:37:56 +00:00
|
|
|
|
time_t cur_time;
|
|
|
|
|
struct tm *time_data;
|
2002-04-30 22:22:54 +00:00
|
|
|
|
|
2003-01-13 23:37:56 +00:00
|
|
|
|
cur_time = time(NULL);
|
|
|
|
|
time_data = localtime( &cur_time );
|
2005-05-05 04:26:52 +00:00
|
|
|
|
if (time_data->tm_isdst>0) {
|
|
|
|
|
// daylight savings in effect
|
|
|
|
|
return (time_data->tm_gmtoff)-3600;
|
|
|
|
|
} else {
|
|
|
|
|
// no daylight savings in effect
|
|
|
|
|
return time_data->tm_gmtoff;
|
|
|
|
|
}
|
2003-05-06 21:43:26 +00:00
|
|
|
|
#elif defined(linux)
|
2005-05-05 20:13:00 +00:00
|
|
|
|
return -1*(__timezone);
|
2003-12-01 22:53:09 +00:00
|
|
|
|
#elif defined(__CYGWIN32__)
|
2005-05-05 20:13:00 +00:00
|
|
|
|
return -1*(_timezone);
|
2003-05-06 21:43:26 +00:00
|
|
|
|
#elif defined(unix)
|
2005-05-05 20:13:00 +00:00
|
|
|
|
return -1*timezone;
|
2005-05-07 16:09:13 +00:00
|
|
|
|
#elif defined(HAVE_TZNAME)
|
|
|
|
|
return -1*timezone;
|
2003-04-30 20:10:37 +00:00
|
|
|
|
#else
|
|
|
|
|
#error timezone
|
2002-07-18 21:21:37 +00:00
|
|
|
|
#endif
|
2002-07-18 23:05:34 +00:00
|
|
|
|
return 0;
|
2002-04-30 22:22:54 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-07-15 23:21:20 +00:00
|
|
|
|
// Returns true if the host is currently running off battery power
|
2004-03-31 19:43:15 +00:00
|
|
|
|
// If you can't figure out, return false
|
|
|
|
|
//
|
2005-04-29 08:32:20 +00:00
|
|
|
|
// TODO: port this to other platforms (Windows, others?)
|
2002-07-15 23:21:20 +00:00
|
|
|
|
//
|
2004-03-31 19:43:15 +00:00
|
|
|
|
bool HOST_INFO::host_is_running_on_batteries() {
|
2005-04-29 08:32:20 +00:00
|
|
|
|
#if defined(__APPLE__)
|
|
|
|
|
CFDictionaryRef pSource = NULL;
|
|
|
|
|
CFStringRef psState;
|
|
|
|
|
int i;
|
|
|
|
|
bool retval = false;
|
|
|
|
|
|
|
|
|
|
CFTypeRef blob = IOPSCopyPowerSourcesInfo();
|
|
|
|
|
CFArrayRef list = IOPSCopyPowerSourcesList(blob);
|
|
|
|
|
|
|
|
|
|
for(i = 0; i < CFArrayGetCount(list); i++) {
|
|
|
|
|
pSource = IOPSGetPowerSourceDescription(blob, CFArrayGetValueAtIndex(list, i));
|
|
|
|
|
if(!pSource) break;
|
|
|
|
|
psState = (CFStringRef)CFDictionaryGetValue(pSource, CFSTR(kIOPSPowerSourceStateKey));
|
|
|
|
|
if(!CFStringCompare(psState,CFSTR(kIOPSBatteryPowerValue),0))
|
|
|
|
|
retval = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CFRelease(blob);
|
|
|
|
|
CFRelease(list);
|
|
|
|
|
return(retval);
|
|
|
|
|
|
|
|
|
|
#elif defined(linux)
|
2004-04-22 19:14:56 +00:00
|
|
|
|
bool retval = false;
|
2004-04-04 05:31:27 +00:00
|
|
|
|
|
|
|
|
|
FILE* fapm = fopen("/proc/apm", "r");
|
2004-04-05 06:32:28 +00:00
|
|
|
|
if (fapm) { // Then we're using APM! Yay.
|
2004-04-22 19:14:56 +00:00
|
|
|
|
|
|
|
|
|
char apm_driver_version[10];
|
|
|
|
|
int apm_major_version;
|
|
|
|
|
int apm_minor_version;
|
|
|
|
|
int apm_flags;
|
|
|
|
|
int apm_ac_line_status=1;
|
|
|
|
|
|
|
|
|
|
// Supposedly we're on batteries if the 5th entry is zero.
|
2007-03-13 19:33:27 +00:00
|
|
|
|
int n = fscanf(fapm, "%10s %d.%d %x %x",
|
2004-04-22 19:14:56 +00:00
|
|
|
|
apm_driver_version,
|
|
|
|
|
&apm_major_version,
|
|
|
|
|
&apm_minor_version,
|
|
|
|
|
&apm_flags,
|
|
|
|
|
&apm_ac_line_status
|
|
|
|
|
);
|
|
|
|
|
retval = (apm_ac_line_status == 0);
|
2004-04-28 21:10:14 +00:00
|
|
|
|
fclose(fapm);
|
2004-04-22 19:14:56 +00:00
|
|
|
|
} else {
|
|
|
|
|
|
|
|
|
|
// we try ACPI
|
|
|
|
|
char buf[128];
|
|
|
|
|
char ac_state[64];
|
2004-07-02 04:49:17 +00:00
|
|
|
|
std::string ac_name;
|
2004-04-22 19:14:56 +00:00
|
|
|
|
FILE* facpi;
|
2004-07-13 13:54:09 +00:00
|
|
|
|
|
|
|
|
|
// we need to find the right ac adapter first
|
2004-04-22 19:14:56 +00:00
|
|
|
|
DirScanner dir("/proc/acpi/ac_adapter/");
|
|
|
|
|
while (dir.scan(ac_name)) {
|
|
|
|
|
if ((ac_name.c_str()==".")||(ac_name.c_str()=="..")) continue;
|
2004-07-13 13:54:09 +00:00
|
|
|
|
|
2004-04-22 19:14:56 +00:00
|
|
|
|
// newer ACPI versions use "state" as filename
|
|
|
|
|
sprintf(ac_state, "/proc/acpi/ac_adapter/%s/state", ac_name.c_str());
|
|
|
|
|
facpi = fopen(ac_state, "r");
|
2004-07-13 13:54:09 +00:00
|
|
|
|
if (!facpi) {
|
2004-04-22 19:14:56 +00:00
|
|
|
|
// older ACPI versions use "status" instead
|
|
|
|
|
sprintf(ac_state, "/proc/acpi/ac_adapter/%s/status", ac_name.c_str());
|
|
|
|
|
facpi = fopen(ac_state, "r");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (facpi) {
|
2007-03-13 19:33:27 +00:00
|
|
|
|
char* p = fgets(buf, 128, facpi);
|
2004-04-30 02:26:23 +00:00
|
|
|
|
fclose(facpi);
|
2004-04-22 19:14:56 +00:00
|
|
|
|
|
|
|
|
|
// only valid state if it contains "state" (newer) or "Status" (older)
|
2004-07-13 13:54:09 +00:00
|
|
|
|
if ((strstr(buf, "state:") != NULL) || (strstr(buf, "Status:") != NULL)) {
|
2004-04-22 19:14:56 +00:00
|
|
|
|
// on batteries if ac adapter is "off-line" (or maybe "offline")
|
|
|
|
|
retval = (strstr(buf, "off") != NULL);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2004-03-31 06:25:40 +00:00
|
|
|
|
}
|
2004-04-22 19:14:56 +00:00
|
|
|
|
|
|
|
|
|
return retval;
|
2004-04-04 05:31:27 +00:00
|
|
|
|
#else
|
|
|
|
|
return false;
|
|
|
|
|
#endif
|
2002-04-30 22:22:54 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifdef linux
|
|
|
|
|
|
|
|
|
|
// Unfortunately the format of /proc/cpuinfo is not standardized.
|
|
|
|
|
// See http://people.nl.linux.org/~hch/cpuinfo/ for some examples.
|
2003-11-25 15:51:19 +00:00
|
|
|
|
//
|
2002-04-30 22:22:54 +00:00
|
|
|
|
void parse_cpuinfo(HOST_INFO& host) {
|
2007-02-12 23:53:16 +00:00
|
|
|
|
char buf[256], features[1024], model_buf[1024];
|
2006-06-09 20:47:09 +00:00
|
|
|
|
bool vendor_found=false, model_found=false;
|
2007-02-12 23:53:16 +00:00
|
|
|
|
bool cache_found=false, features_found=false;
|
2007-03-13 19:33:27 +00:00
|
|
|
|
bool icache_found=false,dcache_found=false;
|
|
|
|
|
bool model_hack=false, vendor_hack=false;
|
2002-04-30 22:22:54 +00:00
|
|
|
|
int n;
|
2007-02-12 23:53:16 +00:00
|
|
|
|
int family=-1, model=-1, stepping=-1;
|
2007-03-13 19:33:27 +00:00
|
|
|
|
char buf2[256];
|
2002-04-30 22:22:54 +00:00
|
|
|
|
|
|
|
|
|
FILE* f = fopen("/proc/cpuinfo", "r");
|
|
|
|
|
if (!f) return;
|
2004-03-12 23:09:48 +00:00
|
|
|
|
|
2006-06-09 20:47:09 +00:00
|
|
|
|
#ifdef __mips__
|
|
|
|
|
strcpy(host.p_model, "MIPS ");
|
2007-03-13 19:33:27 +00:00
|
|
|
|
model_hack = true;
|
2006-06-09 20:47:09 +00:00
|
|
|
|
#elif __alpha__
|
|
|
|
|
strcpy(host.p_vendor, "HP (DEC) ");
|
2007-03-13 19:33:27 +00:00
|
|
|
|
vendor_hack = true;
|
|
|
|
|
#elif __hppa__
|
|
|
|
|
strcpy(host.p_vendor, "HP ");
|
|
|
|
|
vendor_hack = true;
|
|
|
|
|
#elif __ia64__
|
|
|
|
|
strcpy(host.p_model, "IA-64 ");
|
|
|
|
|
model_hack = true;
|
2006-06-09 20:47:09 +00:00
|
|
|
|
#endif
|
|
|
|
|
|
2007-03-13 19:33:27 +00:00
|
|
|
|
host.m_cache=-1;
|
2007-02-12 23:53:16 +00:00
|
|
|
|
strcpy(features, "");
|
2002-04-30 22:22:54 +00:00
|
|
|
|
while (fgets(buf, 256, f)) {
|
2006-06-09 17:31:34 +00:00
|
|
|
|
strip_whitespace(buf);
|
2007-03-13 19:33:27 +00:00
|
|
|
|
if (
|
|
|
|
|
/* there might be conflicts if we dont #ifdef */
|
|
|
|
|
#ifdef __ia64__
|
|
|
|
|
strstr(buf, "vendor : ")
|
2007-03-19 20:03:06 +00:00
|
|
|
|
#elif __hppa__
|
|
|
|
|
strstr(buf, "cpu\t\t: ")
|
2007-03-13 19:33:27 +00:00
|
|
|
|
#elif __powerpc__
|
|
|
|
|
strstr(buf, "machine\t\t: ")
|
|
|
|
|
#elif __sparc__
|
2007-03-19 20:03:06 +00:00
|
|
|
|
strstr(buf, "type\t\t: ")
|
2007-03-13 19:33:27 +00:00
|
|
|
|
#elif __alpha__
|
2007-03-19 20:03:06 +00:00
|
|
|
|
strstr(buf, "cpu\t\t\t: ")
|
2007-03-13 19:33:27 +00:00
|
|
|
|
#else
|
2007-03-19 20:03:06 +00:00
|
|
|
|
strstr(buf, "vendor_id\t: ") || strstr(buf, "system type\t\t: ")
|
2007-03-13 19:33:27 +00:00
|
|
|
|
#endif
|
2007-03-19 20:03:06 +00:00
|
|
|
|
) {
|
2007-03-13 19:33:27 +00:00
|
|
|
|
if (!vendor_hack && !vendor_found) {
|
2006-06-09 20:47:09 +00:00
|
|
|
|
vendor_found = true;
|
|
|
|
|
strlcpy(host.p_vendor, strchr(buf, ':') + 2, sizeof(host.p_vendor));
|
2007-03-13 19:33:27 +00:00
|
|
|
|
} else if (!vendor_found) {
|
2007-03-19 20:03:06 +00:00
|
|
|
|
vendor_found = true;
|
|
|
|
|
strlcpy(buf2, strchr(buf, ':') + 2, sizeof(host.p_vendor) - strlen(host.p_vendor) - 1);
|
|
|
|
|
strcat(host.p_vendor, buf2);
|
2006-06-09 20:47:09 +00:00
|
|
|
|
}
|
2002-04-30 22:22:54 +00:00
|
|
|
|
}
|
2007-03-13 19:33:27 +00:00
|
|
|
|
if (
|
|
|
|
|
#ifdef __ia64__
|
2007-03-19 20:03:06 +00:00
|
|
|
|
strstr(buf, "family : ") || strstr(buf, "model name : ")
|
2007-03-13 19:33:27 +00:00
|
|
|
|
#elif __powerpc__ || __sparc__
|
2007-03-19 20:03:06 +00:00
|
|
|
|
strstr(buf, "cpu\t\t: ")
|
2007-03-13 19:33:27 +00:00
|
|
|
|
#else
|
2007-03-19 20:03:06 +00:00
|
|
|
|
strstr(buf, "model name\t: ") || strstr(buf, "cpu model\t\t: ")
|
2007-03-13 19:33:27 +00:00
|
|
|
|
#endif
|
|
|
|
|
) {
|
|
|
|
|
if (!model_hack && !model_found) {
|
2006-06-09 20:47:09 +00:00
|
|
|
|
model_found = true;
|
2007-03-13 19:33:27 +00:00
|
|
|
|
#ifdef __powerpc__
|
2007-03-19 20:03:06 +00:00
|
|
|
|
char *coma = NULL;
|
2007-03-13 19:33:27 +00:00
|
|
|
|
if ((coma = strrchr(buf, ','))) { /* we have ", altivec supported" */
|
2007-03-19 20:03:06 +00:00
|
|
|
|
*coma = '\0'; /* strip the unwanted line */
|
2007-03-13 19:33:27 +00:00
|
|
|
|
strcpy(features, "altivec");
|
|
|
|
|
features_found = true;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
2006-06-09 20:47:09 +00:00
|
|
|
|
strlcpy(host.p_model, strchr(buf, ':') + 2, sizeof(host.p_model));
|
2007-03-13 19:33:27 +00:00
|
|
|
|
} else if (!model_found) {
|
|
|
|
|
#ifdef __ia64__
|
2007-03-19 20:03:06 +00:00
|
|
|
|
/* depending on kernel version, family can be either
|
|
|
|
|
a number or a string. If number, we have a model name,
|
|
|
|
|
else we don't */
|
|
|
|
|
char *testc = NULL;
|
|
|
|
|
testc = strrchr(buf, ':')+2;
|
|
|
|
|
if (isdigit(*testc)) {
|
|
|
|
|
family = atoi(testc);
|
|
|
|
|
continue; /* skip this line */
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
model_found = true;
|
|
|
|
|
strlcpy(buf2, strchr(buf, ':') + 2, sizeof(host.p_model) - strlen(host.p_model) - 1);
|
|
|
|
|
strcat(host.p_model, buf2);
|
2006-06-09 20:47:09 +00:00
|
|
|
|
}
|
2002-04-30 22:22:54 +00:00
|
|
|
|
}
|
2007-03-13 19:33:27 +00:00
|
|
|
|
#ifndef __hppa__
|
2007-03-19 20:03:06 +00:00
|
|
|
|
/* XXX hppa: "cpu family\t: PA-RISC 2.0" */
|
2007-02-12 23:53:16 +00:00
|
|
|
|
if (strstr(buf, "cpu family\t: ") && family<0) {
|
|
|
|
|
family = atoi(buf+strlen("cpu family\t: "));
|
|
|
|
|
}
|
2007-03-13 19:33:27 +00:00
|
|
|
|
/* XXX hppa: "model\t\t: 9000/785/J6000" */
|
2007-03-19 20:03:06 +00:00
|
|
|
|
/* XXX alpha: "cpu model\t\t: EV6" -> ==buf necessary */
|
2007-03-13 19:33:27 +00:00
|
|
|
|
if ((strstr(buf, "model\t\t: ") == buf) && model<0) {
|
2007-02-12 23:53:16 +00:00
|
|
|
|
model = atoi(buf+strlen("model\t\t: "));
|
|
|
|
|
}
|
2007-03-13 19:33:27 +00:00
|
|
|
|
/* ia64 */
|
|
|
|
|
if (strstr(buf, "model : ") && model<0) {
|
|
|
|
|
model = atoi(buf+strlen("model : "));
|
|
|
|
|
}
|
|
|
|
|
#endif
|
2007-02-12 23:53:16 +00:00
|
|
|
|
if (strstr(buf, "stepping\t: ") && stepping<0) {
|
|
|
|
|
stepping = atoi(buf+strlen("stepping\t: "));
|
|
|
|
|
}
|
2007-03-13 19:33:27 +00:00
|
|
|
|
#ifdef __hppa__
|
|
|
|
|
if (!icache_found && strstr(buf, "I-cache\t\t: ")) {
|
|
|
|
|
icache_found = true;
|
|
|
|
|
sscanf(buf, "I-cache\t\t: %d", &n);
|
|
|
|
|
host.m_cache += n*1024;
|
|
|
|
|
}
|
|
|
|
|
if (!dcache_found && strstr(buf, "D-cache\t\t: ")) {
|
|
|
|
|
dcache_found = true;
|
|
|
|
|
sscanf(buf, "D-cache\t\t: %d", &n);
|
|
|
|
|
host.m_cache += n*1024;
|
|
|
|
|
}
|
|
|
|
|
#elif __powerpc__
|
|
|
|
|
if (!cache_found && strstr(buf, "L2 cache\t: ")) {
|
|
|
|
|
cache_found = true;
|
|
|
|
|
sscanf(buf, "L2 cache\t: %d", &n);
|
|
|
|
|
host.m_cache = n*1024;
|
|
|
|
|
}
|
|
|
|
|
#else
|
2007-01-23 17:24:43 +00:00
|
|
|
|
if (!cache_found && (strstr(buf, "cache size\t: ") == buf)) {
|
|
|
|
|
cache_found = true;
|
2002-04-30 22:22:54 +00:00
|
|
|
|
sscanf(buf, "cache size\t: %d", &n);
|
|
|
|
|
host.m_cache = n*1024;
|
|
|
|
|
}
|
2007-03-13 19:33:27 +00:00
|
|
|
|
#endif
|
2007-02-12 23:53:16 +00:00
|
|
|
|
if (!features_found) {
|
2007-01-23 17:24:43 +00:00
|
|
|
|
// Some versions of the linux kernel call them flags,
|
|
|
|
|
// others call them features, so look for both.
|
|
|
|
|
//
|
|
|
|
|
if ((strstr(buf, "flags\t\t: ") == buf)) {
|
2007-02-12 23:53:16 +00:00
|
|
|
|
strlcpy(features, strchr(buf, ':') + 2, sizeof(features));
|
2007-01-23 17:24:43 +00:00
|
|
|
|
} else if ((strstr(buf, "features\t\t: ") == buf)) {
|
2007-02-12 23:53:16 +00:00
|
|
|
|
strlcpy(features, strchr(buf, ':') + 2, sizeof(features));
|
2007-03-19 20:03:06 +00:00
|
|
|
|
} else if ((strstr(buf, "features : ") == buf)) { /* ia64 */
|
|
|
|
|
strlcpy(features, strchr(buf, ':') + 2, sizeof(features));
|
2007-01-23 17:24:43 +00:00
|
|
|
|
}
|
2007-02-12 23:53:16 +00:00
|
|
|
|
if (strlen(features)) {
|
|
|
|
|
features_found = true;
|
2007-01-23 17:24:43 +00:00
|
|
|
|
}
|
2006-05-19 18:34:23 +00:00
|
|
|
|
}
|
2002-04-30 22:22:54 +00:00
|
|
|
|
}
|
2007-02-12 23:53:16 +00:00
|
|
|
|
strcpy(model_buf, host.p_model);
|
|
|
|
|
if (family>=0 || model>=0 || stepping>0) {
|
|
|
|
|
strcat(model_buf, " [");
|
|
|
|
|
if (family>=0) {
|
|
|
|
|
sprintf(buf, "Family %d ", family);
|
|
|
|
|
strcat(model_buf, buf);
|
|
|
|
|
}
|
|
|
|
|
if (model>=0) {
|
|
|
|
|
sprintf(buf, "Model %d ", model);
|
|
|
|
|
strcat(model_buf, buf);
|
|
|
|
|
}
|
|
|
|
|
if (stepping>=0) {
|
|
|
|
|
sprintf(buf, "Stepping %d", stepping);
|
|
|
|
|
strcat(model_buf, buf);
|
|
|
|
|
}
|
|
|
|
|
strcat(model_buf, "]");
|
|
|
|
|
}
|
|
|
|
|
if (strlen(features)) {
|
2007-03-19 20:03:06 +00:00
|
|
|
|
strlcpy(host.p_features, features, sizeof(host.p_features));
|
2007-02-12 23:53:16 +00:00
|
|
|
|
}
|
2004-03-12 23:09:48 +00:00
|
|
|
|
|
2007-02-12 23:53:16 +00:00
|
|
|
|
strlcpy(host.p_model, model_buf, sizeof(host.p_model));
|
2002-04-30 22:22:54 +00:00
|
|
|
|
fclose(f);
|
|
|
|
|
}
|
2004-03-12 23:09:48 +00:00
|
|
|
|
|
2004-04-04 05:31:27 +00:00
|
|
|
|
#endif // linux
|
2002-04-30 22:22:54 +00:00
|
|
|
|
|
2003-06-14 20:24:29 +00:00
|
|
|
|
// get all relevant host information
|
2002-10-14 05:52:48 +00:00
|
|
|
|
//
|
2004-03-31 19:43:15 +00:00
|
|
|
|
int HOST_INFO::get_host_info() {
|
|
|
|
|
get_filesystem_info(d_total, d_free);
|
2003-05-06 21:43:26 +00:00
|
|
|
|
|
2003-05-10 00:52:36 +00:00
|
|
|
|
#ifdef linux
|
2004-03-31 19:43:15 +00:00
|
|
|
|
parse_cpuinfo(*this);
|
2005-12-02 22:29:35 +00:00
|
|
|
|
#elif defined(__EMX__)
|
|
|
|
|
int mib[2];
|
|
|
|
|
unsigned int mem_size;
|
|
|
|
|
size_t len;
|
2007-03-19 20:03:06 +00:00
|
|
|
|
CPU_INFO_t cpuInfo;
|
2005-12-02 22:29:35 +00:00
|
|
|
|
strcpy( p_vendor, cpuInfo.vendor.company);
|
|
|
|
|
strcpy( p_model, cpuInfo.name.fromID);
|
2003-05-10 00:52:36 +00:00
|
|
|
|
#else
|
2003-04-30 20:10:37 +00:00
|
|
|
|
#if HAVE_SYS_SYSCTL_H
|
2004-03-17 01:26:44 +00:00
|
|
|
|
int mib[2];
|
2003-04-30 20:10:37 +00:00
|
|
|
|
size_t len;
|
2007-03-13 00:41:38 +00:00
|
|
|
|
#ifdef __APPLE__
|
|
|
|
|
long mem_size;
|
|
|
|
|
#else
|
|
|
|
|
unsigned int mem_size;
|
2003-04-30 20:10:37 +00:00
|
|
|
|
|
|
|
|
|
// Get machine
|
|
|
|
|
mib[0] = CTL_HW;
|
|
|
|
|
mib[1] = HW_MACHINE;
|
2004-03-31 19:43:15 +00:00
|
|
|
|
len = sizeof(p_vendor);
|
|
|
|
|
sysctl(mib, 2, &p_vendor, &len, NULL, 0);
|
2004-07-13 13:54:09 +00:00
|
|
|
|
|
2003-04-30 20:10:37 +00:00
|
|
|
|
// Get model
|
|
|
|
|
mib[0] = CTL_HW;
|
|
|
|
|
mib[1] = HW_MODEL;
|
2004-04-03 00:43:55 +00:00
|
|
|
|
len = sizeof(p_model);
|
2004-03-31 19:43:15 +00:00
|
|
|
|
sysctl(mib, 2, &p_model, &len, NULL, 0);
|
2007-01-23 10:20:49 +00:00
|
|
|
|
#endif // ! __APPLE__
|
2005-12-29 00:59:53 +00:00
|
|
|
|
#else
|
|
|
|
|
// Tru64 UNIX.
|
|
|
|
|
// 2005-12-26 SMS.
|
|
|
|
|
#ifdef __osf__
|
|
|
|
|
int mem_size;
|
|
|
|
|
long cpu_type;
|
|
|
|
|
char *cpu_type_name;
|
|
|
|
|
|
|
|
|
|
strcpy(p_vendor, "HP (DEC)");
|
|
|
|
|
|
|
|
|
|
getsysinfo( GSI_PROC_TYPE, (caddr_t) &cpu_type, sizeof( cpu_type));
|
|
|
|
|
CPU_TYPE_TO_TEXT( (cpu_type& 0xffffffff), cpu_type_name);
|
|
|
|
|
strncpy( p_model, "Alpha ", sizeof( p_model));
|
|
|
|
|
strncat( p_model, cpu_type_name, (sizeof( p_model)- strlen( p_model)- 1));
|
|
|
|
|
#endif
|
2003-04-30 20:10:37 +00:00
|
|
|
|
#endif
|
2003-04-08 07:05:22 +00:00
|
|
|
|
#endif
|
2004-07-13 13:54:09 +00:00
|
|
|
|
|
2005-12-02 22:29:35 +00:00
|
|
|
|
// sysconf not working on OS2
|
|
|
|
|
#if defined(_SC_NPROCESSORS_ONLN) && !defined(__EMX__)
|
2004-03-31 19:43:15 +00:00
|
|
|
|
p_ncpus = sysconf(_SC_NPROCESSORS_ONLN);
|
2003-04-30 20:10:37 +00:00
|
|
|
|
#elif defined(HAVE_SYS_SYSCTL_H) && defined(CTL_HW) && defined(HW_NCPU)
|
|
|
|
|
// Get number of CPUs
|
|
|
|
|
mib[0] = CTL_HW;
|
|
|
|
|
mib[1] = HW_NCPU;
|
2004-03-31 19:43:15 +00:00
|
|
|
|
len = sizeof(p_ncpus);
|
|
|
|
|
sysctl(mib, 2, &p_ncpus, &len, NULL, 0);
|
2005-06-14 20:31:15 +00:00
|
|
|
|
#elif defined(_HPUX_SOURCE)
|
|
|
|
|
struct pst_dynamic psd;
|
|
|
|
|
pstat_getdynamic ( &psd, sizeof ( psd ), (size_t)1, 0 );
|
|
|
|
|
p_ncpus = psd.psd_proc_cnt;
|
2003-04-08 18:36:03 +00:00
|
|
|
|
#else
|
|
|
|
|
#error Need to specify a sysconf() define to obtain number of processors
|
|
|
|
|
#endif
|
2002-11-04 04:06:06 +00:00
|
|
|
|
|
2005-10-04 21:44:58 +00:00
|
|
|
|
// There can be a variety of methods to obtain amount of usable memory.
|
|
|
|
|
// You will have to check your sysconf() defines, probably in unistd.h
|
|
|
|
|
// - 2002-11-03 hiram@users.sourceforge.net
|
|
|
|
|
//
|
2005-12-02 22:29:35 +00:00
|
|
|
|
#ifdef __EMX__
|
|
|
|
|
{
|
|
|
|
|
ULONG ulMem;
|
2007-03-19 20:03:06 +00:00
|
|
|
|
CPU_INFO_t cpuInfo;
|
2005-12-02 22:29:35 +00:00
|
|
|
|
DosQuerySysInfo( QSV_TOTPHYSMEM, QSV_TOTPHYSMEM, &ulMem, sizeof(ulMem));
|
|
|
|
|
m_nbytes = ulMem;
|
|
|
|
|
// YD this is not the swap free space, but should be enough
|
|
|
|
|
DosQuerySysInfo( QSV_TOTAVAILMEM, QSV_TOTAVAILMEM, &ulMem, sizeof(ulMem));
|
|
|
|
|
m_swap = ulMem;
|
|
|
|
|
}
|
|
|
|
|
#elif defined(_SC_USEABLE_MEMORY)
|
2004-03-31 19:43:15 +00:00
|
|
|
|
m_nbytes = (double)sysconf(_SC_PAGESIZE)
|
2005-10-04 21:44:58 +00:00
|
|
|
|
* (double)sysconf(_SC_USEABLE_MEMORY); // UnixWare
|
2002-11-04 04:06:06 +00:00
|
|
|
|
#elif defined(_SC_PHYS_PAGES)
|
2005-10-04 21:44:58 +00:00
|
|
|
|
m_nbytes = (double)sysconf(_SC_PAGESIZE) * (double)sysconf(_SC_PHYS_PAGES);
|
|
|
|
|
// Linux
|
2007-03-13 00:41:38 +00:00
|
|
|
|
#elif defined(__APPLE__)
|
|
|
|
|
// On Mac OS X, sysctl with selectors CTL_HW, HW_PHYSMEM returns only a
|
|
|
|
|
// 4-byte value, even if passed an 8-byte buffer, and limits the returned
|
|
|
|
|
// value to 2GB when the actual RAM size is > 2GB. The Gestalt selector
|
|
|
|
|
// gestaltPhysicalRAMSizeInMegabytes is available starting with OS 10.3.0.
|
|
|
|
|
if (Gestalt(gestaltPhysicalRAMSizeInMegabytes, &mem_size))
|
|
|
|
|
msg_printf(NULL, MSG_INTERNAL_ERROR, "Couldn't determine physical RAM size");
|
|
|
|
|
m_nbytes = (1024. * 1024.) * (double)mem_size;
|
2003-04-30 20:10:37 +00:00
|
|
|
|
#elif defined(HAVE_SYS_SYSCTL_H) && defined(CTL_HW) && defined(HW_PHYSMEM)
|
2007-03-13 00:53:14 +00:00
|
|
|
|
#error This code does not properly report physical RAM size > 2GB (see comment above for __APPLE__)
|
2003-04-30 20:10:37 +00:00
|
|
|
|
mib[0] = CTL_HW;
|
|
|
|
|
mib[1] = HW_PHYSMEM;
|
|
|
|
|
len = sizeof(mem_size);
|
2003-06-06 22:08:46 +00:00
|
|
|
|
sysctl(mib, 2, &mem_size, &len, NULL, 0); // Mac OS X
|
2004-03-31 19:43:15 +00:00
|
|
|
|
m_nbytes = mem_size;
|
2005-06-14 20:31:15 +00:00
|
|
|
|
#elif defined(_HPUX_SOURCE)
|
|
|
|
|
struct pst_static pst;
|
|
|
|
|
pstat_getstatic(&pst, sizeof(pst), (size_t)1, 0);
|
2006-03-02 07:17:18 +00:00
|
|
|
|
m_nbytes = (long double)pst.physical_memory * (long double)pst.page_size;
|
2005-12-29 00:59:53 +00:00
|
|
|
|
#elif defined(__osf__)
|
|
|
|
|
// Tru64 UNIX.
|
|
|
|
|
// 2005-12-26 SMS.
|
|
|
|
|
getsysinfo( GSI_PHYSMEM, (caddr_t) &mem_size, sizeof( mem_size));
|
|
|
|
|
m_nbytes = 1024.* (double)mem_size;
|
2002-11-04 04:06:06 +00:00
|
|
|
|
#else
|
|
|
|
|
#error Need to specify a sysconf() define to obtain memory size
|
|
|
|
|
#endif
|
2002-04-30 22:22:54 +00:00
|
|
|
|
|
2003-04-08 18:36:03 +00:00
|
|
|
|
#if defined(HAVE_SYS_SWAP_H) && defined(SC_GETNSWP)
|
2004-08-04 21:14:34 +00:00
|
|
|
|
// Solaris, ...
|
2003-04-08 18:36:03 +00:00
|
|
|
|
char buf[256];
|
2002-04-30 22:22:54 +00:00
|
|
|
|
swaptbl_t* s;
|
2003-04-08 18:36:03 +00:00
|
|
|
|
int i, n;
|
2002-04-30 22:22:54 +00:00
|
|
|
|
n = swapctl(SC_GETNSWP, 0);
|
|
|
|
|
s = (swaptbl_t*)malloc(n*sizeof(swapent_t) + sizeof(struct swaptable));
|
|
|
|
|
for (i=0; i<n; i++) {
|
|
|
|
|
s->swt_ent[i].ste_path = buf;
|
|
|
|
|
}
|
|
|
|
|
s->swt_n = n;
|
|
|
|
|
n = swapctl(SC_LIST, s);
|
2005-12-29 00:59:53 +00:00
|
|
|
|
m_swap = 0.0;
|
2002-04-30 22:22:54 +00:00
|
|
|
|
for (i=0; i<n; i++) {
|
2004-03-31 19:43:15 +00:00
|
|
|
|
m_swap += 512.*(double)s->swt_ent[i].ste_length;
|
2002-04-30 22:22:54 +00:00
|
|
|
|
}
|
2005-07-27 11:59:38 +00:00
|
|
|
|
#elif defined(HAVE_SYS_SWAP_H) && defined(SWAP_NSWAP)
|
|
|
|
|
// NetBSD (the above line should probably be more comprehensive
|
|
|
|
|
struct swapent * s;
|
|
|
|
|
int i, n;
|
|
|
|
|
n = swapctl(SWAP_NSWAP, NULL, 0);
|
|
|
|
|
s = (struct swapent*)malloc(n * sizeof(struct swapent));
|
|
|
|
|
swapctl(SWAP_STATS, s, n);
|
2005-12-29 00:59:53 +00:00
|
|
|
|
m_swap = 0.0;
|
2005-07-27 11:59:38 +00:00
|
|
|
|
for (i = 0; i < n; i ++) {
|
|
|
|
|
if (s[i].se_flags & SWF_ENABLE)
|
|
|
|
|
m_swap += 512. * (double)s[i].se_nblks;
|
|
|
|
|
}
|
2004-08-04 21:14:34 +00:00
|
|
|
|
#elif defined(HAVE__PROC_MEMINFO)
|
|
|
|
|
// Linux
|
|
|
|
|
FILE *fp;
|
|
|
|
|
if ((fp = fopen("/proc/meminfo", "r")) != 0) {
|
|
|
|
|
char minfo_buf[1024];
|
|
|
|
|
int n;
|
|
|
|
|
if ((n = fread(minfo_buf, sizeof(char), sizeof(minfo_buf)-1, fp))) {
|
|
|
|
|
char *p;
|
|
|
|
|
minfo_buf[n] = '\0';
|
|
|
|
|
if ((p = strstr(minfo_buf, "SwapTotal:"))) {
|
|
|
|
|
p += 10; // move past "SwapTotal:"
|
2004-08-04 21:19:40 +00:00
|
|
|
|
m_swap = 1024.*(double) strtoul(p, NULL, 10);
|
2004-08-04 21:14:34 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
fclose(fp);
|
|
|
|
|
}
|
2006-09-27 03:01:52 +00:00
|
|
|
|
#elif defined(__APPLE__)
|
|
|
|
|
// The sysctl(vm.vmmeter) function doesn't work on OS X. However, swap
|
|
|
|
|
// space is limited only by free disk space, so we get that info instead.
|
|
|
|
|
// This is larger than free disk space reported by get_filesystem_info()
|
|
|
|
|
// because it includes space available only to the kernel / super-user.
|
|
|
|
|
//
|
|
|
|
|
// http://developer.apple.com/documentation/Performance/Conceptual/ManagingMemory/Articles/AboutMemory.html says:
|
|
|
|
|
// Unlike most UNIX-based operating systems, Mac OS X does not use a
|
|
|
|
|
// preallocated swap partition for virtual memory. Instead, it uses all
|
|
|
|
|
// of the available space on the machine<6E>s boot partition.
|
|
|
|
|
struct statfs fs_info;
|
|
|
|
|
|
|
|
|
|
statfs(".", &fs_info);
|
|
|
|
|
m_swap = (double)fs_info.f_bsize * (double)fs_info.f_bfree;
|
|
|
|
|
|
2006-09-25 12:07:40 +00:00
|
|
|
|
#elif defined(HAVE_VMMETER_H) && defined(HAVE_SYS_SYSCTL_H) && defined(CTL_VM) && defined(VM_METER)
|
2004-08-04 22:43:42 +00:00
|
|
|
|
// MacOSX, I think...
|
|
|
|
|
// <http://www.osxfaq.com/man/3/sysctl.ws>
|
2006-09-25 12:07:40 +00:00
|
|
|
|
// The sysctl(vm.vmmeter) function doesn't work on OS X, so the following
|
2006-09-27 03:01:52 +00:00
|
|
|
|
// code fails to get the total swap space. See note above for APPLE case.
|
|
|
|
|
// I've left this code here in case it is used by a different platform,
|
|
|
|
|
// though I believe the first argument should be CTL_VM instead of CTL_USER.
|
2004-08-04 22:43:42 +00:00
|
|
|
|
struct vmtotal vm_info;
|
2004-07-13 13:54:09 +00:00
|
|
|
|
|
2006-09-27 03:01:52 +00:00
|
|
|
|
mib[0] = CTL_USER; // Should this be CTL_VM ?
|
2002-10-14 05:52:48 +00:00
|
|
|
|
mib[1] = VM_METER;
|
|
|
|
|
len = sizeof(vm_info);
|
2004-08-04 22:43:42 +00:00
|
|
|
|
if (!sysctl(mib, 2, &vm_info, &len, NULL, 0)) {
|
|
|
|
|
m_swap = 1024. * getpagesize() * (double) vm_info.t_vm;
|
|
|
|
|
}
|
2006-09-25 10:49:39 +00:00
|
|
|
|
|
2005-06-14 20:31:15 +00:00
|
|
|
|
#elif defined(_HPUX_SOURCE)
|
|
|
|
|
struct pst_vminfo vminfo;
|
|
|
|
|
pstat_getvminfo(&vminfo, sizeof(vminfo), (size_t)1, 0);
|
|
|
|
|
m_swap = (vminfo.psv_swapspc_max * pst.page_size);
|
2003-04-30 20:10:37 +00:00
|
|
|
|
#else
|
|
|
|
|
#endif
|
|
|
|
|
|
2004-07-13 13:54:09 +00:00
|
|
|
|
#if defined(HAVE_SYS_SYSTEMINFO_H)
|
2003-10-28 23:45:31 +00:00
|
|
|
|
#if defined(SI_HW_SERIAL)
|
2004-03-31 19:43:15 +00:00
|
|
|
|
sysinfo(SI_HW_SERIAL, serialnum, sizeof(serialnum));
|
2003-04-30 20:10:37 +00:00
|
|
|
|
#else
|
|
|
|
|
//#error Need to specify a method to obtain serial num
|
2002-10-14 05:52:48 +00:00
|
|
|
|
#endif
|
2003-10-28 23:45:31 +00:00
|
|
|
|
#ifdef SI_PLATFORM
|
2004-03-31 19:43:15 +00:00
|
|
|
|
sysinfo(SI_PLATFORM, p_vendor, sizeof(p_vendor));
|
2003-10-28 23:45:31 +00:00
|
|
|
|
#endif
|
2005-06-14 20:31:15 +00:00
|
|
|
|
|
2003-10-28 23:45:31 +00:00
|
|
|
|
#ifdef SI_ISALIST
|
2004-03-31 19:43:15 +00:00
|
|
|
|
sysinfo(SI_ISALIST, p_model, sizeof(p_model));
|
|
|
|
|
for (unsigned int i=0; i<sizeof(p_model); i++) {
|
|
|
|
|
if (p_model[i]==' ') {
|
|
|
|
|
p_model[i]=0;
|
2003-11-25 15:51:19 +00:00
|
|
|
|
}
|
2004-03-31 19:43:15 +00:00
|
|
|
|
if (p_model[i]==0) {
|
|
|
|
|
i=sizeof(p_model);
|
2003-11-25 15:51:19 +00:00
|
|
|
|
}
|
2003-10-28 23:45:31 +00:00
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
#endif
|
2004-07-13 13:54:09 +00:00
|
|
|
|
|
2006-08-17 09:39:18 +00:00
|
|
|
|
#ifdef __APPLE__
|
2007-03-20 00:07:16 +00:00
|
|
|
|
int p_model_size = sizeof(p_model);
|
2006-08-17 09:39:18 +00:00
|
|
|
|
#ifdef __i386__
|
2007-03-19 20:03:06 +00:00
|
|
|
|
char brand_string[256];
|
2007-01-23 10:20:49 +00:00
|
|
|
|
int family, stepping, model;
|
|
|
|
|
|
|
|
|
|
len = sizeof(p_vendor);
|
|
|
|
|
sysctlbyname("machdep.cpu.vendor", p_vendor, &len, NULL, 0);
|
|
|
|
|
|
|
|
|
|
len = sizeof(brand_string);
|
|
|
|
|
sysctlbyname("machdep.cpu.brand_string", brand_string, &len, NULL, 0);
|
|
|
|
|
|
|
|
|
|
len = sizeof(family);
|
|
|
|
|
sysctlbyname("machdep.cpu.family", &family, &len, NULL, 0);
|
|
|
|
|
|
|
|
|
|
len = sizeof(model);
|
|
|
|
|
sysctlbyname("machdep.cpu.model", &model, &len, NULL, 0);
|
|
|
|
|
|
|
|
|
|
len = sizeof(stepping);
|
|
|
|
|
sysctlbyname("machdep.cpu.stepping", &stepping, &len, NULL, 0);
|
|
|
|
|
|
2007-03-19 20:03:06 +00:00
|
|
|
|
len = sizeof(p_features);
|
|
|
|
|
sysctlbyname("machdep.cpu.features", p_features, &len, NULL, 0);
|
2007-01-23 10:20:49 +00:00
|
|
|
|
|
2007-03-19 20:03:06 +00:00
|
|
|
|
snprintf(
|
|
|
|
|
p_model, sizeof(p_model),
|
|
|
|
|
"%s [x86 Family %d Model %d Stepping %d]",
|
|
|
|
|
brand_string, family, model, stepping
|
|
|
|
|
);
|
2007-01-23 10:20:49 +00:00
|
|
|
|
|
2006-08-17 09:39:18 +00:00
|
|
|
|
#else // PowerPC
|
2007-01-23 10:20:49 +00:00
|
|
|
|
char capabilities[256], model[256];
|
2006-08-17 09:39:18 +00:00
|
|
|
|
int response = 0;
|
|
|
|
|
int retval;
|
|
|
|
|
len = sizeof(response);
|
2007-01-23 10:20:49 +00:00
|
|
|
|
safe_strcpy(p_vendor, "Power Macintosh");
|
2006-08-17 09:39:18 +00:00
|
|
|
|
retval = sysctlbyname("hw.optional.altivec", &response, &len, NULL, 0);
|
2007-03-19 20:03:06 +00:00
|
|
|
|
if (response && (!retval)) {
|
2007-01-23 10:20:49 +00:00
|
|
|
|
safe_strcpy(capabilities, "AltiVec");
|
2007-03-19 20:03:06 +00:00
|
|
|
|
}
|
2007-01-23 10:20:49 +00:00
|
|
|
|
|
|
|
|
|
len = sizeof(model);
|
|
|
|
|
sysctlbyname("hw.model", model, &len, NULL, 0);
|
|
|
|
|
|
|
|
|
|
snprintf(p_model, p_model_size, "%s [%s Model %s] [%s]", p_vendor, p_vendor, model, capabilities);
|
|
|
|
|
|
2006-08-17 09:39:18 +00:00
|
|
|
|
#endif // i386 or PowerPC
|
2007-01-23 10:20:49 +00:00
|
|
|
|
|
|
|
|
|
p_model[p_model_size-1] = 0;
|
|
|
|
|
char *in = p_model + 1;
|
|
|
|
|
char *out = in;
|
|
|
|
|
// Strip out runs of multiple spaces
|
|
|
|
|
do {
|
|
|
|
|
if ((!isspace(*(in-1))) || (!isspace(*in)))
|
|
|
|
|
*out++ = *in;
|
|
|
|
|
} while (*in++);
|
|
|
|
|
|
2006-08-17 09:39:18 +00:00
|
|
|
|
#endif // __APPLE__
|
|
|
|
|
|
2006-06-23 20:41:47 +00:00
|
|
|
|
get_local_network_info();
|
2004-06-17 17:00:14 +00:00
|
|
|
|
|
2004-03-31 19:43:15 +00:00
|
|
|
|
timezone = get_timezone();
|
2002-07-03 22:37:24 +00:00
|
|
|
|
#ifdef HAVE_SYS_UTSNAME_H
|
2003-04-08 18:36:03 +00:00
|
|
|
|
struct utsname u;
|
|
|
|
|
uname(&u);
|
2004-03-31 19:43:15 +00:00
|
|
|
|
safe_strcpy(os_name, u.sysname);
|
2005-12-02 22:29:35 +00:00
|
|
|
|
#ifdef __EMX__ // OS2: version is in u.version
|
|
|
|
|
safe_strcpy(os_version, u.version);
|
|
|
|
|
#else
|
2004-03-31 19:43:15 +00:00
|
|
|
|
safe_strcpy(os_version, u.release);
|
2005-12-02 22:29:35 +00:00
|
|
|
|
#endif
|
2005-06-14 20:31:15 +00:00
|
|
|
|
#ifdef _HPUX_SOURCE
|
|
|
|
|
safe_strcpy(p_model, u.machine);
|
|
|
|
|
safe_strcpy(p_vendor, "Hewlett-Packard");
|
|
|
|
|
#endif
|
2003-04-30 20:10:37 +00:00
|
|
|
|
#elif defined(HAVE_SYS_SYSCTL_H) && defined(CTL_KERN) && defined(KERN_OSTYPE) && defined(KERN_OSRELEASE)
|
|
|
|
|
mib[0] = CTL_KERN;
|
|
|
|
|
mib[1] = KERN_OSTYPE;
|
2004-03-31 19:43:15 +00:00
|
|
|
|
len = sizeof(os_name);
|
|
|
|
|
sysctl(mib, 2, &os_name, &len, NULL, 0);
|
2004-07-13 13:54:09 +00:00
|
|
|
|
|
2003-04-30 20:10:37 +00:00
|
|
|
|
mib[0] = CTL_KERN;
|
|
|
|
|
mib[1] = KERN_OSRELEASE;
|
2004-03-31 19:43:15 +00:00
|
|
|
|
len = sizeof(os_version);
|
|
|
|
|
sysctl(mib, 2, &os_version, &len, NULL, 0);
|
2003-04-30 20:10:37 +00:00
|
|
|
|
#elif HAVE_SYS_SYSTEMINFO_H
|
2004-03-31 19:43:15 +00:00
|
|
|
|
sysinfo(SI_SYSNAME, os_name, sizeof(os_name));
|
|
|
|
|
sysinfo(SI_RELEASE, os_version, sizeof(os_version));
|
2003-04-30 20:10:37 +00:00
|
|
|
|
#else
|
|
|
|
|
#error Need to specify a method to obtain OS name/version
|
2002-06-06 22:39:21 +00:00
|
|
|
|
#endif
|
2002-04-30 22:22:54 +00:00
|
|
|
|
|
2005-01-20 18:50:49 +00:00
|
|
|
|
if (!strlen(host_cpid)) {
|
|
|
|
|
generate_host_cpid();
|
|
|
|
|
}
|
2002-04-30 22:22:54 +00:00
|
|
|
|
return 0;
|
|
|
|
|
}
|
2004-06-12 05:44:28 +00:00
|
|
|
|
|
|
|
|
|
// returns true iff device was last accessed before t
|
|
|
|
|
// or if an error occurred looking at the device.
|
2005-02-16 23:17:43 +00:00
|
|
|
|
inline bool device_idle(time_t t, const char *device) {
|
2004-06-12 05:44:28 +00:00
|
|
|
|
struct stat sbuf;
|
|
|
|
|
return stat(device, &sbuf) || (sbuf.st_atime < t);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
inline bool all_tty_idle(time_t t, char *device, char first_char, int num_tty) {
|
|
|
|
|
struct stat sbuf;
|
|
|
|
|
char *tty_index = device + strlen(device) - 1;
|
|
|
|
|
*tty_index = first_char;
|
|
|
|
|
for (int i = 0; i < num_tty; i++, (*tty_index)++) {
|
|
|
|
|
if (stat(device, &sbuf)) {
|
|
|
|
|
// error looking at device; don't try any more
|
|
|
|
|
return true;
|
|
|
|
|
} else if (sbuf.st_atime >= t) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2004-06-16 21:18:40 +00:00
|
|
|
|
#ifdef HAVE_UTMP_H
|
2004-06-15 00:46:59 +00:00
|
|
|
|
inline bool user_idle(time_t t, struct utmp* u) {
|
|
|
|
|
char tty[5 + sizeof u->ut_line + 1] = "/dev/";
|
|
|
|
|
unsigned int i;
|
|
|
|
|
|
2004-06-29 04:34:55 +00:00
|
|
|
|
for (i=0; i < sizeof(u->ut_line); i++) {
|
|
|
|
|
// clean up tty if garbled
|
|
|
|
|
if (isalnum((int) u->ut_line[i]) || (u->ut_line[i]=='/')) {
|
2004-06-15 00:46:59 +00:00
|
|
|
|
tty[i+5] = u->ut_line[i];
|
2004-06-29 04:34:55 +00:00
|
|
|
|
} else {
|
2004-06-15 00:46:59 +00:00
|
|
|
|
tty[i+5] = '\0';
|
2004-06-29 04:34:55 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2004-06-15 00:46:59 +00:00
|
|
|
|
return device_idle(t, tty);
|
|
|
|
|
}
|
|
|
|
|
|
2004-06-16 21:18:40 +00:00
|
|
|
|
#if !defined(HAVE_SETUTENT) || !defined(HAVE_GETUTENT)
|
|
|
|
|
static FILE *ufp = NULL;
|
|
|
|
|
static struct utmp ut;
|
|
|
|
|
|
2004-06-18 05:08:57 +00:00
|
|
|
|
// get next user login record
|
|
|
|
|
// (this is defined on everything except BSD)
|
|
|
|
|
//
|
2004-06-16 21:18:40 +00:00
|
|
|
|
struct utmp *getutent() {
|
|
|
|
|
if (ufp == NULL) {
|
2004-06-17 23:10:52 +00:00
|
|
|
|
#if defined(UTMP_LOCATION)
|
|
|
|
|
if ((ufp = fopen(UTMP_LOCATION, "r")) == NULL) {
|
|
|
|
|
#elif defined(UTMP_FILE)
|
2004-06-16 21:18:40 +00:00
|
|
|
|
if ((ufp = fopen(UTMP_FILE, "r")) == NULL) {
|
2004-06-17 23:10:52 +00:00
|
|
|
|
#elif defined(_PATH_UTMP)
|
|
|
|
|
if ((ufp = fopen(_PATH_UTMP, "r")) == NULL) {
|
|
|
|
|
#else
|
|
|
|
|
if ((ufp = fopen("/etc/utmp", "r")) == NULL) {
|
2004-06-17 21:52:11 +00:00
|
|
|
|
#endif
|
2004-06-16 21:18:40 +00:00
|
|
|
|
return((struct utmp *)NULL);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
do {
|
|
|
|
|
if (fread((char *)&ut, sizeof(ut), 1, ufp) != 1) {
|
|
|
|
|
return((struct utmp *)NULL);
|
|
|
|
|
}
|
|
|
|
|
} while (ut.ut_name[0] == 0);
|
|
|
|
|
return(&ut);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void setutent() {
|
|
|
|
|
if (ufp != NULL) rewind(ufp);
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
2004-06-18 05:08:57 +00:00
|
|
|
|
// scan list of logged-in users, and see if they're all idle
|
|
|
|
|
//
|
2004-06-15 00:46:59 +00:00
|
|
|
|
inline bool all_logins_idle(time_t t) {
|
|
|
|
|
struct utmp* u;
|
|
|
|
|
setutent();
|
|
|
|
|
|
|
|
|
|
while ((u = getutent()) != NULL) {
|
|
|
|
|
if (!user_idle(t, u)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
|
}
|
2004-06-15 23:56:17 +00:00
|
|
|
|
#endif
|
2004-06-15 00:46:59 +00:00
|
|
|
|
|
2007-02-23 13:30:33 +00:00
|
|
|
|
#ifdef __APPLE__
|
|
|
|
|
#include <Carbon/Carbon.h>
|
|
|
|
|
|
|
|
|
|
#ifdef __i386__
|
|
|
|
|
|
|
|
|
|
#include <ApplicationServices/ApplicationServices.h>
|
|
|
|
|
|
|
|
|
|
// Returns the system idle time in seconds
|
|
|
|
|
static double GetOSXIdleTime(void) {
|
|
|
|
|
return (double)CGEventSourceSecondsSinceLastEventType (kCGEventSourceStateCombinedSessionState, kCGAnyInputEventType);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#else
|
|
|
|
|
|
|
|
|
|
// CGEventSourceSecondsSinceLastEventType() is available only in OS 10.4 and later.
|
|
|
|
|
// Since the OS10.3.9 SDK doesn't have this function, the PowerPC build would fail
|
|
|
|
|
// with a link error even with weak linking. So we have to do this the hard way.
|
|
|
|
|
|
|
|
|
|
extern "C" {
|
|
|
|
|
extern double CGSSecondsSinceLastInputEvent(long evType); // private API for pre-10.4 systems
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
enum {
|
|
|
|
|
kCGEventSourceStatePrivate = -1,
|
|
|
|
|
kCGEventSourceStateCombinedSessionState = 0,
|
|
|
|
|
kCGEventSourceStateHIDSystemState = 1
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
#define kCGAnyInputEventType ((CGEventType)(~0))
|
|
|
|
|
typedef uint32_t CGEventSourceStateID;
|
|
|
|
|
typedef uint32_t CGEventType;
|
|
|
|
|
|
|
|
|
|
CG_EXTERN CFTimeInterval CGEventSourceSecondsSinceLastEventType( CGEventSourceStateID source, CGEventType eventType );
|
|
|
|
|
|
|
|
|
|
typedef CFTimeInterval (*GetIdleTimeProc)( CGEventSourceStateID source, CGEventType eventType );
|
|
|
|
|
|
|
|
|
|
// Returns the system idle time in seconds
|
|
|
|
|
static double GetOSXIdleTime(void) {
|
|
|
|
|
static CFBundleRef bundleRef = NULL;
|
|
|
|
|
static GetIdleTimeProc GetSysIdleTime = NULL;
|
|
|
|
|
CFURLRef frameworkURL = NULL;
|
|
|
|
|
double idleTime = 0;
|
|
|
|
|
static bool tryNewAPI = true;
|
|
|
|
|
|
|
|
|
|
if (tryNewAPI) {
|
|
|
|
|
if (bundleRef == NULL) {
|
|
|
|
|
frameworkURL = CFURLCreateWithFileSystemPath (kCFAllocatorSystemDefault,
|
|
|
|
|
CFSTR("/System/Library/Frameworks/ApplicationServices.framework"), kCFURLPOSIXPathStyle, true);
|
|
|
|
|
if (frameworkURL) {
|
|
|
|
|
bundleRef = CFBundleCreate(kCFAllocatorSystemDefault, frameworkURL);
|
|
|
|
|
CFRelease( frameworkURL );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (bundleRef) {
|
|
|
|
|
if ( (GetSysIdleTime == NULL) ||
|
|
|
|
|
( ! CFBundleIsExecutableLoaded( bundleRef ) ) ) // Is this test necessary ?
|
|
|
|
|
GetSysIdleTime = (GetIdleTimeProc)
|
|
|
|
|
CFBundleGetFunctionPointerForName( bundleRef, CFSTR("CGEventSourceSecondsSinceLastEventType") );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (GetSysIdleTime)
|
|
|
|
|
idleTime = (double)GetSysIdleTime (kCGEventSourceStateCombinedSessionState, kCGAnyInputEventType);
|
|
|
|
|
else {
|
|
|
|
|
CFRelease( bundleRef );
|
|
|
|
|
bundleRef = NULL;
|
|
|
|
|
tryNewAPI = false; // CGEventSourceSecondsSinceLastEventType() API is not available on this system
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (GetSysIdleTime)
|
|
|
|
|
return idleTime;
|
|
|
|
|
} // if (tryNewAPI)
|
|
|
|
|
|
|
|
|
|
// On 10.3 use this SPI
|
|
|
|
|
// From Adium:
|
|
|
|
|
// On MDD Powermacs, the above function will return a large value when the machine
|
|
|
|
|
// is active (-1?). 18446744073.0 is the lowest I've seen on my MDD -ai
|
|
|
|
|
// Here we check for that value and correctly return a 0 idle time.
|
|
|
|
|
idleTime = CGSSecondsSinceLastInputEvent (-1);
|
|
|
|
|
if (idleTime >= 18446744000.0) idleTime = 0.0;
|
2007-02-25 11:37:40 +00:00
|
|
|
|
return idleTime;
|
2007-02-23 13:30:33 +00:00
|
|
|
|
// return (double)NXIdleTime(gEventHandle); // Very old and very slow API
|
|
|
|
|
}
|
|
|
|
|
#endif // ! __i386__
|
2007-02-27 09:52:01 +00:00
|
|
|
|
|
|
|
|
|
bool HOST_INFO::users_idle(bool check_all_logins, double idle_time_to_run, double *actual_idle_time) {
|
|
|
|
|
double idleTime = GetOSXIdleTime();
|
|
|
|
|
|
|
|
|
|
if (actual_idle_time)
|
|
|
|
|
*actual_idle_time = idleTime;
|
|
|
|
|
return (idleTime > (60 * idle_time_to_run));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#else // ! __APPLE__
|
2007-02-23 13:30:33 +00:00
|
|
|
|
|
2004-06-29 19:54:50 +00:00
|
|
|
|
bool HOST_INFO::users_idle(bool check_all_logins, double idle_time_to_run) {
|
2004-06-15 00:46:59 +00:00
|
|
|
|
#ifdef HAVE__DEV_TTY1
|
2004-06-12 05:44:28 +00:00
|
|
|
|
char device_tty[] = "/dev/tty1";
|
2004-06-15 00:46:59 +00:00
|
|
|
|
#endif
|
2004-06-29 19:54:50 +00:00
|
|
|
|
time_t idle_time = time(NULL) - (long) (60 * idle_time_to_run);
|
|
|
|
|
return true
|
2004-06-15 23:56:17 +00:00
|
|
|
|
#ifdef HAVE_UTMP_H
|
2004-06-15 00:46:59 +00:00
|
|
|
|
&& (!check_all_logins || all_logins_idle(idle_time))
|
2004-06-15 23:56:17 +00:00
|
|
|
|
#endif
|
2004-06-12 05:44:28 +00:00
|
|
|
|
#ifdef HAVE__DEV_MOUSE
|
|
|
|
|
&& device_idle(idle_time, "/dev/mouse") // solaris, linux
|
|
|
|
|
#endif
|
|
|
|
|
#ifdef HAVE__DEV_KBD
|
|
|
|
|
&& device_idle(idle_time, "/dev/kbd") // solaris
|
|
|
|
|
#endif
|
|
|
|
|
#ifdef HAVE__DEV_TTY1
|
2004-06-15 00:46:59 +00:00
|
|
|
|
&& (check_all_logins || all_tty_idle(idle_time, device_tty, '1', 7))
|
2004-06-12 05:44:28 +00:00
|
|
|
|
#endif
|
2005-03-11 13:08:52 +00:00
|
|
|
|
|
2004-06-12 05:44:28 +00:00
|
|
|
|
;
|
|
|
|
|
}
|
2004-06-15 00:46:59 +00:00
|
|
|
|
|
2007-02-27 09:52:01 +00:00
|
|
|
|
#endif // ! __APPLE__
|
2004-12-08 00:40:19 +00:00
|
|
|
|
|
2005-01-02 18:29:53 +00:00
|
|
|
|
const char *BOINC_RCSID_2cf92d205b = "$Id$";
|