mirror of https://github.com/BOINC/boinc.git
Client spamming server hotfix
svn path=/trunk/boinc/; revision=3734
This commit is contained in:
parent
b564dfa89d
commit
d609e2bc48
|
@ -14411,3 +14411,12 @@ Brian 1 July 2004
|
|||
|
||||
client/
|
||||
gui_rpc_client.h
|
||||
|
||||
Rom 1 July 2004
|
||||
- Introduce skeleton of new transitioner queue class that uses a specialized
|
||||
query for its job. NOTE: I don't know if it will even compile, but need another
|
||||
set of eyes looking over it as well.
|
||||
|
||||
db/
|
||||
db_base.C, .h
|
||||
boinc_db.C, .h
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
// Generated from the TEXTINCLUDE 2 resource.
|
||||
//
|
||||
#include "afxres.h"
|
||||
#include "win_config.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#undef APSTUDIO_READONLY_SYMBOLS
|
||||
|
@ -30,12 +31,12 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
|||
1 TEXTINCLUDE
|
||||
BEGIN
|
||||
"boinc_gui.h\0"
|
||||
"win_config.h\0"
|
||||
END
|
||||
|
||||
2 TEXTINCLUDE
|
||||
BEGIN
|
||||
"#include ""afxres.h""\r\n"
|
||||
"#include ""win_config.h""\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
|
@ -298,8 +299,8 @@ IDI_ICONWARNING ICON "res\\iconwarning.ico"
|
|||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 3,19,0,0
|
||||
PRODUCTVERSION 3,19,0,0
|
||||
FILEVERSION MAJOR_VERSION,MINOR_VERSION,0,0
|
||||
PRODUCTVERSION MAJOR_VERSION,MINOR_VERSION,0,0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
|
@ -316,12 +317,12 @@ BEGIN
|
|||
BEGIN
|
||||
VALUE "CompanyName", "Space Sciences Laboratory"
|
||||
VALUE "FileDescription", "boinc_gui"
|
||||
VALUE "FileVersion", "3.19"
|
||||
VALUE "FileVersion", VERSION "\0"
|
||||
VALUE "InternalName", "boinc_gui"
|
||||
VALUE "LegalCopyright", "Copyright © 2004 University of California"
|
||||
VALUE "OriginalFilename", "boinc_gui.exe"
|
||||
VALUE "ProductName", "BOINC Core Client"
|
||||
VALUE "ProductVersion", "3.19"
|
||||
VALUE "ProductVersion", PACKAGE_VERSION "\0"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
// Microsoft Visual C++ generated resource script.
|
||||
//
|
||||
#include "boinc_ss.h"
|
||||
#include "win_config.h"
|
||||
|
||||
#define APSTUDIO_READONLY_SYMBOLS
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -9,6 +8,7 @@
|
|||
// Generated from the TEXTINCLUDE 2 resource.
|
||||
//
|
||||
#include "afxres.h"
|
||||
#include "win_config.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#undef APSTUDIO_READONLY_SYMBOLS
|
||||
|
@ -31,12 +31,12 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
|||
1 TEXTINCLUDE
|
||||
BEGIN
|
||||
"boinc_ss.h\0"
|
||||
"win_config.h\0"
|
||||
END
|
||||
|
||||
2 TEXTINCLUDE
|
||||
BEGIN
|
||||
"#include ""afxres.h""\r\n"
|
||||
"#include ""win_config.h""\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
|
|
162
db/boinc_db.C
162
db/boinc_db.C
|
@ -34,19 +34,6 @@ static struct random_init {
|
|||
}
|
||||
} random_init;
|
||||
|
||||
// if SQL columns are not 'not null', you must use these safe_atoi, safe_atof
|
||||
// instead of atoi, atof, since the strings returned by MySQL may be NULL.
|
||||
//
|
||||
inline int safe_atoi(const char* s) {
|
||||
if (!s) return 0;
|
||||
return atoi(s);
|
||||
}
|
||||
|
||||
inline float safe_atof(const char* s) {
|
||||
if (!s) return 0;
|
||||
return atof(s);
|
||||
}
|
||||
|
||||
#define ESCAPE(x) escape_string(x, sizeof(x))
|
||||
#define UNESCAPE(x) unescape_string(x, sizeof(x))
|
||||
|
||||
|
@ -72,7 +59,7 @@ DB_HOST::DB_HOST() : DB_BASE(boinc_db, "host"){}
|
|||
DB_WORKUNIT::DB_WORKUNIT() : DB_BASE(boinc_db, "workunit"){}
|
||||
DB_RESULT::DB_RESULT() : DB_BASE(boinc_db, "result"){}
|
||||
DB_MSG_FROM_HOST::DB_MSG_FROM_HOST() : DB_BASE(boinc_db, "msg_from_host"){}
|
||||
DB_MSG_TO_HOST::DB_MSG_TO_HOST() : DB_BASE(boinc_db, "msg_to_host"){}
|
||||
DB_TRANSITIONER_QUEUE::DB_TRANSITIONER_QUEUE() : DB_BASE(boinc_db), current_entry_start_position(0), current_entry_workunit_id(0){}
|
||||
|
||||
int DB_PLATFORM::get_id() {return id;}
|
||||
int DB_CORE_VERSION::get_id() {return id;}
|
||||
|
@ -583,3 +570,150 @@ void DB_MSG_TO_HOST::db_parse(MYSQL_ROW& r) {
|
|||
handled = atol(r[i++]);
|
||||
strcpy2(xml, r[i++]);
|
||||
}
|
||||
|
||||
int DB_TRANSITIONER_QUEUE::enumerate_queue_entries(int transition_time, int ntotal_transitioners, int ntransitioner, int nresult_limit) {
|
||||
int x;
|
||||
char query[MAX_QUERY_LEN];
|
||||
char priority[16];
|
||||
char mod[64];
|
||||
MYSQL_ROW row;
|
||||
int temp_workunit_id;
|
||||
MYSQL_ROW_OFFSET temp_entry_position;
|
||||
|
||||
if (!cursor.active) {
|
||||
cursor.active = true;
|
||||
|
||||
memset(priority, '\0', sizeof(priority));
|
||||
if (db->mysql) { strcpy(priority, "HIGH_PRIORITY"); }
|
||||
|
||||
memset(mod, '\0', sizeof(mod));
|
||||
if (0 < ntotal_transitioners) { sprintf(mod, "MOD(wu.id, %d) = %d", ntotal_transitioners, ntransitioner); }
|
||||
|
||||
sprintf(query,
|
||||
"SELECT %s "
|
||||
" wu.id, "
|
||||
" wu.name, "
|
||||
" wu.appid, "
|
||||
" wu.min_quorum, "
|
||||
" wu.need_validate, "
|
||||
" wu.canonical_resultid, "
|
||||
" wu.transition_time, "
|
||||
" wu.delay_bound, "
|
||||
" wu.error_mask, "
|
||||
" wu.max_error_results, "
|
||||
" wu.max_total_results, "
|
||||
" wu.file_delete_state, "
|
||||
" wu.assimilate_state, "
|
||||
" wu.target_nresults, "
|
||||
" wu.result_template, "
|
||||
" res.id AS res_id, "
|
||||
" res.report_deadline AS res_report_deadline, "
|
||||
" res.server_state AS res_server_state, "
|
||||
" res.outcome AS res_outcome, "
|
||||
" res.validate_state AS res_validate_state, "
|
||||
" res.file_delete_state AS res_file_delete_state, "
|
||||
" res.sent_time AS res_sent_time "
|
||||
"FROM "
|
||||
" workunit AS wu "
|
||||
" LEFT JOIN result AS res ON wu.id = res.workunitid "
|
||||
"WHERE "
|
||||
" wu.transition_time < %d AND "
|
||||
" %s "
|
||||
"LIMIT "
|
||||
" %d ",
|
||||
priority, transition_time, mod, nresult_limit);
|
||||
|
||||
x = db->do_query(query);
|
||||
if (x) return mysql_errno(db->mysql);
|
||||
cursor.rp = mysql_store_result(db->mysql);
|
||||
if (!cursor.rp) return mysql_errno(db->mysql);
|
||||
|
||||
current_entry_start_position = mysql_row_tell(cursor.rp);
|
||||
}
|
||||
|
||||
mysql_row_seek(current_entry_start_position);
|
||||
|
||||
do
|
||||
{
|
||||
temp_entry_position = mysql_row_tell(cursor.rp);
|
||||
row = mysql_fetch_row(cursor.rp);
|
||||
if (!row) {
|
||||
mysql_free_result(cursor.rp);
|
||||
cursor.active = false;
|
||||
return -1;
|
||||
} else {
|
||||
fetch_field_value(cursor.rp, row, "id", temp_workunit_id);
|
||||
}
|
||||
}
|
||||
while ( row && ( temp_workunit_id == current_entry_workunit_id ));
|
||||
|
||||
// New Workunit Detected
|
||||
current_entry_workunit_id = temp_workunit_id;
|
||||
current_entry_start_position = temp_entry_position;
|
||||
|
||||
parse_entry(cursor.rp, row);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void DB_TRANSITIONER_QUEUE::parse_entry(MYSQL_RES *result, MYSQL_ROW& row) {
|
||||
int temp_need_validate = 0;
|
||||
fetch_field_value(result, row, "id", id);
|
||||
fetch_field_value(result, row, "name", name, sizeof(name));
|
||||
fetch_field_value(result, row, "appid", appid);
|
||||
fetch_field_value(result, row, "min_quorum", min_quorum);
|
||||
fetch_field_value(result, row, "need_validate", temp_need_validate);
|
||||
if (temp_need_validate) { need_validate = true; } else { need_validate = false; }
|
||||
fetch_field_value(result, row, "canonical_resultid", canonical_resultid);
|
||||
fetch_field_value(result, row, "transition_time", transition_time);
|
||||
fetch_field_value(result, row, "delay_bound", delay_bound);
|
||||
fetch_field_value(result, row, "error_mask", error_mask);
|
||||
fetch_field_value(result, row, "max_error_results", max_error_results);
|
||||
fetch_field_value(result, row, "max_total_results", max_total_results);
|
||||
fetch_field_value(result, row, "file_delete_state", file_delete_state);
|
||||
fetch_field_value(result, row, "assimilate_state", assimilate_state);
|
||||
fetch_field_value(result, row, "target_nresults", target_nresults);
|
||||
parse_result(result, row);
|
||||
}
|
||||
|
||||
void DB_TRANSITIONER_QUEUE::parse_result(MYSQL_RES *result, MYSQL_ROW& row) {
|
||||
fetch_field_value(result, row, "res_id", res_id);
|
||||
fetch_field_value(result, row, "res_report_deadline", res_report_deadline);
|
||||
fetch_field_value(result, row, "res_server_state", res_server_state);
|
||||
fetch_field_value(result, row, "res_outcome", res_outcome);
|
||||
fetch_field_value(result, row, "res_validate_state", res_validate_state);
|
||||
fetch_field_value(result, row, "res_file_delete_state", res_file_delete_state);
|
||||
fetch_field_value(result, row, "res_sent_time", res_sent_time);
|
||||
}
|
||||
|
||||
int DB_TRANSITIONER_QUEUE::seek_first_result() {
|
||||
int retval;
|
||||
MYSQL_ROW row;
|
||||
|
||||
mysql_row_seek(current_entry_start_position);
|
||||
row = mysql_fetch_row(cursor.rp);
|
||||
if (!row) {
|
||||
retval = -1;
|
||||
} else {
|
||||
parse_result(cursor.rp, row);
|
||||
retval = 0;
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
int DB_TRANSITIONER_QUEUE::seek_next_result() {
|
||||
int retval;
|
||||
MYSQL_ROW row;
|
||||
|
||||
row = mysql_fetch_row(cursor.rp);
|
||||
if (!row) {
|
||||
retval = seek_first_result();
|
||||
} else {
|
||||
parse_result(cursor.rp, row);
|
||||
retval = 0;
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
|
|
@ -427,6 +427,31 @@ struct MSG_TO_HOST {
|
|||
void clear();
|
||||
};
|
||||
|
||||
struct TRANSITIONER_QUEUE {
|
||||
int id;
|
||||
char name[256];
|
||||
int appid;
|
||||
int min_quorum;
|
||||
bool need_validate;
|
||||
int canonical_resultid;
|
||||
int transition_time;
|
||||
int delay_bound;
|
||||
int error_mask;
|
||||
int max_error_results;
|
||||
int max_total_results;
|
||||
int file_delete_state;
|
||||
int assimilate_state;
|
||||
int target_nresults;
|
||||
int res_id;
|
||||
int res_report_deadline;
|
||||
int res_server_state;
|
||||
int res_outcome;
|
||||
int res_validate_state;
|
||||
int res_file_delete_state;
|
||||
int res_sent_time;
|
||||
void clear();
|
||||
};
|
||||
|
||||
#if 0
|
||||
#define WORKSEQ_STATE_UNASSIGNED 0
|
||||
#define WORKSEQ_STATE_ASSIGNED 1
|
||||
|
@ -537,6 +562,22 @@ public:
|
|||
void db_parse(MYSQL_ROW &row);
|
||||
};
|
||||
|
||||
class DB_TRANSITIONER_QUEUE : public DB_BASE, public TRANSITIONER_QUEUE {
|
||||
public:
|
||||
DB_TRANSITIONER_QUEUE();
|
||||
|
||||
MYSQL_ROW_OFFSET current_entry_start_position;
|
||||
int current_entry_workunit_id;
|
||||
|
||||
int enumerate_entries(int transition_time, int ntotal_transitioners, int ntransitioner, int nresult_limit);
|
||||
void parse_entry(MYSQL_RES *result, MYSQL_ROW& row);
|
||||
void parse_result(MYSQL_RES *result, MYSQL_ROW& row);
|
||||
|
||||
int seek_first_result();
|
||||
int seek_next_result();
|
||||
|
||||
};
|
||||
|
||||
#if 0
|
||||
class DB_WORKSEQ : public DB_BASE, public WORKSEQ {
|
||||
public:
|
||||
|
|
61
db/db_base.C
61
db/db_base.C
|
@ -253,6 +253,67 @@ int DB_BASE::sum(double& x, char* field, char* clause) {
|
|||
return get_double(query, x);
|
||||
}
|
||||
|
||||
|
||||
DB_BASE_PERF::DB_BASE_PERF(DB_CONN& p) : db(&p) {
|
||||
cursor.active = false;
|
||||
}
|
||||
|
||||
int DB_BASE_PERF::fetch_field_value(MYSQL_RES *result, MYSQL_ROW& row, const char* field_name, int& field_value)
|
||||
{
|
||||
unsigned int num_fields;
|
||||
unsigned int i;
|
||||
MYSQL_FIELD* fields;
|
||||
|
||||
num_fields = mysql_num_fields(result);
|
||||
fields = mysql_fetch_fields(result);
|
||||
for(i = 0; i < num_fields; i++)
|
||||
{
|
||||
if (0 == strncmp(field_name, fields[i].name, strlen(field_name))) {
|
||||
field_value = safe_atoi(row[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int DB_BASE_PERF::fetch_field_value(MYSQL_RES *result, MYSQL_ROW& row, const char* field_name, float& field_value)
|
||||
{
|
||||
unsigned int num_fields;
|
||||
unsigned int i;
|
||||
MYSQL_FIELD* fields;
|
||||
|
||||
num_fields = mysql_num_fields(result);
|
||||
fields = mysql_fetch_fields(result);
|
||||
for(i = 0; i < num_fields; i++)
|
||||
{
|
||||
if (0 == strncmp(field_name, fields[i].name, strlen(field_name))) {
|
||||
field_value = safe_atof(row[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int DB_BASE_PERF::fetch_field_value(MYSQL_RES *result, MYSQL_ROW& row, const char* field_name, char* field_value, int field_size)
|
||||
{
|
||||
unsigned int num_fields;
|
||||
unsigned int i;
|
||||
MYSQL_FIELD* fields;
|
||||
|
||||
num_fields = mysql_num_fields(result);
|
||||
fields = mysql_fetch_fields(result);
|
||||
for(i = 0; i < num_fields; i++)
|
||||
{
|
||||
if (0 == strncmp(field_name, fields[i].name, strlen(field_name))) {
|
||||
memset(field_value, '\0', field_size);
|
||||
strlcpy(field_value, row[i], field_size);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// convert a string into a form that allows it to be used
|
||||
// in SQL queries delimited by single quotes:
|
||||
// replace ' with \', \ with \\
|
||||
|
|
48
db/db_base.h
48
db/db_base.h
|
@ -22,6 +22,29 @@
|
|||
|
||||
#include "mysql.h"
|
||||
|
||||
// if SQL columns are not 'not null', you must use these safe_atoi, safe_atof
|
||||
// instead of atoi, atof, since the strings returned by MySQL may be NULL.
|
||||
//
|
||||
inline int safe_atoi(const char* s) {
|
||||
if (!s) return 0;
|
||||
return atoi(s);
|
||||
}
|
||||
|
||||
inline float safe_atof(const char* s) {
|
||||
if (!s) return 0;
|
||||
return atof(s);
|
||||
}
|
||||
|
||||
#define strcpy2(x, y) \
|
||||
{ \
|
||||
char* z = y; \
|
||||
if (!z) { \
|
||||
x[0]=0; \
|
||||
} else { \
|
||||
strlcpy(x, z, sizeof(x)); \
|
||||
} \
|
||||
}
|
||||
|
||||
struct CURSOR {
|
||||
bool active;
|
||||
MYSQL_RES *rp;
|
||||
|
@ -38,7 +61,6 @@ public:
|
|||
int insert_id();
|
||||
void print_error(char*);
|
||||
const char* error_string();
|
||||
bool is_high_priority;
|
||||
|
||||
MYSQL* mysql;
|
||||
};
|
||||
|
@ -70,15 +92,21 @@ public:
|
|||
virtual void db_parse(MYSQL_ROW&);
|
||||
};
|
||||
|
||||
#define strcpy2(x, y) \
|
||||
{ \
|
||||
char* z = y; \
|
||||
if (!z) { \
|
||||
x[0]=0; \
|
||||
} else { \
|
||||
strlcpy(x, z, sizeof(x)); \
|
||||
} \
|
||||
}
|
||||
// Base for derived classes that can access the DB
|
||||
// Defines various generic operations on DB tables
|
||||
// for specially designed queries
|
||||
//
|
||||
class DB_BASE_PERF {
|
||||
public:
|
||||
DB_BASE_PERF(DB_CONN&);
|
||||
|
||||
int fetch_field_value(MYSQL_RES* result, MYSQL_ROW& row, const char* field_name, int& field_value);
|
||||
int fetch_field_value(MYSQL_RES* result, MYSQL_ROW& row, const char* field_name, float& field_value);
|
||||
int fetch_field_value(MYSQL_RES* result, MYSQL_ROW& row, const char* field_name, char* field_value, int field_size);
|
||||
|
||||
DB_CONN* db;
|
||||
CURSOR cursor;
|
||||
};
|
||||
|
||||
void escape_string(char* field, int len);
|
||||
void unescape_string(char* p, int len);
|
||||
|
|
Loading…
Reference in New Issue