// The contents of this file are subject to the BOINC Public License // Version 1.0 (the "License"); you may not use this file except in // compliance with the License. You may obtain a copy of the License at // http://boinc.berkeley.edu/license_1.0.txt // // Software distributed under the License is distributed on an "AS IS" // basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the // License for the specific language governing rights and limitations // under the License. // // The Original Code is the Berkeley Open Infrastructure for Network Computing. // // The Initial Developer of the Original Code is the SETI@home project. // Portions created by the SETI@home project are Copyright (C) 2002 // University of California at Berkeley. All Rights Reserved. // // Contributor(s): // #include #include #if HAVE_UNISTD_H #include #endif #if HAVE_NETDB_H #include #endif #if HAVE_ARPA_INET_H #include #endif #if HAVE_SYS_TYPES_H #include #endif #if HAVE_NETINET_IN_H #include #endif #ifdef _WIN32 #include #endif #include "util.h" #include "parse.h" #include "message.h" #include "error_numbers.h" #include "hostinfo.h" // Reset the host info struct to default values // void clear_host_info(HOST_INFO& host) { host.timezone = 0; // seconds added to local time to get UTC strcpy(host.domain_name, ""); strcpy(host.serialnum, ""); strcpy(host.ip_addr, ""); host.on_frac = 0; host.conn_frac = 0; host.active_frac = 0; host.p_ncpus = 0; strcpy(host.p_vendor, ""); strcpy(host.p_model, ""); host.p_fpops = 0; host.p_iops = 0; host.p_membw = 0; host.p_fpop_err = 0; host.p_iop_err = 0; host.p_membw_err = 0; host.p_calculated = 0; strcpy(host.os_name, ""); strcpy(host.os_version, ""); host.m_nbytes = 0; host.m_cache = 0; host.m_swap = 0; host.d_total = 0; host.d_free = 0; } // Parse the host information, usually from the client state XML file // int HOST_INFO::parse(FILE* in) { char buf[256]; memset(this, 0, sizeof(HOST_INFO)); while (fgets(buf, 256, in)) { if (match_tag(buf, "")) return 0; else if (parse_int(buf, "", timezone)) continue; else if (parse_str(buf, "", domain_name, sizeof(domain_name))) continue; else if (parse_str(buf, "", ip_addr, sizeof(ip_addr))) continue; else if (parse_int(buf, "", p_ncpus)) continue; else if (parse_str(buf, "", p_vendor, sizeof(p_vendor))) continue; else if (parse_str(buf, "", p_model, sizeof(p_model))) continue; else if (parse_double(buf, "", p_fpops)) continue; else if (parse_double(buf, "", p_iops)) continue; else if (parse_double(buf, "", p_membw)) continue; else if (parse_int(buf, "", p_fpop_err)) continue; else if (parse_int(buf, "", p_iop_err)) continue; else if (parse_int(buf, "", p_membw_err)) continue; else if (parse_double(buf, "", p_calculated)) continue; else if (parse_str(buf, "", os_name, sizeof(os_name))) continue; else if (parse_str(buf, "", os_version, sizeof(os_version))) continue; else if (parse_double(buf, "", m_nbytes)) continue; else if (parse_double(buf, "", m_cache)) continue; else if (parse_double(buf, "", m_swap)) continue; else if (parse_double(buf, "", d_total)) continue; else if (parse_double(buf, "", d_free)) continue; else msg_printf(NULL, MSG_ERROR, "HOST_INFO::parse(): unrecognized: %s\n", buf); } return 0; } // Write the host information, usually to the client state XML file // int HOST_INFO::write(FILE* out) { fprintf(out, "\n" " %d\n" " %s\n" " %s\n" " %d\n" " %s\n" " %s\n" " %f\n" " %f\n" " %f\n" " %d\n" " %d\n" " %d\n" " %f\n" " %s\n" " %s\n" " %f\n" " %f\n" " %f\n" " %f\n" " %f\n" "\n", timezone, domain_name, ip_addr, p_ncpus, p_vendor, p_model, p_fpops, p_iops, p_membw, p_fpop_err, p_iop_err, p_membw_err, p_calculated, os_name, os_version, m_nbytes, m_cache, m_swap, d_total, d_free ); return 0; } // CPU benchmarks are run in a separate process, // which communicates its result via a file. // The following functions read and write this file. // int HOST_INFO::parse_cpu_benchmarks(FILE* in) { char buf[256]; fgets(buf, 256, in); while (fgets(buf, 256, in)) { if (match_tag(buf, "")); else if (match_tag(buf, "")) return 0; else if (parse_double(buf, "", p_fpops)) continue; else if (parse_double(buf, "", p_iops)) continue; else if (parse_double(buf, "", p_membw)) continue; else if (parse_int(buf, "", p_fpop_err)) continue; else if (parse_int(buf, "", p_iop_err)) continue; else if (parse_int(buf, "", p_membw_err)) continue; else if (parse_double(buf, "", p_calculated)) continue; else if (parse_double(buf, "", m_cache)) continue; else msg_printf(NULL, MSG_ERROR, "HOST_INFO::parse(): unrecognized: %s\n", buf); } return 0; } int HOST_INFO::write_cpu_benchmarks(FILE* out) { fprintf(out, "\n" " %f\n" " %f\n" " %f\n" " %d\n" " %d\n" " %d\n" " %f\n" " %f\n" "\n", p_fpops, p_iops, p_membw, p_fpop_err, p_iop_err, p_membw_err, p_calculated, m_cache ); return 0; } // Returns the domain of the local host // int get_local_domain_name(char* p, int len) { char buf[256]; if (gethostname(buf, 256)) return -1; struct hostent* he = gethostbyname(buf); if (!he) return -1; safe_strncpy(p, he->h_name, len); return 0; } // Returns the name of the local host // int get_local_ip_addr_str(char* p, int len) { strcpy(p, ""); #if HAVE_NETDB_H || _WIN32 char buf[256]; struct in_addr addr; if (gethostname(buf, 256)) { printf("gethostname() didn't return name\n"); return -1; } struct hostent* he = gethostbyname(buf); if (!he || !he->h_addr_list[0]) { printf("gethostbyname() didn't return any IP addresses\n"); return -1; } memcpy(&addr, he->h_addr_list[0], sizeof(addr)); safe_strncpy(p, inet_ntoa(addr), len); #endif return 0; } // Gets the ip address of the local host // int get_local_ip_addr(int& p) { p = 0; #if HAVE_NETDB_H || _WIN32 char buf[256]; struct in_addr addr; if (gethostname(buf, 256)) return -1; struct hostent* he = gethostbyname(buf); if (!he) return -1; memcpy(&addr, he->h_addr_list[0], sizeof(addr)); p = addr.s_addr; #endif return 0; }