2005-01-20 23:22:22 +00:00
|
|
|
// Berkeley Open Infrastructure for Network Computing
|
|
|
|
// http://boinc.berkeley.edu
|
|
|
|
// Copyright (C) 2005 University of California
|
2003-08-21 00:07:03 +00:00
|
|
|
//
|
2005-01-20 23:22:22 +00:00
|
|
|
// This is free software; you can redistribute it and/or
|
|
|
|
// modify it under the terms of the GNU Lesser General Public
|
|
|
|
// License as published by the Free Software Foundation;
|
|
|
|
// either version 2.1 of the License, or (at your option) any later version.
|
2003-08-21 00:07:03 +00:00
|
|
|
//
|
2005-01-20 23:22:22 +00:00
|
|
|
// This software is distributed in the hope that it will be useful,
|
|
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
|
|
// See the GNU Lesser General Public License for more details.
|
2002-09-27 23:43:29 +00:00
|
|
|
//
|
2005-01-20 23:22:22 +00:00
|
|
|
// To view the GNU Lesser General Public License visit
|
|
|
|
// http://www.gnu.org/copyleft/lesser.html
|
|
|
|
// or write to the Free Software Foundation, Inc.,
|
|
|
|
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
2002-09-27 23:43:29 +00:00
|
|
|
|
2004-03-04 11:41:43 +00:00
|
|
|
#ifdef _WIN32
|
2004-06-16 23:16:08 +00:00
|
|
|
#include "boinc_win.h"
|
2004-03-04 11:41:43 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef _WIN32
|
2005-11-21 18:34:44 +00:00
|
|
|
#include "config.h"
|
2004-07-13 13:54:09 +00:00
|
|
|
#include <cstdio>
|
2003-06-24 00:17:36 +00:00
|
|
|
#include <cassert>
|
2004-10-04 18:47:20 +00:00
|
|
|
#ifdef HAVE_SYS_STAT_H
|
|
|
|
#include <sys/stat.h>
|
|
|
|
#endif
|
2004-03-04 11:41:43 +00:00
|
|
|
#endif
|
2002-09-27 23:43:29 +00:00
|
|
|
|
2004-04-08 08:15:23 +00:00
|
|
|
#include "filesys.h"
|
2004-10-01 18:48:34 +00:00
|
|
|
#include "parse.h"
|
2007-02-21 16:26:51 +00:00
|
|
|
#include "str_util.h"
|
2002-09-27 23:43:29 +00:00
|
|
|
#include "client_state.h"
|
2004-04-08 08:15:23 +00:00
|
|
|
#include "client_msgs.h"
|
2006-06-22 19:40:30 +00:00
|
|
|
#include "log_flags.h"
|
2002-09-27 23:43:29 +00:00
|
|
|
#include "error_numbers.h"
|
|
|
|
#include "file_names.h"
|
|
|
|
|
2004-06-30 18:17:21 +00:00
|
|
|
using std::string;
|
|
|
|
|
2004-10-01 18:48:34 +00:00
|
|
|
// write account_*.xml file.
|
|
|
|
// NOTE: this is called only when
|
|
|
|
// 1) attach to a project, and
|
|
|
|
// 2) after a scheduler RPC
|
|
|
|
// So in either case PROJECT.project_prefs
|
|
|
|
// (which normally is undefined) is valid
|
|
|
|
//
|
|
|
|
int PROJECT::write_account_file() {
|
|
|
|
char path[256];
|
|
|
|
FILE* f;
|
|
|
|
int retval;
|
|
|
|
|
|
|
|
get_account_filename(master_url, path);
|
|
|
|
f = boinc_fopen(TEMP_FILE_NAME, "w");
|
|
|
|
if (!f) return ERR_FOPEN;
|
|
|
|
|
|
|
|
fprintf(f,
|
|
|
|
"<account>\n"
|
|
|
|
" <master_url>%s</master_url>\n"
|
|
|
|
" <authenticator>%s</authenticator>\n",
|
|
|
|
master_url,
|
|
|
|
authenticator
|
|
|
|
);
|
|
|
|
// put project name in account file for informational purposes only
|
|
|
|
// (client state file is authoritative)
|
|
|
|
//
|
|
|
|
if (strlen(project_name)) {
|
|
|
|
fprintf(f, " <project_name>%s</project_name>\n", project_name);
|
|
|
|
}
|
|
|
|
fprintf(f, "<project_preferences>\n%s</project_preferences>\n",
|
|
|
|
project_prefs.c_str()
|
|
|
|
);
|
|
|
|
fprintf(f, gui_urls.c_str());
|
|
|
|
fprintf(f, "</account>\n");
|
|
|
|
fclose(f);
|
|
|
|
retval = boinc_rename(TEMP_FILE_NAME, path);
|
|
|
|
if (retval) return ERR_RENAME;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2006-07-14 21:08:12 +00:00
|
|
|
// parse an account_*.xml file, ignoring <venue> elements
|
|
|
|
// (since we don't know the host venue yet)
|
2004-10-01 18:48:34 +00:00
|
|
|
//
|
|
|
|
int PROJECT::parse_account(FILE* in) {
|
2006-07-14 21:08:12 +00:00
|
|
|
char buf[256];
|
2004-10-01 18:48:34 +00:00
|
|
|
int retval;
|
|
|
|
|
|
|
|
strcpy(master_url, "");
|
|
|
|
strcpy(authenticator, "");
|
|
|
|
while (fgets(buf, 256, in)) {
|
|
|
|
if (match_tag(buf, "<account>")) continue;
|
|
|
|
if (match_tag(buf, "<project_preferences>")) continue;
|
|
|
|
if (match_tag(buf, "</project_preferences>")) continue;
|
|
|
|
if (match_tag(buf, "</account>")) {
|
|
|
|
return 0;
|
2006-07-14 21:08:12 +00:00
|
|
|
} else if (match_tag(buf, "<venue")) {
|
|
|
|
std::string devnull;
|
|
|
|
retval = copy_element_contents(in, "</venue>", devnull);
|
|
|
|
if (retval) return retval;
|
2004-10-01 18:48:34 +00:00
|
|
|
continue;
|
2006-07-14 21:08:12 +00:00
|
|
|
} else if (parse_str(buf, "<master_url>", master_url, sizeof(master_url))) {
|
2004-10-01 18:48:34 +00:00
|
|
|
canonicalize_master_url(master_url);
|
|
|
|
continue;
|
2006-07-14 21:08:12 +00:00
|
|
|
} else if (parse_str(buf, "<authenticator>", authenticator, sizeof(authenticator))) continue;
|
2004-10-01 18:48:34 +00:00
|
|
|
else if (parse_double(buf, "<resource_share>", resource_share)) continue;
|
|
|
|
else if (parse_str(buf, "<project_name>", project_name, sizeof(project_name))) continue;
|
2007-05-14 19:18:45 +00:00
|
|
|
else if (match_tag(buf, "<gui_urls>")) {
|
2004-10-01 18:48:34 +00:00
|
|
|
string foo;
|
|
|
|
retval = copy_element_contents(in, "</gui_urls>", foo);
|
|
|
|
if (retval) return retval;
|
|
|
|
gui_urls = "<gui_urls>\n"+foo+"</gui_urls>\n";
|
|
|
|
continue;
|
2006-07-14 21:08:12 +00:00
|
|
|
} else if (match_tag(buf, "<project_specific>")) {
|
2004-10-01 18:48:34 +00:00
|
|
|
retval = copy_element_contents(
|
|
|
|
in,
|
|
|
|
"</project_specific>",
|
|
|
|
project_specific_prefs
|
|
|
|
);
|
|
|
|
if (retval) return retval;
|
|
|
|
continue;
|
2006-07-14 21:08:12 +00:00
|
|
|
} else {
|
2006-06-22 19:40:30 +00:00
|
|
|
if (log_flags.unparsed_xml) {
|
2007-01-25 23:39:06 +00:00
|
|
|
msg_printf(0, MSG_INFO,
|
2006-09-07 20:39:25 +00:00
|
|
|
"[unparsed_xml] PROJECT::parse_account(): unrecognized: %s\n", buf
|
2006-06-22 19:40:30 +00:00
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
2004-10-01 18:48:34 +00:00
|
|
|
}
|
|
|
|
return ERR_XML_PARSE;
|
|
|
|
}
|
|
|
|
|
2006-07-14 21:08:12 +00:00
|
|
|
// scan an account_*.xml file, looking for a <venue> element
|
|
|
|
// that matches this host's venue,
|
|
|
|
// and parsing that for resource share and prefs.
|
|
|
|
// Call this only after client_state.xml has been read
|
|
|
|
// (so that we know the host venue)
|
|
|
|
//
|
|
|
|
int PROJECT::parse_account_file_venue() {
|
|
|
|
char buf[256], venue[256], path[256];
|
|
|
|
int retval;
|
|
|
|
bool in_right_venue = false;
|
|
|
|
|
|
|
|
get_account_filename(master_url, path);
|
|
|
|
FILE* in = boinc_fopen(path, "r");
|
|
|
|
if (!in) return ERR_FOPEN;
|
|
|
|
|
|
|
|
while (fgets(buf, 256, in)) {
|
|
|
|
if (match_tag(buf, "</account>")) {
|
|
|
|
fclose(in);
|
|
|
|
return 0;
|
|
|
|
} else if (match_tag(buf, "<venue")) {
|
|
|
|
parse_attr(buf, "name", venue, sizeof(venue));
|
|
|
|
if (!strcmp(venue, host_venue)) {
|
|
|
|
using_venue_specific_prefs = true;
|
|
|
|
in_right_venue = true;
|
|
|
|
} else {
|
|
|
|
std::string devnull;
|
|
|
|
retval = copy_element_contents(in, "</venue>", devnull);
|
|
|
|
if (retval) return retval;
|
|
|
|
}
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (!in_right_venue) continue;
|
|
|
|
if (match_tag(buf, "</venue>")) {
|
|
|
|
in_right_venue = false;
|
|
|
|
continue;
|
|
|
|
} else if (match_tag(buf, "<project_specific>")) {
|
|
|
|
retval = copy_element_contents(
|
|
|
|
in,
|
|
|
|
"</project_specific>",
|
|
|
|
project_specific_prefs
|
|
|
|
);
|
|
|
|
if (retval) return retval;
|
|
|
|
continue;
|
|
|
|
} else if (parse_double(buf, "<resource_share>", resource_share)) {
|
|
|
|
continue;
|
|
|
|
} else {
|
|
|
|
if (log_flags.unparsed_xml) {
|
2007-01-25 23:39:06 +00:00
|
|
|
msg_printf(0, MSG_INFO,
|
2006-09-07 20:39:25 +00:00
|
|
|
"[unparsed_xml] parse_account_file_venue(): unrecognized: %s\n", buf
|
2006-07-14 21:08:12 +00:00
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
fclose(in);
|
|
|
|
return ERR_XML_PARSE;
|
|
|
|
}
|
|
|
|
|
2004-10-01 18:48:34 +00:00
|
|
|
int PROJECT::parse_account_file() {
|
|
|
|
char path[256];
|
|
|
|
int retval;
|
|
|
|
FILE* f;
|
|
|
|
|
|
|
|
get_account_filename(master_url, path);
|
2005-03-10 22:05:42 +00:00
|
|
|
f = boinc_fopen(path, "r");
|
2004-10-01 18:48:34 +00:00
|
|
|
if (!f) return ERR_FOPEN;
|
|
|
|
retval = parse_account(f);
|
|
|
|
fclose(f);
|
|
|
|
return retval;
|
|
|
|
}
|
|
|
|
|
2006-07-14 21:08:12 +00:00
|
|
|
int CLIENT_STATE::parse_account_files_venue() {
|
|
|
|
unsigned int i;
|
|
|
|
|
|
|
|
for (i=0; i<projects.size(); i++) {
|
|
|
|
PROJECT* p = projects[i];
|
|
|
|
if (strlen(p->host_venue)) {
|
|
|
|
p->parse_account_file_venue();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2002-09-27 23:43:29 +00:00
|
|
|
int CLIENT_STATE::parse_account_files() {
|
2003-06-24 00:17:36 +00:00
|
|
|
string name;
|
2002-09-27 23:43:29 +00:00
|
|
|
PROJECT* project;
|
|
|
|
FILE* f;
|
2004-09-22 21:08:26 +00:00
|
|
|
int retval;
|
2002-09-27 23:43:29 +00:00
|
|
|
|
2003-06-24 00:17:36 +00:00
|
|
|
DirScanner dir(".");
|
|
|
|
while (dir.scan(name)) {
|
2005-06-28 05:43:22 +00:00
|
|
|
if (!is_file(name.c_str())) continue;
|
|
|
|
if (!is_account_file(name.c_str())) continue;
|
|
|
|
|
|
|
|
f = boinc_fopen(name.c_str(), "r");
|
|
|
|
if (!f) continue;
|
|
|
|
project = new PROJECT;
|
|
|
|
|
|
|
|
// Assume master_url_fetch_pending, sched_rpc_pending are
|
|
|
|
// true until we read client_state.xml
|
|
|
|
//
|
|
|
|
project->master_url_fetch_pending = true;
|
2006-09-01 22:21:20 +00:00
|
|
|
project->sched_rpc_pending = RPC_REASON_INIT;
|
2005-06-28 05:43:22 +00:00
|
|
|
retval = project->parse_account(f);
|
|
|
|
fclose(f);
|
|
|
|
if (retval) {
|
2007-01-25 23:39:06 +00:00
|
|
|
msg_printf(NULL, MSG_INTERNAL_ERROR,
|
2005-06-28 05:43:22 +00:00
|
|
|
"Couldn't parse account file %s", name.c_str()
|
|
|
|
);
|
|
|
|
delete project;
|
|
|
|
} else {
|
|
|
|
if (lookup_project(project->master_url)) {
|
2007-01-25 23:39:06 +00:00
|
|
|
msg_printf(NULL, MSG_INFO,
|
2005-06-28 05:43:22 +00:00
|
|
|
"Duplicate account file %s - ignoring", name.c_str()
|
2004-09-22 21:08:26 +00:00
|
|
|
);
|
2005-06-28 05:43:22 +00:00
|
|
|
delete project;
|
2004-09-22 21:08:26 +00:00
|
|
|
} else {
|
2005-06-28 05:43:22 +00:00
|
|
|
projects.push_back(project);
|
2004-09-22 21:08:26 +00:00
|
|
|
}
|
2002-09-27 23:43:29 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2005-08-11 04:45:16 +00:00
|
|
|
void DAILY_STATS::clear() {
|
|
|
|
memset(this, 0, sizeof(DAILY_STATS));
|
|
|
|
}
|
|
|
|
|
|
|
|
int DAILY_STATS::parse(FILE* in) {
|
|
|
|
char buf[256];
|
|
|
|
clear();
|
|
|
|
while (fgets(buf, 256, in)) {
|
2007-01-11 00:20:58 +00:00
|
|
|
if (match_tag(buf, "</daily_statistics>")) {
|
|
|
|
if (day == 0) return ERR_XML_PARSE;
|
|
|
|
return 0;
|
|
|
|
}
|
2005-08-11 04:45:16 +00:00
|
|
|
else if (parse_double(buf, "<day>", day)) continue;
|
|
|
|
else if (parse_double(buf, "<user_total_credit>", user_total_credit)) continue;
|
|
|
|
else if (parse_double(buf, "<user_expavg_credit>", user_expavg_credit)) continue;
|
|
|
|
else if (parse_double(buf, "<host_total_credit>", host_total_credit)) continue;
|
|
|
|
else if (parse_double(buf, "<host_expavg_credit>", host_expavg_credit)) continue;
|
|
|
|
}
|
|
|
|
return ERR_XML_PARSE;
|
|
|
|
}
|
|
|
|
|
2007-01-11 00:20:58 +00:00
|
|
|
bool operator < (const DAILY_STATS& x1, const DAILY_STATS& x2) {
|
|
|
|
return (x1.day < x2.day);
|
|
|
|
}
|
|
|
|
|
2005-04-04 06:02:36 +00:00
|
|
|
// parse an statistics_*.xml file
|
|
|
|
//
|
|
|
|
int PROJECT::parse_statistics(FILE* in) {
|
2005-08-11 04:45:16 +00:00
|
|
|
int retval;
|
2005-04-04 06:02:36 +00:00
|
|
|
char buf[256];
|
|
|
|
|
|
|
|
while (fgets(buf, 256, in)) {
|
2007-01-11 00:20:58 +00:00
|
|
|
if (match_tag(buf, "</project_statistics>")) {
|
|
|
|
sort(statistics.begin(), statistics.end());
|
|
|
|
return 0;
|
|
|
|
}
|
2005-04-04 06:02:36 +00:00
|
|
|
else if (match_tag(buf, "<project_statistics>")) continue;
|
|
|
|
else if (match_tag(buf, "<daily_statistics>")) {
|
2005-08-11 04:45:16 +00:00
|
|
|
DAILY_STATS daily_stats;
|
|
|
|
retval = daily_stats.parse(in);
|
2007-01-11 00:20:58 +00:00
|
|
|
if (!retval) {
|
|
|
|
statistics.push_back(daily_stats);
|
|
|
|
}
|
2005-04-04 06:02:36 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
else if (parse_str(buf, "<master_url>", master_url, sizeof(master_url))) {
|
|
|
|
canonicalize_master_url(master_url);
|
|
|
|
continue;
|
|
|
|
}
|
2006-06-22 19:40:30 +00:00
|
|
|
else {
|
|
|
|
if (log_flags.unparsed_xml) {
|
2007-01-25 23:39:06 +00:00
|
|
|
msg_printf(0, MSG_INFO,
|
2006-09-07 20:39:25 +00:00
|
|
|
"[unparsed_xml] PROJECT::parse_statistics(): unrecognized: %s\n", buf
|
2006-06-22 19:40:30 +00:00
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
2005-04-04 06:02:36 +00:00
|
|
|
}
|
|
|
|
return ERR_XML_PARSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
int CLIENT_STATE::parse_statistics_files() {
|
|
|
|
string name;
|
|
|
|
PROJECT* project;
|
|
|
|
FILE* f;
|
|
|
|
int retval;
|
|
|
|
|
|
|
|
DirScanner dir(".");
|
|
|
|
while (dir.scan(name)) {
|
|
|
|
if (is_statistics_file(name.c_str())) {
|
|
|
|
f = boinc_fopen(name.c_str(), "r");
|
|
|
|
if (!f) continue;
|
|
|
|
PROJECT* temp = new PROJECT;
|
|
|
|
retval = temp->parse_statistics(f);
|
|
|
|
fclose(f);
|
|
|
|
if (retval) {
|
2007-01-25 23:39:06 +00:00
|
|
|
msg_printf(NULL, MSG_INTERNAL_ERROR,
|
2006-08-24 20:33:46 +00:00
|
|
|
"Couldn't parse %s", name.c_str()
|
2005-04-04 06:02:36 +00:00
|
|
|
);
|
|
|
|
} else {
|
|
|
|
project=lookup_project(temp->master_url);
|
|
|
|
if (project==NULL) {
|
2007-01-25 23:39:06 +00:00
|
|
|
msg_printf(NULL, MSG_INFO,
|
2006-08-24 20:33:46 +00:00
|
|
|
"Project for %s not found - ignoring",
|
2006-01-17 22:48:09 +00:00
|
|
|
name.c_str()
|
2005-04-04 06:02:36 +00:00
|
|
|
);
|
|
|
|
} else {
|
2005-08-11 04:45:16 +00:00
|
|
|
for (std::vector<DAILY_STATS>::const_iterator i=temp->statistics.begin();
|
2005-04-04 06:02:36 +00:00
|
|
|
i!=temp->statistics.end(); ++i
|
|
|
|
) {
|
|
|
|
project->statistics.push_back(*i);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int PROJECT::write_statistics_file() {
|
|
|
|
char path[256];
|
|
|
|
FILE* f;
|
|
|
|
int retval;
|
|
|
|
|
|
|
|
get_statistics_filename(master_url, path);
|
|
|
|
f = boinc_fopen(TEMP_FILE_NAME, "w");
|
|
|
|
if (!f) return ERR_FOPEN;
|
|
|
|
fprintf(f,
|
|
|
|
"<project_statistics>\n"
|
|
|
|
" <master_url>%s</master_url>\n",
|
|
|
|
master_url
|
|
|
|
);
|
|
|
|
|
2005-08-11 04:45:16 +00:00
|
|
|
for (std::vector<DAILY_STATS>::iterator i=statistics.begin();
|
2005-04-04 06:02:36 +00:00
|
|
|
i!=statistics.end(); ++i
|
|
|
|
) {
|
|
|
|
fprintf(f,
|
|
|
|
" <daily_statistics>\n"
|
|
|
|
" <day>%f</day>\n"
|
|
|
|
" <user_total_credit>%f</user_total_credit>\n"
|
|
|
|
" <user_expavg_credit>%f</user_expavg_credit>\n"
|
|
|
|
" <host_total_credit>%f</host_total_credit>\n"
|
|
|
|
" <host_expavg_credit>%f</host_expavg_credit>\n"
|
|
|
|
" </daily_statistics>\n",
|
|
|
|
i->day,
|
|
|
|
i->user_total_credit,
|
|
|
|
i->user_expavg_credit,
|
|
|
|
i->host_total_credit,
|
|
|
|
i->host_expavg_credit
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
fprintf(f,
|
|
|
|
"</project_statistics>\n"
|
|
|
|
);
|
|
|
|
|
|
|
|
fclose(f);
|
|
|
|
retval = boinc_rename(TEMP_FILE_NAME, path);
|
|
|
|
if (retval) return ERR_RENAME;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2005-12-09 22:29:21 +00:00
|
|
|
int CLIENT_STATE::add_project(
|
2006-12-26 00:37:25 +00:00
|
|
|
const char* master_url, const char* _auth, const char* project_name,
|
2005-12-09 22:29:21 +00:00
|
|
|
bool attached_via_acct_mgr
|
|
|
|
) {
|
2006-03-03 21:34:03 +00:00
|
|
|
char path[256], canonical_master_url[256], auth[256], dir[256];
|
2002-12-06 19:44:31 +00:00
|
|
|
PROJECT* project;
|
|
|
|
FILE* f;
|
2003-02-06 19:01:49 +00:00
|
|
|
int retval;
|
2002-12-06 19:44:31 +00:00
|
|
|
|
2007-03-13 19:33:27 +00:00
|
|
|
if (config.disallow_attach) {
|
|
|
|
return ERR_USER_PERMISSION;
|
|
|
|
}
|
|
|
|
|
2004-02-28 19:11:40 +00:00
|
|
|
safe_strcpy(canonical_master_url, master_url);
|
2004-07-11 21:54:00 +00:00
|
|
|
strip_whitespace(canonical_master_url);
|
2004-02-28 19:11:40 +00:00
|
|
|
canonicalize_master_url(canonical_master_url);
|
2005-02-27 20:06:51 +00:00
|
|
|
if (!valid_master_url(canonical_master_url)) {
|
2007-01-25 23:39:06 +00:00
|
|
|
msg_printf(0, MSG_USER_ERROR, "Invalid URL: %s", canonical_master_url);
|
2004-07-11 21:54:00 +00:00
|
|
|
return ERR_INVALID_URL;
|
|
|
|
}
|
|
|
|
|
|
|
|
safe_strcpy(auth, _auth);
|
|
|
|
strip_whitespace(auth);
|
|
|
|
if (!strlen(auth)) {
|
2007-01-25 23:39:06 +00:00
|
|
|
msg_printf(0, MSG_USER_ERROR, "Missing account key");
|
2004-07-11 21:54:00 +00:00
|
|
|
return ERR_AUTHENTICATOR;
|
|
|
|
}
|
2003-06-06 17:43:45 +00:00
|
|
|
|
2006-03-03 21:34:03 +00:00
|
|
|
// check if we're already attached to this project
|
2003-02-13 22:49:26 +00:00
|
|
|
//
|
2004-02-28 19:11:40 +00:00
|
|
|
if (lookup_project(canonical_master_url)) {
|
2007-01-25 23:39:06 +00:00
|
|
|
msg_printf(0, MSG_USER_ERROR, "Already attached to %s", canonical_master_url);
|
2003-05-21 17:59:10 +00:00
|
|
|
return ERR_ALREADY_ATTACHED;
|
|
|
|
}
|
2002-12-06 19:44:31 +00:00
|
|
|
|
2003-02-06 19:01:49 +00:00
|
|
|
// create project state
|
2003-02-13 22:49:26 +00:00
|
|
|
//
|
2003-05-13 18:55:07 +00:00
|
|
|
project = new PROJECT;
|
2004-02-28 19:11:40 +00:00
|
|
|
strcpy(project->master_url, canonical_master_url);
|
2004-07-11 21:54:00 +00:00
|
|
|
strcpy(project->authenticator, auth);
|
2006-12-26 00:37:25 +00:00
|
|
|
strcpy(project->project_name, project_name);
|
2005-12-09 22:29:21 +00:00
|
|
|
project->attached_via_acct_mgr = attached_via_acct_mgr;
|
2003-05-15 17:10:26 +00:00
|
|
|
|
2003-05-13 18:55:07 +00:00
|
|
|
retval = project->write_account_file();
|
2003-03-08 23:48:05 +00:00
|
|
|
if (retval) return retval;
|
2003-05-13 18:55:07 +00:00
|
|
|
|
2004-02-28 19:11:40 +00:00
|
|
|
get_account_filename(canonical_master_url, path);
|
2005-03-10 22:05:42 +00:00
|
|
|
f = boinc_fopen(path, "r");
|
2002-12-06 19:44:31 +00:00
|
|
|
if (!f) return ERR_FOPEN;
|
|
|
|
retval = project->parse_account(f);
|
|
|
|
fclose(f);
|
2003-05-13 18:55:07 +00:00
|
|
|
if (retval) return retval;
|
2002-12-06 19:44:31 +00:00
|
|
|
|
2003-02-06 19:01:49 +00:00
|
|
|
// remove any old files
|
2006-03-03 21:34:03 +00:00
|
|
|
// (unless PROJECT/app_info.xml is found, so that
|
|
|
|
// people using anonymous platform don't have to get apps again)
|
2003-02-13 22:49:26 +00:00
|
|
|
//
|
2007-03-13 19:33:27 +00:00
|
|
|
get_project_dir(project, dir, sizeof(dir));
|
2006-03-03 21:34:03 +00:00
|
|
|
sprintf(path, "%s/%s", dir, APP_INFO_FILE_NAME);
|
|
|
|
if (!boinc_file_exists(path)) {
|
|
|
|
retval = remove_project_dir(*project);
|
|
|
|
}
|
2002-12-06 19:44:31 +00:00
|
|
|
|
2003-02-06 19:01:49 +00:00
|
|
|
retval = make_project_dir(*project);
|
2003-02-13 22:49:26 +00:00
|
|
|
if (retval) return retval;
|
2002-12-06 19:44:31 +00:00
|
|
|
projects.push_back(project);
|
2006-09-01 22:21:20 +00:00
|
|
|
project->sched_rpc_pending = RPC_REASON_INIT;
|
2005-01-21 22:03:15 +00:00
|
|
|
set_client_state_dirty("Add project");
|
2003-02-06 19:01:49 +00:00
|
|
|
return 0;
|
2002-12-06 19:44:31 +00:00
|
|
|
}
|
2005-06-22 06:58:49 +00:00
|
|
|
|
2003-11-02 22:51:49 +00:00
|
|
|
int CLIENT_STATE::parse_preferences_for_user_files() {
|
|
|
|
unsigned int i;
|
|
|
|
|
|
|
|
for (i=0; i<projects.size(); i++) {
|
|
|
|
projects[i]->parse_preferences_for_user_files();
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
2004-12-08 00:40:19 +00:00
|
|
|
|
2005-01-02 18:29:53 +00:00
|
|
|
const char *BOINC_RCSID_497223a3f8 = "$Id$";
|