diff --git a/client/cs_account.cpp b/client/cs_account.cpp index 38a29eae67..53c5032924 100644 --- a/client/cs_account.cpp +++ b/client/cs_account.cpp @@ -323,6 +323,7 @@ int CLIENT_STATE::parse_account_files() { PROJECT* project; FILE* f; int retval; + char path[MAXPATHLEN]; DirScanner dir("."); while (dir.scan(name)) { @@ -345,16 +346,50 @@ int CLIENT_STATE::parse_account_files() { "Couldn't parse account file %s", name.c_str() ); delete project; - } else { - if (lookup_project(project->master_url)) { + continue; + } + + // see if the account file name doesn't match the master URL. + // This can happen if a project changes its URL + // + // If this happens, anything in client_state.xml for the old project + // will be ignored. + // + get_account_filename(project->master_url, path, sizeof(path)); + if (strcmp(path, name.c_str())) { + // if not, see if account file with proper name exists + // + if (boinc_file_exists(path)) { + // yes - delete this file + // msg_printf(project, MSG_INFO, - "Duplicate account file %s - ignoring", name.c_str() + "Misnamed account file %s - deleting", name.c_str() ); + boinc_delete_file(name.c_str()); delete project; + continue; } else { - projects.push_back(project); + // no - rename this file + // + msg_printf(project, MSG_INFO, + "Misnamed account file %s - renaming to %s", + name.c_str(), path + ); + boinc_rename(name.c_str(), path); } } + + // shouldn't happen given the above logic, but just in case + // + if (lookup_project(project->master_url)) { + msg_printf(project, MSG_INFO, + "Duplicate account file %s - ignoring", name.c_str() + ); + delete project; + continue; + } + + projects.push_back(project); } return 0; } diff --git a/client/cs_files.cpp b/client/cs_files.cpp index 6c020425a6..e3330ba43a 100644 --- a/client/cs_files.cpp +++ b/client/cs_files.cpp @@ -87,15 +87,39 @@ bool CLIENT_STATE::start_new_file_xfer(PERS_FILE_XFER& pfx) { return true; } -// Make a directory for each of the projects in the client state +// Make a directory for each of the projects in the client state, +// and delete other stuff in projects/ // int CLIENT_STATE::make_project_dirs() { unsigned int i; int retval; + vector pds; for (i=0; iproject_dir()); } + + string name; + char path[MAXPATHLEN]; + DirScanner dir("projects"); + while (dir.scan(name)) { + snprintf(path, sizeof(path), "projects/%s", name.c_str()); + if (std::find(pds.begin(), pds.end(), path) != pds.end()) { + continue; + } + msg_printf(0, MSG_INFO, + "%s is not a project dir - removing", path + ); + if (is_dir(path)) { + clean_out_dir(path); + boinc_rmdir(path); + } else { + boinc_delete_file(path); + } + } + return 0; } diff --git a/client/cs_scheduler.cpp b/client/cs_scheduler.cpp index 2242948945..42a923761f 100644 --- a/client/cs_scheduler.cpp +++ b/client/cs_scheduler.cpp @@ -567,7 +567,9 @@ int CLIENT_STATE::handle_scheduler_reply( // (which comes from the project's config.xml). // - if http -> https transition, use the https: one from now on // - if https -> http transition, keep using the https: one - // - otherwise notify the user. + // - otherwise switch to the new master URL: + // rename and rewrite account file + // rename project dir // if (strlen(sr.master_url)) { canonicalize_master_url(sr.master_url, sizeof(sr.master_url)); @@ -587,9 +589,41 @@ int CLIENT_STATE::handle_scheduler_reply( // keep using https:// } else { msg_printf(project, MSG_USER_ALERT, - _("This project seems to have changed its URL. When convenient, remove the project, then add %s"), - sr.master_url + _("Master URL changed from %s to %s"), + current_url.c_str(), reply_url.c_str() ); + char path[MAXPATHLEN], path2[MAXPATHLEN], old_project_dir[MAXPATHLEN]; + + // rename statistics file + // + get_statistics_filename( + (char*)current_url.c_str(), path, sizeof(path) + ); + get_statistics_filename( + (char*)reply_url.c_str(), path2, sizeof(path2) + ); + boinc_rename(path, path2); + + strcpy(old_project_dir, project->project_dir()); + + // delete account file and write new one + // + get_account_filename(project->master_url, path, sizeof(path)); + boinc_delete_file(path); + strcpy(project->master_url, reply_url.c_str()); + project->write_account_file(); + + // rename project dir + // + strcpy(project->_project_dir, ""); + strcpy(path2, project->project_dir()); + boinc_rename(old_project_dir, path2); + + // reset the project (clear jobs etc.). + // If any jobs are running, their soft links + // point to the old project dir + // + reset_project(project, false); } } }