// This file is part of BOINC.
// http://boinc.berkeley.edu
// Copyright (C) 2008 University of California
//
// BOINC 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 3 of the License, or (at your option) any later version.
//
// BOINC 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.
//
// You should have received a copy of the GNU Lesser General Public License
// along with BOINC. If not, see .
// This file contains:
// 1) functions to clear and parse the various structs
// 2) actual GUI RPCs
// The core client expects all data to be formatted in the "C" locale,
// so each GUI RPC should get the current locale, then switch to the
// "C" locale before formatting messages or parsing results.
// After all work is completed, revert back to the original locale.
//
// Template:
//
// int RPC_CLIENT::template_function( args ) {
// int retval;
// SET_LOCALE sl;
// char buf[256];
// RPC rpc(this);
//
//
//
// return retval;
// }
//
// NOTE: Failing to revert back to the original locale will cause
// formatting failures for any software that has been localized or
// displays localized data.
#if defined(_WIN32) && !defined(__STDWX_H__) && !defined(_BOINC_WIN_) && !defined(_AFX_STDAFX_H_)
#include "boinc_win.h"
#endif
#ifdef _MSC_VER
#define snprintf _snprintf
#endif
#ifdef _WIN32
#include "../version.h"
#else
#include "config.h"
#include
#include
#include
#include
#include
#include
#include
#include
#include
#endif
#include "diagnostics.h"
#include "parse.h"
#include "str_util.h"
#include "util.h"
#include "error_numbers.h"
#include "miofile.h"
#include "md5_file.h"
#include "network.h"
#include "common_defs.h"
#include "gui_rpc_client.h"
using std::string;
using std::vector;
using std::sort;
int TIME_STATS::parse(XML_PARSER& xp) {
memset(this, 0, sizeof(TIME_STATS));
while (!xp.get_tag()) {
if (xp.match_tag("/time_stats")) return 0;
if (xp.parse_double("now", now)) continue;
if (xp.parse_double("on_frac", on_frac)) continue;
if (xp.parse_double("connected_frac", connected_frac)) continue;
if (xp.parse_double("cpu_and_network_available_frac", cpu_and_network_available_frac)) continue;
if (xp.parse_double("active_frac", active_frac)) continue;
if (xp.parse_double("gpu_active_frac", gpu_active_frac)) continue;
if (xp.parse_double("client_start_time", client_start_time)) continue;
if (xp.parse_double("previous_uptime", previous_uptime)) continue;
}
return ERR_XML_PARSE;
}
int DAILY_XFER::parse(XML_PARSER& xp) {
while (!xp.get_tag()) {
if (xp.match_tag("/dx")) return 0;
if (xp.parse_int("when", when)) continue;
if (xp.parse_double("up", up)) continue;
if (xp.parse_double("down", down)) continue;
}
return ERR_XML_PARSE;
}
int DAILY_XFER_HISTORY::parse(XML_PARSER& xp) {
while (!xp.get_tag()) {
if (!xp.is_tag) continue;
if (xp.match_tag("dx")) {
DAILY_XFER dx;
int retval = dx.parse(xp);
if (!retval) {
daily_xfers.push_back(dx);
}
}
}
return 0;
}
int GUI_URL::parse(XML_PARSER& xp) {
while (!xp.get_tag()) {
if (!xp.is_tag) continue;
if (xp.match_tag("/gui_url")) return 0;
if (xp.match_tag("/gui_urls")) break;
if (xp.parse_string("name", name)) continue;
if (xp.parse_string("description", description)) continue;
if (xp.parse_string("url", url)) continue;
}
return ERR_XML_PARSE;
}
PROJECT_LIST_ENTRY::PROJECT_LIST_ENTRY() {
clear();
}
PROJECT_LIST_ENTRY::~PROJECT_LIST_ENTRY() {
clear();
}
int PROJECT_LIST_ENTRY::parse(XML_PARSER& xp) {
string platform;
while (!xp.get_tag()) {
if (xp.match_tag("/project")) return 0;
if (xp.parse_string("name", name)) continue;
if (xp.parse_string("url", url)) {
continue;
}
if (xp.parse_string("general_area", general_area)) continue;
if (xp.parse_string("specific_area", specific_area)) continue;
if (xp.parse_string("description", description)) {
continue;
}
if (xp.parse_string("home", home)) continue;
if (xp.parse_string("image", image)) continue;
if (xp.match_tag("platforms")) {
while (!xp.get_tag()) {
if (xp.match_tag("/platforms")) break;
if (xp.parse_string("name", platform)) {
platforms.push_back(platform);
}
}
}
xp.skip_unexpected(false, "");
}
return ERR_XML_PARSE;
}
void PROJECT_LIST_ENTRY::clear() {
name.clear();
url.clear();
general_area.clear();
specific_area.clear();
description.clear();
platforms.clear();
home.clear();
image.clear();
}
AM_LIST_ENTRY::AM_LIST_ENTRY() {
clear();
}
AM_LIST_ENTRY::~AM_LIST_ENTRY() {
clear();
}
int AM_LIST_ENTRY::parse(XML_PARSER& xp) {
while (!xp.get_tag()) {
if (xp.match_tag("/account_manager")) return 0;
if (xp.parse_string("name", name)) continue;
if (xp.parse_string("url", url)) continue;
if (xp.parse_string("description", description)) continue;
if (xp.parse_string("image", image)) continue;
}
return 0;
}
void AM_LIST_ENTRY::clear() {
name.clear();
url.clear();
description.clear();
image.clear();
}
ALL_PROJECTS_LIST::ALL_PROJECTS_LIST() {
}
ALL_PROJECTS_LIST::~ALL_PROJECTS_LIST() {
clear();
}
bool compare_project_list_entry(
const PROJECT_LIST_ENTRY* a, const PROJECT_LIST_ENTRY* b
) {
#ifdef _WIN32
return _stricmp(a->name.c_str(), b->name.c_str()) < 0;
#else
return strcasecmp(a->name.c_str(), b->name.c_str()) < 0;
#endif
}
bool compare_am_list_entry(const AM_LIST_ENTRY* a, const AM_LIST_ENTRY* b) {
#ifdef _WIN32
return _stricmp(a->name.c_str(), b->name.c_str()) < 0;
#else
return strcasecmp(a->name.c_str(), b->name.c_str()) < 0;
#endif
}
void ALL_PROJECTS_LIST::alpha_sort() {
sort(projects.begin(), projects.end(), compare_project_list_entry);
sort(account_managers.begin(), account_managers.end(), compare_am_list_entry);
}
void ALL_PROJECTS_LIST::clear() {
unsigned int i;
for (i=0; i", buf);
stderr_out = buf;
continue;
}
#endif
if (xp.parse_int("app_version_num", app_version_num)) continue;
if (xp.parse_int("slot", slot)) continue;
if (xp.parse_int("pid", pid)) continue;
if (xp.parse_double("checkpoint_cpu_time", checkpoint_cpu_time)) continue;
if (xp.parse_double("current_cpu_time", current_cpu_time)) continue;
if (xp.parse_double("elapsed_time", elapsed_time)) continue;
if (xp.parse_double("swap_size", swap_size)) continue;
if (xp.parse_double("working_set_size_smoothed", working_set_size_smoothed)) continue;
if (xp.parse_double("fraction_done", fraction_done)) continue;
if (xp.parse_double("estimated_cpu_time_remaining", estimated_cpu_time_remaining)) continue;
if (xp.parse_bool("too_large", too_large)) continue;
if (xp.parse_bool("needs_shmem", needs_shmem)) continue;
if (xp.parse_bool("edf_scheduled", edf_scheduled)) continue;
if (xp.parse_str("graphics_exec_path", graphics_exec_path, sizeof(graphics_exec_path))) continue;
if (xp.parse_str("web_graphics_url", web_graphics_url, sizeof(web_graphics_url))) continue;
if (xp.parse_str("remote_desktop_addr", remote_desktop_addr, sizeof(remote_desktop_addr))) continue;
if (xp.parse_str("slot_path", slot_path, sizeof(slot_path))) continue;
if (xp.parse_str("resources", resources, sizeof(resources))) continue;
}
return ERR_XML_PARSE;
}
void RESULT::clear() {
strcpy(name, "");
strcpy(wu_name, "");
version_num = 0;
strcpy(plan_class, "");
strcpy(project_url, "");
strcpy(graphics_exec_path, "");
strcpy(web_graphics_url, "");
strcpy(remote_desktop_addr, "");
strcpy(slot_path, "");
strcpy(resources, "");
report_deadline = 0;
received_time = 0;
ready_to_report = false;
got_server_ack = false;
final_cpu_time = 0;
final_elapsed_time = 0;
state = 0;
scheduler_state = 0;
exit_status = 0;
signal = 0;
//stderr_out.clear();
suspended_via_gui = false;
project_suspended_via_gui = false;
coproc_missing = false;
scheduler_wait = false;
strcpy(scheduler_wait_reason, "");
network_wait = false;
active_task = false;
active_task_state = 0;
app_version_num = 0;
slot = -1;
pid = 0;
checkpoint_cpu_time = 0;
current_cpu_time = 0;
fraction_done = 0;
elapsed_time = 0;
swap_size = 0;
working_set_size_smoothed = 0;
estimated_cpu_time_remaining = 0;
too_large = false;
needs_shmem = false;
edf_scheduled = false;
app = NULL;
wup = NULL;
project = NULL;
avp = NULL;
}
FILE_TRANSFER::FILE_TRANSFER() {
clear();
}
FILE_TRANSFER::~FILE_TRANSFER() {
clear();
}
int FILE_TRANSFER::parse(XML_PARSER& xp) {
while (!xp.get_tag()) {
if (xp.match_tag("/file_transfer")) return 0;
if (xp.parse_string("name", name)) continue;
if (xp.parse_string("project_url", project_url)) continue;
if (xp.parse_string("project_name", project_name)) continue;
if (xp.parse_double("nbytes", nbytes)) continue;
if (xp.parse_bool("sticky", sticky)) continue;
if (xp.match_tag("persistent_file_xfer")) {
pers_xfer_active = true;
continue;
}
if (xp.match_tag("file_xfer")) {
xfer_active = true;
continue;
}
if (xp.parse_bool("is_upload", is_upload)) {
generated_locally = is_upload;
continue;
}
if (xp.parse_bool("generated_locally", generated_locally)) {
is_upload = generated_locally;
}
if (xp.parse_int("num_retries", num_retries)) continue;
if (xp.parse_double("first_request_time", first_request_time)) continue;
if (xp.parse_double("next_request_time", next_request_time)) continue;
if (xp.parse_int("status", status)) continue;
if (xp.parse_double("time_so_far", time_so_far)) continue;
if (xp.parse_double("last_bytes_xferred", bytes_xferred)) continue;
if (xp.parse_double("file_offset", file_offset)) continue;
if (xp.parse_double("xfer_speed", xfer_speed)) continue;
if (xp.parse_string("hostname", hostname)) continue;
if (xp.parse_double("project_backoff", project_backoff)) continue;
}
return ERR_XML_PARSE;
}
void FILE_TRANSFER::clear() {
name.clear();
project_url.clear();
project_name.clear();
nbytes = 0;
sticky = false;
pers_xfer_active = false;
xfer_active = false;
num_retries = 0;
first_request_time = 0;
next_request_time = 0;
status = 0;
time_so_far = 0;
bytes_xferred = 0;
file_offset = 0;
xfer_speed = 0;
hostname.clear();
project = NULL;
project_backoff = 0;
}
MESSAGE::MESSAGE() {
clear();
}
MESSAGE::~MESSAGE() {
clear();
}
int MESSAGE::parse(XML_PARSER& xp) {
char buf[1024];
while (!xp.get_tag()) {
if (xp.match_tag("/msg")) return 0;
if (xp.parse_string("project", project)) continue;
if (xp.match_tag("body")) {
xp.element_contents("