Skip to content

Commit

Permalink
Shutdown the server in potential data loss situations, iteration cleanup
Browse files Browse the repository at this point in the history
Changes suggested by @shikadiqueen.
  • Loading branch information
kabachuha authored and irydacea committed Oct 15, 2020
1 parent e75b862 commit 7f2385b
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 32 deletions.
23 changes: 9 additions & 14 deletions src/addon/client.cpp
Expand Up @@ -287,31 +287,26 @@ bool addons_client::install_addon(config& archive_cfg, const addon_info& info)
add_maindir.add_child("file", file);

// A consistency check
config::all_children_itors itors = archive_cfg.all_children_range();
auto iter = itors.begin();
while(iter != itors.end()) {
if(iter->key == "removelist" || iter->key == "addlist") {
if(!check_names_legal(iter->cfg)) {
for(const config::any_child entry : archive_cfg.all_children_range()) {
if(entry.key == "removelist" || entry.key == "addlist") {
if(!check_names_legal(entry.cfg)) {
gui2::show_error_message(VGETTEXT("The add-on <i>$addon_title</i> has an invalid file or directory "
"name and cannot be installed.", i18n_symbols));
return false;
}
if(!check_case_insensitive_duplicates(iter->cfg)) {
if(!check_case_insensitive_duplicates(entry.cfg)) {
gui2::show_error_message(VGETTEXT("The add-on <i>$addon_title</i> has file or directory names "
"with case conflicts. This may cause problems.", i18n_symbols));
}
}
iter++;
}

iter = itors.begin();
while(iter != itors.end()) {
if(iter->key == "removelist") {
purge_addon(iter->cfg);
} else if(iter->key == "addlist") {
unarchive_addon(iter->cfg);
for(const config::any_child entry : archive_cfg.all_children_range()) {
if(entry.key == "removelist") {
purge_addon(entry.cfg);
} else if(entry.key == "addlist") {
unarchive_addon(entry.cfg);
}
iter++;
}

LOG_ADDONS << "Update completed.\n";
Expand Down
30 changes: 12 additions & 18 deletions src/server/campaignd/server.cpp
Expand Up @@ -234,7 +234,7 @@ void server::load_config()
if(meta) {
addons_.emplace(meta["name"].str(), meta);
} else {
WRN_CS << "Failed to load addon from dir '" << addon_dir << "'\n";
throw filesystem::io_exception("Failed to load addon from dir '" + addon_dir + "'\n");
}
}

Expand All @@ -247,23 +247,19 @@ void server::load_config()
const std::string& addon_id = campaign["name"].str();
const std::string& addon_file = campaign["filename"].str();
if(get_addon(addon_id)) {
ERR_CS << "The addon '" << addon_id
<< "' already exists in the new form! The old version will be ignored and its file deleted!\n";
filesystem::delete_file(filesystem::normalize_path(addon_file));
continue;
throw filesystem::io_exception("The addon '" + addon_id
+ "' already exists in the new form! Possible code or filesystem interference!\n");
}
if(std::find(legacy_addons.begin(), legacy_addons.end(), addon_id) == legacy_addons.end()) {
ERR_CS << "No file has been found for the legacy addon '" << addon_id
<< "'. Please, check the file structure!\n";
continue;
throw filesystem::io_exception("No file has been found for the legacy addon '" + addon_id
+ "'. Please, check the file structure!\n");
}

config data;
in = filesystem::istream_file(filesystem::normalize_path(addon_file));
read_gz(data, *in);
if(!data) {
ERR_CS << "Couldn't read the content file for the legacy addon '" << addon_id << "'!\n";
continue;
throw filesystem::io_exception("Couldn't read the content file for the legacy addon '" + addon_id + "'!\n");
}

const std::string file_hash = utils::md5(campaign["version"].str()).hex_digest();
Expand Down Expand Up @@ -602,7 +598,7 @@ config& server::get_addon(const std::string& id)
{
auto addon = addons_.find(id);
if(addon != addons_.end()) {
return addons_.at(id);
return addon->second;
} else {
return config::get_invalid();
}
Expand Down Expand Up @@ -769,10 +765,8 @@ void server::handle_request_campaign(const server::request& req)
auto version_map = get_version_map(campaign);

if(version_map.empty()) {
// Old format ?
ERR_CS << "The (" + to + ") version of the addon '" << req.cfg["name"].str()
<< "' is stored in the old format (bug?)! Trying to send a legacy full-pack.";
to = campaign["version"].str();
send_error("No versions of the addon '" + req.cfg["name"].str() + "' have been found by the server!", req.sock);
return;
} else {
auto version = version_map.find(version_info(to));
if(version != version_map.end()) {
Expand All @@ -787,7 +781,7 @@ void server::handle_request_campaign(const server::request& req)
// Negotiate an update pack if possible
if(!from.empty() && version_map.count(version_info(from)) != 0) {
config pack_data;
// Make a line of consequential updates beginning from the old version to the new one.
// Make a line of consecutive updates beginning from the old version to the new one.
// Every pair of increasing versions on the server side should contain an update_pack
// transition guaranteed during the upload.

Expand All @@ -810,7 +804,7 @@ void server::handle_request_campaign(const server::request& req)
pack_data.append(update_pack);
size += filesystem::file_size(campaign["filename"].str() + pack["filename"].str());
} else {
WRN_CS << "Unable to create an update pack sequence from version (" << from << ") to ("
WRN_CS << "Unable to find an update pack sequence from version (" << from << ") to ("
<< to << ") for the addon '" << req.cfg["name"].str() << "'. A full pack will be sent instead!\n";
failed = true;
break;
Expand Down Expand Up @@ -1098,7 +1092,7 @@ void server::handle_upload(const server::request& req)
campaign_file.commit();
}

(*campaign)["size"] = filesystem::file_size(filename + version_cfg["filename"].str()) + filesystem::file_size(filename + "/addon.cfg");
(*campaign)["size"] = filesystem::file_size(filename + version_cfg["filename"].str());

//Remove the update packs with expired lifespan
for(const config& pack : (*campaign).child_range("update_pack")) {
Expand Down

0 comments on commit 7f2385b

Please sign in to comment.