diff --git a/checkin_notes b/checkin_notes index 8d1170f489..8284eaf5e1 100644 --- a/checkin_notes +++ b/checkin_notes @@ -6862,3 +6862,17 @@ David 5 Oct client/ pers_file_xfer.cpp + +David 5 Oct + - GUI RPC: add get_daily_xfer_history() RPC for getting + the daily records of #bytes uploaded and downloaded + + lib/ + gui_rpc_client_print.cpp + gui_rpc_client_ops.cpp + gui_rpc_client.h + client/ + boinc_cmd.cpp + gui_rpc_server_ops.cpp + net_stats.cpp,h + main.cpp diff --git a/client/boinc_cmd.cpp b/client/boinc_cmd.cpp index e0a2b261a0..74f1fce2a1 100644 --- a/client/boinc_cmd.cpp +++ b/client/boinc_cmd.cpp @@ -60,6 +60,7 @@ Commands:\n\ --file_transfer URL filename op file transfer operation\n\ op = retry | abort\n\ --get_cc_status\n\ + --get_daily_xfer_history show network traffic history\n\ --get_disk_usage show disk usage\n\ --get_file_transfers show file transfers\n\ --get_host_info\n\ @@ -227,6 +228,10 @@ int main(int argc, char** argv) { FILE_TRANSFERS ft; retval = rpc.get_file_transfers(ft); if (!retval) ft.print(); + } else if (!strcmp(cmd, "--get_daily_xfer_history")) { + DAILY_XFER_HISTORY dxh; + retval = rpc.get_daily_xfer_history(dxh); + if (!retval) dxh.print(); } else if (!strcmp(cmd, "--get_project_status")) { PROJECTS ps; retval = rpc.get_project_status(ps); diff --git a/client/gui_rpc_server_ops.cpp b/client/gui_rpc_server_ops.cpp index 9012b1ff57..cc3a4da2c5 100644 --- a/client/gui_rpc_server_ops.cpp +++ b/client/gui_rpc_server_ops.cpp @@ -1090,6 +1090,10 @@ static void handle_read_cc_config(GUI_RPC_CONN& grc) { set_no_rsc_config(); } +static void handle_get_daily_xfer_history(GUI_RPC_CONN& grc) { + daily_xfer_history.write_xml(grc.mfout); +} + static bool complete_post_request(char* buf) { if (strncmp(buf, "POST", 4)) return false; char* p = strstr(buf, "Content-Length: "); @@ -1144,6 +1148,8 @@ GUI_RPC gui_rpcs[] = { GUI_RPC("get_all_projects_list", handle_get_all_projects_list, false, false, true), GUI_RPC("get_cc_status", handle_get_cc_status, false, false, true), GUI_RPC("get_disk_usage", handle_get_disk_usage, false, false, true), + GUI_RPC("get_daily_xfer_history", handle_get_daily_xfer_history, + false, false, true), GUI_RPC("get_file_transfers", handle_get_file_transfers, false, false, true), GUI_RPC("get_host_info", handle_get_host_info, false, false, true), GUI_RPC("get_messages", handle_get_messages, false, false, true), diff --git a/client/main.cpp b/client/main.cpp index f7b0c8e2b7..ffd462c2c6 100644 --- a/client/main.cpp +++ b/client/main.cpp @@ -273,7 +273,7 @@ static int finalize() { if (finalized) return 0; finalized = true; gstate.quit_activities(); - daily_xfer_history.write_state(); + daily_xfer_history.write_file(); #ifdef _WIN32 shutdown_idle_monitor(); diff --git a/client/net_stats.cpp b/client/net_stats.cpp index 46353eef6f..e7dba4597a 100644 --- a/client/net_stats.cpp +++ b/client/net_stats.cpp @@ -295,8 +295,8 @@ int DAILY_XFER::parse(XML_PARSER& xp) { return ERR_XML_PARSE; } -void DAILY_XFER::write(FILE* f) { - fprintf(f, +void DAILY_XFER::write(MIOFILE& mf) { + mf.printf( "\n" " %d\n" " %f\n" @@ -368,22 +368,29 @@ void DAILY_XFER_HISTORY::poll() { if (!dirty) return; if (gstate.now - last_time < DAILY_XFER_HISTORY_PERIOD) return; last_time = gstate.now; - write_state(); + write_file(); } - -void DAILY_XFER_HISTORY::write_state() { - FILE* f = fopen(TEMP_FILE_NAME, "w"); - if (!f) return; - fprintf(f, "\n"); +int DAILY_XFER_HISTORY::write_xml(MIOFILE& out) { + out.printf("\n"); for (unsigned int i=0; i\n"); + int n = out.printf("\n"); + if (n != 1) return ERR_FWRITE; + return 0; +} + +void DAILY_XFER_HISTORY::write_file() { + FILE* f = fopen(TEMP_FILE_NAME, "w"); + if (!f) return; + MIOFILE mf; + mf.init_file(f); + int retval = write_xml(mf); fclose(f); - if (n > 0) { - int retval = boinc_rename(TEMP_FILE_NAME, DAILY_XFER_HISTORY_FILENAME); + if (!retval) { + retval = boinc_rename(TEMP_FILE_NAME, DAILY_XFER_HISTORY_FILENAME); if (!retval) { dirty = false; } diff --git a/client/net_stats.h b/client/net_stats.h index 23051c8070..3897b44358 100644 --- a/client/net_stats.h +++ b/client/net_stats.h @@ -123,7 +123,7 @@ struct DAILY_XFER { up = down = 0; } int parse(XML_PARSER&); - void write(FILE*); + void write(MIOFILE&); }; struct DAILY_XFER_HISTORY { @@ -135,7 +135,8 @@ struct DAILY_XFER_HISTORY { void init(); void poll(); void totals(int ndays, double& up, double& down); - void write_state(); + int write_xml(MIOFILE&); + void write_file(); void write_scheduler_request(MIOFILE&, int ndays); DAILY_XFER_HISTORY() { dirty = false; diff --git a/lib/gui_rpc_client.h b/lib/gui_rpc_client.h index cd763c68ed..6e10184fe4 100644 --- a/lib/gui_rpc_client.h +++ b/lib/gui_rpc_client.h @@ -615,8 +615,21 @@ struct SIMPLE_GUI_INFO { void print(); }; -class RPC_CLIENT { -public: +struct DAILY_XFER { + int when; + double up; + double down; + + int parse(XML_PARSER&); +}; + +struct DAILY_XFER_HISTORY { + std::vector daily_xfers; + int parse(XML_PARSER&); + void print(); +}; + +struct RPC_CLIENT { int sock; double start_time; double timeout; @@ -716,7 +729,7 @@ public: int set_global_prefs_override_struct(GLOBAL_PREFS&, GLOBAL_PREFS_MASK&); int get_cc_config(CONFIG& config, LOG_FLAGS& log_flags); int set_cc_config(CONFIG& config, LOG_FLAGS& log_flags); - + int get_daily_xfer_history(DAILY_XFER_HISTORY&); }; struct RPC { @@ -773,7 +786,7 @@ extern int freelocale(locale_t) __attribute__((weak_import)); extern locale_t newlocale(int, __const char *, locale_t) __attribute__((weak_import)); extern locale_t uselocale(locale_t) __attribute__((weak_import)); - struct SET_LOCALE { +struct SET_LOCALE { locale_t old_locale, RPC_locale; std::string locale; inline SET_LOCALE() { @@ -803,4 +816,3 @@ struct SET_LOCALE { extern int read_gui_rpc_password(char*); #endif /* _GUI_RPC_CLIENT_H_ */ - diff --git a/lib/gui_rpc_client_ops.cpp b/lib/gui_rpc_client_ops.cpp index 45af3fb3a6..d6b63b15d9 100644 --- a/lib/gui_rpc_client_ops.cpp +++ b/lib/gui_rpc_client_ops.cpp @@ -75,6 +75,30 @@ using std::string; using std::vector; using std::sort; +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; +} + DISPLAY_INFO::DISPLAY_INFO() { memset(this, 0, sizeof(DISPLAY_INFO)); } @@ -2483,3 +2507,12 @@ int RPC_CLIENT::get_notices_public(int seqno, NOTICES& notices) { return parse_notices(rpc.xp, notices); } +int RPC_CLIENT::get_daily_xfer_history(DAILY_XFER_HISTORY& dxh) { + SET_LOCALE sl; + RPC rpc(this); + int retval; + + retval = rpc.do_rpc("\n"); + if (retval) return retval; + return dxh.parse(rpc.xp); +} diff --git a/lib/gui_rpc_client_print.cpp b/lib/gui_rpc_client_print.cpp index b24ea45811..8801435d27 100644 --- a/lib/gui_rpc_client_print.cpp +++ b/lib/gui_rpc_client_print.cpp @@ -48,6 +48,19 @@ using std::string; using std::vector; +void DAILY_XFER_HISTORY::print() { + for (unsigned int i=0; i