Skip to content

Commit

Permalink
campaignd: Refactor add-on deletion code into its own method
Browse files Browse the repository at this point in the history
This changes the order in which the hook_post_erase hook (currently
unused in production and fully untested) is fired so it will be run
*before* displaying the confirmation message to clients. This might need
to be changed at a later point if the hook functionality ever gets used
again, but for now it'll do.
  • Loading branch information
irydacea committed Apr 17, 2018
1 parent fab229b commit e6b17f8
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 24 deletions.
68 changes: 44 additions & 24 deletions src/campaign_server/campaign_server.cpp
Expand Up @@ -493,6 +493,45 @@ void server::send_error(const std::string& msg, const std::string& extra_data, s
async_send_doc(sock, doc, std::bind(&server::handle_new_client, this, _1), null_handler);
}

void server::delete_campaign(const std::string& id)
{
config::child_itors itors = campaigns().child_range("campaign");

size_t pos = 0;
bool found = false;
std::string fn;

for(config& cfg : itors) {
if(cfg["name"] == id) {
fn = cfg["filename"].str();
found = true;
break;
}

++pos;
}

if(!found) {
ERR_CS << "Cannot delete unrecognized add-on '" << id << "'\n";
return;
}

if(fn.empty()) {
ERR_CS << "Add-on '" << id << "' does not have an associated filename, cannot delete\n";
}

filesystem::write_file(fn, {});
if(std::remove(fn.c_str()) != 0) {
ERR_CS << "Could not delete archive for campaign '" << id
<< "' (" << fn << "): " << strerror(errno) << '\n';
}

campaigns().remove_child("campaign", pos);
write_config();

fire("hook_post_erase", id);
}

#define REGISTER_CAMPAIGND_HANDLER(req_id) \
handlers_[#req_id] = std::bind(&server::handle_##req_id, \
std::placeholders::_1, std::placeholders::_2)
Expand Down Expand Up @@ -853,16 +892,17 @@ void server::handle_upload(const server::request& req)
void server::handle_delete(const server::request& req)
{
const config& erase = req.cfg;
const std::string& id = erase["name"].str();

if(read_only_) {
LOG_CS << "in read-only mode, request to delete '" << erase["name"] << "' from " << req.addr << " denied\n";
LOG_CS << "in read-only mode, request to delete '" << id << "' from " << req.addr << " denied\n";
send_error("Cannot delete add-on: The server is currently in read-only mode.", req.sock);
return;
}

LOG_CS << "deleting campaign '" << erase["name"] << "' requested from " << req.addr << "\n";
LOG_CS << "deleting campaign '" << id << "' requested from " << req.addr << "\n";

config& campaign = get_campaign(erase["name"]);
config& campaign = get_campaign(id);

if(!campaign) {
send_error("The add-on does not exist.", req.sock);
Expand All @@ -884,29 +924,9 @@ void server::handle_delete(const server::request& req)
return;
}

// Erase the campaign.
filesystem::write_file(campaign["filename"], std::string());
if(remove(campaign["filename"].str().c_str()) != 0) {
ERR_CS << "failed to delete archive for campaign '" << erase["name"]
<< "' (" << campaign["filename"] << "): " << strerror(errno)
<< '\n';
}

config::child_itors itors = campaigns().child_range("campaign");
for(size_t index = 0; !itors.empty(); ++index, itors.pop_front())
{
if(&campaign == &itors.front()) {
campaigns().remove_child("campaign", index);
break;
}
}

write_config();
delete_campaign(id);

send_message("Add-on deleted.", req.sock);

fire("hook_post_erase", erase["name"]);

}

void server::handle_change_passphrase(const server::request& req)
Expand Down
2 changes: 2 additions & 0 deletions src/campaign_server/campaign_server.hpp
Expand Up @@ -143,6 +143,8 @@ class server : public server_base
/** Retrieves a campaign by id if found, or a null config otherwise. */
config& get_campaign(const std::string& id) { return campaigns().find_child("campaign", "name", id); }

void delete_campaign(const std::string& id);

/** Retrieves the contents of the [server_info] WML node. */
const config& server_info() const { return cfg_.child("server_info"); }

Expand Down

0 comments on commit e6b17f8

Please sign in to comment.