// Berkeley Open Infrastructure for Network Computing // http://boinc.berkeley.edu // Copyright (C) 2005 University of California // // 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. // // 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. // // 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 #ifdef _WIN32 #include "boinc_win.h" #endif #ifndef _WIN32 #include "config.h" #endif #include "parse.h" #include "error_numbers.h" #include "client_msgs.h" #include "util.h" #include "file_names.h" #include "filesys.h" #include "client_state.h" #include "gui_http.h" #include "acct_mgr.h" static const char *run_mode_name[] = {"", "always", "auto", "never"}; int ACCT_MGR_OP::do_rpc( std::string url, std::string name, std::string password_hash ) { int retval; unsigned int i; char buf[256]; strcpy(buf, url.c_str()); error_num = ERR_IN_PROGRESS; if (!strlen(buf) && strlen(gstate.acct_mgr_info.acct_mgr_url)) { msg_printf(NULL, MSG_INFO, "Removing account manager info"); gstate.acct_mgr_info.clear(); boinc_delete_file(ACCT_MGR_URL_FILENAME); boinc_delete_file(ACCT_MGR_LOGIN_FILENAME); error_num = 0; return 0; } canonicalize_master_url(buf); if (!valid_master_url(buf)) { error_num = ERR_INVALID_URL; return 0; } strcpy(ami.acct_mgr_url, url.c_str()); strcpy(ami.acct_mgr_name, ""); strcpy(ami.login_name, name.c_str()); strcpy(ami.password_hash, password_hash.c_str()); FILE* f = boinc_fopen(ACCT_MGR_REQUEST_FILENAME, "w"); if (!f) return ERR_FOPEN; fprintf(f, "\n" " %s\n" " %s\n" " %s\n" " %d.%d.%d\n" " %s\n", name.c_str(), password_hash.c_str(), gstate.host_info.host_cpid, gstate.core_client_major_version, gstate.core_client_minor_version, gstate.core_client_release, run_mode_name[gstate.user_run_request] ); for (i=0; iattached_via_acct_mgr) { fprintf(f, " \n" " %s\n" " %s\n" " %d\n" " %s\n" " \n", p->master_url, p->project_name, p->suspended_via_gui, p->authenticator ); } } fprintf(f, "\n"); fclose(f); sprintf(buf, "%srpc.php", url.c_str()); retval = gstate.gui_http.do_rpc_post( this, buf, ACCT_MGR_REQUEST_FILENAME, ACCT_MGR_REPLY_FILENAME ); if (retval) { error_num = retval; return retval; } msg_printf(NULL, MSG_INFO, "Contacting account manager at %s", url.c_str()); return 0; } int AM_ACCOUNT::parse(MIOFILE& in) { char buf[256]; detach = false; while (in.fgets(buf, sizeof(buf))) { if (match_tag(buf, "")) { if (url.length() && authenticator.length()) return 0; return ERR_XML_PARSE; } if (parse_str(buf, "", url)) continue; if (parse_str(buf, "", authenticator)) continue; if (parse_bool(buf, "detach", detach)) continue; } return ERR_XML_PARSE; } int ACCT_MGR_OP::parse(MIOFILE& in) { char buf[256]; int retval; accounts.clear(); error_str = ""; repeat_sec = 0; while (in.fgets(buf, sizeof(buf))) { if (match_tag(buf, "")) return 0; if (parse_str(buf, "", ami.acct_mgr_name, 256)) continue; if (parse_str(buf, "", error_str)) continue; if (parse_double(buf, "", repeat_sec)) continue; if (match_tag(buf, "")) { AM_ACCOUNT account; retval = account.parse(in); if (!retval) accounts.push_back(account); } } return ERR_XML_PARSE; } void ACCT_MGR_OP::handle_reply(int http_op_retval) { unsigned int i; int retval; PROJECT* pp; if (http_op_retval == 0) { FILE* f = fopen(ACCT_MGR_REPLY_FILENAME, "r"); if (f) { MIOFILE mf; mf.init_file(f); retval = parse(mf); fclose(f); } else { retval = ERR_FOPEN; } } else if (error_str.size()) { retval = ERR_XML_PARSE; // ?? what should we use here ?? } else { retval = http_op_retval; } error_num = retval; if (retval) return; gstate.acct_mgr_info = ami; gstate.acct_mgr_info.write_info(); // attach to new projects // for (i=0; iauthenticator, acct.authenticator.c_str())) { msg_printf(pp, MSG_ERROR, "Already attached under another account" ); } else { msg_printf(pp, MSG_INFO, "Already attached"); pp->attached_via_acct_mgr = true; } } } else { if (!acct.detach) { msg_printf(NULL, MSG_INFO, "Attaching to %s", acct.url.c_str()); gstate.add_project(acct.url.c_str(), acct.authenticator.c_str(), true); } } } if (repeat_sec) { gstate.acct_mgr_info.next_rpc_time = gstate.now + repeat_sec; } else { gstate.acct_mgr_info.next_rpc_time = gstate.now + 86400; } gstate.set_client_state_dirty("account manager RPC"); gstate.acct_mgr_info.write_info(); } int ACCT_MGR_INFO::write_info() { FILE* p; if (strlen(acct_mgr_url)) { p = fopen(ACCT_MGR_URL_FILENAME, "w"); if (p) { fprintf( p, "\n" " %s\n" " %s\n" "\n", acct_mgr_name, acct_mgr_url ); fclose(p); } } if (strlen(login_name)) { p = fopen(ACCT_MGR_LOGIN_FILENAME, "w"); if (p) { fprintf( p, "\n" " %s\n" " %s\n" " %f\n" "\n", login_name, password_hash, next_rpc_time ); fclose(p); } } return 0; } void ACCT_MGR_INFO::clear() { strcpy(acct_mgr_name, ""); strcpy(acct_mgr_url, ""); strcpy(login_name, ""); strcpy(password_hash, ""); next_rpc_time = 0; } ACCT_MGR_INFO::ACCT_MGR_INFO() { clear(); } int ACCT_MGR_INFO::init() { char buf[256]; MIOFILE mf; FILE* p; clear(); p = fopen(ACCT_MGR_URL_FILENAME, "r"); if (p) { mf.init_file(p); while(mf.fgets(buf, sizeof(buf))) { if (match_tag(buf, "")) break; else if (parse_str(buf, "", acct_mgr_name, 256)) continue; else if (parse_str(buf, "", acct_mgr_url, 256)) continue; } fclose(p); } else { return 0; } p = fopen(ACCT_MGR_LOGIN_FILENAME, "r"); if (p) { mf.init_file(p); while(mf.fgets(buf, sizeof(buf))) { if (match_tag(buf, "")) break; else if (parse_str(buf, "", login_name, 256)) continue; else if (parse_str(buf, "", password_hash, 256)) continue; else if (parse_double(buf, "", next_rpc_time)) continue; } fclose(p); } return 0; } bool ACCT_MGR_INFO::poll() { if (gstate.acct_mgr_op.error_num == ERR_IN_PROGRESS) return false; if (gstate.now > next_rpc_time) { next_rpc_time = gstate.now + 86400; gstate.acct_mgr_op.do_rpc(acct_mgr_url, login_name, password_hash); return true; } return false; } const char *BOINC_RCSID_8fd9e873bf="$Id$";