From 5d801ddcd025f68d2ec91edf0462091a32c779c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Sun, 22 Jan 2017 21:31:50 +0100 Subject: Add a linger_time configuration option on IRC servers --- database/database.xml | 1 + src/bridge/bridge.cpp | 22 +++++++++++++++++++++- src/bridge/bridge.hpp | 5 +++++ src/xmpp/biboumi_adhoc_commands.cpp | 15 +++++++++++++++ tests/end_to_end/__main__.py | 1 + 5 files changed, 43 insertions(+), 1 deletion(-) diff --git a/database/database.xml b/database/database.xml index af15ad5..7dc70e1 100644 --- a/database/database.xml +++ b/database/database.xml @@ -24,6 +24,7 @@ + diff --git a/src/bridge/bridge.cpp b/src/bridge/bridge.cpp index 16b1c68..ca9c9fa 100644 --- a/src/bridge/bridge.cpp +++ b/src/bridge/bridge.cpp @@ -11,6 +11,7 @@ #include #include "result_set_management.hpp" #include +#include using namespace std::string_literals; @@ -865,7 +866,7 @@ void Bridge::send_muc_leave(Iid&& iid, std::string&& nick, const std::string& me this->user_jid + "/" + res, self); IrcClient* irc = this->find_irc_client(iid.get_server()); if (irc && irc->number_of_joined_channels() == 0) - irc->send_quit_command(""); + this->quit_or_start_linger_timer(iid.get_server()); } void Bridge::send_nick_change(Iid&& iid, @@ -1212,3 +1213,22 @@ void Bridge::set_record_history(const bool val) this->record_history = val; } #endif + +void Bridge::quit_or_start_linger_timer(const std::string& irc_hostname) +{ +#ifdef USE_DATABASE + auto options = Database::get_irc_server_options(this->get_bare_jid(), + irc_hostname); + const auto timeout = std::chrono::seconds(options.lingerTime.value()); +#else + const auto timeout = 0s; +#endif + + const auto event_name = "IRCLINGER:" + irc_hostname + ".." + this->get_bare_jid(); + TimedEvent event(std::chrono::steady_clock::now() + timeout, [this, irc_hostname]() { + IrcClient* irc = this->find_irc_client(irc_hostname); + if (irc) + irc->send_quit_command(""); + }, event_name); + TimedEventsManager::instance().add_event(std::move(event)); +} diff --git a/src/bridge/bridge.hpp b/src/bridge/bridge.hpp index fc839b4..7d0166c 100644 --- a/src/bridge/bridge.hpp +++ b/src/bridge/bridge.hpp @@ -236,6 +236,11 @@ public: #ifdef USE_DATABASE void set_record_history(const bool val); #endif + /** + * Start a timer that will send a QUIT command after the + * configured linger time is expired. + */ + void quit_or_start_linger_timer(const std::string& irc_hostname); private: /** diff --git a/src/xmpp/biboumi_adhoc_commands.cpp b/src/xmpp/biboumi_adhoc_commands.cpp index f6f3cd1..ccb3517 100644 --- a/src/xmpp/biboumi_adhoc_commands.cpp +++ b/src/xmpp/biboumi_adhoc_commands.cpp @@ -329,6 +329,17 @@ void ConfigureIrcServerStep1(XmppComponent&, AdhocSession& session, XmlNode& com encoding_in_value.set_inner(options.encodingIn.value()); } encoding_in.add_child(required); + + XmlSubNode linger_time(x, "field"); + linger_time["var"] = "linger_time"; + linger_time["type"] = "text-single"; + linger_time["desc"] = "The number of seconds to wait before sending a QUIT command, after the last channel on that server has been left."; + linger_time["label"] = "Linger time"; + { + XmlSubNode linger_time_value(linger_time, "value"); + linger_time_value.set_inner(std::to_string(options.lingerTime.value())); + } + encoding_in.add_child(required); } void ConfigureIrcServerStep2(XmppComponent&, AdhocSession& session, XmlNode& command_node) @@ -408,6 +419,10 @@ void ConfigureIrcServerStep2(XmppComponent&, AdhocSession& session, XmlNode& com value && !value->get_inner().empty()) options.encodingIn = value->get_inner(); + else if (field->get_tag("var") == "linger_time" && + value && !value->get_inner().empty()) + options.lingerTime = value->get_inner(); + } options.update(); diff --git a/tests/end_to_end/__main__.py b/tests/end_to_end/__main__.py index 29c2804..20730a7 100644 --- a/tests/end_to_end/__main__.py +++ b/tests/end_to_end/__main__.py @@ -1939,6 +1939,7 @@ if __name__ == '__main__': "/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='text-single'][@var='realname']/dataform:value[text()='realname']", "/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='text-single'][@var='encoding_in']/dataform:value[text()='latin-1']", "/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='text-single'][@var='encoding_out']/dataform:value[text()='UTF-8']", + "/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='text-single'][@var='linger_time']/dataform:value[text()='0']", "/iq/commands:command/commands:actions/commands:next", ), after = partial(save_value, "sessionid", partial(extract_attribute, "/iq[@type='result']/commands:command[@node='configure']", "sessionid")) -- cgit v1.2.3