diff --git a/api/gutil.C b/api/gutil.C
index c137d418b8..fea63622c3 100755
--- a/api/gutil.C
+++ b/api/gutil.C
@@ -729,13 +729,13 @@ void RIBBON_GRAPH::draw_y(int i) {
void RIBBON_GRAPH::draw_tick(int i) {
GLfloat pt[3];
- double r1 = i/(double)len;
+ double r1 = ticks[i]/(double)len;
pt[0] = pos[0] + r1*size[0];
pt[1] = pos[1] + (1.-tick_yfrac)*size[1];
pt[2] = pos[2];
glVertex3fv(pt);
- pt[1] = pos[1] + size[1];
+ pt[1] = pos[1] + size[1]*1.1;
glVertex3fv(pt);
pt[2] = pos[2] + size[2];
glVertex3fv(pt);
@@ -763,6 +763,7 @@ void RIBBON_GRAPH::draw(float* d, int ln, bool with_ticks) {
}
draw_x(len-1);
if (with_ticks) {
+ mode_shaded(tick_color);
for (i=0; i<3; i++) {
draw_tick(i);
}
diff --git a/client/client_state.C b/client/client_state.C
index 441ef76190..6093bd23b2 100644
--- a/client/client_state.C
+++ b/client/client_state.C
@@ -1060,7 +1060,7 @@ int CLIENT_STATE::link_app_version(PROJECT* p, APP_VERSION* avp) {
app = lookup_app(p, avp->app_name);
if (!app) {
msg_printf(0, MSG_ERROR, "app_version refers to nonexistent app: %s\n", avp->app_name);
- return 1;
+ return ERR_NULL;
}
avp->app = app;
@@ -1068,9 +1068,11 @@ int CLIENT_STATE::link_app_version(PROJECT* p, APP_VERSION* avp) {
file_ref = avp->app_files[i];
fip = lookup_file_info(p, file_ref.file_name);
if (!fip) {
- msg_printf(0, MSG_ERROR, "app_version refers to nonexistent file: %s\n",
- file_ref.file_name);
- return 1;
+ msg_printf(0, MSG_ERROR,
+ "app_version refers to nonexistent file: %s\n",
+ file_ref.file_name
+ );
+ return ERR_NULL;
}
// any executable file associated with an app version must be signed
@@ -1089,7 +1091,7 @@ int CLIENT_STATE::link_file_ref(PROJECT* p, FILE_REF* file_refp) {
fip = lookup_file_info(p, file_refp->file_name);
if (!fip) {
msg_printf(0, MSG_ERROR, "File ref refers to nonexistent file: %s\n", file_refp->file_name);
- return 1;
+ return ERR_NULL;
}
file_refp->file_info = fip;
return 0;
@@ -1104,13 +1106,15 @@ int CLIENT_STATE::link_workunit(PROJECT* p, WORKUNIT* wup) {
app = lookup_app(p, wup->app_name);
if (!app) {
msg_printf(0, MSG_ERROR, "WU refers to nonexistent app: %s\n", wup->app_name);
- return 1;
+ return ERR_NULL;
}
avp = lookup_app_version(app, wup->version_num);
if (!avp) {
- msg_printf(0, MSG_ERROR, "WU refers to nonexistent app_version: %s %d\n",
- wup->app_name, wup->version_num);
- return 1;
+ msg_printf(0, MSG_ERROR,
+ "WU refers to nonexistent app_version: %s %d\n",
+ wup->app_name, wup->version_num
+ );
+ return ERR_NULL;
}
wup->project = p;
wup->app = app;
@@ -1130,7 +1134,7 @@ int CLIENT_STATE::link_result(PROJECT* p, RESULT* rp) {
wup = lookup_workunit(p, rp->wu_name);
if (!wup) {
fprintf(stderr, "result refers to nonexistent WU: %s\n", rp->wu_name);
- return 1;
+ return ERR_NULL;
}
rp->project = p;
rp->wup = wup;
@@ -1358,7 +1362,10 @@ bool CLIENT_STATE::garbage_collect() {
fip = *fi_iter;
if (fip->ref_cnt==0 && fip->pers_file_xfer==NULL && !fip->sticky) {
fip->delete_file();
- scope_messages.printf("CLIENT_STATE::garbage_collect(): deleting file %s\n", fip->name);
+ scope_messages.printf(
+ "CLIENT_STATE::garbage_collect(): deleting file %s\n",
+ fip->name
+ );
delete fip;
fi_iter = file_infos.erase(fi_iter);
action = true;
diff --git a/client/client_state.h b/client/client_state.h
index 27ed54fe71..ff9bd5bcad 100644
--- a/client/client_state.h
+++ b/client/client_state.h
@@ -187,6 +187,8 @@ private:
bool contacted_sched_server;
void compute_resource_debts();
public:
+ void approve_executables();
+ // get user approval of any executables for which approval is pending
bool start_new_file_xfer();
PROJECT* next_project(PROJECT*);
PROJECT* next_project_master_pending();
@@ -220,6 +222,8 @@ public:
APP_VERSION* lookup_app_version(APP*, int);
ACTIVE_TASK* lookup_active_task_by_result(RESULT*);
+ // stuff related to data-structure integrity checking
+ //
void check_project_pointer(PROJECT*);
void check_app_pointer(APP*);
void check_file_info_pointer(FILE_INFO*);
diff --git a/client/client_types.C b/client/client_types.C
index ea5af6038c..5c9711f65b 100644
--- a/client/client_types.C
+++ b/client/client_types.C
@@ -391,7 +391,7 @@ int FILE_INFO::parse(FILE* in, bool from_server) {
generated_locally = false;
status = FILE_NOT_PRESENT;
executable = false;
- approval_required = false;
+ approval_pending = false;
uploaded = false;
upload_when_present = false;
sticky = false;
@@ -439,7 +439,7 @@ int FILE_INFO::parse(FILE* in, bool from_server) {
else if (match_tag(buf, "")) generated_locally = true;
else if (parse_int(buf, "", status)) continue;
else if (match_tag(buf, "")) executable = true;
- else if (match_tag(buf, "")) approval_required = true;
+ else if (match_tag(buf, "")) approval_pending = true;
else if (match_tag(buf, "")) uploaded = true;
else if (match_tag(buf, "")) upload_when_present = true;
else if (match_tag(buf, "")) sticky = true;
@@ -467,9 +467,7 @@ int FILE_INFO::parse(FILE* in, bool from_server) {
msg_printf(NULL, MSG_ERROR, "FILE_INFO::parse(): unrecognized: %s\n", buf);
}
}
- if (from_server)
- approval_required = executable;
- return 1;
+ return ERR_XML_PARSE;
}
// Write out XML based file info
@@ -495,7 +493,7 @@ int FILE_INFO::write(FILE* out, bool to_server) {
if (generated_locally) fprintf(out, " \n");
fprintf(out, " %d\n", status);
if (executable) fprintf(out, " \n");
- if (approval_required) fprintf(out, " \n");
+ if (approval_pending) fprintf(out, " \n");
if (uploaded) fprintf(out, " \n");
if (upload_when_present) fprintf(out, " \n");
if (sticky) fprintf(out, " \n");
@@ -586,7 +584,7 @@ int APP_VERSION::parse(FILE* in) {
else if (parse_int(buf, "", version_num)) continue;
else msg_printf(NULL, MSG_ERROR, "APP_VERSION::parse(): unrecognized: %s\n", buf);
}
- return 1;
+ return ERR_XML_PARSE;
}
int APP_VERSION::write(FILE* out) {
@@ -633,7 +631,7 @@ int FILE_REF::parse(FILE* in) {
else if (match_tag(buf, "")) copy_file = true;
else msg_printf(NULL, MSG_ERROR, "FILE_REF::parse(): unrecognized: %s\n", buf);
}
- return 1;
+ return ERR_XML_PARSE;
}
int FILE_REF::write(FILE* out) {
@@ -694,7 +692,7 @@ int WORKUNIT::parse(FILE* in) {
}
else msg_printf(NULL, MSG_ERROR, "WORKUNIT::parse(): unrecognized: %s\n", buf);
}
- return 1;
+ return ERR_XML_PARSE;
}
int WORKUNIT::write(FILE* out) {
@@ -761,7 +759,7 @@ int RESULT::parse_ack(FILE* in) {
else if (parse_str(buf, "", name, sizeof(name))) continue;
else msg_printf(NULL, MSG_ERROR, "RESULT::parse(): unrecognized: %s\n", buf);
}
- return 1;
+ return ERR_XML_PARSE;
}
void RESULT::clear() {
@@ -802,7 +800,7 @@ int RESULT::parse_server(FILE* in) {
}
else msg_printf(NULL, MSG_ERROR, "RESULT::parse(): unrecognized: %s\n", buf);
}
- return 1;
+ return ERR_XML_PARSE;
}
// parse a element from state file
@@ -836,7 +834,7 @@ int RESULT::parse_state(FILE* in) {
}
else msg_printf(NULL, MSG_ERROR, "RESULT::parse(): unrecognized: %s\n", buf);
}
- return 1;
+ return ERR_XML_PARSE;
}
int RESULT::write(FILE* out, bool to_server) {
diff --git a/client/client_types.h b/client/client_types.h
index c0ce2bc7e7..7b504b69e5 100644
--- a/client/client_types.h
+++ b/client/client_types.h
@@ -153,7 +153,7 @@ public:
char signed_xml[MAX_BLOB_LEN];
char xml_signature[MAX_BLOB_LEN];
char file_signature[MAX_BLOB_LEN];
- bool approval_required; // true if the file requires user approval
+ bool approval_pending; // true if the file requires user approval
string error_msg; // if permanent error occurs during file xfer,
// it's recorded here
diff --git a/client/cs_apps.C b/client/cs_apps.C
index 4a908d5afc..c93ee48219 100644
--- a/client/cs_apps.C
+++ b/client/cs_apps.C
@@ -199,6 +199,7 @@ bool CLIENT_STATE::input_files_available(RESULT* rp) {
}
fip = fr.file_info;
if (fip->status != FILE_PRESENT) return false;
+ if (fip->approval_pending) return false;
}
for (i=0; iinput_files.size(); i++) {
diff --git a/client/cs_files.C b/client/cs_files.C
index 6c3d9412f4..2fb72515db 100644
--- a/client/cs_files.C
+++ b/client/cs_files.C
@@ -95,20 +95,26 @@ int verify_downloaded_file(char* pathname, FILE_INFO& file_info) {
pathname, file_info.file_signature, project->code_sign_key, verified
);
if (retval) {
- msg_printf(project, MSG_ERROR, "verify_downloaded_file(): %s: internal error\n",
- pathname);
+ msg_printf(project, MSG_ERROR,
+ "verify_downloaded_file(): %s: internal error\n",
+ pathname
+ );
return ERR_RSA_FAILED;
}
if (!verified) {
- msg_printf(project, MSG_ERROR, "verify_downloaded_file(): %s: file not verified\n",
- pathname);
+ msg_printf(project, MSG_ERROR,
+ "verify_downloaded_file(): %s: file not verified\n",
+ pathname
+ );
return ERR_RSA_FAILED;
}
} else if (strlen(file_info.md5_cksum)) {
retval = md5_file(pathname, cksum, file_info.nbytes);
if (strcmp(cksum, file_info.md5_cksum) || retval) {
- msg_printf(project, MSG_ERROR, "verify_downloaded_file(): %s: MD5 check failed\n",
- pathname);
+ msg_printf(project, MSG_ERROR,
+ "verify_downloaded_file(): %s: MD5 check failed\n",
+ pathname
+ );
return ERR_MD5_FAILED;
}
}
diff --git a/client/main.C b/client/main.C
index 69c433886b..69be6fca09 100644
--- a/client/main.C
+++ b/client/main.C
@@ -43,6 +43,31 @@
void create_curtain(){}
void delete_curtain(){}
+void CLIENT_STATE::approve_executables() {
+ unsigned int i;
+ char buf[256];
+
+ for (i=0; iapproval_pending) {
+ printf(
+ "BOINC has received the executable file %s\n"
+ "from project %s.\n"
+ "Its MD5 checksum is %s\n"
+ "Should BOINC accept this file (y/n)? ",
+ fip->name,
+ fip->project->project_name,
+ fip->md5_cksum
+ );
+ scanf("%s", buf);
+ if (buf[0]=='y' || buf[0]=='Y') {
+ fip->approval_pending = false;
+ set_client_state_dirty("approve_executables");
+ }
+ }
+ }
+}
+
// This gets called when the client fails to add a project
//
void project_add_failed(PROJECT* project) {
@@ -163,6 +188,11 @@ int main(int argc, char** argv) {
fflush(stdout);
}
+ // check for executables files that need approval;
+ // in the GUI version this is done in event loop
+ //
+ gstate.approve_executables();
+
if (gstate.time_to_exit()) {
msg_printf(NULL, MSG_INFO, "Time to exit");
break;
diff --git a/client/pers_file_xfer.C b/client/pers_file_xfer.C
index ecda8fc018..824864d0f7 100644
--- a/client/pers_file_xfer.C
+++ b/client/pers_file_xfer.C
@@ -225,6 +225,11 @@ bool PERS_FILE_XFER::poll(time_t now) {
// it's an executable or normal file
//
retval = fip->set_permissions();
+ if (fip->executable && gstate.global_prefs.confirm_executable) {
+#ifndef _WIN32
+ fip->approval_pending = true;
+#endif
+ }
fip->status = FILE_PRESENT;
}
xfer_done = true;
diff --git a/todo b/todo
index bfb1d52a46..0b8a6b1235 100755
--- a/todo
+++ b/todo
@@ -1,4 +1,5 @@
Don't render graphics if minimized
+add executable approval to win GUI
------------------------
DON'T ADD ANYTHING TO HERE. USE THE TASKBASE INSTEAD.