diff --git a/checkin_notes b/checkin_notes index 879b163f1c..4f02190740 100755 --- a/checkin_notes +++ b/checkin_notes @@ -4144,7 +4144,7 @@ Erik May 13 2003 test/ test_uc.php -Erik May 15 2003 +Erik May 14 2003 - added function to "reset" project (stop all current activities and delete everything except sticky files) - added function to "detach" from project (the above, plus @@ -4159,3 +4159,16 @@ Erik May 15 2003 util.C test/ test_uc.php + +Erik May 15 2003 + - added cmdline options for show/detach/reset project + - -update_prefs command now takes a URL + - added license text to some files + + client/ + account.C + client_state.C,h + lib/ + util.C + doc/ + client.html diff --git a/client/account.C b/client/account.C index e21469e57a..21ef8f7a38 100644 --- a/client/account.C +++ b/client/account.C @@ -63,8 +63,8 @@ int CLIENT_STATE::add_project(char* master_url, char* authenticator) { project = new PROJECT; strcpy(project->master_url, master_url); strcpy(project->authenticator, authenticator); - // Strip any whitespace out of the authenticator strip_whitespace(project->authenticator); + project->tentative = true; retval = project->write_account_file(); if (retval) return retval; @@ -85,88 +85,3 @@ int CLIENT_STATE::add_project(char* master_url, char* authenticator) { projects.push_back(project); return 0; } - -#if 0 -// Wrong approach. -// The user must detach and reattach. -// In any case the following has a major bug: -// the call to remove_project_dir() won't work because -// it gets the new, not the old, project URL -// -int CLIENT_STATE::change_project( - int index, char* master_url, char* authenticator -) { - char path[256]; - PROJECT* project; - FILE* f; - int retval; - - // check if this project is already running - // - if (lookup_project(master_url)) return -1; - - // delete old account file - // - project = projects[index]; - get_account_filename(project->master_url, path); - retval = file_delete(path); - - // create project state - // - retval = write_account_file(master_url, authenticator); - if (retval) return retval; - get_account_filename(master_url, path); - f = fopen(path, "r"); - if (!f) return ERR_FOPEN; - retval = project->parse_account(f); - fclose(f); - if (retval) return retval; - - // remove any old files - retval = remove_project_dir(*project); - - retval = make_project_dir(*project); - if(retval) { - return retval; - } - return 0; -} - -// TODO: see if any activities are in progress for this project, and stop them -// -int CLIENT_STATE::quit_project(PROJECT* project) { - PROJECT* p; - vector ::iterator iter; - char path[256]; - int retval; - - // find project and remove it from the vector - // - for (iter = projects.begin(); iter != projects.end(); iter++) { - p = *iter; - if (p == project) { - projects.erase(iter); - break; - } - } - - // delete account file - // - get_account_filename(project->master_url, path); - retval = file_delete(path); - - // if tentative, there are no activities so we can safely delete everything - // - if (project->tentative) { - // remove project directory and its contents - // - remove_project_dir(*project); - delete project; - } else { -#ifdef _WIN32 - AfxMessageBox("Please restart the client to complete the quit.", MB_OK, 0); -#endif - } - return 0; -} -#endif diff --git a/client/account.h b/client/account.h index 95d104cfee..51b789bbaf 100644 --- a/client/account.h +++ b/client/account.h @@ -1,3 +1,22 @@ +// The contents of this file are subject to the Mozilla 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://www.mozilla.org/MPL/ +// +// 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): +// + #ifndef _ACCOUNT_ #define _ACCOUNT_ diff --git a/client/client_state.C b/client/client_state.C index b683eddf11..a552c585ef 100644 --- a/client/client_state.C +++ b/client/client_state.C @@ -66,7 +66,6 @@ CLIENT_STATE::CLIENT_STATE() { scheduler_op = new SCHEDULER_OP(http_ops); client_state_dirty = false; exit_when_idle = false; - update_prefs = false; run_cpu_benchmarks = false; skip_cpu_benchmarks = false; file_xfer_giveup_period = PERS_GIVEUP; @@ -81,6 +80,8 @@ CLIENT_STATE::CLIENT_STATE() { user_idle = true; use_http_proxy = false; use_socks_proxy = false; + show_projects = false; + strcpy(detach_project_url, ""); strcpy(proxy_server_name, ""); proxy_server_port = 80; strcpy(socks_user_name, ""); @@ -168,6 +169,7 @@ void CLIENT_STATE::install_global_prefs() { int CLIENT_STATE::init() { int retval; unsigned int i; + char buf[256]; srand(time(NULL)); @@ -201,7 +203,60 @@ int CLIENT_STATE::init() { print_summary(); } - show_message(NULL, "Starting BOINC client", MSG_INFO); + if (show_projects) { + printf("projects:\n"); + for (i=0; imaster_url, projects[i]->project_name + ); + } + exit(0); + } + + if (strlen(detach_project_url)) { + PROJECT* project = lookup_project(detach_project_url); + if (project) { + detach_project(project); + } else { + printf("project %s not found\n", detach_project_url); + } + exit(0); + } + + if (strlen(reset_project_url)) { + PROJECT* project = lookup_project(reset_project_url); + if (project) { + reset_project(project); + } else { + printf("project %s not found\n", reset_project_url); + } + exit(0); + } + + if (strlen(update_prefs_url)) { + PROJECT* project = lookup_project(update_prefs_url); + if (project) { + project->sched_rpc_pending = true; + } else { + printf("project %s not found\n", update_prefs_url); + } + } + + sprintf(buf, "Starting BOINC client version %d.%02d", + core_client_major_version, core_client_minor_version + ); + show_message(NULL, buf, MSG_INFO); + + if (core_client_major_version != old_major_version) { + sprintf(buf, + "State file has different major version (%d.%02d); resetting projects\n", + old_major_version, old_minor_version + ); + show_message(NULL, buf, MSG_INFO); + for (i=0; isched_rpc_pending = true; - projects[i]->min_rpc_time = 0; - } - } - return 0; } @@ -593,7 +639,6 @@ int CLIENT_STATE::parse_state_file() { PROJECT temp_project, *project; int retval=0; int failnum; - int old_major_vers, old_minor_vers; if (!f) { if (log_flags.state_debug) { @@ -616,11 +661,10 @@ int CLIENT_STATE::parse_state_file() { if (project) { project->copy_state_fields(temp_project); } else { - sprintf(buf, - "Missing account file for project %s. Please attach to project.\n", + fprintf(stderr, + "Project %s found in state file but not prefs.\n", temp_project.master_url ); - show_message(NULL, buf, MSG_ERROR); } } else if (match_tag(buf, "")) { APP* app = new APP; @@ -697,8 +741,8 @@ int CLIENT_STATE::parse_state_file() { } else if (match_tag(buf, "")) { // could put logic here to detect incompatible state files // after core client update - } else if (parse_int(buf, "", old_major_vers)) { - } else if (parse_int(buf, "", old_minor_vers)) { + } else if (parse_int(buf, "", old_major_version)) { + } else if (parse_int(buf, "", old_minor_version)) { } else if (match_tag(buf, "")) { use_http_proxy = true; } else if (parse_str(buf, "", proxy_server_name, sizeof(proxy_server_name))) { @@ -822,21 +866,11 @@ int CLIENT_STATE::write_state_file_if_needed() { } // See if the project specified by master_url already exists -// in the client state record. Ignore trailing backslashes, -// i.e. http://project.com == http://project.com/ +// in the client state record. // PROJECT* CLIENT_STATE::lookup_project(char* master_url) { - int in_len, proj_len, max_len; - // Get the length of the master_url string - // If there's a '/' at the end, ignore it - in_len = strlen(master_url); - if (master_url[strlen(master_url)-1] == '/') in_len--; - for (unsigned int i=0; imaster_url); - if (projects[i]->master_url[strlen(projects[i]->master_url)-1] == '/') proj_len--; - max_len = max(in_len, proj_len); - if (!strncmp(master_url, projects[i]->master_url, max_len)) { + if (!strcmp(master_url, projects[i]->master_url)) { return projects[i]; } } @@ -1310,12 +1344,18 @@ void CLIENT_STATE::parse_cmdline(int argc, char** argv) { // the above options are private (i.e. not shown by -help) + } else if (!strcmp(argv[i], "-attach_project")) { + add_new_project(); + } else if (!strcmp(argv[i], "-show_projects")) { + show_projects = true; + } else if (!strcmp(argv[i], "-detach_project")) { + strcpy(detach_project_url, argv[++i]); + } else if (!strcmp(argv[i], "-reset_project")) { + strcpy(reset_project_url, argv[++i]); } else if (!strcmp(argv[i], "-update_prefs")) { - update_prefs = true; + strcpy(update_prefs_url, argv[++i]); } else if (!strcmp(argv[i], "-run_cpu_benchmarks")) { run_cpu_benchmarks = true; - } else if (!strcmp(argv[i], "-add_new_project")) { - add_new_project(); } else if (!strcmp(argv[i], "-version")) { printf( "%.2f %s\n", MAJOR_VERSION+(MINOR_VERSION/100.0), HOST ); exit(0); @@ -1547,6 +1587,7 @@ int CLIENT_STATE::reset_project(PROJECT* project) { } garbage_collect(); + write_state_file(); return 0; } @@ -1582,6 +1623,7 @@ int CLIENT_STATE::detach_project(PROJECT* project) { // remove_project_dir(*project); delete project; + write_state_file(); return 0; } diff --git a/client/client_state.h b/client/client_state.h index 524203964d..b704b0bb3c 100644 --- a/client/client_state.h +++ b/client/client_state.h @@ -94,13 +94,19 @@ public: int file_xfer_giveup_period; bool user_idle; bool suspend_requested; - bool update_prefs; bool start_saver; bool exit_when_idle; + bool show_projects; bool requested_exit; bool use_http_proxy; bool use_socks_proxy; int proxy_server_port; + char detach_project_url[256]; + // stores URL for -detach_project option + char reset_project_url[256]; + // stores URL for -reset_project option + char update_prefs_url[256]; + // stores URL for -update_prefs option char proxy_server_name[256]; char socks_user_name[256]; char socks_user_passwd[256]; @@ -114,6 +120,8 @@ private: TIME_STATS time_stats; int core_client_major_version; int core_client_minor_version; + int old_major_version; + int old_minor_version; char* platform_name; int nslots; bool skip_cpu_benchmarks; diff --git a/client/message.h b/client/message.h index 6449ce5242..e47710a0af 100644 --- a/client/message.h +++ b/client/message.h @@ -1,3 +1,22 @@ +// The contents of this file are subject to the Mozilla 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://www.mozilla.org/MPL/ +// +// 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): +// + // Show a message, preceded by timestamp and project name // priorities: diff --git a/client/speed_stats.h b/client/speed_stats.h index e8b6050bbb..8b09d4c423 100644 --- a/client/speed_stats.h +++ b/client/speed_stats.h @@ -1,3 +1,22 @@ +// The contents of this file are subject to the Mozilla 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://www.mozilla.org/MPL/ +// +// 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): +// + //#define RUN_TEST #define THOUSAND 1000 diff --git a/client/ss_logic.C b/client/ss_logic.C index 4ccc5bbb32..903ea73ce3 100644 --- a/client/ss_logic.C +++ b/client/ss_logic.C @@ -1,3 +1,22 @@ +// The contents of this file are subject to the Mozilla 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://www.mozilla.org/MPL/ +// +// 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 "client_state.h" #include "ss_logic.h" diff --git a/client/ss_logic.h b/client/ss_logic.h index 7345dd2f59..388c5e23ed 100644 --- a/client/ss_logic.h +++ b/client/ss_logic.h @@ -1,3 +1,22 @@ +// The contents of this file are subject to the Mozilla 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://www.mozilla.org/MPL/ +// +// 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): +// + // BOINC core client screensaver logic. // The basic idea: // when the core client goes into screensaver mode, diff --git a/doc/client.html b/doc/client.html index bec385b63b..a4d8c02ec9 100644 --- a/doc/client.html +++ b/doc/client.html @@ -122,11 +122,38 @@ Otherwise it draws the BOINC logo bouncing around the screen.

The command line client has several options:

-
-add_new_project -
Enroll in a new project. -You will be asked for the project URL and an account ID. + +
-attach_project +
Attach this computer to a new project. +You must have an account with that project. +You will be asked for the project URL and the account ID. + +
-show_projects +
Print a list of projects to which this computer is attached. + +
-detach_project +
Detach this computer from a project. +You will be asked for the project URL. + +
-reset_project +
Clear pending work for a project. +Use this if there is a problem that is preventing +your computer from working. +You will be asked for the project URL. + +
-update_prefs +
+Contact a project's server to obtain new preferences. +You will be asked for the project URL. + +
-run_cpu_benchmarks +
+Run CPU benchmarks. +Do this if you have modified your computer's hardware. +
-help
Show client options. +
-version
Show client version.
diff --git a/lib/util.C b/lib/util.C index 6f008da729..ed377c12ca 100755 --- a/lib/util.C +++ b/lib/util.C @@ -249,16 +249,14 @@ void c2x(char *what) { } void strip_whitespace(char *str) { - int read_pos, write_pos; - read_pos = write_pos = 0; - while(str[read_pos] != 0) { + int read_pos=0, write_pos=0; + while (str[read_pos]) { if (!isspace(str[read_pos])) { - str[write_pos] = str[read_pos]; - write_pos++; + str[write_pos++] = str[read_pos]; } read_pos++; } - str[write_pos] = '\0'; + str[write_pos] = 0; } void unescape_url(char *url) {