summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/bridge/bridge.cpp22
-rw-r--r--src/bridge/bridge.hpp5
-rw-r--r--src/xmpp/biboumi_adhoc_commands.cpp15
3 files changed, 41 insertions, 1 deletions
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 <database/database.hpp>
#include "result_set_management.hpp"
#include <algorithm>
+#include <utils/timed_events.hpp>
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();