From 0f9b83a55bc1ba82d666261ca9c60046ca549563 Mon Sep 17 00:00:00 2001 From: David Anderson Date: Mon, 26 Jun 2006 22:58:24 +0000 Subject: [PATCH] project files svn path=/trunk/boinc/; revision=10517 --- checkin_notes | 25 +++++++++++ client/app_start.C | 2 +- client/client_types.C | 97 +++++++++++++++++++++++++++++++++++++++++++ client/client_types.h | 7 ++++ client/cs_account.C | 14 ++----- client/cs_files.C | 7 ++++ client/cs_statefile.C | 3 ++ client/scheduler_op.C | 10 +---- sched/main.C | 2 + sched/main.h | 1 + sched/server_types.C | 8 ++++ sched/server_types.h | 5 +++ 12 files changed, 162 insertions(+), 19 deletions(-) diff --git a/checkin_notes b/checkin_notes index 05225e8242..4305054cc7 100755 --- a/checkin_notes +++ b/checkin_notes @@ -6859,3 +6859,28 @@ David 26 June 2006 gui_rpc_client_ops.C sched/ server_types.C + +David 26 June 2006 + - Add support for "project files". + These are files that are downloaded to all clients + attached to that project, + but are not associated with an app version, WU or result. + Example: graphics files for use by the BOINC Manager. + - Scheduling server: look for "project_files.xml" in project dir. + If found, include it verbatim in scheduler replies. + Intended to describe "project files" + - core client: parse list of project files in scheduler reply + or client state file. + Create corresponding FILE_INFO and FILE_REF. + Write list to client state file. + When a project file finishes downloading, + create link file(s) for it. + + client/ + client_types.C,h + cs_account.C + cs_statefile.C + scheduler_op.C + sched/ + main.C,h + server_types.C,h diff --git a/client/app_start.C b/client/app_start.C index 896ecdc808..036c0f677d 100644 --- a/client/app_start.C +++ b/client/app_start.C @@ -86,7 +86,7 @@ static void debug_print_argv(char** argv) { static int make_link(const char *existing, const char *new_link) { FILE *fp; - fp = fopen(new_link, "w"); + fp = boinc_fopen(new_link, "w"); if (!fp) return ERR_FOPEN; fprintf(fp, "%s\n", existing); fclose(fp); diff --git a/client/client_types.C b/client/client_types.C index 34f53bd219..67c0c8bf84 100644 --- a/client/client_types.C +++ b/client/client_types.C @@ -89,6 +89,7 @@ void PROJECT::init() { attached_via_acct_mgr = false; strcpy(code_sign_key, ""); user_files.clear(); + project_files.clear(); anticipated_debt = 0; wall_cpu_time_this_period = 0; next_runnable_result = NULL; @@ -260,6 +261,7 @@ int PROJECT::write_state(MIOFILE& out, bool gui_rpc) { " \n%s\n", code_sign_key ); } + write_project_files(out); } out.printf( "\n" @@ -440,6 +442,98 @@ void PROJECT::file_xfer_succeeded(const bool is_upload) { } } +int PROJECT::parse_project_files(FILE* in) { + char buf[256]; + + project_files.clear(); + + while (fgets(buf, 256, in)) { + if (match_tag(buf, "")) return 0; + if (match_tag(buf, "")) { + parse_project_file(in); + } else { + if (log_flags.unparsed_xml) { + msg_printf(0, MSG_ERROR, + "APP::parse(): unrecognized: %s\n", buf + ); + } + } + } + return ERR_XML_PARSE; +} + +int PROJECT::parse_project_file(FILE* in) { + char buf[1024], url[1024]; + FILE_REF fref; + FILE_INFO finfo, *fip; + + while (fgets(buf, 256, in)) { + if (match_tag(buf, "")) { + if (!strlen(fref.open_name)) { + return ERR_XML_PARSE; + } + if (!strlen(finfo.name)) { + return ERR_XML_PARSE; + } + fip = gstate.lookup_file_info(this, finfo.name); + if (fip) { + fip->merge_info(finfo); + fref.file_info = fip; + } else { + fip = new FILE_INFO; + *fip = finfo; + fip->is_project_file = true; + gstate.file_infos.push_back(fip); + fref.file_info = fip; + } + project_files.push_back(fref); + return 0; + } + if (parse_str(buf, "", fref.open_name, sizeof(fref.open_name))) continue; + if (parse_str(buf, "", finfo.name, sizeof(finfo.name))) continue; + if (parse_str(buf, "", url, sizeof(url))) { + finfo.urls.push_back(url); + } + } + return ERR_XML_PARSE; +} + +void PROJECT::write_project_files(MIOFILE& f) { + unsigned int i; + + if (!project_files.size()) return; + f.printf("\n"); + for (i=0; i\n" + " %s\n" + " %s\n" + " \n", + fip->name, + fref.open_name + ); + } + f.printf("\n"); +} + +int PROJECT::link_project_file(FILE_INFO* fip) { + char project_dir[256], path[256]; + unsigned int i; + + get_project_dir(this, project_dir); + for (i=0; i%s/%s\n", project_dir, fip->name); + } + return 0; +} + int APP::parse(MIOFILE& in) { char buf[256]; @@ -488,6 +582,7 @@ FILE_INFO::FILE_INFO() { gzip_when_done = false; signature_required = false; is_user_file = false; + is_project_file = false; pers_file_xfer = NULL; result = NULL; project = NULL; @@ -618,6 +713,7 @@ int FILE_INFO::parse(MIOFILE& in, bool from_server) { else if (match_tag(buf, "")) report_on_rpc = true; else if (parse_bool(buf, "gzip_when_done", gzip_when_done)) continue; else if (match_tag(buf, "")) signature_required = true; + else if (match_tag(buf, "")) is_project_file = true; else if (match_tag(buf, "")) { pfxp = new PERS_FILE_XFER; retval = pfxp->parse(in); @@ -685,6 +781,7 @@ int FILE_INFO::write(MIOFILE& out, bool to_server) { if (report_on_rpc) out.printf(" \n"); if (gzip_when_done) out.printf(" \n"); if (signature_required) out.printf(" \n"); + if (is_user_file) out.printf(" \n"); if (strlen(file_signature)) out.printf(" \n%s\n", file_signature); } for (i=0; i user_files; + std::vector project_files; + // files not specific to apps or work - e.g. icons int parse_preferences_for_user_files(); + int parse_project_files(FILE*); + int parse_project_file(FILE*); + void write_project_files(MIOFILE&); + int link_project_file(FILE_INFO*); // Multiply by this when estimating the CPU time of a result // (based on FLOPs estimated and benchmarks). diff --git a/client/cs_account.C b/client/cs_account.C index 99b0fb0ea7..37315569f4 100644 --- a/client/cs_account.C +++ b/client/cs_account.C @@ -135,16 +135,6 @@ int PROJECT::parse_account(FILE* in) { tentative = true; continue; } -#if 0 - else if (match_tag(buf, "")) { - deletion_policy_priority = true; - continue; - } - else if (match_tag(buf, "")) { - deletion_policy_expire = true; - continue; - } -#endif else if (match_tag(buf, "")) { string foo; retval = copy_element_contents(in, "", foo); @@ -152,6 +142,10 @@ int PROJECT::parse_account(FILE* in) { gui_urls = "\n"+foo+"\n"; continue; } + else if (match_tag(buf, "")) { + parse_project_files(in); + continue; + } else if (match_tag(buf, "")) { retval = copy_element_contents( in, diff --git a/client/cs_files.C b/client/cs_files.C index 629509f940..f8f17d8a30 100644 --- a/client/cs_files.C +++ b/client/cs_files.C @@ -273,6 +273,13 @@ bool CLIENT_STATE::handle_pers_file_xfers() { if (fip->is_user_file) { active_tasks.request_reread_prefs(fip->project); } + + // if it's a project file, make a link in project dir + // + if (fip->is_project_file) { + PROJECT* p = fip->project; + p->link_project_file(fip); + } } iter = pers_file_xfers->pers_file_xfers.erase(iter); delete pfx; diff --git a/client/cs_statefile.C b/client/cs_statefile.C index c1d30a5ffb..4c9d91cc65 100644 --- a/client/cs_statefile.C +++ b/client/cs_statefile.C @@ -284,6 +284,9 @@ int CLIENT_STATE::parse_state_file() { delete rp; } } + } else if (match_tag(buf, "")) { + project->parse_project_files(f); + continue; } else if (match_tag(buf, "")) { retval = host_info.parse(mf); if (retval) { diff --git a/client/scheduler_op.C b/client/scheduler_op.C index 7721d26689..52b4451f60 100644 --- a/client/scheduler_op.C +++ b/client/scheduler_op.C @@ -677,14 +677,6 @@ int SCHEDULER_REPLY::parse(FILE* in, PROJECT* project) { } project->gui_urls = "\n"+foo+"\n"; continue; -#if 0 - } else if (match_tag(buf, "")) { - project->deletion_policy_priority = true; - continue; - } else if (match_tag(buf, "")) { - project->deletion_policy_expire = true; - continue; -#endif } else if (match_tag(buf, "")) { retval = dup_element_contents( in, @@ -831,6 +823,8 @@ int SCHEDULER_REPLY::parse(FILE* in, PROJECT* project) { send_file_list = true; } else if (parse_int(buf, "", scheduler_version)) { continue; + } else if (match_tag(buf, "")) { + retval = project->parse_project_files(in); } else if (strlen(buf)>1){ if (log_flags.unparsed_xml) { msg_printf(0, MSG_ERROR, diff --git a/sched/main.C b/sched/main.C index 4cd64d978a..67644fcb9b 100644 --- a/sched/main.C +++ b/sched/main.C @@ -73,6 +73,7 @@ bool use_files = false; // use disk files for req/reply msgs (for debugging) SCHED_CONFIG config; GUI_URLS gui_urls; +PROJECT_FILES project_files; key_t sema_key; int g_pid; static bool db_opened=false; @@ -301,6 +302,7 @@ int main(int argc, char** argv) { log_messages.set_debug_level(config.sched_debug_level); gui_urls.init(); + project_files.init(); sprintf(path, "%s/code_sign_public", config.key_dir); retval = read_file_malloc(path, code_sign_key); diff --git a/sched/main.h b/sched/main.h index ce0a0a3496..17c10e8585 100644 --- a/sched/main.h +++ b/sched/main.h @@ -24,6 +24,7 @@ extern SCHED_CONFIG config; extern GUI_URLS gui_urls; +extern PROJECT_FILES project_files; extern key_t sema_key; extern int g_pid; diff --git a/sched/server_types.C b/sched/server_types.C index 44fd02d113..9b6a29f961 100644 --- a/sched/server_types.C +++ b/sched/server_types.C @@ -624,6 +624,9 @@ int SCHEDULER_REPLY::write(FILE* fout) { gui_urls.get_gui_urls(user, host, team, buf); fputs(buf, fout); + if (project_files.text) { + fputs(project_files.text, fout); + } end: fprintf(fout, @@ -906,4 +909,9 @@ void GUI_URLS::get_gui_urls(USER& user, HOST& host, TEAM& team, char* buf) { } } +void PROJECT_FILES::init() { + text = 0; + read_file_malloc("../project_files.xml", text); +} + const char *BOINC_RCSID_ea659117b3 = "$Id$"; diff --git a/sched/server_types.h b/sched/server_types.h index 19cb638fb8..c7c0cb3bdb 100644 --- a/sched/server_types.h +++ b/sched/server_types.h @@ -93,6 +93,11 @@ struct GUI_URLS { void get_gui_urls(USER& user, HOST& host, TEAM& team, char*); }; +struct PROJECT_FILES { + char* text; + void init(); +}; + struct IP_RESULT { double report_deadline; double cpu_time_remaining;