mirror of https://github.com/BOINC/boinc.git
*** empty log message ***
svn path=/trunk/boinc/; revision=4809
This commit is contained in:
parent
b4aeaca73d
commit
7a3f2d4939
|
@ -20987,3 +20987,15 @@ David 9 Dec 2004
|
|||
boinc_api.C
|
||||
client/
|
||||
http.C,h
|
||||
|
||||
David 10 Dec 2004
|
||||
- added a function get_file_dir() (in lib/filesys.C)
|
||||
that searches the directories in the PATH env var,
|
||||
looking for an executable file with a given name
|
||||
(this is so boincmgr can find boinc on Unix)
|
||||
|
||||
client/
|
||||
http.C
|
||||
lib/
|
||||
filesys.C,h
|
||||
util.C,h
|
||||
|
|
148
client/http.C
148
client/http.C
|
@ -116,7 +116,7 @@ static void http_get_request_header_proxy(
|
|||
"%s"
|
||||
"Connection: close\015\012"
|
||||
"Accept: */*\015\012"
|
||||
"Proxy-Authorization: Basic %s\015\012"
|
||||
"Proxy-Authorization: Basic %s\015\012"
|
||||
"\015\012",
|
||||
file, host, port, offset?offset_info:"", encstr
|
||||
);
|
||||
|
@ -144,7 +144,7 @@ static void http_head_request_header_proxy(char* buf, char* host, int port, char
|
|||
"Host: %s:%d\015\012"
|
||||
"Connection: close\015\012"
|
||||
"Accept: */*\015\012"
|
||||
"Proxy-Authorization: Basic %s\015\012"
|
||||
"Proxy-Authorization: Basic %s\015\012"
|
||||
"\015\012",
|
||||
file, host, port, encstr
|
||||
);
|
||||
|
@ -180,7 +180,7 @@ static void http_post_request_header_proxy(
|
|||
"Connection: close\015\012"
|
||||
"Content-Type: application/octet-stream\015\012"
|
||||
"Content-Length: %d\015\012"
|
||||
"Proxy-Authorization: Basic %s\015\012"
|
||||
"Proxy-Authorization: Basic %s\015\012"
|
||||
"\015\012",
|
||||
file, host, port, size, encstr
|
||||
);
|
||||
|
@ -199,7 +199,7 @@ void HTTP_REPLY_HEADER::parse() {
|
|||
istringstream h(recv_buf);
|
||||
string line, w;
|
||||
|
||||
if (getline(h, line)) {
|
||||
if (getline(h, line)) {
|
||||
istringstream iline(line);
|
||||
|
||||
iline >> w;
|
||||
|
@ -328,18 +328,18 @@ int HTTP_OP::init_head(const char* url) {
|
|||
http_head_request_header(
|
||||
request_header, url_hostname, port, proxy_buf
|
||||
);
|
||||
} else {
|
||||
char id_passwd[512];
|
||||
string encstr = "";
|
||||
memset(id_passwd,0,sizeof(id_passwd));
|
||||
strcpy(id_passwd,pi.http_user_name);
|
||||
strcat(id_passwd,":");
|
||||
strcat(id_passwd,pi.http_user_passwd);
|
||||
encstr = r_base64_encode(id_passwd,strlen(id_passwd));
|
||||
} else {
|
||||
char id_passwd[512];
|
||||
string encstr = "";
|
||||
memset(id_passwd,0,sizeof(id_passwd));
|
||||
strcpy(id_passwd,pi.http_user_name);
|
||||
strcat(id_passwd,":");
|
||||
strcat(id_passwd,pi.http_user_passwd);
|
||||
encstr = r_base64_encode(id_passwd,strlen(id_passwd));
|
||||
http_head_request_header_proxy(
|
||||
request_header, url_hostname, port, proxy_buf, (char*)encstr.c_str()
|
||||
request_header, url_hostname, port, proxy_buf, (char*)encstr.c_str()
|
||||
);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -356,9 +356,9 @@ int HTTP_OP::init_get(const char* url, char* out, bool del_old_file, double off)
|
|||
PROXY::init(url_hostname, port);
|
||||
NET_XFER::init(get_proxy_server_name(url_hostname),get_proxy_port(port), HTTP_BLOCKSIZE);
|
||||
safe_strcpy(outfile, out);
|
||||
if (off != 0){
|
||||
bytes_xferred = off;
|
||||
}
|
||||
if (off != 0){
|
||||
bytes_xferred = off;
|
||||
}
|
||||
http_op_type = HTTP_OP_GET;
|
||||
http_op_state = HTTP_STATE_CONNECTING;
|
||||
if (pi.use_http_proxy) {
|
||||
|
@ -366,19 +366,21 @@ int HTTP_OP::init_get(const char* url, char* out, bool del_old_file, double off)
|
|||
} else {
|
||||
sprintf(proxy_buf, "/%s", filename);
|
||||
}
|
||||
if (!pi.use_http_auth){
|
||||
if (!pi.use_http_auth) {
|
||||
http_get_request_header(request_header, url_hostname, port, proxy_buf, (int)file_offset);
|
||||
} else {
|
||||
char id_passwd[512];
|
||||
string encstr = "";
|
||||
memset(id_passwd,0,sizeof(id_passwd));
|
||||
strcpy(id_passwd,pi.http_user_name);
|
||||
strcat(id_passwd,":");
|
||||
strcat(id_passwd,pi.http_user_passwd);
|
||||
encstr = r_base64_encode(id_passwd,strlen(id_passwd));
|
||||
http_get_request_header_proxy(request_header, url_hostname,
|
||||
port, proxy_buf, (int)file_offset, (char*)encstr.c_str() );
|
||||
}
|
||||
} else {
|
||||
char id_passwd[512];
|
||||
string encstr = "";
|
||||
memset(id_passwd,0,sizeof(id_passwd));
|
||||
strcpy(id_passwd,pi.http_user_name);
|
||||
strcat(id_passwd,":");
|
||||
strcat(id_passwd,pi.http_user_passwd);
|
||||
encstr = r_base64_encode(id_passwd,strlen(id_passwd));
|
||||
http_get_request_header_proxy(
|
||||
request_header, url_hostname,
|
||||
port, proxy_buf, (int)file_offset, (char*)encstr.c_str()
|
||||
);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -408,23 +410,23 @@ int HTTP_OP::init_post(const char* url, char* in, char* out) {
|
|||
sprintf(proxy_buf, "/%s", filename);
|
||||
}
|
||||
|
||||
if (!pi.use_http_auth){
|
||||
if (!pi.use_http_auth) {
|
||||
http_post_request_header(
|
||||
request_header, url_hostname, port, proxy_buf, content_length
|
||||
);
|
||||
} else {
|
||||
char id_passwd[512];
|
||||
string encstr = "";
|
||||
memset(id_passwd,0,sizeof(id_passwd));
|
||||
strcpy(id_passwd,pi.http_user_name);
|
||||
strcat(id_passwd,":");
|
||||
strcat(id_passwd,pi.http_user_passwd);
|
||||
encstr = r_base64_encode(id_passwd,strlen(id_passwd));
|
||||
} else {
|
||||
char id_passwd[512];
|
||||
string encstr = "";
|
||||
memset(id_passwd,0,sizeof(id_passwd));
|
||||
strcpy(id_passwd,pi.http_user_name);
|
||||
strcat(id_passwd,":");
|
||||
strcat(id_passwd,pi.http_user_passwd);
|
||||
encstr = r_base64_encode(id_passwd,strlen(id_passwd));
|
||||
http_post_request_header_proxy(
|
||||
request_header, url_hostname, port, proxy_buf, content_length,
|
||||
(char*)encstr.c_str()
|
||||
(char*)encstr.c_str()
|
||||
);
|
||||
}
|
||||
}
|
||||
scope_messages.printf("HTTP_OP::init_post(): %p io_done %d\n", this, io_done);
|
||||
return 0;
|
||||
}
|
||||
|
@ -460,23 +462,23 @@ int HTTP_OP::init_post2(
|
|||
} else {
|
||||
sprintf(proxy_buf, "/%s", filename);
|
||||
}
|
||||
if (!pi.use_http_auth){
|
||||
if (!pi.use_http_auth) {
|
||||
http_post_request_header(
|
||||
request_header, url_hostname, port, proxy_buf, content_length
|
||||
);
|
||||
} else {
|
||||
char id_passwd[512];
|
||||
string encstr = "";
|
||||
memset(id_passwd,0,sizeof(id_passwd));
|
||||
strcpy(id_passwd,pi.http_user_name);
|
||||
strcat(id_passwd,":");
|
||||
strcat(id_passwd,pi.http_user_passwd);
|
||||
encstr = r_base64_encode(id_passwd,strlen(id_passwd));
|
||||
} else {
|
||||
char id_passwd[512];
|
||||
string encstr = "";
|
||||
memset(id_passwd,0,sizeof(id_passwd));
|
||||
strcpy(id_passwd,pi.http_user_name);
|
||||
strcat(id_passwd,":");
|
||||
strcat(id_passwd,pi.http_user_passwd);
|
||||
encstr = r_base64_encode(id_passwd,strlen(id_passwd));
|
||||
http_post_request_header_proxy(
|
||||
request_header, url_hostname, port, proxy_buf, content_length,
|
||||
(char*)encstr.c_str()
|
||||
(char*)encstr.c_str()
|
||||
);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -537,27 +539,27 @@ bool HTTP_OP_SET::poll(double) {
|
|||
htp->http_op_state = HTTP_STATE_DONE;
|
||||
htp->http_op_retval = htp->proxy_retval;
|
||||
switch (htp->proxy_retval) {
|
||||
case ERR_SOCKS_UNKNOWN_FAILURE:
|
||||
msg_printf(NULL, MSG_ERROR, "An unknown SOCKS server error occurred\n");
|
||||
break;
|
||||
case ERR_SOCKS_REQUEST_FAILED:
|
||||
msg_printf(NULL, MSG_ERROR, "The SOCKS server denied access for this computer\n");
|
||||
break;
|
||||
case ERR_SOCKS_BAD_USER_PASS:
|
||||
msg_printf(NULL, MSG_ERROR, "Incorrect SOCKS user name and/or password\n");
|
||||
break;
|
||||
case ERR_SOCKS_UNKNOWN_SERVER_VERSION:
|
||||
msg_printf(NULL, MSG_ERROR, "The SOCKS server is using an unknown version\n");
|
||||
break;
|
||||
case ERR_SOCKS_UNSUPPORTED:
|
||||
msg_printf(NULL, MSG_ERROR, "The SOCKS server is using unsupported features unknown to BOINC\n");
|
||||
break;
|
||||
case ERR_SOCKS_CANT_REACH_HOST:
|
||||
msg_printf(NULL, MSG_ERROR, "The SOCKS server is unable to contact the host\n");
|
||||
break;
|
||||
case ERR_SOCKS_CONN_REFUSED:
|
||||
msg_printf(NULL, MSG_ERROR, "The connection from the SOCKS server to the host was refused\n");
|
||||
break;
|
||||
case ERR_SOCKS_UNKNOWN_FAILURE:
|
||||
msg_printf(NULL, MSG_ERROR, "An unknown SOCKS server error occurred\n");
|
||||
break;
|
||||
case ERR_SOCKS_REQUEST_FAILED:
|
||||
msg_printf(NULL, MSG_ERROR, "The SOCKS server denied access for this computer\n");
|
||||
break;
|
||||
case ERR_SOCKS_BAD_USER_PASS:
|
||||
msg_printf(NULL, MSG_ERROR, "Incorrect SOCKS user name and/or password\n");
|
||||
break;
|
||||
case ERR_SOCKS_UNKNOWN_SERVER_VERSION:
|
||||
msg_printf(NULL, MSG_ERROR, "The SOCKS server is using an unknown version\n");
|
||||
break;
|
||||
case ERR_SOCKS_UNSUPPORTED:
|
||||
msg_printf(NULL, MSG_ERROR, "The SOCKS server is using unsupported features unknown to BOINC\n");
|
||||
break;
|
||||
case ERR_SOCKS_CANT_REACH_HOST:
|
||||
msg_printf(NULL, MSG_ERROR, "The SOCKS server is unable to contact the host\n");
|
||||
break;
|
||||
case ERR_SOCKS_CONN_REFUSED:
|
||||
msg_printf(NULL, MSG_ERROR, "The connection from the SOCKS server to the host was refused\n");
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
htp->http_op_state = HTTP_STATE_REQUEST_HEADER;
|
||||
|
@ -722,7 +724,7 @@ bool HTTP_OP_SET::poll(double) {
|
|||
break;
|
||||
}
|
||||
|
||||
if ((htp->hrh.http_status/100)*100 != HTTP_STATUS_OK) {
|
||||
if ((htp->hrh.http_status/100)*100 != HTTP_STATUS_OK) {
|
||||
htp->http_op_state = HTTP_STATE_DONE;
|
||||
htp->http_op_retval = htp->hrh.http_status;
|
||||
break;
|
||||
|
|
|
@ -73,6 +73,8 @@ before getting into the source code.
|
|||
<li> <a href=python.php>Python framework</a>
|
||||
<li> <a href=prefs_impl.php>Preferences</a>
|
||||
<li> <a href=trickle_impl.php>Trickle messages</a>
|
||||
<li> <a href=version_diff.txt>How to see what has changed
|
||||
between two versions of an executable</a>.
|
||||
</ul>
|
||||
|
||||
";
|
||||
|
|
|
@ -76,6 +76,8 @@ This tells the validator to write an error message and exit.
|
|||
<p>
|
||||
Neither function should delete files.
|
||||
<p>
|
||||
A more detailed description is <a href=validate_logic.txt>here</a>.
|
||||
<p>
|
||||
Two example validators are supplied
|
||||
(each implements check_set() and check_pair()):
|
||||
<ul>
|
||||
|
|
|
@ -0,0 +1,135 @@
|
|||
int check_set(
|
||||
vector<RESULT> results,
|
||||
DB_WORKUNIT& wu,
|
||||
int& canonicalid,
|
||||
double& credit,
|
||||
bool& retry
|
||||
);
|
||||
|
||||
Define N := length of result vector, and let M := N.
|
||||
|
||||
check_set() will ALWAYS be called with N>=wu.min_quorum.
|
||||
|
||||
check_set() will ALWAYS be called with ALL results satisfying
|
||||
result.outcome == RESULT_OUTCOME_SUCCESS
|
||||
result.validate_state == VALIDATE_STATE_INIT
|
||||
|
||||
check_set() should NEVER modify wu [although it is not declared
|
||||
const]
|
||||
|
||||
[1] Syntax pass (optional)
|
||||
|
||||
for (all N results) {
|
||||
|
||||
if (one or more of the output files can be read and one or
|
||||
more of those files contains erroneous or invalid or
|
||||
incorrect output, i.e. the file syntax is wrong)
|
||||
{
|
||||
set result.outcome=RESULT_OUTCOME_VALIDATE_ERROR;
|
||||
set result.validate_state=VALIDATE_STATE_INVALID;
|
||||
decrement counter: M = M-1;
|
||||
} // erroneous or incorrect or invalid output files
|
||||
|
||||
else if (result has a potentially recoverable error,
|
||||
i.e. NFS directory not mounted, server
|
||||
is unreachable, upload server unreachable)
|
||||
{
|
||||
dont not modify result.validate_state;
|
||||
dont not modify result.outcome;
|
||||
decrement counter M = M-1;
|
||||
set retry=true;
|
||||
} // recoverable error
|
||||
|
||||
else if (every output file of the result is unreadable or
|
||||
fails to exist)
|
||||
{
|
||||
set result.outcome=RESULT_OUTCOME_VALIDATE_ERROR;
|
||||
set result.validate_state=VALIDATE_STATE_INIT;
|
||||
decrement counter: M = M-1;
|
||||
} // all result output files unreadable or nonexistent
|
||||
|
||||
} // end of syntax pass loop over all N results
|
||||
|
||||
Define REMAINING RESULTS to be those that do NOT fall into one of
|
||||
the two categories above. There are M of these. If the syntax pass
|
||||
has been skipped, then M == N.
|
||||
|
||||
if (M < wu.min_quorum)
|
||||
{
|
||||
dont modify canonicalid;
|
||||
dont modify credit;
|
||||
leave retry as set above;
|
||||
leave result.outcome unchanged for M remaining results;
|
||||
leave result.validate_state unchanged for M remaining results;
|
||||
return 0;
|
||||
} // fewer than min_quorum results remain
|
||||
|
||||
At any point in this process, if a major error occurs, check_set
|
||||
should return nonzero. This will cause the validator to exit. If
|
||||
this happens, it does not matter how you have set or modified
|
||||
result.outcome, result.validate_state, retry, credit, or canonicalid.
|
||||
|
||||
// END OF OPTIONAL SYNTAX PASS
|
||||
|
||||
|
||||
[2] Comparison pass (required). We have
|
||||
M>=wu.min_quorum REMAINING RESULTS results with
|
||||
result.outcome == RESULT_OUTCOME_SUCCESS
|
||||
result.validate_state == VALIDATE_STATE_INIT
|
||||
|
||||
All the output files of all of these results are
|
||||
readable. All of the output files for a given result
|
||||
are, when taken "in isolation" apparently valid. If
|
||||
these conditions are not met then you must do the
|
||||
"syntax pass" above.
|
||||
|
||||
if (one of these results is determined to be THE correct
|
||||
[canonical] result)
|
||||
{
|
||||
|
||||
for correct result {
|
||||
set result.validate_state=VALIDATE_STATE_VALID;
|
||||
set canonicalid=result.id;
|
||||
} // canonical result
|
||||
|
||||
for (the REMAINING M - 1 results)
|
||||
{
|
||||
// NOTE: what is below can be done by calling
|
||||
// check_pair(result, canonical_result)
|
||||
if (result is correct, matches canonical)
|
||||
{
|
||||
result.validate_state=VALIDATE_STATE_VALID;
|
||||
}
|
||||
else
|
||||
{
|
||||
result.validate_state=VALIDATE_STATE_INVALID;
|
||||
}
|
||||
} // loop over remaining M-1 results
|
||||
|
||||
set credit;
|
||||
|
||||
leave retry as set from the syntax pass above;
|
||||
|
||||
return 0;
|
||||
} // found canonical result
|
||||
else
|
||||
{
|
||||
// You are UNABLE to determine if one of the M REMAINING RESULTS
|
||||
// is correct, so:
|
||||
|
||||
do not modify result.outcome for ANY of M remaining results;
|
||||
do not modify result.validate_state for ANY of M remaining results;
|
||||
do not set credit;
|
||||
do not set canonicalid;
|
||||
leave retry as set from the syntax pass;
|
||||
return 0;
|
||||
|
||||
} // did not find canonical result
|
||||
|
||||
At any point in this process, if a major error occurs, check_set
|
||||
should return nonzero. This will cause the validator to exit. If
|
||||
this happens, it does not matter how you have set result.outcome,
|
||||
result.validate_state, retry, credit, or canonicalid for ANY of the
|
||||
results.
|
||||
|
||||
// end of Comparison pass
|
|
@ -546,6 +546,33 @@ int get_filesystem_info(double &total_space, double &free_space) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
#ifndef _WIN32
|
||||
|
||||
int get_file_dir(char* filename, char* dir) {
|
||||
char buf[8192], *p, path[256];
|
||||
struct stat sbuf;
|
||||
int retval;
|
||||
|
||||
p = getenv("PATH");
|
||||
if (!p) return ERR_NOT_FOUND;
|
||||
strcpy(buf, p);
|
||||
|
||||
p = strtok(buf, ":");
|
||||
while (p) {
|
||||
sprintf(path, "%s/%s", p, filename);
|
||||
retval = stat(path, &sbuf);
|
||||
if (!retval && (sbuf.st_mode & 0111)) {
|
||||
strcpy(dir, p);
|
||||
return 0;
|
||||
}
|
||||
p = strtok(0, ":");
|
||||
}
|
||||
return ERR_NOT_FOUND;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __GNUC__
|
||||
static volatile const char __attribute__((unused)) *BOINCrcsid="$Id$";
|
||||
#else
|
||||
|
|
|
@ -114,6 +114,15 @@ public:
|
|||
bool scan(std::string& name); // return true if file returned
|
||||
};
|
||||
|
||||
#ifndef _WIN32
|
||||
|
||||
// search PATH, find the directory that a program is in, if any
|
||||
//
|
||||
extern int get_file_dir(char* filename, char* dir);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* c++ */
|
||||
|
||||
#endif /* double-inclusion protection */
|
||||
|
|
|
@ -192,7 +192,8 @@ void nbytes_to_string(double nbytes, double total_bytes, char* str, int len) {
|
|||
|
||||
#define EPOCHFILETIME_SEC (11644473600.)
|
||||
#define TEN_MILLION 10000000.
|
||||
// return time of day as a double
|
||||
|
||||
// return time of day (seconds since 1970) as a double
|
||||
//
|
||||
double dtime() {
|
||||
#ifdef _WIN32
|
||||
|
|
23
lib/util.h
23
lib/util.h
|
@ -56,8 +56,8 @@ extern void safe_strncpy(char*, const char*, int);
|
|||
#define safe_strcpy(x, y) safe_strncpy(x, y, sizeof(x))
|
||||
#define safe_strcat(x, y) if (strlen(x)+strlen(y)<sizeof(x)) strcat(x, y)
|
||||
extern char* time_to_string(double);
|
||||
std::string timediff_format(double);
|
||||
int read_file_string(const char* pathname, std::string& result);
|
||||
extern std::string timediff_format(double);
|
||||
extern int read_file_string(const char* pathname, std::string& result);
|
||||
|
||||
inline bool ends_with(std::string const& s, std::string const& suffix) {
|
||||
return
|
||||
|
@ -89,16 +89,17 @@ static inline double drand() {
|
|||
}
|
||||
|
||||
// return a random integer in the range [rmin,rmax)
|
||||
static inline double rand_range(double rmin, double rmax)
|
||||
{
|
||||
if (rmin < rmax)
|
||||
static inline double rand_range(double rmin, double rmax) {
|
||||
if (rmin < rmax) {
|
||||
return drand() * (rmax-rmin) + rmin;
|
||||
else
|
||||
} else {
|
||||
return rmin;
|
||||
}
|
||||
}
|
||||
|
||||
// return a random integer in the range [MIN,min(e^n,MAX))
|
||||
double calculate_exponential_backoff(
|
||||
//
|
||||
extern double calculate_exponential_backoff(
|
||||
const char* debug_descr, int n, double MIN, double MAX,
|
||||
double factor=1.0
|
||||
);
|
||||
|
@ -106,12 +107,14 @@ extern bool debug_fake_exponential_backoff;
|
|||
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
#include <windows.h>
|
||||
char* windows_error_string(char* pszBuf, int iSize);
|
||||
char* windows_format_error_string(
|
||||
extern char* windows_error_string(char* pszBuf, int iSize);
|
||||
extern char* windows_format_error_string(
|
||||
unsigned long dwError, char* pszBuf, int iSize
|
||||
);
|
||||
int boinc_thread_cpu_time(HANDLE thread_handle, double& cpu);
|
||||
extern int boinc_thread_cpu_time(HANDLE thread_handle, double& cpu);
|
||||
|
||||
#endif
|
||||
|
||||
extern void update_average(double, double, double, double&, double&);
|
||||
|
|
Loading…
Reference in New Issue