From 9f7782bb0c5915969fd7477e0ed7c10b1a5c2d9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Thu, 6 Jul 2017 22:24:42 +0200 Subject: =?UTF-8?q?Add=20a=20global=20=E2=80=9Cpersistent=E2=80=9D=20optio?= =?UTF-8?q?n?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/bridge/bridge.cpp | 11 ++++++++--- src/database/database.hpp | 2 +- src/xmpp/biboumi_adhoc_commands.cpp | 18 ++++++++++++++++++ 3 files changed, 27 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/bridge/bridge.cpp b/src/bridge/bridge.cpp index 23ecfe9..81ca147 100644 --- a/src/bridge/bridge.cpp +++ b/src/bridge/bridge.cpp @@ -436,9 +436,14 @@ void Bridge::leave_irc_channel(Iid&& iid, const std::string& status_message, con // acknowledgment from the server bool persistent = false; #ifdef USE_DATABASE - const auto coptions = Database::get_irc_channel_options_with_server_default(this->user_jid, - iid.get_server(), iid.get_local()); - persistent = coptions.col(); + const auto goptions = Database::get_global_options(this->user_jid); + if (goptions.col()) + persistent = true; + else + { + const auto coptions = Database::get_irc_channel_options_with_server_default(this->user_jid, iid.get_server(), iid.get_local()); + persistent = coptions.col(); + } #endif if (channel->joined && !channel->parting && !persistent) { diff --git a/src/database/database.hpp b/src/database/database.hpp index 28b6b1b..8364abc 100644 --- a/src/database/database.hpp +++ b/src/database/database.hpp @@ -98,7 +98,7 @@ class Database using MucLogLineTable = Table; using MucLogLine = MucLogLineTable::RowType; - using GlobalOptionsTable = Table; + using GlobalOptionsTable = Table; using GlobalOptions = GlobalOptionsTable::RowType; using IrcServerOptionsTable = Table; diff --git a/src/xmpp/biboumi_adhoc_commands.cpp b/src/xmpp/biboumi_adhoc_commands.cpp index ad4faf8..c1b7323 100644 --- a/src/xmpp/biboumi_adhoc_commands.cpp +++ b/src/xmpp/biboumi_adhoc_commands.cpp @@ -147,6 +147,21 @@ void ConfigureGlobalStep1(XmppComponent&, AdhocSession& session, XmlNode& comman else value.set_inner("false"); } + + XmlSubNode persistent(x, "field"); + persistent["var"] = "persistent"; + persistent["type"] = "boolean"; + persistent["label"] = "Make all channels persistent"; + persistent["desc"] = "If true, all channels will be persistent"; + + { + XmlSubNode value(persistent, "value"); + value.set_name("value"); + if (options.col()) + value.set_inner("true"); + else + value.set_inner("false"); + } } void ConfigureGlobalStep2(XmppComponent& xmpp_component, AdhocSession& session, XmlNode& command_node) @@ -173,6 +188,9 @@ void ConfigureGlobalStep2(XmppComponent& xmpp_component, AdhocSession& session, if (bridge) bridge->set_record_history(options.col()); } + else if (field->get_tag("var") == "persistent" && + value) + options.col() = to_bool(value->get_inner()); } options.save(Database::db); -- cgit v1.2.3 From 43b5b696a311e1dbaa2623284eed042b4ca24dc5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Thu, 6 Jul 2017 22:38:09 +0200 Subject: Add some scopes around various XmlSubNode --- src/xmpp/biboumi_adhoc_commands.cpp | 364 +++++++++++++++++++----------------- 1 file changed, 196 insertions(+), 168 deletions(-) (limited to 'src') diff --git a/src/xmpp/biboumi_adhoc_commands.cpp b/src/xmpp/biboumi_adhoc_commands.cpp index c1b7323..4129517 100644 --- a/src/xmpp/biboumi_adhoc_commands.cpp +++ b/src/xmpp/biboumi_adhoc_commands.cpp @@ -122,45 +122,48 @@ void ConfigureGlobalStep1(XmppComponent&, AdhocSession& session, XmlNode& comman XmlSubNode instructions(x, "instructions"); instructions.set_inner("Edit the form, to configure your global settings for the component."); - XmlSubNode max_histo_length(x, "field"); - 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"; - { - XmlSubNode value(max_histo_length, "value"); - value.set_inner(std::to_string(options.col())); + XmlSubNode max_histo_length(x, "field"); + 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"; + { + XmlSubNode value(max_histo_length, "value"); + value.set_inner(std::to_string(options.col())); + } } - XmlSubNode record_history(x, "field"); - 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"; - { - XmlSubNode value(record_history, "value"); - value.set_name("value"); - if (options.col()) - value.set_inner("true"); - else - value.set_inner("false"); + XmlSubNode record_history(x, "field"); + 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"; + { + XmlSubNode value(record_history, "value"); + value.set_name("value"); + if (options.col()) + value.set_inner("true"); + else + value.set_inner("false"); + } } - XmlSubNode persistent(x, "field"); - persistent["var"] = "persistent"; - persistent["type"] = "boolean"; - persistent["label"] = "Make all channels persistent"; - persistent["desc"] = "If true, all channels will be persistent"; - { - XmlSubNode value(persistent, "value"); - value.set_name("value"); - if (options.col()) - value.set_inner("true"); - else - value.set_inner("false"); + XmlSubNode persistent(x, "field"); + persistent["var"] = "persistent"; + persistent["type"] = "boolean"; + persistent["label"] = "Make all channels persistent"; + persistent["desc"] = "If true, all channels will be persistent"; + { + XmlSubNode value(persistent, "value"); + value.set_name("value"); + if (options.col()) + value.set_inner("true"); + else + value.set_inner("false"); + } } } @@ -224,96 +227,112 @@ void ConfigureIrcServerStep1(XmppComponent&, AdhocSession& session, XmlNode& com XmlSubNode instructions(x, "instructions"); instructions.set_inner("Edit the form, to configure the settings of the IRC server "s + server_domain); - XmlSubNode ports(x, "field"); - ports["var"] = "ports"; - ports["type"] = "text-multi"; - ports["label"] = "Ports"; - ports["desc"] = "List of ports to try, without TLS. Defaults: 6667."; - for (const auto& val: utils::split(options.col(), ';', false)) - { - XmlSubNode ports_value(ports, "value"); - ports_value.set_inner(val); - } + { + XmlSubNode ports(x, "field"); + ports["var"] = "ports"; + ports["type"] = "text-multi"; + ports["label"] = "Ports"; + ports["desc"] = "List of ports to try, without TLS. Defaults: 6667."; + for (const auto& val: utils::split(options.col(), ';', false)) + { + XmlSubNode ports_value(ports, "value"); + ports_value.set_inner(val); + } + } #ifdef BOTAN_FOUND - XmlSubNode tls_ports(x, "field"); - 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."; - for (const auto& val: utils::split(options.col(), ';', false)) - { - XmlSubNode tls_ports_value(tls_ports, "value"); - tls_ports_value.set_inner(val); - } + { + XmlSubNode tls_ports(x, "field"); + 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."; + for (const auto& val: utils::split(options.col(), ';', false)) + { + XmlSubNode tls_ports_value(tls_ports, "value"); + tls_ports_value.set_inner(val); + } + } - XmlSubNode verify_cert(x, "field"); - 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"; - XmlSubNode verify_cert_value(verify_cert, "value"); - if (options.col()) - verify_cert_value.set_inner("true"); - else - verify_cert_value.set_inner("false"); + { + XmlSubNode verify_cert(x, "field"); + 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"; + XmlSubNode verify_cert_value(verify_cert, "value"); + if (options.col()) + verify_cert_value.set_inner("true"); + else + verify_cert_value.set_inner("false"); + } - XmlSubNode fingerprint(x, "field"); - fingerprint["var"] = "fingerprint"; - fingerprint["type"] = "text-single"; - fingerprint["label"] = "SHA-1 fingerprint of the TLS certificate to trust."; - if (!options.col().empty()) - { - XmlSubNode fingerprint_value(fingerprint, "value"); - fingerprint_value.set_inner(options.col()); - } + { + XmlSubNode fingerprint(x, "field"); + fingerprint["var"] = "fingerprint"; + fingerprint["type"] = "text-single"; + fingerprint["label"] = "SHA-1 fingerprint of the TLS certificate to trust."; + if (!options.col().empty()) + { + XmlSubNode fingerprint_value(fingerprint, "value"); + fingerprint_value.set_inner(options.col()); + } + } #endif + { + XmlSubNode pass(x, "field"); + pass["var"] = "pass"; + pass["type"] = "text-private"; + pass["label"] = "Server password"; + pass["desc"] = "Will be used in a PASS command when connecting"; + if (!options.col().empty()) + { + XmlSubNode pass_value(pass, "value"); + pass_value.set_inner(options.col()); + } + } - XmlSubNode pass(x, "field"); - pass["var"] = "pass"; - pass["type"] = "text-private"; - pass["label"] = "Server password"; - pass["desc"] = "Will be used in a PASS command when connecting"; - if (!options.col().empty()) - { - XmlSubNode pass_value(pass, "value"); - pass_value.set_inner(options.col()); - } - - XmlSubNode after_cnt_cmd(x, "field"); - after_cnt_cmd["var"] = "after_connect_command"; - after_cnt_cmd["type"] = "text-single"; - after_cnt_cmd["desc"] = "Custom IRC command sent after the connection is established with the server."; - after_cnt_cmd["label"] = "After-connection IRC command"; - if (!options.col().empty()) - { - XmlSubNode after_cnt_cmd_value(after_cnt_cmd, "value"); - after_cnt_cmd_value.set_inner(options.col()); - } + { + XmlSubNode after_cnt_cmd(x, "field"); + after_cnt_cmd["var"] = "after_connect_command"; + after_cnt_cmd["type"] = "text-single"; + after_cnt_cmd["desc"] = "Custom IRC command sent after the connection is established with the server."; + after_cnt_cmd["label"] = "After-connection IRC command"; + if (!options.col().empty()) + { + XmlSubNode after_cnt_cmd_value(after_cnt_cmd, "value"); + after_cnt_cmd_value.set_inner(options.col()); + } + } if (Config::get("realname_customization", "true") == "true") { - XmlSubNode username(x, "field"); - username["var"] = "username"; - username["type"] = "text-single"; - username["label"] = "Username"; - if (!options.col().empty()) - { - XmlSubNode username_value(username, "value"); - username_value.set_inner(options.col()); - } - - XmlSubNode realname(x, "field"); - realname["var"] = "realname"; - realname["type"] = "text-single"; - realname["label"] = "Realname"; - if (!options.col().empty()) - { - XmlSubNode realname_value(realname, "value"); - realname_value.set_inner(options.col()); - } + { + XmlSubNode username(x, "field"); + username["var"] = "username"; + username["type"] = "text-single"; + username["label"] = "Username"; + if (!options.col().empty()) + { + XmlSubNode username_value(username, "value"); + username_value.set_inner(options.col()); + } + } + + { + XmlSubNode realname(x, "field"); + realname["var"] = "realname"; + realname["type"] = "text-single"; + realname["label"] = "Realname"; + if (!options.col().empty()) + { + XmlSubNode realname_value(realname, "value"); + realname_value.set_inner(options.col()); + } + } } + { XmlSubNode encoding_out(x, "field"); encoding_out["var"] = "encoding_out"; encoding_out["type"] = "text-single"; @@ -324,17 +343,20 @@ void ConfigureIrcServerStep1(XmppComponent&, AdhocSession& session, XmlNode& com XmlSubNode encoding_out_value(encoding_out, "value"); encoding_out_value.set_inner(options.col()); } + } - 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."; - encoding_in["label"] = "In encoding"; - if (!options.col().empty()) - { - XmlSubNode encoding_in_value(encoding_in, "value"); - encoding_in_value.set_inner(options.col()); - } + { + 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."; + encoding_in["label"] = "In encoding"; + if (!options.col().empty()) + { + XmlSubNode encoding_in_value(encoding_in, "value"); + encoding_in_value.set_inner(options.col()); + } + } } void ConfigureIrcServerStep2(XmppComponent&, AdhocSession& session, XmlNode& command_node) @@ -444,7 +466,6 @@ 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()); - XmlSubNode x(node, "jabber:x:data:x"); x["type"] = "form"; XmlSubNode title(x, "title"); @@ -452,60 +473,67 @@ void insert_irc_channel_configuration_form(XmlNode& node, const Jid& requester, XmlSubNode instructions(x, "instructions"); instructions.set_inner("Edit the form, to configure the settings of the IRC channel "s + iid.get_local()); - XmlSubNode record_history(x, "field"); - 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"; - { - // Value selected by default - XmlSubNode value(record_history, "value"); - value.set_inner(options.col().to_string()); + XmlSubNode record_history(x, "field"); + 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"; + { + // Value selected by default + XmlSubNode value(record_history, "value"); + value.set_inner(options.col().to_string()); + } + // All three possible values + for (const auto& val: {"unset", "true", "false"}) + { + XmlSubNode option(record_history, "option"); + option["label"] = val; + XmlSubNode value(option, "value"); + value.set_inner(val); + } } - // All three possible values - for (const auto& val: {"unset", "true", "false"}) + { - XmlSubNode option(record_history, "option"); - option["label"] = val; - XmlSubNode value(option, "value"); - value.set_inner(val); + 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"; + encoding_out["label"] = "Out encoding"; + if (!options.col().empty()) + { + XmlSubNode encoding_out_value(encoding_out, "value"); + encoding_out_value.set_inner(options.col()); + } } - 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"; - encoding_out["label"] = "Out encoding"; - if (!options.col().empty()) - { - XmlSubNode encoding_out_value(encoding_out, "value"); - encoding_out_value.set_inner(options.col()); - } + { + 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"; + encoding_in["label"] = "In encoding"; + if (!options.col().empty()) + { + XmlSubNode encoding_in_value(encoding_in, "value"); + encoding_in_value.set_inner(options.col()); + } + } - 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"; - encoding_in["label"] = "In encoding"; - if (!options.col().empty()) + { + 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."; + persistent["label"] = "Persistent"; { - XmlSubNode encoding_in_value(encoding_in, "value"); - encoding_in_value.set_inner(options.col()); + XmlSubNode value(persistent, "value"); + value.set_name("value"); + if (options.col()) + value.set_inner("true"); + else + value.set_inner("false"); } - - 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."; - persistent["label"] = "Persistent"; - { - XmlSubNode value(persistent, "value"); - value.set_name("value"); - if (options.col()) - value.set_inner("true"); - else - value.set_inner("false"); } } -- cgit v1.2.3 From cf56b60fd340dc62f90b5b8d3c86d68da347abee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Sat, 8 Jul 2017 12:36:08 +0200 Subject: =?UTF-8?q?Remove=20all=20the=20empty=20=E2=80=9Coptions=E2=80=9D?= =?UTF-8?q?=20members=20in=20Column=20classes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit By using SFINAE to use that member only when it exists. --- src/database/database.hpp | 57 ++++++++++++++--------------------------------- src/database/table.hpp | 14 ++++++++++-- 2 files changed, 29 insertions(+), 42 deletions(-) (limited to 'src') diff --git a/src/database/database.hpp b/src/database/database.hpp index 8364abc..b5f2ff0 100644 --- a/src/database/database.hpp +++ b/src/database/database.hpp @@ -20,79 +20,56 @@ class Database public: using time_point = std::chrono::system_clock::time_point; - struct Uuid: Column { static constexpr auto name = "uuid_"; - static constexpr auto options = ""; }; + struct Uuid: Column { static constexpr auto name = "uuid_"; }; - struct Owner: Column { static constexpr auto name = "owner_"; - static constexpr auto options = ""; }; + struct Owner: Column { static constexpr auto name = "owner_"; }; - struct IrcChanName: Column { static constexpr auto name = "ircChanName_"; - static constexpr auto options = ""; }; + struct IrcChanName: Column { static constexpr auto name = "ircChanName_"; }; - struct Channel: Column { static constexpr auto name = "channel_"; - static constexpr auto options = ""; }; + struct Channel: Column { static constexpr auto name = "channel_"; }; - struct IrcServerName: Column { static constexpr auto name = "ircServerName_"; - static constexpr auto options = ""; }; + struct IrcServerName: Column { static constexpr auto name = "ircServerName_"; }; - struct Server: Column { static constexpr auto name = "server_"; - static constexpr auto options = ""; }; + struct Server: Column { static constexpr auto name = "server_"; }; - struct Date: Column { static constexpr auto name = "date_"; - static constexpr auto options = ""; }; + struct Date: Column { static constexpr auto name = "date_"; }; - struct Body: Column { static constexpr auto name = "body_"; - static constexpr auto options = ""; }; + struct Body: Column { static constexpr auto name = "body_"; }; - struct Nick: Column { static constexpr auto name = "nick_"; - static constexpr auto options = ""; }; + struct Nick: Column { static constexpr auto name = "nick_"; }; - struct Pass: Column { static constexpr auto name = "pass_"; - static constexpr auto options = ""; }; + struct Pass: Column { static constexpr auto name = "pass_"; }; struct Ports: Column { static constexpr auto name = "ports_"; - static constexpr auto options = ""; Ports(): Column("6667") {} }; struct TlsPorts: Column { static constexpr auto name = "tlsPorts_"; - static constexpr auto options = ""; TlsPorts(): Column("6697;6670") {} }; - struct Username: Column { static constexpr auto name = "username_"; - static constexpr auto options = ""; }; + struct Username: Column { static constexpr auto name = "username_"; }; - struct Realname: Column { static constexpr auto name = "realname_"; - static constexpr auto options = ""; }; + struct Realname: Column { static constexpr auto name = "realname_"; }; - struct AfterConnectionCommand: Column { static constexpr auto name = "afterConnectionCommand_"; - static constexpr auto options = ""; }; + struct AfterConnectionCommand: Column { static constexpr auto name = "afterConnectionCommand_"; }; - struct TrustedFingerprint: Column { static constexpr auto name = "trustedFingerprint_"; - static constexpr auto options = ""; }; + struct TrustedFingerprint: Column { static constexpr auto name = "trustedFingerprint_"; }; - struct EncodingOut: Column { static constexpr auto name = "encodingOut_"; - static constexpr auto options = ""; }; + struct EncodingOut: Column { static constexpr auto name = "encodingOut_"; }; - struct EncodingIn: Column { static constexpr auto name = "encodingIn_"; - static constexpr auto options = ""; }; + struct EncodingIn: Column { static constexpr auto name = "encodingIn_"; }; struct MaxHistoryLength: Column { static constexpr auto name = "maxHistoryLength_"; - static constexpr auto options = ""; MaxHistoryLength(): Column(20) {} }; struct RecordHistory: Column { static constexpr auto name = "recordHistory_"; - static constexpr auto options = ""; RecordHistory(): Column(true) {}}; - struct RecordHistoryOptional: Column { static constexpr auto name = "recordHistory_"; - static constexpr auto options = ""; }; + struct RecordHistoryOptional: Column { static constexpr auto name = "recordHistory_"; }; struct VerifyCert: Column { static constexpr auto name = "verifyCert_"; - static constexpr auto options = ""; VerifyCert(): Column(true) {} }; struct Persistent: Column { static constexpr auto name = "persistent_"; - static constexpr auto options = ""; Persistent(): Column(false) {} }; using MucLogLineTable = Table; diff --git a/src/database/table.hpp b/src/database/table.hpp index 411ac6a..f2f70bb 100644 --- a/src/database/table.hpp +++ b/src/database/table.hpp @@ -28,6 +28,17 @@ void add_column_to_table(sqlite3* db, const std::string& table_name) } } + +template +void append_option(std::string& s) +{ + s += " "s + ColumnType::options; +} + +template +void append_option(...) +{ } + template class Table { @@ -110,14 +121,13 @@ class Table str += ColumnType::name; str += " "; str += TypeToSQLType::type; - str += " "s + ColumnType::options; + append_option(str); if (N != sizeof...(T) - 1) str += ","; str += "\n"; add_column_create(str); } - template typename std::enable_if::type add_column_create(std::string&) -- cgit v1.2.3 From 7a9b2dca06c390531ec7f5d85e58cc27e17e7b74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Sat, 8 Jul 2017 12:37:03 +0200 Subject: Use a more precise return type, instead of auto --- src/database/row.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/database/row.hpp b/src/database/row.hpp index e7a58c4..a8e8579 100644 --- a/src/database/row.hpp +++ b/src/database/row.hpp @@ -45,7 +45,7 @@ struct Row {} template - auto& col() + typename Type::real_type& col() { auto&& col = std::get(this->columns); return col.value; -- cgit v1.2.3 From faed8952cb6ba063e5424364df69cef193fb736e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Sat, 8 Jul 2017 14:04:35 +0200 Subject: Remove a bunch of useless string_literal usage --- src/bridge/bridge.cpp | 10 +++++----- src/database/select_query.hpp | 2 +- src/database/table.cpp | 2 +- src/database/table.hpp | 2 +- src/irc/irc_client.cpp | 22 +++++++++++----------- src/network/tcp_client_socket_handler.cpp | 6 +++--- src/xmpp/adhoc_command.cpp | 2 +- src/xmpp/adhoc_commands_handler.cpp | 8 ++++---- src/xmpp/biboumi_adhoc_commands.cpp | 12 ++++++------ src/xmpp/biboumi_component.cpp | 10 +++++----- src/xmpp/xmpp_component.cpp | 6 +++--- 11 files changed, 41 insertions(+), 41 deletions(-) (limited to 'src') diff --git a/src/bridge/bridge.cpp b/src/bridge/bridge.cpp index 81ca147..f4c7412 100644 --- a/src/bridge/bridge.cpp +++ b/src/bridge/bridge.cpp @@ -378,7 +378,7 @@ void Bridge::forward_affiliation_role_change(const Iid& iid, const std::string& } else if (message.command == "472" && message.arguments.size() >= 2) { - std::string error_message = "Unknown mode: "s + message.arguments[1]; + std::string error_message = "Unknown mode: " + message.arguments[1]; if (message.arguments.size() >= 3) error_message = message.arguments[2]; this->xmpp.send_stanza_error("iq", from, std::to_string(iid), id, "cancel", "not-allowed", @@ -465,7 +465,7 @@ void Bridge::leave_irc_channel(Iid&& iid, const std::string& status_message, con { if (channel && channel->joined) this->send_muc_leave(iid, channel->get_self()->nick, - "Biboumi note: "s + std::to_string(resources - 1) + " resources are still in this channel.", + "Biboumi note: " + std::to_string(resources - 1) + " resources are still in this channel.", true, resource); this->remove_resource_from_chan(key, resource); if (this->number_of_channels_the_resource_is_in(iid.get_server(), resource) == 0) @@ -702,12 +702,12 @@ void Bridge::send_xmpp_version_to_irc(const Iid& iid, const std::string& name, c { std::string result(name + " " + version + " " + os); - this->send_private_message(iid, "\01VERSION "s + result + "\01", "NOTICE"); + this->send_private_message(iid, "\01VERSION " + result + "\01", "NOTICE"); } void Bridge::send_irc_ping_result(const Iid& iid, const std::string& id) { - this->send_private_message(iid, "\01PING "s + utils::revstr(id) + "\01", "NOTICE"); + this->send_private_message(iid, "\01PING " + utils::revstr(id) + "\01", "NOTICE"); } void Bridge::send_irc_user_ping_request(const std::string& irc_hostname, const std::string& nick, @@ -923,7 +923,7 @@ void Bridge::send_xmpp_message(const std::string& from, const std::string& autho if (!author.empty()) { IrcUser user(author); - body = "\u000303"s + user.nick + (user.host.empty()? + body = "\u000303" + user.nick + (user.host.empty()? "\u0003: ": (" (\u000310" + user.host + "\u000303)\u0003: ")) + msg; } diff --git a/src/database/select_query.hpp b/src/database/select_query.hpp index f4d71af..872001c 100644 --- a/src/database/select_query.hpp +++ b/src/database/select_query.hpp @@ -79,7 +79,7 @@ struct SelectQuery: public Query using ColumnsType = std::tuple; using ColumnType = typename std::remove_reference(std::declval()))>::type; - this->body += " "s + ColumnType::name; + this->body += " " + std::string{ColumnType::name}; if (N < (sizeof...(T) - 1)) this->body += ", "; diff --git a/src/database/table.cpp b/src/database/table.cpp index 5929f33..160f426 100644 --- a/src/database/table.cpp +++ b/src/database/table.cpp @@ -4,7 +4,7 @@ std::set get_all_columns_from_table(sqlite3* db, const std::string& { std::set result; char* errmsg; - std::string query{"PRAGMA table_info("s + table_name + ")"}; + std::string query{"PRAGMA table_info(" + table_name + ")"}; log_debug(query); int res = sqlite3_exec(db, query.data(), [](void* param, int columns_nb, char** columns, char**) -> int { constexpr int name_column = 1; diff --git a/src/database/table.hpp b/src/database/table.hpp index f2f70bb..c9e35d3 100644 --- a/src/database/table.hpp +++ b/src/database/table.hpp @@ -17,7 +17,7 @@ template void add_column_to_table(sqlite3* db, const std::string& table_name) { const std::string name = ColumnType::name; - std::string query{"ALTER TABLE "s + table_name + " ADD " + ColumnType::name + " " + TypeToSQLType::type}; + std::string query{"ALTER TABLE " + table_name + " ADD " + ColumnType::name + " " + TypeToSQLType::type}; log_debug(query); char* error; const auto result = sqlite3_exec(db, query.data(), nullptr, nullptr, &error); diff --git a/src/irc/irc_client.cpp b/src/irc/irc_client.cpp index bacb89e..00a7158 100644 --- a/src/irc/irc_client.cpp +++ b/src/irc/irc_client.cpp @@ -178,7 +178,7 @@ IrcClient::~IrcClient() { // This event may or may not exist (if we never got connected, it // doesn't), but it's ok - TimedEventsManager::instance().cancel("PING"s + this->hostname + this->bridge.get_jid()); + TimedEventsManager::instance().cancel("PING" + this->hostname + this->bridge.get_jid()); } void IrcClient::start() @@ -194,7 +194,7 @@ void IrcClient::start() bool tls; std::tie(port, tls) = this->ports_to_try.top(); this->ports_to_try.pop(); - this->bridge.send_xmpp_message(this->hostname, "", "Connecting to "s + + this->bridge.send_xmpp_message(this->hostname, "", "Connecting to " + this->hostname + ":" + port + " (" + (tls ? "encrypted" : "not encrypted") + ")"); @@ -213,7 +213,7 @@ void IrcClient::start() void IrcClient::on_connection_failed(const std::string& reason) { this->bridge.send_xmpp_message(this->hostname, "", - "Connection failed: "s + reason); + "Connection failed: " + reason); if (this->hostname_resolution_failed) while (!this->ports_to_try.empty()) @@ -260,7 +260,7 @@ void IrcClient::on_connected() { if (this->is_connected()) { - this->on_connection_close("Could not resolve hostname "s + this->user_hostname + + this->on_connection_close("Could not resolve hostname " + this->user_hostname + ": " + error_msg); this->send_quit_command(""); } @@ -585,7 +585,7 @@ void IrcClient::on_notice(const IrcMessage& message) // The notice was directed at a channel we are in. Modify the message // to indicate that it is a notice, and make it a MUC message coming // from the MUC JID - IrcMessage modified_message(std::move(from), "PRIVMSG", {to, "\u000303[notice]\u0003 "s + body}); + IrcMessage modified_message(std::move(from), "PRIVMSG", {to, "\u000303[notice]\u0003 " + body}); this->on_channel_message(modified_message); } } @@ -697,7 +697,7 @@ void IrcClient::on_channel_message(const IrcMessage& message) { if (body.substr(1, 6) == "ACTION") this->bridge.send_message(iid, nick, - "/me"s + body.substr(7, body.size() - 8), muc); + "/me" + body.substr(7, body.size() - 8), muc); else if (body.substr(1, 8) == "VERSION\01") this->bridge.send_iq_version_request(nick, this->hostname); else if (body.substr(1, 5) == "PING ") @@ -899,7 +899,7 @@ void IrcClient::on_welcome_message(const IrcMessage& message) #endif // Install a repeated events to regularly send a PING TimedEventsManager::instance().add_event(TimedEvent(240s, std::bind(&IrcClient::send_ping_command, this), - "PING"s + this->hostname + this->bridge.get_jid())); + "PING" + this->hostname + this->bridge.get_jid())); std::string channels{}; std::string channels_with_key{}; std::string keys{}; @@ -1002,7 +1002,7 @@ void IrcClient::on_error(const IrcMessage& message) this->bridge.send_muc_leave(iid, std::move(own_nick), leave_message, true); } this->channels.clear(); - this->send_gateway_message("ERROR: "s + leave_message); + this->send_gateway_message("ERROR: " + leave_message); } void IrcClient::on_quit(const IrcMessage& message) @@ -1135,7 +1135,7 @@ void IrcClient::on_channel_mode(const IrcMessage& message) mode_arguments += message.arguments[i]; } } - this->bridge.send_message(iid, "", "Mode "s + iid.get_local() + + this->bridge.send_message(iid, "", "Mode " + iid.get_local() + " [" + mode_arguments + "] by " + user.nick, true); const IrcChannel* channel = this->get_channel(iid.get_local()); @@ -1213,7 +1213,7 @@ void IrcClient::on_channel_mode(const IrcMessage& message) void IrcClient::on_user_mode(const IrcMessage& message) { this->bridge.send_xmpp_message(this->hostname, "", - "User mode for "s + message.arguments[0] + + "User mode for " + message.arguments[0] + " is [" + message.arguments[1] + "]"); } @@ -1252,7 +1252,7 @@ void IrcClient::leave_dummy_channel(const std::string& exit_message, const std:: this->dummy_channel.joined = false; this->dummy_channel.joining = false; this->dummy_channel.remove_all_users(); - this->bridge.send_muc_leave(Iid("%"s + this->hostname, this->chantypes), std::string(this->current_nick), exit_message, true, resource); + this->bridge.send_muc_leave(Iid("%" + this->hostname, this->chantypes), std::string(this->current_nick), exit_message, true, resource); } #ifdef BOTAN_FOUND diff --git a/src/network/tcp_client_socket_handler.cpp b/src/network/tcp_client_socket_handler.cpp index 35f2446..aac13d0 100644 --- a/src/network/tcp_client_socket_handler.cpp +++ b/src/network/tcp_client_socket_handler.cpp @@ -146,7 +146,7 @@ void TCPClientSocketHandler::connect(const std::string& address, const std::stri || errno == EISCONN) { log_info("Connection success."); - TimedEventsManager::instance().cancel("connection_timeout"s + + TimedEventsManager::instance().cancel("connection_timeout" + std::to_string(this->socket)); this->poller->add_socket_handler(this); this->connected = true; @@ -196,7 +196,7 @@ void TCPClientSocketHandler::connect(const std::string& address, const std::stri TimedEventsManager::instance().add_event( TimedEvent(std::chrono::steady_clock::now() + 5s, std::bind(&TCPClientSocketHandler::on_connection_timeout, this), - "connection_timeout"s + std::to_string(this->socket))); + "connection_timeout" + std::to_string(this->socket))); return ; } log_info("Connection failed:", std::strerror(errno)); @@ -220,7 +220,7 @@ void TCPClientSocketHandler::connect() void TCPClientSocketHandler::close() { - TimedEventsManager::instance().cancel("connection_timeout"s + + TimedEventsManager::instance().cancel("connection_timeout" + std::to_string(this->socket)); TCPSocketHandler::close(); diff --git a/src/xmpp/adhoc_command.cpp b/src/xmpp/adhoc_command.cpp index e02bf35..fbf4ce2 100644 --- a/src/xmpp/adhoc_command.cpp +++ b/src/xmpp/adhoc_command.cpp @@ -59,7 +59,7 @@ void HelloStep2(XmppComponent&, AdhocSession& session, XmlNode& command_node) command_node.delete_all_children(); XmlSubNode note(command_node, "note"); note["type"] = "info"; - note.set_inner("Hello "s + value_str + "!"s); + note.set_inner("Hello " + value_str + "!"s); return; } } diff --git a/src/xmpp/adhoc_commands_handler.cpp b/src/xmpp/adhoc_commands_handler.cpp index 040d0ff..e4dcd5c 100644 --- a/src/xmpp/adhoc_commands_handler.cpp +++ b/src/xmpp/adhoc_commands_handler.cpp @@ -19,7 +19,7 @@ void AdhocCommandsHandler::add_command(std::string name, AdhocCommand command) { const auto found = this->commands.find(name); if (found != this->commands.end()) - throw std::runtime_error("Trying to add an ad-hoc command that already exist: "s + name); + throw std::runtime_error("Trying to add an ad-hoc command that already exist: " + name); this->commands.emplace(std::make_pair(std::move(name), std::move(command))); } @@ -59,7 +59,7 @@ XmlNode AdhocCommandsHandler::handle_request(const std::string& executor_jid, co std::forward_as_tuple(command_it->second, executor_jid, to)); TimedEventsManager::instance().add_event(TimedEvent(std::chrono::steady_clock::now() + 3600s, std::bind(&AdhocCommandsHandler::remove_session, this, sessionid, executor_jid), - "adhocsession"s + sessionid + executor_jid)); + "adhocsession" + sessionid + executor_jid)); } auto session_it = this->sessions.find(std::make_pair(sessionid, executor_jid)); if ((session_it != this->sessions.end()) && @@ -74,7 +74,7 @@ XmlNode AdhocCommandsHandler::handle_request(const std::string& executor_jid, co { this->sessions.erase(session_it); command_node["status"] = "completed"; - TimedEventsManager::instance().cancel("adhocsession"s + sessionid + executor_jid); + TimedEventsManager::instance().cancel("adhocsession" + sessionid + executor_jid); } else { @@ -87,7 +87,7 @@ XmlNode AdhocCommandsHandler::handle_request(const std::string& executor_jid, co { this->sessions.erase(session_it); command_node["status"] = "canceled"; - TimedEventsManager::instance().cancel("adhocsession"s + sessionid + executor_jid); + TimedEventsManager::instance().cancel("adhocsession" + sessionid + executor_jid); } else // unsupported action { diff --git a/src/xmpp/biboumi_adhoc_commands.cpp b/src/xmpp/biboumi_adhoc_commands.cpp index 4129517..27b079b 100644 --- a/src/xmpp/biboumi_adhoc_commands.cpp +++ b/src/xmpp/biboumi_adhoc_commands.cpp @@ -223,9 +223,9 @@ void ConfigureIrcServerStep1(XmppComponent&, AdhocSession& session, XmlNode& com XmlSubNode x(command_node, "jabber:x:data:x"); x["type"] = "form"; XmlSubNode title(x, "title"); - title.set_inner("Configure the IRC server "s + server_domain); + title.set_inner("Configure the IRC server " + server_domain); XmlSubNode instructions(x, "instructions"); - instructions.set_inner("Edit the form, to configure the settings of the IRC server "s + server_domain); + instructions.set_inner("Edit the form, to configure the settings of the IRC server " + server_domain); { XmlSubNode ports(x, "field"); @@ -469,9 +469,9 @@ void insert_irc_channel_configuration_form(XmlNode& node, const Jid& requester, XmlSubNode x(node, "jabber:x:data:x"); x["type"] = "form"; XmlSubNode title(x, "title"); - title.set_inner("Configure the IRC channel "s + iid.get_local() + " on server "s + iid.get_server()); + title.set_inner("Configure the IRC channel " + iid.get_local() + " on server " + iid.get_server()); XmlSubNode instructions(x, "instructions"); - instructions.set_inner("Edit the form, to configure the settings of the IRC channel "s + iid.get_local()); + instructions.set_inner("Edit the form, to configure the settings of the IRC channel " + iid.get_local()); { XmlSubNode record_history(x, "field"); @@ -693,7 +693,7 @@ void DisconnectUserFromServerStep2(XmppComponent& xmpp_component, AdhocSession& { XmlSubNode note(command_node, "note"); note["type"] = "info"; - note.set_inner("User "s + jid_to_disconnect + " is not connected to any IRC server."); + note.set_inner("User " + jid_to_disconnect + " is not connected to any IRC server."); session.terminate(); return ; } @@ -797,7 +797,7 @@ void GetIrcConnectionInfoStep1(XmppComponent& component, AdhocSession& session, IrcClient* irc = bridge->find_irc_client(hostname); if (!irc || !irc->is_connected()) { - message = "You are not connected to the IRC server "s + hostname; + message = "You are not connected to the IRC server " + hostname; return; } diff --git a/src/xmpp/biboumi_component.cpp b/src/xmpp/biboumi_component.cpp index 32f3968..1c7cd92 100644 --- a/src/xmpp/biboumi_component.cpp +++ b/src/xmpp/biboumi_component.cpp @@ -177,7 +177,7 @@ void BiboumiComponent::handle_presence(const Stanza& stanza) if (type != "unavailable") this->send_stanza_error("presence", from_str, to_str, id, "cancel", "remote-server-not-found", - "Not connected to IRC server "s + ex.hostname, + "Not connected to IRC server " + ex.hostname, true); } stanza_error.disable(); @@ -277,7 +277,7 @@ void BiboumiComponent::handle_message(const Stanza& stanza) { this->send_stanza_error("message", from_str, to_str, id, "cancel", "remote-server-not-found", - "Not connected to IRC server "s + ex.hostname, + "Not connected to IRC server " + ex.hostname, true); } stanza_error.disable(); @@ -586,7 +586,7 @@ void BiboumiComponent::handle_iq(const Stanza& stanza) { this->send_stanza_error("iq", from, to_str, id, "cancel", "remote-server-not-found", - "Not connected to IRC server "s + ex.hostname, + "Not connected to IRC server " + ex.hostname, true); stanza_error.disable(); return; @@ -806,7 +806,7 @@ void BiboumiComponent::send_irc_server_disco_info(const std::string& id, const s XmlSubNode identity(query, "identity"); identity["category"] = "conference"; identity["type"] = "irc"; - identity["name"] = "IRC server "s + from.local + " over Biboumi"; + identity["name"] = "IRC server " + from.local + " over Biboumi"; for (const char *ns: {DISCO_INFO_NS, MUC_NS, ADHOC_NS, PING_NS, MAM_NS, VERSION_NS}) { XmlSubNode feature(query, "feature"); @@ -849,7 +849,7 @@ void BiboumiComponent::send_irc_channel_disco_info(const std::string& id, const XmlSubNode identity(query, "identity"); identity["category"] = "conference"; identity["type"] = "irc"; - identity["name"] = "IRC channel "s + iid.get_local() + " from server " + iid.get_server() + " over biboumi"; + identity["name"] = "IRC channel " + iid.get_local() + " from server " + iid.get_server() + " over biboumi"; for (const char *ns: {DISCO_INFO_NS, MUC_NS, ADHOC_NS, PING_NS, MAM_NS, VERSION_NS}) { XmlSubNode feature(query, "feature"); diff --git a/src/xmpp/xmpp_component.cpp b/src/xmpp/xmpp_component.cpp index b138ed9..3c69b36 100644 --- a/src/xmpp/xmpp_component.cpp +++ b/src/xmpp/xmpp_component.cpp @@ -92,7 +92,7 @@ void XmppComponent::on_connected() { log_info("connected to XMPP server"); this->first_connection_try = true; - auto data = "served_hostname + \ "' xmlns:stream='http://etherx.jabber.org/streams' xmlns='" COMPONENT_NS "'>"; log_debug("XMPP SENDING: ", data); this->send_data(std::move(data)); @@ -142,7 +142,7 @@ void XmppComponent::on_remote_stream_open(const XmlNode& node) } // Try to authenticate - auto data = ""s + get_handshake_digest(this->stream_id, this->secret) + ""; + auto data = "" + get_handshake_digest(this->stream_id, this->secret) + ""; log_debug("XMPP SENDING: ", data); this->send_data(std::move(data)); } @@ -642,7 +642,7 @@ void XmppComponent::send_iq_version_request(const std::string& from, Stanza iq("iq"); { iq["type"] = "get"; - iq["id"] = "version_"s + XmppComponent::next_id(); + iq["id"] = "version_" + XmppComponent::next_id(); iq["from"] = from + "@" + this->served_hostname; iq["to"] = jid_to; XmlSubNode query(iq, "query"); -- cgit v1.2.3 From 3a95076db40dbdff4b130c5d9b8db81e537a750d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Sat, 8 Jul 2017 16:59:29 +0200 Subject: Send a 110 status code on a QUIT received for ourself --- src/irc/irc_client.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/irc/irc_client.cpp b/src/irc/irc_client.cpp index 00a7158..00314b2 100644 --- a/src/irc/irc_client.cpp +++ b/src/irc/irc_client.cpp @@ -1015,6 +1015,9 @@ void IrcClient::on_quit(const IrcMessage& message) const std::string& chan_name = pair.first; IrcChannel* channel = pair.second.get(); const IrcUser* user = channel->find_user(message.prefix); + bool self = false; + if (user == channel->get_self()) + self = true; if (user) { std::string nick = user->nick; @@ -1023,7 +1026,7 @@ void IrcClient::on_quit(const IrcMessage& message) iid.set_local(chan_name); iid.set_server(this->hostname); iid.type = Iid::Type::Channel; - this->bridge.send_muc_leave(iid, std::move(nick), txt, false); + this->bridge.send_muc_leave(iid, std::move(nick), txt, self); } } } -- cgit v1.2.3 From 9fa1852c7ea094086f45e840fa22cc83d56b744e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Sat, 8 Jul 2017 18:10:47 +0200 Subject: =?UTF-8?q?Send=20status=20code=3D'332'=20on=20biboumi=20or=20IRC?= =?UTF-8?q?=20server=E2=80=99s=20shutdown?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/bridge/bridge.cpp | 9 +++++---- src/bridge/bridge.hpp | 5 ++++- src/irc/irc_client.cpp | 8 ++++---- src/xmpp/xmpp_component.cpp | 8 +++++++- src/xmpp/xmpp_component.hpp | 7 ++++++- 5 files changed, 26 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/bridge/bridge.cpp b/src/bridge/bridge.cpp index f4c7412..89a0af3 100644 --- a/src/bridge/bridge.cpp +++ b/src/bridge/bridge.cpp @@ -455,7 +455,7 @@ void Bridge::leave_irc_channel(Iid&& iid, const std::string& status_message, con } else if (channel->joined) { - this->send_muc_leave(iid, channel->get_self()->nick, "", true, resource); + this->send_muc_leave(iid, channel->get_self()->nick, "", true, true, resource); } // Since there are no resources left in that channel, we don't // want to receive private messages using this room's JID @@ -466,7 +466,7 @@ void Bridge::leave_irc_channel(Iid&& iid, const std::string& status_message, con if (channel && channel->joined) this->send_muc_leave(iid, channel->get_self()->nick, "Biboumi note: " + std::to_string(resources - 1) + " resources are still in this channel.", - true, resource); + true, true, resource); this->remove_resource_from_chan(key, resource); if (this->number_of_channels_the_resource_is_in(iid.get_server(), resource) == 0) this->remove_resource_from_server(iid.get_server(), resource); @@ -883,16 +883,17 @@ void Bridge::send_presence_error(const Iid& iid, const std::string& nick, void Bridge::send_muc_leave(const Iid& iid, const std::string& nick, const std::string& message, const bool self, + const bool user_requested, const std::string& resource) { if (!resource.empty()) this->xmpp.send_muc_leave(std::to_string(iid), nick, this->make_xmpp_body(message), - this->user_jid + "/" + resource, self); + this->user_jid + "/" + resource, self, user_requested); else { for (const auto &res: this->resources_in_chan[iid.to_tuple()]) this->xmpp.send_muc_leave(std::to_string(iid), nick, this->make_xmpp_body(message), - this->user_jid + "/" + res, self); + this->user_jid + "/" + res, self, user_requested); if (self) this->remove_all_resources_from_chan(iid.to_tuple()); diff --git a/src/bridge/bridge.hpp b/src/bridge/bridge.hpp index 033291c..496b439 100644 --- a/src/bridge/bridge.hpp +++ b/src/bridge/bridge.hpp @@ -169,7 +169,10 @@ public: /** * Send an unavailable presence from this participant */ - void send_muc_leave(const Iid& iid, const std::string& nick, const std::string& message, const bool self, const std::string& resource = ""); + void send_muc_leave(const Iid& iid, const std::string& nick, + const std::string& message, const bool self, + const bool user_requested, + const std::string& resource=""); /** * Send presences to indicate that an user old_nick (ourself if self == * true) changed his nick to new_nick. The user_mode is needed because diff --git a/src/irc/irc_client.cpp b/src/irc/irc_client.cpp index 00314b2..67221c5 100644 --- a/src/irc/irc_client.cpp +++ b/src/irc/irc_client.cpp @@ -981,7 +981,7 @@ void IrcClient::on_part(const IrcMessage& message) // channel pointer is now invalid channel = nullptr; } - this->bridge.send_muc_leave(iid, std::move(nick), txt, self); + this->bridge.send_muc_leave(iid, std::move(nick), txt, self, true); } } @@ -999,7 +999,7 @@ void IrcClient::on_error(const IrcMessage& message) if (!channel->joined) continue; std::string own_nick = channel->get_self()->nick; - this->bridge.send_muc_leave(iid, std::move(own_nick), leave_message, true); + this->bridge.send_muc_leave(iid, std::move(own_nick), leave_message, true, false); } this->channels.clear(); this->send_gateway_message("ERROR: " + leave_message); @@ -1026,7 +1026,7 @@ void IrcClient::on_quit(const IrcMessage& message) iid.set_local(chan_name); iid.set_server(this->hostname); iid.type = Iid::Type::Channel; - this->bridge.send_muc_leave(iid, std::move(nick), txt, self); + this->bridge.send_muc_leave(iid, std::move(nick), txt, self, false); } } } @@ -1255,7 +1255,7 @@ void IrcClient::leave_dummy_channel(const std::string& exit_message, const std:: this->dummy_channel.joined = false; this->dummy_channel.joining = false; this->dummy_channel.remove_all_users(); - this->bridge.send_muc_leave(Iid("%" + this->hostname, this->chantypes), std::string(this->current_nick), exit_message, true, resource); + this->bridge.send_muc_leave(Iid("%" + this->hostname, this->chantypes), std::string(this->current_nick), exit_message, true, true, resource); } #ifdef BOTAN_FOUND diff --git a/src/xmpp/xmpp_component.cpp b/src/xmpp/xmpp_component.cpp index 3c69b36..7366422 100644 --- a/src/xmpp/xmpp_component.cpp +++ b/src/xmpp/xmpp_component.cpp @@ -441,7 +441,8 @@ void XmppComponent::send_history_message(const std::string& muc_name, const std: this->send_stanza(message); } -void XmppComponent::send_muc_leave(const std::string& muc_name, const std::string& nick, Xmpp::body&& message, const std::string& jid_to, const bool self) +void XmppComponent::send_muc_leave(const std::string& muc_name, const std::string& nick, Xmpp::body&& message, + const std::string& jid_to, const bool self, const bool user_requested) { Stanza presence("presence"); { @@ -456,6 +457,11 @@ void XmppComponent::send_muc_leave(const std::string& muc_name, const std::strin XmlSubNode status(x, "status"); status["code"] = "110"; } + if (!user_requested) + { + XmlSubNode status(x, "status"); + status["code"] = "332"; + } if (!message_str.empty()) { XmlSubNode status(presence, "status"); diff --git a/src/xmpp/xmpp_component.hpp b/src/xmpp/xmpp_component.hpp index ebe3ec8..f4a7655 100644 --- a/src/xmpp/xmpp_component.hpp +++ b/src/xmpp/xmpp_component.hpp @@ -146,7 +146,12 @@ public: /** * Send an unavailable presence for this nick */ - void send_muc_leave(const std::string& muc_name, const std::string& nick, Xmpp::body&& message, const std::string& jid_to, const bool self); + void send_muc_leave(const std::string& muc_name, + const std::string& nick, + Xmpp::body&& message, + const std::string& jid_to, + const bool self, + const bool user_requested); /** * Indicate that a participant changed his nick */ -- cgit v1.2.3 From fd7ee48a86aee6a6c83cc22a167717de781ed3f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Sat, 8 Jul 2017 18:11:25 +0200 Subject: Remove many log_debug from the database module --- src/database/count_query.hpp | 1 - src/database/insert_query.hpp | 4 ---- src/database/query.hpp | 5 +---- src/database/row.hpp | 3 --- src/database/table.cpp | 2 -- src/database/table.hpp | 5 ----- 6 files changed, 1 insertion(+), 19 deletions(-) (limited to 'src') diff --git a/src/database/count_query.hpp b/src/database/count_query.hpp index b7bbf51..0dde63c 100644 --- a/src/database/count_query.hpp +++ b/src/database/count_query.hpp @@ -29,7 +29,6 @@ struct CountQuery: public Query if (sqlite3_step(statement.get()) != SQLITE_DONE) log_warning("Count request returned more than one result."); - log_debug("Returning count: ", res); return res; } }; diff --git a/src/database/insert_query.hpp b/src/database/insert_query.hpp index 9e410ce..2ece69d 100644 --- a/src/database/insert_query.hpp +++ b/src/database/insert_query.hpp @@ -20,8 +20,6 @@ actual_bind(Statement& statement, std::vector& params, const std::t params.erase(params.begin()); if (sqlite3_bind_text(statement.get(), N + 1, value.data(), static_cast(value.size()), SQLITE_TRANSIENT) != SQLITE_OK) log_error("Failed to bind ", value, " to param ", N); - else - log_debug("Bound (not id) [", value, "] to ", N); } template @@ -36,8 +34,6 @@ actual_bind(Statement& statement, std::vector&, const std::tuplebody); auto res = sqlite3_prepare(db, this->body.data(), static_cast(this->body.size()) + 1, &stmt, nullptr); if (res != SQLITE_OK) @@ -36,9 +35,7 @@ struct Query for (const std::string& param: this->params) { if (sqlite3_bind_text(statement.get(), i, param.data(), static_cast(param.size()), SQLITE_TRANSIENT) != SQLITE_OK) - log_debug("Failed to bind ", param, " to param ", i); - else - log_debug("Bound ", param, " to ", i); + log_error("Failed to bind ", param, " to param ", i); i++; } diff --git a/src/database/row.hpp b/src/database/row.hpp index a8e8579..2b50874 100644 --- a/src/database/row.hpp +++ b/src/database/row.hpp @@ -17,9 +17,7 @@ typename std::enable_if, Id>::value, void> update_id(std::tuple& columns, sqlite3* db) { auto&& column = std::get(columns); - log_debug("Found an autoincrement col."); auto res = sqlite3_last_insert_rowid(db); - log_debug("Value is now: ", res); column.value = static_cast(res); } @@ -63,7 +61,6 @@ struct Row InsertQuery query(this->table_name); query.insert_col_names(this->columns); query.insert_values(this->columns); - log_debug(query.body); query.execute(this->columns, db); diff --git a/src/database/table.cpp b/src/database/table.cpp index 160f426..9224d79 100644 --- a/src/database/table.cpp +++ b/src/database/table.cpp @@ -5,11 +5,9 @@ std::set get_all_columns_from_table(sqlite3* db, const std::string& std::set result; char* errmsg; std::string query{"PRAGMA table_info(" + table_name + ")"}; - log_debug(query); int res = sqlite3_exec(db, query.data(), [](void* param, int columns_nb, char** columns, char**) -> int { constexpr int name_column = 1; std::set* result = static_cast*>(param); - log_debug("Table has column ", columns[name_column]); if (name_column < columns_nb) result->insert(columns[name_column]); return 0; diff --git a/src/database/table.hpp b/src/database/table.hpp index c9e35d3..24418d9 100644 --- a/src/database/table.hpp +++ b/src/database/table.hpp @@ -2,7 +2,6 @@ #include #include -#include #include #include @@ -18,7 +17,6 @@ void add_column_to_table(sqlite3* db, const std::string& table_name) { const std::string name = ColumnType::name; std::string query{"ALTER TABLE " + table_name + " ADD " + ColumnType::name + " " + TypeToSQLType::type}; - log_debug(query); char* error; const auto result = sqlite3_exec(db, query.data(), nullptr, nullptr, &error); if (result != SQLITE_OK) @@ -66,11 +64,8 @@ class Table this->add_column_create(res); res += ")"; - log_debug(res); - char* error; const auto result = sqlite3_exec(db, res.data(), nullptr, nullptr, &error); - log_debug("result: ", +result); if (result != SQLITE_OK) { log_error("Error executing query: ", error); -- cgit v1.2.3 From 3974371e7b1c3af9eea47d25138b96298fc037f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Sat, 8 Jul 2017 19:07:53 +0200 Subject: Replace a function argument from ... to the template Args&&... thing --- src/database/table.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/database/table.hpp b/src/database/table.hpp index 24418d9..0060211 100644 --- a/src/database/table.hpp +++ b/src/database/table.hpp @@ -33,8 +33,8 @@ void append_option(std::string& s) s += " "s + ColumnType::options; } -template -void append_option(...) +template +void append_option(Args&& ...) { } template -- cgit v1.2.3 From 8232c2cccc07f78a573f4bc39841f9b20693d8db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Sat, 8 Jul 2017 19:21:53 +0200 Subject: Remove an unused variable --- src/bridge/bridge.cpp | 1 - 1 file changed, 1 deletion(-) (limited to 'src') diff --git a/src/bridge/bridge.cpp b/src/bridge/bridge.cpp index 89a0af3..27726e4 100644 --- a/src/bridge/bridge.cpp +++ b/src/bridge/bridge.cpp @@ -856,7 +856,6 @@ void Bridge::send_message(const Iid& iid, const std::string& nick, const std::st } else { - std::string target = std::to_string(iid); const auto it = this->preferred_user_from.find(iid.get_local()); if (it != this->preferred_user_from.end()) { -- cgit v1.2.3 From b2334707107e65dd15590b7472c990bbf79549eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Fri, 14 Jul 2017 15:18:01 +0200 Subject: Send the 332 status only for our own presences --- src/xmpp/xmpp_component.cpp | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/xmpp/xmpp_component.cpp b/src/xmpp/xmpp_component.cpp index 7366422..9c3ba90 100644 --- a/src/xmpp/xmpp_component.cpp +++ b/src/xmpp/xmpp_component.cpp @@ -454,13 +454,15 @@ void XmppComponent::send_muc_leave(const std::string& muc_name, const std::strin x["xmlns"] = MUC_USER_NS; if (self) { - XmlSubNode status(x, "status"); - status["code"] = "110"; - } - if (!user_requested) - { - XmlSubNode status(x, "status"); - status["code"] = "332"; + { + XmlSubNode status(x, "status"); + status["code"] = "110"; + } + if (!user_requested) + { + XmlSubNode status(x, "status"); + status["code"] = "332"; + } } if (!message_str.empty()) { -- cgit v1.2.3 From 84034ed3dc19f718dcc93a35dbf4c840a55efb1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Fri, 23 Jun 2017 00:16:24 +0200 Subject: =?UTF-8?q?Use=20a=20db=20roster=20to=20manage=20biboumi=E2=80=99s?= =?UTF-8?q?=20presence=20with=20the=20contacts?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/database/database.cpp | 51 ++++++++++++++++++++++++++++++++++- src/database/database.hpp | 15 +++++++++++ src/xmpp/biboumi_component.cpp | 61 +++++++++++++++++++++++++++++++++++++++--- src/xmpp/biboumi_component.hpp | 3 +++ 4 files changed, 126 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/database/database.cpp b/src/database/database.cpp index 92f7682..85c675e 100644 --- a/src/database/database.cpp +++ b/src/database/database.cpp @@ -13,6 +13,8 @@ Database::MucLogLineTable Database::muc_log_lines("MucLogLine_"); Database::GlobalOptionsTable Database::global_options("GlobalOptions_"); Database::IrcServerOptionsTable Database::irc_server_options("IrcServerOptions_"); Database::IrcChannelOptionsTable Database::irc_channel_options("IrcChannelOptions_"); +Database::RosterTable Database::roster("roster"); + void Database::open(const std::string& filename) { @@ -36,6 +38,8 @@ void Database::open(const std::string& filename) Database::irc_server_options.upgrade(Database::db); Database::irc_channel_options.create(Database::db); Database::irc_channel_options.upgrade(Database::db); + Database::roster.create(Database::db); + Database::roster.upgrade(Database::db); } @@ -177,6 +181,51 @@ std::vector Database::get_muc_logs(const std::string& owne return {result.crbegin(), result.crend()}; } +void Database::add_roster_item(const std::string& local, const std::string& remote) +{ + auto roster_item = Database::roster.row(); + + roster_item.col() = local; + roster_item.col() = remote; + + roster_item.save(Database::db); +} + +void Database::delete_roster_item(const std::string& local, const std::string& remote) +{ + Query query("DELETE FROM "s + Database::roster.get_name()); + query << " WHERE " << Database::RemoteJid{} << "=" << remote << \ + " AND " << Database::LocalJid{} << "=" << local; + + query.execute(Database::db); +} + +bool Database::has_roster_item(const std::string& local, const std::string& remote) +{ + auto query = Database::roster.select(); + query.where() << Database::LocalJid{} << "=" << local << \ + " and " << Database::RemoteJid{} << "=" << remote; + + auto res = query.execute(Database::db); + + return !res.empty(); +} + +std::vector Database::get_contact_list(const std::string& local) +{ + auto query = Database::roster.select(); + query.where() << Database::LocalJid{} << "=" << local; + + return query.execute(Database::db); +} + +std::vector Database::get_full_roster() +{ + auto query = Database::roster.select(); + + return query.execute(Database::db); +} + void Database::close() { sqlite3_close_v2(Database::db); @@ -192,4 +241,4 @@ std::string Database::gen_uuid() return uuid_str; } -#endif \ No newline at end of file +#endif diff --git a/src/database/database.hpp b/src/database/database.hpp index b5f2ff0..c00c938 100644 --- a/src/database/database.hpp +++ b/src/database/database.hpp @@ -72,6 +72,11 @@ class Database struct Persistent: Column { static constexpr auto name = "persistent_"; Persistent(): Column(false) {} }; + struct LocalJid: Column { static constexpr auto name = "local"; }; + + struct RemoteJid: Column { static constexpr auto name = "remote"; }; + + using MucLogLineTable = Table; using MucLogLine = MucLogLineTable::RowType; @@ -84,6 +89,9 @@ class Database using IrcChannelOptionsTable = Table; using IrcChannelOptions = IrcChannelOptionsTable::RowType; + using RosterTable = Table; + using RosterItem = RosterTable::RowType; + Database() = default; ~Database() = default; @@ -109,6 +117,12 @@ class Database static std::string store_muc_message(const std::string& owner, const std::string& chan_name, const std::string& server_name, time_point date, const std::string& body, const std::string& nick); + static void add_roster_item(const std::string& local, const std::string& remote); + static bool has_roster_item(const std::string& local, const std::string& remote); + static void delete_roster_item(const std::string& local, const std::string& remote); + static std::vector get_contact_list(const std::string& local); + static std::vector get_full_roster(); + static void close(); static void open(const std::string& filename); @@ -123,6 +137,7 @@ class Database static GlobalOptionsTable global_options; static IrcServerOptionsTable irc_server_options; static IrcChannelOptionsTable irc_channel_options; + static RosterTable roster; static sqlite3* db; private: diff --git a/src/xmpp/biboumi_component.cpp b/src/xmpp/biboumi_component.cpp index 1c7cd92..f3381aa 100644 --- a/src/xmpp/biboumi_component.cpp +++ b/src/xmpp/biboumi_component.cpp @@ -83,6 +83,15 @@ void BiboumiComponent::shutdown() { for (auto& pair: this->bridges) pair.second->shutdown("Gateway shutdown"); +#ifdef USE_DATABASE + const auto full_roster = Database::get_full_roster(); + for (const Database::RosterItem& roster_item: full_roster) + { + this->send_presence_to_contact(roster_item.col(), + roster_item.col(), + "unavailable"); + } +#endif } void BiboumiComponent::clean() @@ -160,10 +169,28 @@ void BiboumiComponent::handle_presence(const Stanza& stanza) { if (type == "subscribe") { // Auto-accept any subscription request for an IRC server - this->accept_subscription(to_str, from.bare()); - this->ask_subscription(to_str, from.bare()); + this->send_presence_to_contact(to_str, from.bare(), "subscribed", id); + if (iid.type == Iid::Type::None) + this->send_presence_to_contact(to_str, from.bare(), ""); + this->send_presence_to_contact(to_str, from.bare(), "subscribe"); +#ifdef USE_DATABASE + if (!Database::has_roster_item(to_str, from.bare())) + Database::add_roster_item(to_str, from.bare()); +#endif + } + else if (type == "unsubscribe") + { +#ifdef USE_DATABASE + const bool res = Database::has_roster_item(to_str, from.bare()); + if (res) + Database::delete_roster_item(to_str, from.bare()); +#endif + } + else if (type.empty()) + { // We just receive a presence from someone (as the result of a probe, + // or a directed presence, or a normal presence change) + this->send_presence_to_contact(to_str, from.bare(), ""); } - } else { @@ -979,3 +1006,31 @@ void BiboumiComponent::ask_subscription(const std::string& from, const std::stri presence["type"] = "subscribe"; this->send_stanza(presence); } + +void BiboumiComponent::send_presence_to_contact(const std::string& from, const std::string& to, + const std::string& type, const std::string& id) +{ + Stanza presence("presence"); + presence["from"] = from; + presence["to"] = to; + if (!type.empty()) + presence["type"] = type; + if (!id.empty()) + presence["id"] = id; + this->send_stanza(presence); +} + +void BiboumiComponent::after_handshake() +{ + XmppComponent::after_handshake(); + +#ifdef USE_DATABASE + const auto contacts = Database::get_contact_list(this->get_served_hostname()); + + for (const Database::RosterItem& roster_item: contacts) + { + const auto remote_jid = roster_item.col(); + this->send_presence_to_contact(this->get_served_hostname(), remote_jid, "probe"); + } +#endif +} diff --git a/src/xmpp/biboumi_component.hpp b/src/xmpp/biboumi_component.hpp index 87311f9..2d67f8b 100644 --- a/src/xmpp/biboumi_component.hpp +++ b/src/xmpp/biboumi_component.hpp @@ -36,6 +36,8 @@ public: BiboumiComponent& operator=(const BiboumiComponent&) = delete; BiboumiComponent& operator=(BiboumiComponent&&) = delete; + void after_handshake() override final; + /** * Returns the bridge for the given user. If it does not exist, return * nullptr. @@ -87,6 +89,7 @@ public: void send_invitation(const std::string& room_target, const std::string& jid_to, const std::string& author_nick); void accept_subscription(const std::string& from, const std::string& to); void ask_subscription(const std::string& from, const std::string& to); + void send_presence_to_contact(const std::string& from, const std::string& to, const std::string& type, const std::string& id=""); /** * Handle the various stanza types */ -- cgit v1.2.3 From 71f125db1a11f4b728beee1d1aa2ef7d37f38000 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Fri, 23 Jun 2017 14:45:44 +0200 Subject: Send responses when we receive an unsubscribed presence --- src/xmpp/biboumi_component.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/xmpp/biboumi_component.cpp b/src/xmpp/biboumi_component.cpp index f3381aa..263b7bd 100644 --- a/src/xmpp/biboumi_component.cpp +++ b/src/xmpp/biboumi_component.cpp @@ -180,6 +180,8 @@ void BiboumiComponent::handle_presence(const Stanza& stanza) } else if (type == "unsubscribe") { + this->send_presence_to_contact(to_str, from.bare(), "unavailable", id); + this->send_presence_to_contact(to_str, from.bare(), "unsubscribe"); #ifdef USE_DATABASE const bool res = Database::has_roster_item(to_str, from.bare()); if (res) -- cgit v1.2.3 From 368bb82818d4b68e4984698ea4454091ecb049a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Fri, 23 Jun 2017 15:05:07 +0200 Subject: Send an additional unsubscribed presence when receiving an unsubscribe one --- src/xmpp/biboumi_component.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/xmpp/biboumi_component.cpp b/src/xmpp/biboumi_component.cpp index 263b7bd..91e92aa 100644 --- a/src/xmpp/biboumi_component.cpp +++ b/src/xmpp/biboumi_component.cpp @@ -181,6 +181,7 @@ void BiboumiComponent::handle_presence(const Stanza& stanza) else if (type == "unsubscribe") { this->send_presence_to_contact(to_str, from.bare(), "unavailable", id); + this->send_presence_to_contact(to_str, from.bare(), "unsubscribed"); this->send_presence_to_contact(to_str, from.bare(), "unsubscribe"); #ifdef USE_DATABASE const bool res = Database::has_roster_item(to_str, from.bare()); -- cgit v1.2.3 From f9a6f973966430b108642ac57d54db5fd0d5535e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Tue, 4 Jul 2017 20:42:40 +0200 Subject: Implement the roster presences from IRC servers --- src/bridge/bridge.cpp | 10 ++++++++++ src/bridge/bridge.hpp | 4 +++- src/irc/irc_client.cpp | 2 ++ src/xmpp/biboumi_component.cpp | 18 ++++++++++++++---- src/xmpp/biboumi_component.hpp | 3 +++ 5 files changed, 32 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/bridge/bridge.cpp b/src/bridge/bridge.cpp index 27726e4..33006c3 100644 --- a/src/bridge/bridge.cpp +++ b/src/bridge/bridge.cpp @@ -1081,6 +1081,16 @@ void Bridge::send_xmpp_invitation(const Iid& iid, const std::string& author) this->xmpp.send_invitation(std::to_string(iid), this->user_jid + "/" + resource, author); } +void Bridge::on_irc_client_connected(const std::string& hostname) +{ + this->xmpp.on_irc_client_connected(hostname, this->user_jid); +} + +void Bridge::on_irc_client_disconnected(const std::string& hostname) +{ + this->xmpp.on_irc_client_disconnected(hostname, this->user_jid); +} + void Bridge::set_preferred_from_jid(const std::string& nick, const std::string& full_jid) { auto it = this->preferred_user_from.find(nick); diff --git a/src/bridge/bridge.hpp b/src/bridge/bridge.hpp index 496b439..c10631b 100644 --- a/src/bridge/bridge.hpp +++ b/src/bridge/bridge.hpp @@ -201,6 +201,8 @@ public: void send_xmpp_ping_request(const std::string& nick, const std::string& hostname, const std::string& id); void send_xmpp_invitation(const Iid& iid, const std::string& author); + void on_irc_client_connected(const std::string& hostname); + void on_irc_client_disconnected(const std::string& hostname); /** * Misc @@ -301,8 +303,8 @@ private: using ChannelKey = std::tuple; public: std::map> resources_in_chan; -private: std::map> resources_in_server; +private: /** * Manage which resource is in which channel */ diff --git a/src/irc/irc_client.cpp b/src/irc/irc_client.cpp index 67221c5..46dbdbe 100644 --- a/src/irc/irc_client.cpp +++ b/src/irc/irc_client.cpp @@ -297,6 +297,7 @@ void IrcClient::on_connected() #endif this->send_gateway_message("Connected to IRC server"s + (this->use_tls ? " (encrypted)": "") + "."); this->send_pending_data(); + this->bridge.on_irc_client_connected(this->get_hostname()); } void IrcClient::on_connection_close(const std::string& error_msg) @@ -309,6 +310,7 @@ void IrcClient::on_connection_close(const std::string& error_msg) const IrcMessage error{"ERROR", {message}}; this->on_error(error); log_warning(message); + this->bridge.on_irc_client_disconnected(this->get_hostname()); } IrcChannel* IrcClient::get_channel(const std::string& n) diff --git a/src/xmpp/biboumi_component.cpp b/src/xmpp/biboumi_component.cpp index 91e92aa..71a5f3d 100644 --- a/src/xmpp/biboumi_component.cpp +++ b/src/xmpp/biboumi_component.cpp @@ -84,8 +84,7 @@ void BiboumiComponent::shutdown() for (auto& pair: this->bridges) pair.second->shutdown("Gateway shutdown"); #ifdef USE_DATABASE - const auto full_roster = Database::get_full_roster(); - for (const Database::RosterItem& roster_item: full_roster) + for (const Database::RosterItem& roster_item: Database::get_full_roster()) { this->send_presence_to_contact(roster_item.col(), roster_item.col(), @@ -170,7 +169,7 @@ void BiboumiComponent::handle_presence(const Stanza& stanza) if (type == "subscribe") { // Auto-accept any subscription request for an IRC server this->send_presence_to_contact(to_str, from.bare(), "subscribed", id); - if (iid.type == Iid::Type::None) + if (iid.type == Iid::Type::None || bridge->find_irc_client(iid.get_server())) this->send_presence_to_contact(to_str, from.bare(), ""); this->send_presence_to_contact(to_str, from.bare(), "subscribe"); #ifdef USE_DATABASE @@ -192,7 +191,8 @@ void BiboumiComponent::handle_presence(const Stanza& stanza) else if (type.empty()) { // We just receive a presence from someone (as the result of a probe, // or a directed presence, or a normal presence change) - this->send_presence_to_contact(to_str, from.bare(), ""); + if (iid.type == Iid::Type::None) + this->send_presence_to_contact(to_str, from.bare(), ""); } } else @@ -1023,6 +1023,16 @@ void BiboumiComponent::send_presence_to_contact(const std::string& from, const s this->send_stanza(presence); } +void BiboumiComponent::on_irc_client_connected(const std::string& irc_hostname, const std::string& jid) +{ + this->send_presence_to_contact(irc_hostname + "@" + this->served_hostname, jid, ""); +} + +void BiboumiComponent::on_irc_client_disconnected(const std::string& irc_hostname, const std::string& jid) +{ + this->send_presence_to_contact(irc_hostname + "@" + this->served_hostname, jid, "unavailable"); +} + void BiboumiComponent::after_handshake() { XmppComponent::after_handshake(); diff --git a/src/xmpp/biboumi_component.hpp b/src/xmpp/biboumi_component.hpp index 2d67f8b..e5547f9 100644 --- a/src/xmpp/biboumi_component.hpp +++ b/src/xmpp/biboumi_component.hpp @@ -90,6 +90,9 @@ public: void accept_subscription(const std::string& from, const std::string& to); void ask_subscription(const std::string& from, const std::string& to); void send_presence_to_contact(const std::string& from, const std::string& to, const std::string& type, const std::string& id=""); + void on_irc_client_connected(const std::string& irc_hostname, const std::string& jid); + void on_irc_client_disconnected(const std::string& irc_hostname, const std::string& jid); + /** * Handle the various stanza types */ -- cgit v1.2.3 From dd343609d561c95a3231ab9db26d44dec6395a6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Wed, 5 Jul 2017 20:18:26 +0200 Subject: Only send the IRC server presence if the user has this JID in their roster --- src/xmpp/biboumi_component.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/xmpp/biboumi_component.cpp b/src/xmpp/biboumi_component.cpp index 71a5f3d..b951629 100644 --- a/src/xmpp/biboumi_component.cpp +++ b/src/xmpp/biboumi_component.cpp @@ -1025,12 +1025,20 @@ void BiboumiComponent::send_presence_to_contact(const std::string& from, const s void BiboumiComponent::on_irc_client_connected(const std::string& irc_hostname, const std::string& jid) { - this->send_presence_to_contact(irc_hostname + "@" + this->served_hostname, jid, ""); +#ifdef USE_DATABASE + const auto local_jid = irc_hostname + "@" + this->served_hostname; + if (Database::has_roster_item(local_jid, jid)) + this->send_presence_to_contact(local_jid, jid, ""); +#endif } void BiboumiComponent::on_irc_client_disconnected(const std::string& irc_hostname, const std::string& jid) { - this->send_presence_to_contact(irc_hostname + "@" + this->served_hostname, jid, "unavailable"); +#ifdef USE_DATABASE + const auto local_jid = irc_hostname + "@" + this->served_hostname; + if (Database::has_roster_item(local_jid, jid)) + this->send_presence_to_contact(irc_hostname + "@" + this->served_hostname, jid, "unavailable"); +#endif } void BiboumiComponent::after_handshake() -- cgit v1.2.3 From 50a2bd736ef76f7ebb7067372d5f89b59a337bec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Tue, 11 Jul 2017 19:52:09 +0200 Subject: Answer to presences of type='probe' --- src/xmpp/biboumi_component.cpp | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src') diff --git a/src/xmpp/biboumi_component.cpp b/src/xmpp/biboumi_component.cpp index b951629..ab66519 100644 --- a/src/xmpp/biboumi_component.cpp +++ b/src/xmpp/biboumi_component.cpp @@ -188,6 +188,12 @@ void BiboumiComponent::handle_presence(const Stanza& stanza) Database::delete_roster_item(to_str, from.bare()); #endif } + else if (type == "probe") + { + if ((iid.type == Iid::Type::Server && bridge->find_irc_client(iid.get_server())) || + iid.type == Iid::Type::None) + this->send_presence_to_contact(to_str, from.bare(), ""); + } else if (type.empty()) { // We just receive a presence from someone (as the result of a probe, // or a directed presence, or a normal presence change) -- cgit v1.2.3 From 729ea131c9857ecb2e9579359e174483c73194d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Fri, 14 Jul 2017 15:15:53 +0200 Subject: =?UTF-8?q?Send=20an=20unsubscribed=20presence=20on=20a=20probe=20?= =?UTF-8?q?if=20we=20don=E2=80=99t=20have=20a=20roster=20entry?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/xmpp/biboumi_component.cpp | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/xmpp/biboumi_component.cpp b/src/xmpp/biboumi_component.cpp index ab66519..d1c75d0 100644 --- a/src/xmpp/biboumi_component.cpp +++ b/src/xmpp/biboumi_component.cpp @@ -190,9 +190,18 @@ void BiboumiComponent::handle_presence(const Stanza& stanza) } else if (type == "probe") { - if ((iid.type == Iid::Type::Server && bridge->find_irc_client(iid.get_server())) || - iid.type == Iid::Type::None) - this->send_presence_to_contact(to_str, from.bare(), ""); + if ((iid.type == Iid::Type::Server && bridge->find_irc_client(iid.get_server())) + || iid.type == Iid::Type::None) + { +#ifdef USE_DATABASE + if (Database::has_roster_item(to_str, from.bare())) +#endif + this->send_presence_to_contact(to_str, from.bare(), ""); +#ifdef USE_DATABASE + else // rfc 6121 4.3.2.1 + this->send_presence_to_contact(to_str, from.bare(), "unsubscribed"); +#endif + } } else if (type.empty()) { // We just receive a presence from someone (as the result of a probe, @@ -1057,6 +1066,12 @@ void BiboumiComponent::after_handshake() for (const Database::RosterItem& roster_item: contacts) { const auto remote_jid = roster_item.col(); + // In response, we will receive a presence indicating the + // contact is online, to which we will respond with our own + // presence. + // If the contact removed us from their roster while we were + // offline, we will receive an unsubscribed presence, letting us + // stay in sync. this->send_presence_to_contact(this->get_served_hostname(), remote_jid, "probe"); } #endif -- cgit v1.2.3 From f7cbe8531dd6bd2f91718ac14a564e21d6a0ef11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Sun, 16 Jul 2017 20:20:38 +0200 Subject: Correctly remove the last resource from the channel, in persistent mode fix #3277 --- src/bridge/bridge.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/bridge/bridge.cpp b/src/bridge/bridge.cpp index 33006c3..e0cb36d 100644 --- a/src/bridge/bridge.cpp +++ b/src/bridge/bridge.cpp @@ -457,6 +457,8 @@ void Bridge::leave_irc_channel(Iid&& iid, const std::string& status_message, con { this->send_muc_leave(iid, channel->get_self()->nick, "", true, true, resource); } + if (persistent) + this->remove_resource_from_chan(key, resource); // Since there are no resources left in that channel, we don't // want to receive private messages using this room's JID this->remove_all_preferred_from_jid_of_room(iid.get_local()); -- cgit v1.2.3 From ffb402f0adb9f808c7b8bc9616e71f7b3f8931ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Thu, 20 Jul 2017 21:22:58 +0200 Subject: Drop support for botan < 2.0 fix #3274 --- src/network/credentials_manager.cpp | 23 ----------------------- src/network/credentials_manager.hpp | 5 ----- src/network/tcp_socket_handler.cpp | 9 --------- src/network/tcp_socket_handler.hpp | 20 +++++--------------- src/utils/sha1.cpp | 6 ------ 5 files changed, 5 insertions(+), 58 deletions(-) (limited to 'src') diff --git a/src/network/credentials_manager.cpp b/src/network/credentials_manager.cpp index f93a366..7f07cef 100644 --- a/src/network/credentials_manager.cpp +++ b/src/network/credentials_manager.cpp @@ -54,29 +54,6 @@ void check_tls_certificate(const std::vector& certs, std::rethrow_exception(exc); } -#if BOTAN_VERSION_CODE < BOTAN_VERSION_CODE_FOR(1,11,34) -void BasicCredentialsManager::verify_certificate_chain(const std::string& type, - const std::string& purported_hostname, - const std::vector& certs) -{ - log_debug("Checking remote certificate (", type, ") for hostname ", purported_hostname); - try - { - Botan::Credentials_Manager::verify_certificate_chain(type, purported_hostname, certs); - log_debug("Certificate is valid"); - } - catch (const std::exception& tls_exception) - { - log_warning("TLS certificate check failed: ", tls_exception.what()); - std::exception_ptr exception_ptr{}; - if (this->socket_handler->abort_on_invalid_cert()) - exception_ptr = std::current_exception(); - - check_tls_certificate(certs, purported_hostname, this->trusted_fingerprint, exception_ptr); - } -} -#endif - bool BasicCredentialsManager::try_to_open_one_ca_bundle(const std::vector& paths) { for (const auto& path: paths) diff --git a/src/network/credentials_manager.hpp b/src/network/credentials_manager.hpp index e7c247d..aa4732a 100644 --- a/src/network/credentials_manager.hpp +++ b/src/network/credentials_manager.hpp @@ -31,11 +31,6 @@ public: BasicCredentialsManager& operator=(const BasicCredentialsManager&) = delete; BasicCredentialsManager& operator=(BasicCredentialsManager&&) = delete; -#if BOTAN_VERSION_CODE < BOTAN_VERSION_CODE_FOR(1,11,34) - void verify_certificate_chain(const std::string& type, - const std::string& purported_hostname, - const std::vector&) override final; -#endif std::vector trusted_certificate_authorities(const std::string& type, const std::string& context) override final; void set_trusted_fingerprint(const std::string& fingerprint); diff --git a/src/network/tcp_socket_handler.cpp b/src/network/tcp_socket_handler.cpp index 1049375..6239162 100644 --- a/src/network/tcp_socket_handler.cpp +++ b/src/network/tcp_socket_handler.cpp @@ -237,14 +237,7 @@ void TCPSocketHandler::start_tls(const std::string& address, const std::string& this->policy.load(policy_directory + "policy.txt"); this->policy.load(policy_directory + address + ".policy.txt"); this->tls = std::make_unique( -# if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,11,32) *this, -# else - [this](const Botan::byte* data, size_t size) { this->tls_emit_data(data, size); }, - [this](const Botan::byte* data, size_t size) { this->tls_record_received(0, data, size); }, - [this](Botan::TLS::Alert alert, const Botan::byte*, size_t) { this->tls_alert(alert); }, - [this](const Botan::TLS::Session& session) { return this->tls_session_established(session); }, -# endif get_session_manager(), this->credential_manager, this->policy, get_rng(), server_info, Botan::TLS::Protocol_Version::latest_tls_version()); } @@ -327,7 +320,6 @@ bool TCPSocketHandler::tls_session_established(const Botan::TLS::Session& sessio return true; } -#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,11,34) void TCPSocketHandler::tls_verify_cert_chain(const std::vector& cert_chain, const std::vector>& ocsp_responses, const std::vector& trusted_roots, @@ -350,7 +342,6 @@ void TCPSocketHandler::tls_verify_cert_chain(const std::vectorcredential_manager.get_trusted_fingerprint(), exception_ptr); } } -#endif void TCPSocketHandler::on_tls_activated() { diff --git a/src/network/tcp_socket_handler.hpp b/src/network/tcp_socket_handler.hpp index f68698e..5cef739 100644 --- a/src/network/tcp_socket_handler.hpp +++ b/src/network/tcp_socket_handler.hpp @@ -25,22 +25,14 @@ # include # include -# if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,11,32) -# define BOTAN_TLS_CALLBACKS_OVERRIDE override final -# else -# define BOTAN_TLS_CALLBACKS_OVERRIDE -# endif #endif - /** * Does all the read/write, buffering etc. With optional tls. * But doesn’t do any connect() or accept() or anything else. */ class TCPSocketHandler: public SocketHandler #ifdef BOTAN_FOUND -# if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,11,32) ,public Botan::TLS::Callbacks -# endif #endif { protected: @@ -146,31 +138,29 @@ private: * Called by the tls object that some data has been decrypt. We call * parse_in_buffer() to handle that unencrypted data. */ - void tls_record_received(uint64_t rec_no, const Botan::byte* data, size_t size) BOTAN_TLS_CALLBACKS_OVERRIDE; + void tls_record_received(uint64_t rec_no, const Botan::byte* data, size_t size) override final; /** * Called by the tls object to indicate that some data has been encrypted * and is now ready to be sent on the socket as is. */ - void tls_emit_data(const Botan::byte* data, size_t size) BOTAN_TLS_CALLBACKS_OVERRIDE; + void tls_emit_data(const Botan::byte* data, size_t size) override final; /** * Called by the tls object to indicate that a TLS alert has been * received. We don’t use it, we just log some message, at the moment. */ - void tls_alert(Botan::TLS::Alert alert) BOTAN_TLS_CALLBACKS_OVERRIDE; + void tls_alert(Botan::TLS::Alert alert) override final; /** * Called by the tls object at the end of the TLS handshake. We don't do * anything here appart from logging the TLS session information. */ - bool tls_session_established(const Botan::TLS::Session& session) BOTAN_TLS_CALLBACKS_OVERRIDE; + bool tls_session_established(const Botan::TLS::Session& session) override final; -#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,11,34) void tls_verify_cert_chain(const std::vector& cert_chain, const std::vector>& ocsp_responses, const std::vector& trusted_roots, Botan::Usage_Type usage, const std::string& hostname, - const Botan::TLS::Policy& policy) BOTAN_TLS_CALLBACKS_OVERRIDE; -#endif + const Botan::TLS::Policy& policy) override final; /** * Called whenever the tls session goes from inactive to active. This * means that the handshake has just been successfully done, and we can diff --git a/src/utils/sha1.cpp b/src/utils/sha1.cpp index 2e6efc2..1a0d185 100644 --- a/src/utils/sha1.cpp +++ b/src/utils/sha1.cpp @@ -18,13 +18,7 @@ std::string sha1(const std::string& input) { #ifdef BOTAN_FOUND -# if BOTAN_VERSION_CODE < BOTAN_VERSION_CODE_FOR(1,11,34) - auto sha1 = Botan::HashFunction::create("SHA-1"); - if (!sha1) - throw Botan::Algorithm_Not_Found("SHA-1"); -# else auto sha1 = Botan::HashFunction::create_or_throw("SHA-1"); -# endif sha1->update(input); return Botan::hex_encode(sha1->final(), false); #endif -- cgit v1.2.3 From 24f2511d7ba105d65c9684dd5606a57c5af95445 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Thu, 20 Jul 2017 21:28:18 +0200 Subject: In fixed mode, fix the iid type of the component JID --- src/irc/iid.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/irc/iid.cpp b/src/irc/iid.cpp index a63a1c3..131c18c 100644 --- a/src/irc/iid.cpp +++ b/src/irc/iid.cpp @@ -35,7 +35,8 @@ Iid::Iid(const std::string& iid, const Bridge *bridge) void Iid::set_type(const std::set& chantypes) { - if (this->local.empty() && this->server.empty()) + if (this->local.empty() && ( + !Config::get("fixed_irc_server", "").empty() || this->server.empty())) this->type = Iid::Type::None; if (this->local.empty()) return; -- cgit v1.2.3 From 407f95a108c275db5e9b07398f553ab573cd46bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Thu, 20 Jul 2017 21:29:33 +0200 Subject: Do not reply with an error when receiving a presence for a user JID fix #3224 --- src/xmpp/biboumi_component.cpp | 7 ++----- src/xmpp/xmpp_component.cpp | 30 ------------------------------ src/xmpp/xmpp_component.hpp | 6 ------ 3 files changed, 2 insertions(+), 41 deletions(-) (limited to 'src') diff --git a/src/xmpp/biboumi_component.cpp b/src/xmpp/biboumi_component.cpp index d1c75d0..13fabd7 100644 --- a/src/xmpp/biboumi_component.cpp +++ b/src/xmpp/biboumi_component.cpp @@ -210,11 +210,8 @@ void BiboumiComponent::handle_presence(const Stanza& stanza) this->send_presence_to_contact(to_str, from.bare(), ""); } } - else - { - // A user wants to join an invalid IRC channel, return a presence error to him/her - if (type.empty()) - this->send_invalid_room_error(to.local, to.resource, from_str); + else if (iid.type == Iid::Type::User) + { // Do nothing yet } } catch (const IRCNotConnected& ex) diff --git a/src/xmpp/xmpp_component.cpp b/src/xmpp/xmpp_component.cpp index 9c3ba90..42a5392 100644 --- a/src/xmpp/xmpp_component.cpp +++ b/src/xmpp/xmpp_component.cpp @@ -261,7 +261,6 @@ void XmppComponent::handle_error(const Stanza& stanza) if (!this->ever_auth) sd_notifyf(0, "STATUS=Failed to authenticate to the XMPP server: %s", error_message.data()); #endif - } void* XmppComponent::get_receive_buffer(const size_t size) const @@ -338,35 +337,6 @@ void XmppComponent::send_user_join(const std::string& from, this->send_stanza(presence); } -void XmppComponent::send_invalid_room_error(const std::string& muc_name, - const std::string& nick, - const std::string& to) -{ - Stanza presence("presence"); - { - if (!muc_name.empty ()) - presence["from"] = muc_name + "@" + this->served_hostname + "/" + nick; - else - presence["from"] = this->served_hostname; - presence["to"] = to; - presence["type"] = "error"; - XmlSubNode x(presence, "x"); - x["xmlns"] = MUC_NS; - XmlSubNode error(presence, "error"); - error["by"] = muc_name + "@" + this->served_hostname; - error["type"] = "cancel"; - XmlSubNode item_not_found(error, "item-not-found"); - item_not_found["xmlns"] = STANZA_NS; - XmlSubNode text(error, "text"); - text["xmlns"] = STANZA_NS; - text["xml:lang"] = "en"; - text.set_inner(muc_name + - " is not a valid IRC channel name. A correct room jid is of the form: #%@" + - this->served_hostname); - } - this->send_stanza(presence); -} - void XmppComponent::send_topic(const std::string& from, Xmpp::body&& topic, const std::string& to, const std::string& who) { Stanza message("message"); diff --git a/src/xmpp/xmpp_component.hpp b/src/xmpp/xmpp_component.hpp index f4a7655..22d5c48 100644 --- a/src/xmpp/xmpp_component.hpp +++ b/src/xmpp/xmpp_component.hpp @@ -123,12 +123,6 @@ public: const std::string& role, const std::string& to, const bool self); - /** - * Send an error to indicate that the user tried to join an invalid room - */ - void send_invalid_room_error(const std::string& muc_jid, - const std::string& nick, - const std::string& to); /** * Send the MUC topic to the user */ -- cgit v1.2.3 From f125de4833d65a83d1f550f4bfbff4d5e4c333b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Thu, 20 Jul 2017 23:09:37 +0200 Subject: Add the possibility to invite any external JID to a room fix #3285 --- src/xmpp/biboumi_component.cpp | 21 ++++++++++++++++----- src/xmpp/biboumi_component.hpp | 3 +++ 2 files changed, 19 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/xmpp/biboumi_component.cpp b/src/xmpp/biboumi_component.cpp index 13fabd7..0e1d270 100644 --- a/src/xmpp/biboumi_component.cpp +++ b/src/xmpp/biboumi_component.cpp @@ -310,7 +310,11 @@ void BiboumiComponent::handle_message(const Stanza& stanza) const auto invite_to = invite->get_tag("to"); if (!invite_to.empty()) { - bridge->send_irc_invitation(iid, invite_to); + Jid invited_jid{invite_to}; + if (invited_jid.domain == this->get_served_hostname() || invited_jid.local.empty()) + bridge->send_irc_invitation(iid, invite_to); + else + this->send_invitation_from_fulljid(std::to_string(iid), invite_to, from_str); } } @@ -986,6 +990,16 @@ void BiboumiComponent::send_iq_room_list_result(const std::string& id, const std void BiboumiComponent::send_invitation(const std::string& room_target, const std::string& jid_to, const std::string& author_nick) +{ + if (author_nick.empty()) + this->send_invitation_from_fulljid(room_target, jid_to, room_target + "@" + this->served_hostname); + else + this->send_invitation_from_fulljid(room_target, jid_to, room_target + "@" + this->served_hostname + "/" + author_nick); +} + +void BiboumiComponent::send_invitation_from_fulljid(const std::string& room_target, + const std::string& jid_to, + const std::string& from) { Stanza message("message"); { @@ -994,10 +1008,7 @@ void BiboumiComponent::send_invitation(const std::string& room_target, XmlSubNode x(message, "x"); x["xmlns"] = MUC_USER_NS; XmlSubNode invite(x, "invite"); - if (author_nick.empty()) - invite["from"] = room_target + "@" + this->served_hostname; - else - invite["from"] = room_target + "@" + this->served_hostname + "/" + author_nick; + invite["from"] = from; } this->send_stanza(message); } diff --git a/src/xmpp/biboumi_component.hpp b/src/xmpp/biboumi_component.hpp index e5547f9..caf990e 100644 --- a/src/xmpp/biboumi_component.hpp +++ b/src/xmpp/biboumi_component.hpp @@ -87,6 +87,9 @@ public: const ChannelList& channel_list, std::vector::const_iterator begin, std::vector::const_iterator end, const ResultSetInfo& rs_info); void send_invitation(const std::string& room_target, const std::string& jid_to, const std::string& author_nick); +private: + void send_invitation_from_fulljid(const std::string& room_target, const std::string& jid_to, const std::string& from); +public: void accept_subscription(const std::string& from, const std::string& to); void ask_subscription(const std::string& from, const std::string& to); void send_presence_to_contact(const std::string& from, const std::string& to, const std::string& type, const std::string& id=""); -- cgit v1.2.3 From 308869aa73c7c03d7e9fad2a780bf132e03c8c5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Fri, 21 Jul 2017 17:27:03 +0200 Subject: Do not ignore empty values when receiving a data form Otherwise, these fields cannot be emptied by the user fix #3281 --- src/xmpp/biboumi_adhoc_commands.cpp | 30 ++++++++++-------------------- 1 file changed, 10 insertions(+), 20 deletions(-) (limited to 'src') diff --git a/src/xmpp/biboumi_adhoc_commands.cpp b/src/xmpp/biboumi_adhoc_commands.cpp index 27b079b..60af506 100644 --- a/src/xmpp/biboumi_adhoc_commands.cpp +++ b/src/xmpp/biboumi_adhoc_commands.cpp @@ -399,24 +399,20 @@ void ConfigureIrcServerStep2(XmppComponent&, AdhocSession& session, XmlNode& com options.col() = val; } - else if (field->get_tag("var") == "fingerprint" && value && - !value->get_inner().empty()) + else if (field->get_tag("var") == "fingerprint" && value) { options.col() = value->get_inner(); } #endif // BOTAN_FOUND - else if (field->get_tag("var") == "pass" && - value && !value->get_inner().empty()) + else if (field->get_tag("var") == "pass" && value) options.col() = value->get_inner(); - else if (field->get_tag("var") == "after_connect_command" && - value && !value->get_inner().empty()) + else if (field->get_tag("var") == "after_connect_command") options.col() = value->get_inner(); - else if (field->get_tag("var") == "username" && - value && !value->get_inner().empty()) + else if (field->get_tag("var") == "username" && value) { auto username = value->get_inner(); // The username must not contain spaces @@ -424,16 +420,13 @@ void ConfigureIrcServerStep2(XmppComponent&, AdhocSession& session, XmlNode& com options.col() = username; } - else if (field->get_tag("var") == "realname" && - value && !value->get_inner().empty()) + else if (field->get_tag("var") == "realname" && value) options.col() = value->get_inner(); - else if (field->get_tag("var") == "encoding_out" && - value && !value->get_inner().empty()) + else if (field->get_tag("var") == "encoding_out" && value) options.col() = value->get_inner(); - else if (field->get_tag("var") == "encoding_in" && - value && !value->get_inner().empty()) + else if (field->get_tag("var") == "encoding_in" && value) options.col() = value->get_inner(); } @@ -572,16 +565,13 @@ bool handle_irc_channel_configuration_form(XmppComponent& xmpp_component, const { const XmlNode *value = field->get_child("value", "jabber:x:data"); - if (field->get_tag("var") == "encoding_out" && - value && !value->get_inner().empty()) + if (field->get_tag("var") == "encoding_out" && value) options.col() = value->get_inner(); - else if (field->get_tag("var") == "encoding_in" && - value && !value->get_inner().empty()) + else if (field->get_tag("var") == "encoding_in" && value) options.col() = value->get_inner(); - else if (field->get_tag("var") == "persistent" && - value) + else if (field->get_tag("var") == "persistent" && value) options.col() = to_bool(value->get_inner()); else if (field->get_tag("var") == "record_history" && value && !value->get_inner().empty()) -- cgit v1.2.3