diff --git a/checkin_notes b/checkin_notes index 35069efa4b..228b2188b8 100755 --- a/checkin_notes +++ b/checkin_notes @@ -17332,3 +17332,35 @@ David 12 Sept 2004 ss_logic.C lib/ app_ipc.h + +David 13 Sept 2004 + - Preliminary checkin for "GUI URLs" feature + (allows projects to send URLs to be use as links in GUIs) + This is implemented in a new class GUI_URLS. + Its init() member reads template file. + Its get_gui_urls() member macro-substitutes user/team/host IDs + into the URLs, and produces XML to be included in scheduler replies. + - renamed replace_element() to replace_element_contents() + - moved try_fopen() from lib/util.C to sched/sched_util.C + - added old and new docs to CVS + + doc/ (all new) + sched_locality.php + client_mac.php + delete_file.php + get_file.php + get_file_list.php + gui_rpc_control.php + gui_urls.php + info.php + send_file.php + lib/ + parse.C,h + util.C,h + sched/ + handle_request.C + main.C,h + make_work.C + sched_locality.C + sched_util.C,h + server_types.C,h diff --git a/doc/client_mac.php b/doc/client_mac.php new file mode 100644 index 0000000000..6783d41d81 --- /dev/null +++ b/doc/client_mac.php @@ -0,0 +1,62 @@ + +

Installing BOINC on Mac OS/X

+

+The Mac OS X client will unpack correctly with gunzip on Mac OS X +10.2 (jaguar) or 10.3 (panther) as long as you type the command +within Terminal. Stuffit 7.x or newer will work under the Finder +in either OS X or OS 9, but I'd recommend using 'gunzip' or 'gzip -d' +within Terminal instead. + +

+However, the two main browsers on OS X (IE 5.2.x and Safari 1.x) will +automatically unpack downloads by default, so your work may already +be done. + +

+If you use IE, the boinc client will download and automatically unpack +leaving two files: +

    +
  1. + boinc_2.12_powerpc-apple-darwin + [this will have the stuffit icon in the finder] + +
  2. + boinc_2.12_powerpc-apple-darwin7.0.0 + [this will not have any icon in the finder] + +
+

+ #2 is the unpacked program ready-to-run. You can just start Terminal + and run boinc. + +

+If you use Safari, the boinc client will download and automatically +unpack, leaving a single file: +

+ This is the unpacked program, but it's not yet ready-to-run (this is + a bug with how Safari handles gzipped downloads; we'll fix this soon). + +

+ Here's what you have to do to fix the Safari download (apologies if + you already know how to do this): + +

+ Now you can run BOINC. + "; +page_tail(); +?> diff --git a/doc/community.php b/doc/community.php index b5ed93f5ac..d963464dd5 100644 --- a/doc/community.php +++ b/doc/community.php @@ -6,7 +6,7 @@ page_head("Community and resources"); echo "

Participants

-To ask questions or report bugs in the BOINC client software, +To ask questions, or to report bugs in the BOINC client software, please go to the Message board area of SETI@home. @@ -50,8 +50,7 @@ At any given point there are two different versions of the BOINC source code (maintained as separate CVS projects):

+"; + +page_tail(); +?> diff --git a/doc/gui_urls.php b/doc/gui_urls.php new file mode 100644 index 0000000000..f7fdf09e74 --- /dev/null +++ b/doc/gui_urls.php @@ -0,0 +1,46 @@ + +GUI URLs is a mechanism allowing projects to pass URLs to the client, +for display as links in the GUI. +

+Projects can includes a file 'gui_urls.xml' in the project root directory, +with the following form: + +",html_text(" + + + Your account + View your account information and credit totals + http://foo.project.com/blah.php?userid= + + + Help + Get help about SETI@home + http://foo.project.com/help.php + + ... + +")," +

+Each entry describes a GUI URL. +The elements are: +"; +list_start(); +list_item("name", "A short name, used e.g. as a menu item"); +list_item("description", "An explanation, used e.g. as a rollover popup"); +list_item("url", "The URL"); +list_end(); +echo " +All items are macro-substituted as follows: +"; +list_start(); +list_item(htmlspecialchars(""), "The user ID"); +list_item(htmlspecialchars(""), "The team ID"); +list_item(htmlspecialchars(""), "The host ID"); +list_item(htmlspecialchars(""), "The user's account ID"); +list_end(); +page_tail(); +?> diff --git a/doc/index.php b/doc/index.php index bdeab6e665..e67686dd1b 100644 --- a/doc/index.php +++ b/doc/index.php @@ -81,6 +81,7 @@ Solve biomedical questions of protein-related diseases. Analyze radio-telescope data, looking for evidence of extraterrestrial life. +Visit any of these sites to download BOINC client software. We encourage you to participate in multiple projects, so that your computer will be kept busy even while projects are down or out of work. diff --git a/doc/info.php b/doc/info.php new file mode 100644 index 0000000000..c7718f27cc --- /dev/null +++ b/doc/info.php @@ -0,0 +1,76 @@ +Run BOINC only on authorized computers + +

+Run BOINC only on computers that you own, +or for which you have obtained the owner's permission. +Some companies and schools have policies that prohibit using their computers +for BOINC-based projects. + +

How BOINC will use your computer

+ +

+When you run BOINC on your computer, +it will use part of the computer's CPU power, disk space, and network bandwidth. +You can control how much of your resources are used by BOINC, +and when it uses them. + +

Privacy policy

+ +

+To avoid computing while you're typing, +BOINC monitors mouse and keyboard and activity +(it does not record keystrokes). +This may trigger some anti-virus software. + +

+Your account on a BOINC-based project is identified by a name that you choose. +This name may be shown on the project's web site, +along with a summary of the work your computer has done for the project +and other BOINC projects. +If you want to be anonymous, choose a name that doesn't reveal your identity. + +

+If you participate in a BOINC-based project, +information about your computer +(such as its processor type, amount of memory, etc.) +will be recorded by the project and used to decide +what type of work to assign to your computer. +This information will also be shown on the project's web site. +Nothing that reveals your computer's location +(e.g. its domain name or network address) will be shown. + +

+To participate in a BOINC-based project, +you must give an address where you receive email. +This address will not be shown on the project's web site +or shared with organizations. +The project may send you periodic newsletters; +however, you can choose not to be sent these at any time. + +

Is it safe to run BOINC?

+ +

+Any time you download a program through the Internet you are taking a chance: +the program might have dangerous errors, +or the download server might have been hacked. + +

Liability

+ +

+The BOINC project and the University of California +assume no liability for damage to your computer, +loss of data, or any other event or condition that may occur +as a result of participating in BOINC-based projects. + +"; +page_tail(); +?> diff --git a/doc/sched_locality.php b/doc/sched_locality.php new file mode 100644 index 0000000000..367acf7496 --- /dev/null +++ b/doc/sched_locality.php @@ -0,0 +1,47 @@ +Locality scheduling is intended for projects for which +

+ +The goal of locality scheduling is to minimize +the amount of data transfer to hosts. +In sending work to at given host, +the scheduler tries to send results +that uses input files already on the host. + +

+To use locality scheduling, projects must do the following: + +

+ +

+Locality scheduling works as follows: +

+"; +page_tail(); +?> diff --git a/doc/send_file.php b/doc/send_file.php new file mode 100644 index 0000000000..5cd9d95fa2 --- /dev/null +++ b/doc/send_file.php @@ -0,0 +1,54 @@ + +send_file(int host_id, const char* file_name, int priority, long int exp_date) + +or the command line program +
+send_file -host_id X -file_name Y -priority Z -days_exp
+
+ +

+send_file creates a result and initializes it with a name of the form +send_FILENAME_HOSTID_TIME. +

+A message is created for the host and added to the msg_to_host table. +This message instructs the client to download the file +and acknowledge a successful download. +The download message included in the next RPC reply to the host. +The message has the form: +", html_text(" + + FILE_MOVER + + + FILE_MOVER + n + + RESULT_XML + + file_name + download_dir/file_name + md5 + file->nbytes + + priority + exp_date + + + result.name + FILE_MOVER + + file_name + +"), " +"; +page_tail(); +?> diff --git a/doc/work_distribution.php b/doc/work_distribution.php index 6431e45458..3530e4bd24 100644 --- a/doc/work_distribution.php +++ b/doc/work_distribution.php @@ -25,11 +25,7 @@ results of the same workunit, in an attempt to obtain unearned credit or have erroneous results accepted as correct. -In general, the BOINC scheduler responds to a work request -by enumerating unsent results from the database, -sending them to the host, -and continuing until requested duration X is reached. -However, this process is limited in various ways: +Work distribution is constrained by a number of rules:

+In general, the BOINC scheduler responds to a work request +by enumerating unsent results from the database, +filtering them by the above criteria, +sending them to the host, +and continuing until requested duration X is reached. +

+For projects that have very large input files, +each of which is used by many workunit, +BOINC offers an alternative work distribution policy +called locality scheduling. "; page_tail(); ?> diff --git a/lib/parse.C b/lib/parse.C index abf0f035bd..987f0451df 100644 --- a/lib/parse.C +++ b/lib/parse.C @@ -206,9 +206,11 @@ int read_file_malloc(const char* pathname, char*& str) { } -// replace XML element contents. not currently used +// replace XML element contents (element must be present) // -void replace_element(char* buf, char* start, char* end, char* replacement) { +void replace_element_contents( + char* buf, char* start, char* end, char* replacement +) { char temp[4096], *p, *q; p = strstr(buf, start); @@ -219,6 +221,20 @@ void replace_element(char* buf, char* start, char* end, char* replacement) { strcat(p, temp); } +// replace a substring. Do at most one instance. +// +bool str_replace(char* str, char* substr, char* replacement) { + char temp[4096], *p; + + p = strstr(str, substr); + if (!p) return false; + int n = strlen(substr); + strcpy(temp, p+n); + strcpy(p, replacement); + strcat(p, temp); + return true; +} + // if the given XML has an element of the form // // ... diff --git a/lib/parse.h b/lib/parse.h index aa0fd2600b..c0ca2a9fa0 100644 --- a/lib/parse.h +++ b/lib/parse.h @@ -40,7 +40,10 @@ extern int dup_element_contents(FILE* in, const char* end_tag, char** pp); extern int copy_element_contents(FILE* in, const char* end_tag, char* p, int len); extern int copy_element_contents(FILE* in, const char* end_tag, std::string&); extern int read_file_malloc(const char* pathname, char*& str); -extern void replace_element(char* buf, char* start, char* end, char* replacement); +extern void replace_element_contents( + char* buf, char* start, char* end, char* replacement +); +extern bool str_replace(char* str, char* old, char* neww); extern char* sgets(char* buf, int len, char* &in); extern void xml_escape(std::string&, std::string&); extern void xml_escape(char*, std::string&); diff --git a/lib/util.C b/lib/util.C index 669cccff44..5dd24a28a1 100755 --- a/lib/util.C +++ b/lib/util.C @@ -765,37 +765,3 @@ int dir_hier_url( sprintf(result, "%s/%x/%s", root, sum, filename); return 0; } - -#ifndef _WIN32 -// try to open a file. -// On failure: -// return ERR_FOPEN if the dir is there but not file -// (this is generally a nonrecoverable failure) -// return ERR_OPENDIR if dir is not there. -// (this is generally a recoverable error, -// like NFS mount failure, that may go away later) -// -int try_fopen(char* path, FILE*& f, char* mode) { - char* p; - DIR* d; - char dirpath[256]; - - f = fopen(path, mode); - if (!f) { - memset(dirpath, '\0', sizeof(dirpath)); - p = strrchr(path, '/'); - if (p) { - strncpy(dirpath, path, (int)(p-path)); - } else { - strcpy(dirpath, "."); - } - if ((d = opendir(dirpath)) == NULL) { - return ERR_OPENDIR; - } else { - closedir(d); - return ERR_FOPEN; - } - } - return 0; -} -#endif \ No newline at end of file diff --git a/lib/util.h b/lib/util.h index 87f534299e..1628e83839 100755 --- a/lib/util.h +++ b/lib/util.h @@ -127,6 +127,4 @@ extern int dir_hier_url( const char* filename, const char* root, int fanout, char* result ); -extern int try_fopen(char* path, FILE*& f, char* mode); - #endif diff --git a/sched/handle_request.C b/sched/handle_request.C index 401ff233bc..e05a614e69 100644 --- a/sched/handle_request.C +++ b/sched/handle_request.C @@ -789,7 +789,8 @@ void handle_request( if (sreq.parse(fin) == 0){ log_messages.printf( - SCHED_MSG_LOG::NORMAL, "Handling request: IP %s, auth %s, host %d, platform %s, version %d.%02d\n", + SCHED_MSG_LOG::NORMAL, + "Handling request: IP %s, auth %s, host %d, platform %s, version %d.%02d\n", get_remote_addr(), sreq.authenticator, sreq.hostid, sreq.platform_name, sreq.core_client_major_version, sreq.core_client_minor_version ); diff --git a/sched/main.C b/sched/main.C index 89a33608b5..b040201d8c 100644 --- a/sched/main.C +++ b/sched/main.C @@ -66,6 +66,7 @@ void get_log_path(char* p) { bool use_files = false; // use disk files for req/reply msgs (for debugging) SCHED_CONFIG config; +GUI_URLS gui_urls; key_t sema_key; int g_pid; @@ -129,6 +130,8 @@ int main() { exit(0); } + gui_urls.init(); + sprintf(path, "%s/code_sign_public", config.key_dir); retval = read_file_malloc(path, code_sign_key); if (retval) { diff --git a/sched/main.h b/sched/main.h index 326069e2e4..9d0c54b234 100644 --- a/sched/main.h +++ b/sched/main.h @@ -20,8 +20,10 @@ #include "boinc_db.h" #include "sched_config.h" #include "synch.h" +#include "server_types.h" extern SCHED_CONFIG config; +extern GUI_URLS gui_urls; extern key_t sema_key; extern int g_pid; extern void lock_sema(); diff --git a/sched/make_work.C b/sched/make_work.C index 2d60d06c00..35653a5ef9 100644 --- a/sched/make_work.C +++ b/sched/make_work.C @@ -68,15 +68,21 @@ void replace_file_name( while (p) { if (parse_str(p, "", temp, sizeof(temp))) { if(!strcmp(filename, temp)) { - replace_element(xml_doc + (p - buf),"","",new_filename); + replace_element_contents( + xml_doc + (p - buf),"","", new_filename + ); } } else if (parse_str(p, "", temp, sizeof(temp))) { if(!strcmp(filename, temp)) { - replace_element(xml_doc + (p - buf),"","",new_filename); + replace_element_contents( + xml_doc+(p-buf), "","", new_filename + ); } } else if (parse_str(p, "", temp, sizeof(temp))) { if(!strcmp(temp, download_path)) { - replace_element(xml_doc + (p - buf),"","",new_download_path); + replace_element_contents( + xml_doc + (p - buf),"","", new_download_path + ); } } p = strtok(0, "\n"); diff --git a/sched/sched_locality.C b/sched/sched_locality.C index 568bc874f7..1fde545af8 100644 --- a/sched/sched_locality.C +++ b/sched/sched_locality.C @@ -1,13 +1,29 @@ +// The contents of this file are subject to the BOINC 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://boinc.berkeley.edu/license_1.0.txt +// +// 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): +// + // "Locality scheduling": a scheduling discipline in which // there are large sticky input files, // and many WUs share a single input file. // If a host already has an input file, // we try to send him another result that uses that file. // -// The rules for using locality scheduling: -// - the input files must have names such that -// no name is a substring of another -// - result names must be of the form FILENAME__xxx +// see doc/sched_locality.php #include diff --git a/sched/sched_util.C b/sched/sched_util.C index 4b62cbb0b4..e79c14a15d 100644 --- a/sched/sched_util.C +++ b/sched/sched_util.C @@ -24,6 +24,7 @@ using namespace std; #include #include "filesys.h" +#include "error_numbers.h" #include "sched_msgs.h" #include "sched_util.h" @@ -74,3 +75,35 @@ void check_stop_daemons() { bool check_stop_sched() { return boinc_file_exists(STOP_SCHED_FILENAME); } + +// try to open a file. +// On failure: +// return ERR_FOPEN if the dir is there but not file +// (this is generally a nonrecoverable failure) +// return ERR_OPENDIR if dir is not there. +// (this is generally a recoverable error, +// like NFS mount failure, that may go away later) +// +int try_fopen(char* path, FILE*& f, char* mode) { + char* p; + DIR* d; + char dirpath[256]; + + f = fopen(path, mode); + if (!f) { + memset(dirpath, '\0', sizeof(dirpath)); + p = strrchr(path, '/'); + if (p) { + strncpy(dirpath, path, (int)(p-path)); + } else { + strcpy(dirpath, "."); + } + if ((d = opendir(dirpath)) == NULL) { + return ERR_OPENDIR; + } else { + closedir(d); + return ERR_FOPEN; + } + } + return 0; +} diff --git a/sched/sched_util.h b/sched/sched_util.h index 6f5b79df63..8ed366a6f1 100644 --- a/sched/sched_util.h +++ b/sched/sched_util.h @@ -33,5 +33,6 @@ extern void set_debug_level(int); extern void check_stop_daemons(); extern bool check_stop_sched(); extern void install_stop_signal_handler(); +extern int try_fopen(char* path, FILE*& f, char* mode); #endif diff --git a/sched/server_types.C b/sched/server_types.C index 94f8f2385e..d9fb512399 100644 --- a/sched/server_types.C +++ b/sched/server_types.C @@ -213,6 +213,7 @@ SCHEDULER_REPLY::~SCHEDULER_REPLY() { int SCHEDULER_REPLY::write(FILE* fout) { unsigned int i, j; string u1, u2, t1, t2; + char buf[LARGE_BLOB_SIZE]; fprintf(fout, "\n" @@ -370,6 +371,10 @@ int SCHEDULER_REPLY::write(FILE* fout) { file_deletes[i].name ); } + + gui_urls.get_gui_urls(user, team, host, buf); + fputs(buf, fout); + end: fprintf(fout, "\n" @@ -555,3 +560,28 @@ void GLOBAL_PREFS::parse(char* buf, char* venue) { parse_double(buf2, "", disk_max_used_pct); parse_double(buf2, "", disk_min_free_gb); } + +void GUI_URLS::init() { + text = 0; + read_file_malloc("../gui_urls.xml", text); +} + +void GUI_URLS::get_gui_urls(USER& user, TEAM& team, HOST& host, char* buf) { + bool found; + char userid[256], teamid[256], hostid[256]; + strcpy(buf, ""); + if (!text) return; + strcpy(buf, text); + + sprintf(userid, "%d", user.id); + sprintf(teamid, "%d", team.id); + sprintf(hostid, "%d", host.id); + while (1) { + found = false; + found |= str_replace(buf, "", userid); + found |= str_replace(buf, "", hostid); + found |= str_replace(buf, "", teamid); + found |= str_replace(buf, "", user.authenticator); + if (!found) break; + } +} diff --git a/sched/server_types.h b/sched/server_types.h index 6848ab2436..70d558ea98 100644 --- a/sched/server_types.h +++ b/sched/server_types.h @@ -84,6 +84,12 @@ struct GLOBAL_PREFS { void parse(char* buf, char* venue); }; +struct GUI_URLS { + char* text; + void init(); + void get_gui_urls(USER& user, TEAM& team, HOST& host, char*); +}; + struct SCHEDULER_REQUEST { char authenticator[256]; char platform_name[256];