diff --git a/checkin_notes b/checkin_notes index 25e71dfce4..44aa48a3bf 100755 --- a/checkin_notes +++ b/checkin_notes @@ -3658,3 +3658,36 @@ David Mar 4 2003 prefs.inc prefs_edit_action.php project_specific_prefs.inc + +David Mar 5 2003 + - use venue-specific prefs on client side: + - schedule server passes element in scheduler reply + (but only when it passes back new global prefs) + - when parsing global prefs, if find a matching + element, parse its contents and ignore all else + - when passing project-specific prefs to app, + look for matching element + - changed XML syntax of venue-specific prefs: instead of + ..., e.g., use + ... + - added safe_strncpy(): always adds zero byte at end. + Use this instead of strncpy(). + + client/ + app.C + client_state.C,h + cs_scheduler.C + hostinfo.C + prefs.C,h + scheduler_op.C,h + html_users/ + add_venue_action.php + prefs.inc + show_host_detail.php + user.inc + lib/ + parse.C,h + util.C,h + sched/ + Makefile.in + server_types.C diff --git a/client/app.C b/client/app.C index 418ff56c7e..a36eb420a2 100644 --- a/client/app.C +++ b/client/app.C @@ -104,7 +104,8 @@ int ACTIVE_TASK::init(RESULT* rp) { return 0; } -// Start a task in a slot directory. This includes setting up soft links, +// Start a task in a slot directory. +// This includes setting up soft links, // passing preferences, and starting the process // // Current dir is top-level BOINC dir @@ -134,13 +135,13 @@ int ACTIVE_TASK::start(bool first_time) { memset(&aid, 0, sizeof(aid)); - strncpy(aid.user_name, wup->project->user_name, sizeof(aid.user_name)); - strncpy(aid.team_name, wup->project->team_name, sizeof(aid.team_name)); + safe_strncpy(aid.user_name, wup->project->user_name, sizeof(aid.user_name)); + safe_strncpy(aid.team_name, wup->project->team_name, sizeof(aid.team_name)); if (wup->project->project_specific_prefs) { - strncpy( - aid.app_preferences, + extract_venue( wup->project->project_specific_prefs, - sizeof(aid.app_preferences) + gstate.host_venue, + aid.app_preferences ); } aid.user_total_credit = wup->project->user_total_credit; diff --git a/client/client_state.C b/client/client_state.C index 7fcbe08451..741deb5ee0 100644 --- a/client/client_state.C +++ b/client/client_state.C @@ -83,6 +83,7 @@ CLIENT_STATE::CLIENT_STATE() { proxy_server_port = 80; strcpy(socks_user_name,""); strcpy(socks_user_passwd,""); + strcpy(host_venue,""); suspend_requested = false; start_saver = false; #ifdef _WIN32 @@ -104,14 +105,6 @@ int CLIENT_STATE::init() { srand(time(NULL)); - // Read the global preferences file, if it exists. - // - retval = global_prefs.parse_file(); - if (retval) { - printf("No global preferences file; will use defaults.\n"); - } - install_global_prefs(); - // parse account files. // If there are none, prompt user for project URL and create file // @@ -142,13 +135,23 @@ int CLIENT_STATE::init() { print_summary(); } - // Run the time tests and host information check if needed + // Read the global preferences file, if it exists. + // Do this after reading the state file so we know our venue + // + retval = global_prefs.parse_file(host_venue); + if (retval) { + printf("No global preferences file; will use defaults.\n"); + } + install_global_prefs(); // Getting host info is very fast, so we can do it anytime + // get_host_info(host_info); + // running CPU benchmarks is slow, so do it infrequently + // if (gstate.should_run_time_tests()) { - time_tests_start = time(NULL); + time_tests_start = time(0); show_message(NULL, "Running time tests", "low"); #ifdef _WIN32 time_tests_handle = CreateThread( @@ -477,9 +480,6 @@ int CLIENT_STATE::parse_state_file() { int retval=0; int failnum; - global_prefs.confirm_before_connecting = false; - global_prefs.hangup_if_dialed = false; - if (!f) { if (log_flags.state_debug) { printf("No state file; will create one\n"); @@ -579,16 +579,13 @@ int CLIENT_STATE::parse_state_file() { // after core client update } else if (match_tag(buf, "")) { } else if (match_tag(buf, "")) { - } else if (match_tag(buf, "")) { - global_prefs.confirm_before_connecting = true; - } else if (match_tag(buf, "")) { - global_prefs.hangup_if_dialed = true; } else if (match_tag(buf, "")) { use_http_proxy = true; } else if (parse_str(buf, "", proxy_server_name, sizeof(proxy_server_name))) { } else if (parse_int(buf, "", proxy_server_port)) { } else if (parse_str(buf, "", socks_user_name, sizeof(socks_user_name))) { } else if (parse_str(buf, "", socks_user_passwd, sizeof(socks_user_passwd))) { + } else if (parse_str(buf, "", host_venue, sizeof(host_venue))) { } else { fprintf(stderr, "CLIENT_STATE::parse_state_file: unrecognized: %s\n", buf); } @@ -647,11 +644,9 @@ int CLIENT_STATE::write_state_file() { core_client_minor_version ); - // save proxy and preferences info + // save proxy info // fprintf(f, - "%s" - "%s" "%s" "%s" "%s\n" @@ -660,13 +655,14 @@ int CLIENT_STATE::write_state_file() { "%s\n", use_http_proxy?"\n":"", use_socks_proxy?"\n":"", - global_prefs.confirm_before_connecting?"\n":"", - global_prefs.hangup_if_dialed?"\n":"", proxy_server_name, proxy_server_port, socks_user_name, socks_user_passwd ); + if (strlen(host_venue)) { + fprintf(f, "%s\n", host_venue); + } fprintf(f, "\n"); fclose(f); retval = boinc_rename(STATE_FILE_TEMP, STATE_FILE_NAME); @@ -1300,7 +1296,6 @@ int CLIENT_STATE::report_project_error( strcat(res.stderr_out, total_err ); } } - if (res.state == RESULT_NEW) { for (i=0;iinput_files.size();i++) { diff --git a/client/client_state.h b/client/client_state.h index d7884146a3..4944ffe3d2 100644 --- a/client/client_state.h +++ b/client/client_state.h @@ -100,7 +100,8 @@ public: char proxy_server_name[256]; char socks_user_name[256]; char socks_user_passwd[256]; - + char host_venue[256]; // venue, as reported by project that sent us + // most recent global prefs private: bool client_state_dirty; diff --git a/client/cs_scheduler.C b/client/cs_scheduler.C index 8c025544ab..d9f096dde9 100644 --- a/client/cs_scheduler.C +++ b/client/cs_scheduler.C @@ -382,7 +382,8 @@ int CLIENT_STATE::handle_scheduler_reply( sr.global_prefs_xml ); fclose(f); - global_prefs.parse_file(); + safe_strncpy(host_venue, sr.host_venue, sizeof(host_venue)); + global_prefs.parse_file(host_venue); install_global_prefs(); } diff --git a/client/hostinfo.C b/client/hostinfo.C index dc25d39c33..13d3936570 100644 --- a/client/hostinfo.C +++ b/client/hostinfo.C @@ -40,6 +40,7 @@ #include #endif +#include "util.h" #include "parse.h" #include "hostinfo.h" #include "error_numbers.h" @@ -198,7 +199,7 @@ int get_local_domain_name(char* p, int len) { gethostname(buf, 256); struct hostent* he = gethostbyname(buf); if (!he) return -1; - strncpy(p, he->h_name, len); + safe_strncpy(p, he->h_name, len); return 0; } diff --git a/client/prefs.C b/client/prefs.C index 5f5006bf4d..7436aa1422 100644 --- a/client/prefs.C +++ b/client/prefs.C @@ -33,7 +33,7 @@ // the following values determine how the client behaves // if there are no global prefs yet // -GLOBAL_PREFS::GLOBAL_PREFS() { +void GLOBAL_PREFS::init() { run_on_batteries = true; run_if_user_active = true; run_minimized = false; @@ -50,12 +50,47 @@ GLOBAL_PREFS::GLOBAL_PREFS() { max_bytes_sec_down = 1e9; }; -// Parse XML global prefs +GLOBAL_PREFS::GLOBAL_PREFS() { + init(); +} + +// Parse XML global prefs. +// If host_venue is nonempty and we find an element of the form +// +// ... +// +// then parse that and ignore the rest. +// Otherwise ignore elements. // -int GLOBAL_PREFS::parse(FILE* in) { - char buf[256]; +int GLOBAL_PREFS::parse(FILE* in, char* host_venue) { + char buf[256], buf2[256]; + bool in_venue = false, in_correct_venue=false; while (fgets(buf, 256, in)) { + if (in_venue) { + if (match_tag(buf, "")) { + if (in_correct_venue) { + return 0; + } else { + in_venue = false; + continue; + } + } else { + if(!in_correct_venue) continue; + } + } else { + if (match_tag(buf, "")) { return 0; } else if (match_tag(buf, "")) { @@ -86,10 +121,10 @@ int GLOBAL_PREFS::parse(FILE* in) { } else if (parse_double(buf, "", idle_time_to_run)) { continue; } else if (parse_double(buf, "", max_bytes_sec_up)) { - if (max_bytes_sec_up <= 0) max_bytes_sec_up = 1e9; + if (max_bytes_sec_up <= 0) max_bytes_sec_up = 1e12; continue; } else if (parse_double(buf, "", max_bytes_sec_down)) { - if (max_bytes_sec_down <= 0) max_bytes_sec_down = 1e9; + if (max_bytes_sec_down <= 0) max_bytes_sec_down = 1e12; continue; } } @@ -98,13 +133,13 @@ int GLOBAL_PREFS::parse(FILE* in) { // Parse global prefs file // -int GLOBAL_PREFS::parse_file() { +int GLOBAL_PREFS::parse_file(char* host_venue) { FILE* f; int retval; f = fopen(GLOBAL_PREFS_FILE_NAME, "r"); if (!f) return ERR_FOPEN; - retval = parse(f); + retval = parse(f, host_venue); fclose(f); return retval; } diff --git a/client/prefs.h b/client/prefs.h index b53faa70d4..4e114ab6b1 100644 --- a/client/prefs.h +++ b/client/prefs.h @@ -50,8 +50,9 @@ struct GLOBAL_PREFS { double max_bytes_sec_down; GLOBAL_PREFS(); - int parse(FILE*); - int parse_file(); + void init(); + int parse(FILE*, char* venue); + int parse_file(char* venue); }; #endif diff --git a/client/scheduler_op.C b/client/scheduler_op.C index fd0352bc8a..5ac1b98f76 100644 --- a/client/scheduler_op.C +++ b/client/scheduler_op.C @@ -507,6 +507,7 @@ int SCHEDULER_REPLY::parse(FILE* in) { strcpy(user_name, ""); user_total_credit = 0; user_expavg_credit = 0; + strcpy(host_venue, ""); user_create_time = 0; code_sign_key = 0; code_sign_key_signature = 0; @@ -535,6 +536,7 @@ int SCHEDULER_REPLY::parse(FILE* in) { else if (parse_int(buf, "", hostid)) continue; else if (parse_double(buf, "", host_total_credit)) continue; else if (parse_double(buf, "", host_expavg_credit)) continue; + else if (parse_str(buf, "", host_venue, sizeof(host_venue))) continue; else if (parse_int(buf, "", (int &)host_create_time)) continue; else if (parse_int(buf, "", request_delay)) continue; else if (match_tag(buf, "")) { diff --git a/client/scheduler_op.h b/client/scheduler_op.h index 3ff12f501b..51f90e8c64 100644 --- a/client/scheduler_op.h +++ b/client/scheduler_op.h @@ -106,6 +106,7 @@ struct SCHEDULER_REPLY { char user_name[256],team_name[256]; double user_total_credit; double user_expavg_credit; + char host_venue[256]; unsigned int user_create_time; vector apps; vector file_infos; diff --git a/html/user/add_venue_action.php b/html/user/add_venue_action.php index e60dae7ed7..2da4b739c5 100644 --- a/html/user/add_venue_action.php +++ b/html/user/add_venue_action.php @@ -24,7 +24,7 @@ $prefs->$venue = $new_prefs; $retval = project_prefs_update($user, $prefs); } - if (retval) { + if ($retval) { Header("Location: prefs.php?subset=$subset"); } else { db_error_page(); diff --git a/html/user/host_venue_action.php b/html/user/host_venue_action.php new file mode 100644 index 0000000000..e1651ebe64 --- /dev/null +++ b/html/user/host_venue_action.php @@ -0,0 +1,33 @@ +userid != $user->id) { + echo "Not your host\n"; + exit(); + } + + $retval = mysql_query("update host set venue='$venue' where id = $hostid"); + if ($retval) { + Header("Location: show_host_detail.php?hostid=$hostid"); + } else { + db_error_page(); + } +?> diff --git a/html/user/prefs.inc b/html/user/prefs.inc index 4fa28ee5ee..7a455feecf 100644 --- a/html/user/prefs.inc +++ b/html/user/prefs.inc @@ -44,6 +44,7 @@ global $text; global $parse_result; global $top_parse_result; global $in_project_specific; +global $venue_name; // functions to parse preferences XML into a struct // @@ -52,11 +53,11 @@ function element_start_project($parser, $name, $attrs) { global $parse_result; global $text; global $in_project_specific; + global $venue_name; switch($name) { - case "home": - case "school": - case "work": + case "venue": + $venue_name = $attrs["name"]; $top_parse_result = $parse_result; $parse_result = null; break; @@ -77,11 +78,11 @@ function element_start_global($parser, $name, $attrs) { global $top_parse_result; global $parse_result; global $text; + global $venue_name; switch($name) { - case "home": - case "school": - case "work": + case "venue": + $venue_name = $attrs["name"]; $top_parse_result = $parse_result; $parse_result = null; break; @@ -94,12 +95,11 @@ function element_end_project($parser, $name) { global $parse_result; global $in_project_specific; global $top_parse_result; + global $venue_name; switch($name) { - case "home": - case "school": - case "work": - $top_parse_result->$name = $parse_result; + case "venue": + $top_parse_result->$venue_name = $parse_result; $parse_result = $top_parse_result; break; case "project_specific": @@ -130,12 +130,11 @@ function element_end_global($parser, $name) { global $text; global $parse_result; global $top_parse_result; + global $venue_name; switch($name) { - case "home": - case "school": - case "work": - $top_parse_result->$name = $parse_result; + case "venue": + $top_parse_result->$venue_name = $parse_result; $parse_result = $top_parse_result; break; case "run_on_batteries": @@ -565,13 +564,13 @@ function global_prefs_make_xml($prefs, $primary=true) { ."$prefs->max_bytes_sec_down\n" ."$prefs->max_bytes_sec_up\n"; if ($prefs->home) { - $xml = $xml."\n".global_prefs_make_xml($prefs->home, false)."\n"; + $xml = $xml."\n".global_prefs_make_xml($prefs->home, false)."\n"; } if ($prefs->work) { - $xml = $xml."\n".global_prefs_make_xml($prefs->work, false)."\n"; + $xml = $xml."\n".global_prefs_make_xml($prefs->work, false)."\n"; } if ($prefs->school) { - $xml = $xml."\n".global_prefs_make_xml($prefs->school, false)."\n"; + $xml = $xml."\n".global_prefs_make_xml($prefs->school, false)."\n"; } if ($primary) { $xml = $xml."\n"; @@ -600,13 +599,13 @@ function project_prefs_make_xml($prefs, $primary=true) { ."\n$x\n\n"; } if ($prefs->home) { - $xml = $xml."\n".project_prefs_make_xml($prefs->home, false)."\n"; + $xml = $xml."\n".project_prefs_make_xml($prefs->home, false)."\n"; } if ($prefs->work) { - $xml = $xml."\n".project_prefs_make_xml($prefs->work, false)."\n"; + $xml = $xml."\n".project_prefs_make_xml($prefs->work, false)."\n"; } if ($prefs->school) { - $xml = $xml."\n".project_prefs_make_xml($prefs->school, false)."\n"; + $xml = $xml."\n".project_prefs_make_xml($prefs->school, false)."\n"; } if ($primary) { $xml = $xml."\n"; diff --git a/html/user/prefs_edit_form.php b/html/user/prefs_edit_form.php new file mode 100644 index 0000000000..e63cf37971 --- /dev/null +++ b/html/user/prefs_edit_form.php @@ -0,0 +1,71 @@ +$title\n"; + +if ($subset == "global") { + $prefs = prefs_parse_global($user->global_prefs); + if ($venue) { + $prefs = $prefs->$venue; + } + echo " + These preferences apply to all the BOINC projects + in which you participate. +
If you participate in multiple BOINC projects, + edit your preferences only one project's web site; +
otherwise edits may be overwritten. + "; +} else { + $prefs = prefs_parse_project($user->project_prefs); + if ($venue) { + $prefs = $prefs->$venue; + } +} + +$x = $venue?"&\$venue=$venue":""; +echo "
+ +"; +if ($venue) { + echo "\n"; +} + +start_table(); +if ($subset == "global") { + prefs_form_global($user, $prefs); +} else { + prefs_form_resource($prefs); + prefs_form_project($prefs->project_specific); + if (!$venue) { + prefs_form_email($prefs); + venue_form($user); + } +} + +row2("
", ""); +end_table(); +echo "
\n"; + +echo "Back to preferences\n"; +page_tail(); + +?> diff --git a/html/user/show_host_detail.php b/html/user/show_host_detail.php index c10539fdda..2f3c7e0b76 100644 --- a/html/user/show_host_detail.php +++ b/html/user/show_host_detail.php @@ -4,10 +4,26 @@ require_once("db.inc"); require_once("user.inc"); -function show_host($host) { +function location_form($host) { + if ($host->venue == "home") $h = "selected"; + if ($host->venue == "work") $w = "selected"; + if ($host->venue == "school") $s = "selected"; + $x = "
+ id> + + +
+ "; + return $x; +} - echo TABLE2."\n"; - echo "".TD2.LG_FONT."Host Information:\n"; +function show_host($host) { + start_table(); + row1("Host Information"); row2("IP address", "$host->last_ip_addr
(same the last $host->nsame_ip_addr times)"); row2("Domain name", $host->domain_name); $x = $host->timezone/3600; @@ -45,22 +61,23 @@ function show_host($host) { $x = $host->n_bwup/(1024); $y = round($x, 2); if ($y > 0) { - row2("Average upload speed", "$y KB/sec"); + row2("Average upload rate", "$y KB/sec"); } else { - row2("Average upload speed", "Unknown"); + row2("Average upload rate", "Unknown"); } $x = $host->n_bwdown/(1024); $y = round($x, 2); if ($y > 0) { - row2("Average download speed", "$y KB/sec"); + row2("Average download rate", "$y KB/sec"); } else { - row2("Average download speed", "Unknown"); + row2("Average download rate", "Unknown"); } row2("Number of times client has contacted server", $host->rpc_seqno); row2("Last time contacted server", time_str($host->rpc_time)); - row2("% of time client on", 100*$host->on_frac." %"); - row2("% of time host connected", 100*$host->connected_frac." %"); - row2("% of time user active", 100*$host->active_frac." %"); + row2("% of time client is on", 100*$host->on_frac." %"); + row2("% of time host is connected", 100*$host->connected_frac." %"); + row2("% of time user is active", 100*$host->active_frac." %"); + row2("Location", location_form($host)); echo "\n"; } diff --git a/html/user/user.inc b/html/user/user.inc index 4e443f6ca7..b592abe253 100644 --- a/html/user/user.inc +++ b/html/user/user.inc @@ -41,7 +41,7 @@ function show_user_profile($user) { function show_hosts($user) { $result = mysql_query("select * from host where userid=$user->id order by rpc_time desc"); - echo VISTABLE."\n"; + start_table(); echo "Host nameTotal CreditRecent credit"; while ($host = mysql_fetch_object($result)) { echo "

\n"; @@ -78,9 +78,11 @@ function show_user_page_private($user) { } function user_table_start() { - echo VISTABLE." + start_table(); + echo " NameAverage creditTotal credit - Participant since"; + Participant since + "; } function show_user_row($user) { diff --git a/lib/parse.C b/lib/parse.C index 051931c3f6..f695c44ef8 100644 --- a/lib/parse.C +++ b/lib/parse.C @@ -31,8 +31,9 @@ #include #include -#include "parse.h" #include "error_numbers.h" +#include "util.h" +#include "parse.h" // return true if the tag appears in the line // @@ -70,7 +71,7 @@ bool parse_str(char* buf, char* tag, char* dest, int len) { char* q = strchr(p+1, '<'); if (!q) return false; *q = 0; - strncpy(dest, p+1, len); + safe_strncpy(dest, p+1, len); dest[len-1] = 0; *q = '<'; return true; @@ -89,7 +90,7 @@ void parse_attr(char* buf, char* name, char* dest, int len) { q = strchr(p+1, '"'); if (!q) return; *q = 0; - strncpy(dest, p+1, len); + safe_strncpy(dest, p+1, len); dest[len-1] = 0; } @@ -164,6 +165,7 @@ int read_file_malloc(char* pathname, char*& str) { } +#if 0 // replace XML element contents. not currently used // void replace_element(char* buf, char* start, char* end, char* replacement) { @@ -176,4 +178,33 @@ void replace_element(char* buf, char* start, char* end, char* replacement) { strcpy(p, replacement); strcat(p, temp); } +#endif +// if the given XML has an element of the form +// +// ... +// +// then return the contents of that element. +// Otherwise strip out all elements +// +void extract_venue(char* in, char* venue_name, char* out) { + char* p, *q; + char buf[256]; + sprintf(buf, "", venue_name); + p = strstr(in, buf); + if (p) { + p += strlen(buf); + strcpy(out, p); + q = strstr(out, "\n"); + if (!q) break; + strcpy(p, q+strlen("\n")); + } + } +} diff --git a/lib/parse.h b/lib/parse.h index 80f1e751a3..576988f21a 100644 --- a/lib/parse.h +++ b/lib/parse.h @@ -30,4 +30,7 @@ extern void strcatdup(char*& p, char* buf); extern int dup_element_contents(FILE* in, char* end_tag, char** pp); extern int copy_element_contents(FILE* in, char* end_tag, char* p, int len); extern int read_file_malloc(char* pathname, char*& str); +#if 0 extern void replace_element(char* buf, char* start, char* end, char* replacement); +#endif +extern void extract_venue(char* in, char* venue_name, char* out); diff --git a/lib/util.C b/lib/util.C index 048637564a..f68bfd3c7c 100755 --- a/lib/util.C +++ b/lib/util.C @@ -279,3 +279,7 @@ void escape_url(char *in, char*out) { out[y] = 0; } +void safe_strncpy(char* dst, char* src, int len) { + strncpy(dst, src, len); + dst[len-1]=0; +} diff --git a/lib/util.h b/lib/util.h index e5a34af1d2..2db3c6f8c8 100755 --- a/lib/util.h +++ b/lib/util.h @@ -27,6 +27,7 @@ extern int lock_file(char*); extern double drand(); extern void unescape_url(char *url); extern void escape_url(char *in, char*out); +extern void safe_strncpy(char*, char*, int); #ifndef max #define max(a,b) (((a) > (b)) ? (a) : (b)) diff --git a/sched/Makefile.in b/sched/Makefile.in index bbc43b41db..3385bec8e7 100644 --- a/sched/Makefile.in +++ b/sched/Makefile.in @@ -31,6 +31,7 @@ CGI_OBJS = \ ../db/db_mysql.o \ ../db/mysql_util.o \ ../lib/shmem.o \ + ../lib/util.o \ ../lib/parse.o FEEDER_OBJS = \ @@ -49,6 +50,7 @@ SHOW_SHMEM_OBJS = \ config.o \ ../db/db_mysql.o \ ../db/mysql_util.o \ + ../lib/util.o \ ../lib/parse.o \ ../lib/shmem.o @@ -56,6 +58,7 @@ FILE_UPLOAD_OBJS = \ file_upload_handler.o \ config.o \ ../lib/crypt.o \ + ../lib/util.o \ ../lib/parse.o \ ../lib/md5.o \ ../lib/md5_file.o \ @@ -124,6 +127,7 @@ DB_DUMP_OBJS = \ db_dump.o START_SERVERS_OBJS = \ + ../lib/util.o \ ../lib/parse.o \ config.o \ start_servers.o diff --git a/sched/server_types.C b/sched/server_types.C index 89af999530..90ef454207 100644 --- a/sched/server_types.C +++ b/sched/server_types.C @@ -145,13 +145,15 @@ int SCHEDULER_REPLY::write(FILE* fout) { "%f\n" "%d\n" "%f\n" - "%f\n", + "%f\n" + "%s\n", user.name, user.total_credit, user.expavg_credit, user.create_time, host.total_credit, - host.expavg_credit + host.expavg_credit, + host.venue ); // might want to send team credit too.