summaryrefslogtreecommitdiff
path: root/src/xmpp/biboumi_adhoc_commands.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/xmpp/biboumi_adhoc_commands.cpp')
-rw-r--r--src/xmpp/biboumi_adhoc_commands.cpp104
1 files changed, 83 insertions, 21 deletions
diff --git a/src/xmpp/biboumi_adhoc_commands.cpp b/src/xmpp/biboumi_adhoc_commands.cpp
index 3bd2e5a..113943c 100644
--- a/src/xmpp/biboumi_adhoc_commands.cpp
+++ b/src/xmpp/biboumi_adhoc_commands.cpp
@@ -15,10 +15,17 @@
#ifdef USE_DATABASE
#include <database/database.hpp>
#include <database/save.hpp>
+
+static void set_desc(XmlSubNode& field, const char* text)
+{
+ XmlSubNode desc(field, "desc");
+ desc.set_inner(text);
+}
+
#endif
#ifndef HAS_PUT_TIME
-#include <ctime>
+# include <time.h>
#endif
using namespace std::string_literals;
@@ -116,6 +123,7 @@ void ConfigureGlobalStep1(XmppComponent&, AdhocSession& session, XmlNode& comman
auto options = Database::get_global_options(owner.bare());
+ command_node.delete_all_children();
XmlSubNode x(command_node, "jabber:x:data:x");
x["type"] = "form";
XmlSubNode title(x, "title");
@@ -128,7 +136,7 @@ void ConfigureGlobalStep1(XmppComponent&, AdhocSession& session, XmlNode& comman
max_histo_length["var"] = "max_history_length";
max_histo_length["type"] = "text-single";
max_histo_length["label"] = "Max history length";
- max_histo_length["desc"] = "The maximum number of lines in the history that the server sends when joining a channel";
+ set_desc(max_histo_length, "The maximum number of lines in the history that the server sends when joining a channel");
{
XmlSubNode value(max_histo_length, "value");
value.set_inner(std::to_string(options.col<Database::MaxHistoryLength>()));
@@ -140,7 +148,7 @@ void ConfigureGlobalStep1(XmppComponent&, AdhocSession& session, XmlNode& comman
record_history["var"] = "record_history";
record_history["type"] = "boolean";
record_history["label"] = "Record history";
- record_history["desc"] = "Whether to save the messages into the database, or not";
+ set_desc(record_history, "Whether to save the messages into the database, or not");
{
XmlSubNode value(record_history, "value");
value.set_name("value");
@@ -156,7 +164,7 @@ void ConfigureGlobalStep1(XmppComponent&, AdhocSession& session, XmlNode& comman
persistent["var"] = "persistent";
persistent["type"] = "boolean";
persistent["label"] = "Make all channels persistent";
- persistent["desc"] = "If true, all channels will be persistent";
+ set_desc(persistent, "If true, all channels will be persistent");
{
XmlSubNode value(persistent, "value");
value.set_name("value");
@@ -184,7 +192,13 @@ void ConfigureGlobalStep2(XmppComponent& xmpp_component, AdhocSession& session,
if (field->get_tag("var") == "max_history_length" &&
value && !value->get_inner().empty())
- options.col<Database::MaxHistoryLength>() = atoi(value->get_inner().data());
+ {
+ try {
+ options.col<Database::MaxHistoryLength>() = std::stol(value->get_inner().data());
+ } catch (const std::logic_error&) {
+ options.col<Database::MaxHistoryLength>() = 20;
+ }
+ }
else if (field->get_tag("var") == "record_history" &&
value && !value->get_inner().empty())
{
@@ -223,6 +237,7 @@ void ConfigureIrcServerStep1(XmppComponent&, AdhocSession& session, XmlNode& com
server_domain);
auto commands = Database::get_after_connection_commands(options);
+ command_node.delete_all_children();
XmlSubNode x(command_node, "jabber:x:data:x");
x["type"] = "form";
XmlSubNode title(x, "title");
@@ -236,7 +251,7 @@ void ConfigureIrcServerStep1(XmppComponent&, AdhocSession& session, XmlNode& com
field["var"] = "address";
field["type"] = "text-single";
field["label"] = "Address";
- field["desc"] = "The address (hostname or IP) to connect to.";
+ set_desc(field, "The address (hostname or IP) to connect to.");
XmlSubNode value(field, "value");
if (options.col<Database::Address>().empty())
value.set_inner(server_domain);
@@ -249,7 +264,7 @@ void ConfigureIrcServerStep1(XmppComponent&, AdhocSession& session, XmlNode& com
ports["var"] = "ports";
ports["type"] = "text-multi";
ports["label"] = "Ports";
- ports["desc"] = "List of ports to try, without TLS. Defaults: 6667.";
+ set_desc(ports, "List of ports to try, without TLS. Defaults: 6667.");
for (const auto& val: utils::split(options.col<Database::Ports>(), ';', false))
{
XmlSubNode ports_value(ports, "value");
@@ -263,7 +278,7 @@ void ConfigureIrcServerStep1(XmppComponent&, AdhocSession& session, XmlNode& com
tls_ports["var"] = "tls_ports";
tls_ports["type"] = "text-multi";
tls_ports["label"] = "TLS ports";
- tls_ports["desc"] = "List of ports to try, with TLS. Defaults: 6697, 6670.";
+ set_desc(tls_ports, "List of ports to try, with TLS. Defaults: 6697, 6670.");
for (const auto& val: utils::split(options.col<Database::TlsPorts>(), ';', false))
{
XmlSubNode tls_ports_value(tls_ports, "value");
@@ -276,7 +291,7 @@ void ConfigureIrcServerStep1(XmppComponent&, AdhocSession& session, XmlNode& com
verify_cert["var"] = "verify_cert";
verify_cert["type"] = "boolean";
verify_cert["label"] = "Verify certificate";
- verify_cert["desc"] = "Whether or not to abort the connection if the server’s TLS certificate is invalid";
+ set_desc(verify_cert, "Whether or not to abort the connection if the server’s TLS certificate is invalid");
XmlSubNode verify_cert_value(verify_cert, "value");
if (options.col<Database::VerifyCert>())
verify_cert_value.set_inner("true");
@@ -302,7 +317,7 @@ void ConfigureIrcServerStep1(XmppComponent&, AdhocSession& session, XmlNode& com
field["var"] = "nick";
field["type"] = "text-single";
field["label"] = "Nickname";
- field["desc"] = "If set, will override the nickname provided in the initial presence sent to join the first server channel";
+ set_desc(field, "If set, will override the nickname provided in the initial presence sent to join the first server channel");
if (!options.col<Database::Nick>().empty())
{
XmlSubNode value(field, "value");
@@ -315,7 +330,7 @@ void ConfigureIrcServerStep1(XmppComponent&, AdhocSession& session, XmlNode& com
pass["var"] = "pass";
pass["type"] = "text-private";
pass["label"] = "Server password";
- pass["desc"] = "Will be used in a PASS command when connecting";
+ set_desc(pass, "Will be used in a PASS command when connecting");
if (!options.col<Database::Pass>().empty())
{
XmlSubNode pass_value(pass, "value");
@@ -327,7 +342,7 @@ void ConfigureIrcServerStep1(XmppComponent&, AdhocSession& session, XmlNode& com
XmlSubNode after_cnt_cmd(x, "field");
after_cnt_cmd["var"] = "after_connect_commands";
after_cnt_cmd["type"] = "text-multi";
- after_cnt_cmd["desc"] = "Custom IRC commands sent after the connection is established with the server.";
+ set_desc(after_cnt_cmd, "Custom IRC commands sent after the connection is established with the server.");
after_cnt_cmd["label"] = "After-connection IRC commands";
for (const auto& command: commands)
{
@@ -364,10 +379,28 @@ void ConfigureIrcServerStep1(XmppComponent&, AdhocSession& session, XmlNode& com
}
{
+ XmlSubNode throttle_limit(x, "field");
+ throttle_limit["var"] = "throttle_limit";
+ throttle_limit["type"] = "text-single";
+ throttle_limit["label"] = "Throttle limit";
+ XmlSubNode value(throttle_limit, "value");
+ value.set_inner(std::to_string(options.col<Database::ThrottleLimit>()));
+ }
+
+ {
+ XmlSubNode max_history_length(x, "field");
+ max_history_length["var"] = "max_history_length";
+ max_history_length["type"] = "text-single";
+ max_history_length["label"] = "Throttle limit";
+ XmlSubNode value(max_history_length, "value");
+ value.set_inner(std::to_string(options.col<Database::MaxHistoryLength>()));
+ }
+
+ {
XmlSubNode encoding_out(x, "field");
encoding_out["var"] = "encoding_out";
encoding_out["type"] = "text-single";
- encoding_out["desc"] = "The encoding used when sending messages to the IRC server.";
+ set_desc(encoding_out, "The encoding used when sending messages to the IRC server.");
encoding_out["label"] = "Out encoding";
if (!options.col<Database::EncodingOut>().empty())
{
@@ -380,7 +413,7 @@ void ConfigureIrcServerStep1(XmppComponent&, AdhocSession& session, XmlNode& com
XmlSubNode encoding_in(x, "field");
encoding_in["var"] = "encoding_in";
encoding_in["type"] = "text-single";
- encoding_in["desc"] = "The encoding used to decode message received from the IRC server.";
+ set_desc(encoding_in, "The encoding used to decode message received from the IRC server.");
encoding_in["label"] = "In encoding";
if (!options.col<Database::EncodingIn>().empty())
{
@@ -390,8 +423,10 @@ void ConfigureIrcServerStep1(XmppComponent&, AdhocSession& session, XmlNode& com
}
}
-void ConfigureIrcServerStep2(XmppComponent&, AdhocSession& session, XmlNode& command_node)
+void ConfigureIrcServerStep2(XmppComponent& xmpp_component, AdhocSession& session, XmlNode& command_node)
{
+ auto& biboumi_component = dynamic_cast<BiboumiComponent&>(xmpp_component);
+
const XmlNode* x = command_node.get_child("x", "jabber:x:data");
if (x)
{
@@ -472,6 +507,31 @@ void ConfigureIrcServerStep2(XmppComponent&, AdhocSession& session, XmlNode& com
else if (field->get_tag("var") == "realname" && value)
options.col<Database::Realname>() = value->get_inner();
+ else if (field->get_tag("var") == "throttle_limit" && value)
+ {
+ try {
+ options.col<Database::ThrottleLimit>() = std::stol(value->get_inner());
+ } catch (const std::logic_error&) {
+ options.col<Database::ThrottleLimit>() = 10;
+ }
+ Bridge* bridge = biboumi_component.find_user_bridge(session.get_owner_jid());
+ if (bridge)
+ {
+ IrcClient* client = bridge->find_irc_client(server_domain);
+ if (client)
+ client->set_throttle_limit(options.col<Database::ThrottleLimit>());
+ }
+ }
+
+ else if (field->get_tag("var") == "max_history_length" && value)
+ {
+ try {
+ options.col<Database::MaxHistoryLength>() = std::stol(value->get_inner());
+ } catch (const std::logic_error&) {
+ options.col<Database::MaxHistoryLength>() = 20;
+ }
+ }
+
else if (field->get_tag("var") == "encoding_out" && value)
options.col<Database::EncodingOut>() = value->get_inner();
@@ -509,6 +569,7 @@ void insert_irc_channel_configuration_form(XmlNode& node, const Jid& requester,
auto options = Database::get_irc_channel_options_with_server_default(requester.local + "@" + requester.domain,
iid.get_server(), iid.get_local());
+ node.delete_all_children();
XmlSubNode x(node, "jabber:x:data:x");
x["type"] = "form";
XmlSubNode title(x, "title");
@@ -521,7 +582,7 @@ void insert_irc_channel_configuration_form(XmlNode& node, const Jid& requester,
record_history["var"] = "record_history";
record_history["type"] = "list-single";
record_history["label"] = "Record history for this channel";
- record_history["desc"] = "If unset, the value is the one configured globally";
+ set_desc(record_history, "If unset, the value is the one configured globally");
{
// Value selected by default
XmlSubNode value(record_history, "value");
@@ -541,7 +602,7 @@ void insert_irc_channel_configuration_form(XmlNode& node, const Jid& requester,
XmlSubNode encoding_out(x, "field");
encoding_out["var"] = "encoding_out";
encoding_out["type"] = "text-single";
- encoding_out["desc"] = "The encoding used when sending messages to the IRC server. Defaults to the server's “out encoding” if unset for the channel";
+ set_desc(encoding_out, "The encoding used when sending messages to the IRC server. Defaults to the server's “out encoding” if unset for the channel");
encoding_out["label"] = "Out encoding";
if (!options.col<Database::EncodingOut>().empty())
{
@@ -554,7 +615,7 @@ void insert_irc_channel_configuration_form(XmlNode& node, const Jid& requester,
XmlSubNode encoding_in(x, "field");
encoding_in["var"] = "encoding_in";
encoding_in["type"] = "text-single";
- encoding_in["desc"] = "The encoding used to decode message received from the IRC server. Defaults to the server's “in encoding” if unset for the channel";
+ set_desc(encoding_in, "The encoding used to decode message received from the IRC server. Defaults to the server's “in encoding” if unset for the channel");
encoding_in["label"] = "In encoding";
if (!options.col<Database::EncodingIn>().empty())
{
@@ -567,7 +628,7 @@ void insert_irc_channel_configuration_form(XmlNode& node, const Jid& requester,
XmlSubNode persistent(x, "field");
persistent["var"] = "persistent";
persistent["type"] = "boolean";
- persistent["desc"] = "If set to true, when all XMPP clients have left this channel, biboumi will stay idle in it, without sending a PART command.";
+ set_desc(persistent, "If set to true, when all XMPP clients have left this channel, biboumi will stay idle in it, without sending a PART command.");
persistent["label"] = "Persistent";
{
XmlSubNode value(persistent, "value");
@@ -847,12 +908,13 @@ void GetIrcConnectionInfoStep1(XmppComponent& component, AdhocSession& session,
if (irc->is_using_tls())
ss << " (using TLS)";
const std::time_t now_c = std::chrono::system_clock::to_time_t(irc->connection_date);
+ struct tm tm;
#ifdef HAS_PUT_TIME
- ss << " since " << std::put_time(std::localtime(&now_c), "%F %T");
+ ss << " since " << std::put_time(localtime_r(&now_c, &tm), "%F %T");
#else
constexpr std::size_t timestamp_size{10 + 1 + 8 + 1};
char buf[timestamp_size] = {};
- const auto res = std::strftime(buf, timestamp_size, "%F %T", std::localtime(&now_c));
+ const auto res = std::strftime(buf, timestamp_size, "%F %T", localtime(&now_c, &tm));
if (res > 0)
ss << " since " << buf;
#endif