summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorlouiz’ <louiz@louiz.org>2016-08-08 20:49:00 +0200
committerlouiz’ <louiz@louiz.org>2016-08-10 15:48:28 +0200
commit0d2dd71de5292895f69d5f08b000e03e928bdd34 (patch)
tree19e41b1df4cfc0da65368efe5c26daee623cc7b4 /src
parent183f53d0efac4183ae657776357caf8d619a4aa6 (diff)
downloadbiboumi-0d2dd71de5292895f69d5f08b000e03e928bdd34.tar.gz
biboumi-0d2dd71de5292895f69d5f08b000e03e928bdd34.tar.bz2
biboumi-0d2dd71de5292895f69d5f08b000e03e928bdd34.tar.xz
biboumi-0d2dd71de5292895f69d5f08b000e03e928bdd34.zip
Don’t use ! as the separator for nicknames, use % instead
It’s now easier to use. The distinction between a nick and a channel name is based on the first character (by default it's '#' and '&'). The user doesn’t have to worry about which separator to use anymore. fix #3066
Diffstat (limited to 'src')
-rw-r--r--src/bridge/bridge.cpp26
-rw-r--r--src/bridge/bridge.hpp3
-rw-r--r--src/irc/iid.cpp109
-rw-r--r--src/irc/iid.hpp58
-rw-r--r--src/irc/irc_client.cpp26
-rw-r--r--src/irc/irc_client.hpp3
-rw-r--r--src/xmpp/biboumi_adhoc_commands.cpp4
-rw-r--r--src/xmpp/biboumi_component.cpp61
8 files changed, 157 insertions, 133 deletions
diff --git a/src/bridge/bridge.cpp b/src/bridge/bridge.cpp
index 17d3ec6..ac61dbc 100644
--- a/src/bridge/bridge.cpp
+++ b/src/bridge/bridge.cpp
@@ -133,7 +133,7 @@ IrcClient* Bridge::get_irc_client(const std::string& hostname)
}
}
-IrcClient* Bridge::find_irc_client(const std::string& hostname)
+IrcClient* Bridge::find_irc_client(const std::string& hostname) const
{
try
{
@@ -470,7 +470,7 @@ void Bridge::send_irc_user_ping_request(const std::string& irc_hostname, const s
const std::string& iq_id, const std::string& to_jid,
const std::string& from_jid)
{
- Iid iid(nick + "!" + irc_hostname);
+ Iid iid(nick, irc_hostname, Iid::Type::User);
this->send_private_message(iid, "\01PING " + iq_id + "\01");
irc_responder_callback_t cb = [this, nick=utils::tolower(nick), iq_id, to_jid, irc_hostname, from_jid](const std::string& hostname, const IrcMessage& message) -> bool
@@ -541,7 +541,7 @@ void Bridge::send_irc_version_request(const std::string& irc_hostname, const std
const std::string& iq_id, const std::string& to_jid,
const std::string& from_jid)
{
- Iid iid(target + "!" + irc_hostname);
+ Iid iid(target, irc_hostname, Iid::Type::User);
this->send_private_message(iid, "\01VERSION\01");
// TODO, add a timer to remove that waiting iq if the server does not
// respond with a matching command before n seconds
@@ -590,7 +590,7 @@ void Bridge::send_message(const Iid& iid, const std::string& nick, const std::st
const auto it = this->preferred_user_from.find(iid.get_local());
if (it != this->preferred_user_from.end())
{
- const auto chan_name = Iid(Jid(it->second).local).get_local();
+ const auto chan_name = Iid(Jid(it->second).local, {}).get_local();
for (const auto& resource: this->resources_in_chan[ChannelKey{chan_name, iid.get_server()}])
this->xmpp.send_message(it->second, this->make_xmpp_body(body, encoding),
this->user_jid + "/" + resource, "chat", true);
@@ -653,7 +653,7 @@ void Bridge::send_xmpp_message(const std::string& from, const std::string& autho
else
body = msg;
- const auto encoding = in_encoding_for(*this, {from});
+ const auto encoding = in_encoding_for(*this, {from, this});
for (const auto& resource: this->resources_in_server[from])
{
this->xmpp.send_message(from, this->make_xmpp_body(body, encoding), this->user_jid + "/" + resource, "chat");
@@ -696,7 +696,7 @@ void Bridge::send_topic(const std::string& hostname, const std::string& chan_nam
{
std::string encoded_chan_name(chan_name);
xep0106::encode(encoded_chan_name);
- const auto encoding = in_encoding_for(*this, {encoded_chan_name + '%' + hostname});
+ const auto encoding = in_encoding_for(*this, {encoded_chan_name, hostname, Iid::Type::Channel});
this->xmpp.send_topic(encoded_chan_name + utils::empty_if_fixed_server(
"%" + hostname), this->make_xmpp_body(topic, encoding), this->user_jid + "/" + resource, who);
@@ -741,7 +741,7 @@ void Bridge::send_iq_version_request(const std::string& nick, const std::string&
{
const auto resources = this->resources_in_server[hostname];
if (resources.begin() != resources.end())
- this->xmpp.send_iq_version_request(utils::tolower(nick) + "!" + utils::empty_if_fixed_server(hostname), this->user_jid + "/" + *resources.begin());
+ this->xmpp.send_iq_version_request(utils::tolower(nick) + "%" + utils::empty_if_fixed_server(hostname), this->user_jid + "/" + *resources.begin());
}
void Bridge::send_xmpp_ping_request(const std::string& nick, const std::string& hostname,
@@ -753,7 +753,7 @@ void Bridge::send_xmpp_ping_request(const std::string& nick, const std::string&
// Forward to the first resource (arbitrary, based on the “order” of the std::set) only
const auto resources = this->resources_in_server[hostname];
if (resources.begin() != resources.end())
- this->xmpp.send_ping_request(utils::tolower(nick) + "!" + utils::empty_if_fixed_server(hostname), this->user_jid + "/" + *resources.begin(), utils::revstr(id));
+ this->xmpp.send_ping_request(utils::tolower(nick) + "%" + utils::empty_if_fixed_server(hostname), this->user_jid + "/" + *resources.begin(), utils::revstr(id));
}
void Bridge::set_preferred_from_jid(const std::string& nick, const std::string& full_jid)
@@ -776,7 +776,7 @@ void Bridge::remove_all_preferred_from_jid_of_room(const std::string& channel_na
{
for (auto it = this->preferred_user_from.begin(); it != this->preferred_user_from.end();)
{
- Iid iid(Jid(it->second).local);
+ Iid iid(Jid(it->second).local, {});
if (iid.get_local() == channel_name)
it = this->preferred_user_from.erase(it);
else
@@ -806,6 +806,14 @@ std::unordered_map<std::string, std::shared_ptr<IrcClient>>& Bridge::get_irc_cli
return this->irc_clients;
}
+std::set<char> Bridge::get_chantypes(const std::string& hostname) const
+{
+ IrcClient* irc = this->find_irc_client(hostname);
+ if (!irc)
+ return {'#', '&'};
+ return irc->get_chantypes();
+}
+
void Bridge::add_resource_to_chan(const Bridge::ChannelKey& channel, const std::string& resource)
{
auto it = this->resources_in_chan.find(channel);
diff --git a/src/bridge/bridge.hpp b/src/bridge/bridge.hpp
index 69b7bd5..d7b2a5c 100644
--- a/src/bridge/bridge.hpp
+++ b/src/bridge/bridge.hpp
@@ -201,6 +201,7 @@ public:
*/
void trigger_on_irc_message(const std::string& irc_hostname, const IrcMessage& message);
std::unordered_map<std::string, std::shared_ptr<IrcClient>>& get_irc_clients();
+ std::set<char> get_chantypes(const std::string& hostname) const;
private:
/**
@@ -217,7 +218,7 @@ private:
/**
* Idem, but returns nullptr if the server does not exist.
*/
- IrcClient* find_irc_client(const std::string& hostname);
+ IrcClient* find_irc_client(const std::string& hostname) const;
/**
* The bare JID of the user associated with this bridge. Messages from/to this
* JID are only managed by this bridge.
diff --git a/src/irc/iid.cpp b/src/irc/iid.cpp
index 0e2841e..c951a49 100644
--- a/src/irc/iid.cpp
+++ b/src/irc/iid.cpp
@@ -1,62 +1,70 @@
#include <utils/tolower.hpp>
#include <config/config.hpp>
-
+#include <bridge/bridge.hpp>
#include <irc/iid.hpp>
#include <utils/encoding.hpp>
-Iid::Iid(const std::string& iid):
- is_channel(false),
- is_user(false)
+Iid::Iid(const std::string local, const std::string server, Iid::Type type):
+ type(type),
+ local(local),
+ server(server)
{
- const std::string fixed_irc_server = Config::get("fixed_irc_server", "");
- if (fixed_irc_server.empty())
- this->init(iid);
- else
- this->init_with_fixed_server(iid, fixed_irc_server);
}
+Iid::Iid(const std::string& iid, const std::set<char>& chantypes)
+{
+ this->init(iid);
+ this->set_type(std::set<char>(chantypes));
+}
-void Iid::init(const std::string& iid)
+Iid::Iid(const std::string& iid, const std::initializer_list<char>& chantypes):
+ Iid(iid, std::set<char>(chantypes))
{
- const std::string::size_type sep = iid.find_first_of("%!");
- if (sep != std::string::npos)
- {
- if (iid[sep] == '%')
- this->is_channel = true;
- else
- this->is_user = true;
- this->set_local(iid.substr(0, sep));
- this->set_server(iid.substr(sep + 1));
- }
- else
- this->set_server(iid);
}
-void Iid::init_with_fixed_server(const std::string& iid, const std::string& hostname)
+Iid::Iid(const std::string& iid, const Bridge *bridge)
+{
+ this->init(iid);
+ const auto chantypes = bridge->get_chantypes(this->server);
+ this->set_type(chantypes);
+}
+
+void Iid::set_type(const std::set<char>& chantypes)
{
- this->set_server(hostname);
+ if (this->local.empty())
+ return;
- const std::string::size_type sep = iid.find("!");
+ if (chantypes.count(this->local[0]) == 1)
+ this->type = Iid::Type::Channel;
+ else
+ this->type = Iid::Type::User;
+}
- // Without any separator, we consider that it's a channel
- if (sep == std::string::npos)
+void Iid::init(const std::string& iid)
+{
+ const std::string fixed_irc_server = Config::get("fixed_irc_server", "");
+
+ if (fixed_irc_server.empty())
+ {
+ const std::string::size_type sep = iid.find('%');
+ if (sep != std::string::npos)
{
- this->is_channel = true;
- this->set_local(iid);
+ this->set_local(iid.substr(0, sep));
+ this->set_server(iid.substr(sep + 1));
+ this->type = Iid::Type::Channel;
}
- else // A separator can be present to differenciate a channel from a user,
- // but the part behind it (the hostname) is ignored
+ else
{
- this->set_local(iid.substr(0, sep));
- this->is_user = true;
+ this->set_server(iid);
+ this->type = Iid::Type::Server;
}
-}
-
-Iid::Iid():
- is_channel(false),
- is_user(false)
-{
+ }
+ else
+ {
+ this->set_server(fixed_irc_server);
+ this->set_local(iid);
+ }
}
void Iid::set_local(const std::string& loc)
@@ -88,27 +96,18 @@ const std::string& Iid::get_server() const
return this->server;
}
-std::string Iid::get_sep() const
-{
- if (this->is_channel)
- return "%";
- else if (this->is_user)
- return "!";
- return "";
-}
-
namespace std {
const std::string to_string(const Iid& iid)
{
if (Config::get("fixed_irc_server", "").empty())
- return iid.get_encoded_local() + iid.get_sep() + iid.get_server();
+ {
+ if (iid.type == Iid::Type::Server)
+ return iid.get_server();
+ else
+ return iid.get_encoded_local() + iid.separator + iid.get_server();
+ }
else
- {
- if (iid.get_sep() == "!")
- return iid.get_encoded_local() + iid.get_sep();
- else
- return iid.get_encoded_local();
- }
+ return iid.get_encoded_local();
}
}
diff --git a/src/irc/iid.hpp b/src/irc/iid.hpp
index 3b11470..7361c51 100644
--- a/src/irc/iid.hpp
+++ b/src/irc/iid.hpp
@@ -2,48 +2,64 @@
#include <string>
+#include <set>
+
+class Bridge;
/**
* A name representing an IRC channel on an IRC server, or an IRC user on an
* IRC server, or just an IRC server.
*
- * The separator for an user is '!', for a channel it's '%'. If no separator
- * is present, it's just an irc server.
+ * The separator is '%' between the local part (nickname or channel) and the
+ * server part. If no separator is present, it's just an irc server.
+ * If it is present, the first character of the local part determines if it’s
+ * a channel or a user: ff the local part is empty or if its first character
+ * is part of the chantypes characters, then it’s a channel, otherwise it’s
+ * a user.
+ *
* It’s possible to have an empty-string server, but it makes no sense in
- * the biboumi context.
+ * biboumi’s context.
+ *
+ * Assuming the chantypes are '#' and '&':
*
* #test%irc.example.org has :
* - local: "#test" (the # is part of the name, it could very well be absent, or & (for example) instead)
* - server: "irc.example.org"
- * - is_channel: true
- * - is_user: false
+ * - type: channel
*
* %irc.example.org:
* - local: ""
* - server: "irc.example.org"
- * - is_channel: true
- * - is_user: false
- * Note: this is the special empty-string channel, used internal in biboumi
+ * - type: channel
+ * Note: this is the special empty-string channel, used internally in biboumi
* but has no meaning on IRC.
*
- * foo!irc.example.org
+ * foo%irc.example.org
* - local: "foo"
* - server: "irc.example.org"
- * - is_channel: false
- * - is_user: true
- * Note: the empty-string user (!irc.example.org) has no special meaning in biboumi
+ * - type: user
+ * Note: the empty-string user (!irc.example.org) makes no sense for biboumi
*
* irc.example.org:
* - local: ""
* - server: "irc.example.org"
- * - is_channel: false
- * - is_user: false
+ * - type: server
*/
class Iid
{
public:
- Iid(const std::string& iid);
- Iid();
+ enum class Type
+ {
+ Channel,
+ User,
+ Server,
+ };
+ static constexpr auto separator = "%";
+ Iid(const std::string& iid, const std::set<char>& chantypes);
+ Iid(const std::string& iid, const std::initializer_list<char>& chantypes);
+ Iid(const std::string& iid, const Bridge* bridge);
+ Iid(const std::string local, const std::string server, Type type);
+ Iid() = default;
Iid(const Iid&) = default;
Iid(Iid&&) = delete;
@@ -52,21 +68,19 @@ public:
void set_local(const std::string& loc);
void set_server(const std::string& serv);
+
const std::string& get_local() const;
const std::string get_encoded_local() const;
const std::string& get_server() const;
- bool is_channel;
- bool is_user;
-
- std::string get_sep() const;
-
std::tuple<std::string, std::string> to_tuple() const;
+ Type type { Type::Server };
+
private:
void init(const std::string& iid);
- void init_with_fixed_server(const std::string& iid, const std::string& hostname);
+ void set_type(const std::set<char>& chantypes);
std::string local;
std::string server;
diff --git a/src/irc/irc_client.cpp b/src/irc/irc_client.cpp
index dd83307..d00b6ee 100644
--- a/src/irc/irc_client.cpp
+++ b/src/irc/irc_client.cpp
@@ -213,7 +213,7 @@ void IrcClient::on_connection_failed(const std::string& reason)
// Send an error message for all room that the user wanted to join
for (const auto& tuple: this->channels_to_join)
{
- Iid iid(std::get<0>(tuple) + "%" + this->hostname);
+ Iid iid(std::get<0>(tuple) + "%" + this->hostname, this->chantypes);
this->bridge.send_presence_error(iid, this->current_nick,
"cancel", "item-not-found",
"", reason);
@@ -551,7 +551,7 @@ void IrcClient::on_notice(const IrcMessage& message)
if (this->nicks_to_treat_as_private.find(nick) !=
this->nicks_to_treat_as_private.end())
{ // We previously sent a message to that nick)
- this->bridge.send_message({nick + "!" + this->hostname}, nick, body,
+ this->bridge.send_message({nick, this->hostname, Iid::Type::User}, nick, body,
false);
}
else
@@ -663,12 +663,12 @@ void IrcClient::on_channel_message(const IrcMessage& message)
bool muc = true;
if (!this->get_channel(iid.get_local())->joined)
{
- iid.is_user = true;
+ iid.type = Iid::Type::User;
iid.set_local(nick);
muc = false;
}
else
- iid.is_channel = true;
+ iid.type = Iid::Type::Channel;
if (!body.empty() && body[0] == '\01')
{
if (body.substr(1, 6) == "ACTION")
@@ -780,7 +780,7 @@ void IrcClient::on_nickname_conflict(const IrcMessage& message)
Iid iid;
iid.set_local(it->first);
iid.set_server(this->hostname);
- iid.is_channel = true;
+ iid.type = Iid::Type::Channel;
this->bridge.send_nickname_conflict_error(iid, nickname);
}
}
@@ -797,7 +797,7 @@ void IrcClient::on_nickname_change_too_fast(const IrcMessage& message)
Iid iid;
iid.set_local(it->first);
iid.set_server(this->hostname);
- iid.is_channel = true;
+ iid.type = Iid::Type::Channel;
this->bridge.send_presence_error(iid, nickname,
"cancel", "not-acceptable",
"", txt);
@@ -858,7 +858,7 @@ void IrcClient::on_part(const IrcMessage& message)
Iid iid;
iid.set_local(chan_name);
iid.set_server(this->hostname);
- iid.is_channel = true;
+ iid.type = Iid::Type::Channel;
bool self = channel->get_self()->nick == nick;
if (self)
{
@@ -880,7 +880,7 @@ void IrcClient::on_error(const IrcMessage& message)
Iid iid;
iid.set_local(it->first);
iid.set_server(this->hostname);
- iid.is_channel = true;
+ iid.type = Iid::Type::Channel;
IrcChannel* channel = it->second.get();
if (!channel->joined)
continue;
@@ -908,7 +908,7 @@ void IrcClient::on_quit(const IrcMessage& message)
Iid iid;
iid.set_local(chan_name);
iid.set_server(this->hostname);
- iid.is_channel = true;
+ iid.type = Iid::Type::Channel;
this->bridge.send_muc_leave(std::move(iid), std::move(nick), txt, false);
}
}
@@ -928,7 +928,7 @@ void IrcClient::on_nick(const IrcMessage& message)
Iid iid;
iid.set_local(chan_name);
iid.set_server(this->hostname);
- iid.is_channel = true;
+ iid.type = Iid::Type::Channel;
const bool self = channel->get_self()->nick == old_nick;
const char user_mode = user->get_most_significant_mode(this->sorted_user_modes);
this->bridge.send_nick_change(std::move(iid), old_nick, new_nick, user_mode, self);
@@ -956,7 +956,7 @@ void IrcClient::on_kick(const IrcMessage& message)
Iid iid;
iid.set_local(chan_name);
iid.set_server(this->hostname);
- iid.is_channel = true;
+ iid.type = Iid::Type::Channel;
this->bridge.kick_muc_user(std::move(iid), target, reason, author.nick);
}
@@ -976,7 +976,7 @@ void IrcClient::on_channel_mode(const IrcMessage& message)
Iid iid;
iid.set_local(message.arguments[0]);
iid.set_server(this->hostname);
- iid.is_channel = true;
+ iid.type = Iid::Type::Channel;
IrcUser user(message.prefix);
std::string mode_arguments;
for (size_t i = 1; i < message.arguments.size(); ++i)
@@ -1105,7 +1105,7 @@ void IrcClient::leave_dummy_channel(const std::string& exit_message)
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), std::string(this->current_nick), exit_message, true);
+ this->bridge.send_muc_leave(Iid("%"s + this->hostname, this->chantypes), std::string(this->current_nick), exit_message, true);
}
#ifdef BOTAN_FOUND
diff --git a/src/irc/irc_client.hpp b/src/irc/irc_client.hpp
index fc3918e..fa35e65 100644
--- a/src/irc/irc_client.hpp
+++ b/src/irc/irc_client.hpp
@@ -280,8 +280,9 @@ public:
const Resolver& get_resolver() const { return this->dns_resolver; }
- const std::vector<char>& get_sorted_user_modes() const { return sorted_user_modes; }
+ const std::vector<char>& get_sorted_user_modes() const { return this->sorted_user_modes; }
+ std::set<char> get_chantypes() const { return this->chantypes; }
private:
/**
* The hostname of the server we are connected to.
diff --git a/src/xmpp/biboumi_adhoc_commands.cpp b/src/xmpp/biboumi_adhoc_commands.cpp
index eec930d..b14081f 100644
--- a/src/xmpp/biboumi_adhoc_commands.cpp
+++ b/src/xmpp/biboumi_adhoc_commands.cpp
@@ -381,7 +381,7 @@ void ConfigureIrcChannelStep1(XmppComponent&, AdhocSession& session, XmlNode& co
{
const Jid owner(session.get_owner_jid());
const Jid target(session.get_target_jid());
- const Iid iid(target.local);
+ const Iid iid(target.local, {});
auto options = Database::get_irc_channel_options_with_server_default(owner.local + "@" + owner.domain,
iid.get_server(), iid.get_local());
@@ -434,7 +434,7 @@ void ConfigureIrcChannelStep2(XmppComponent&, AdhocSession& session, XmlNode& co
{
const Jid owner(session.get_owner_jid());
const Jid target(session.get_target_jid());
- const Iid iid(target.local);
+ const Iid iid(target.local, {});
auto options = Database::get_irc_channel_options(owner.local + "@" + owner.domain,
iid.get_server(), iid.get_local());
for (const XmlNode* field: x->get_children("field", "jabber:x:data"))
diff --git a/src/xmpp/biboumi_component.cpp b/src/xmpp/biboumi_component.cpp
index a6aac21..f621a6d 100644
--- a/src/xmpp/biboumi_component.cpp
+++ b/src/xmpp/biboumi_component.cpp
@@ -126,7 +126,7 @@ void BiboumiComponent::handle_presence(const Stanza& stanza)
Bridge* bridge = this->get_user_bridge(from_str);
Jid to(to_str);
Jid from(from_str);
- Iid iid(to.local);
+ Iid iid(to.local, bridge);
// An error stanza is sent whenever we exit this function without
// disabling this scopeguard. If error_type and error_name are not
@@ -142,7 +142,7 @@ void BiboumiComponent::handle_presence(const Stanza& stanza)
});
try {
- if (iid.is_channel && !iid.get_server().empty())
+ if (iid.type == Iid::Type::Channel && !iid.get_server().empty())
{ // presence toward a MUC that corresponds to an irc channel, or a
// dummy channel if iid.chan is empty
if (type.empty())
@@ -191,7 +191,7 @@ void BiboumiComponent::handle_message(const Stanza& stanza)
type = "normal";
Bridge* bridge = this->get_user_bridge(from);
Jid to(to_str);
- Iid iid(to.local);
+ Iid iid(to.local, bridge);
std::string error_type("cancel");
std::string error_name("internal-server-error");
@@ -202,7 +202,7 @@ void BiboumiComponent::handle_message(const Stanza& stanza)
const XmlNode* body = stanza.get_child("body", COMPONENT_NS);
try { // catch IRCNotConnected exceptions
- if (type == "groupchat" && iid.is_channel)
+ if (type == "groupchat" && iid.type == Iid::Type::Channel)
{
if (body && !body->get_inner().empty())
{
@@ -234,27 +234,27 @@ void BiboumiComponent::handle_message(const Stanza& stanza)
if (body && !body->get_inner().empty())
{
// a message for nick!server
- if (iid.is_user && !iid.get_local().empty())
+ if (iid.type == Iid::Type::User && !iid.get_local().empty())
{
bridge->send_private_message(iid, body->get_inner());
bridge->remove_preferred_from_jid(iid.get_local());
}
- else if (!iid.is_user && !to.resource.empty())
+ else if (iid.type != Iid::Type::User && !to.resource.empty())
{ // a message for chan%server@biboumi/Nick or
// server@biboumi/Nick
// Convert that into a message to nick!server
- Iid user_iid(utils::tolower(to.resource) + "!" + iid.get_server());
+ Iid user_iid(utils::tolower(to.resource), iid.get_server(), Iid::Type::User);
bridge->send_private_message(user_iid, body->get_inner());
bridge->set_preferred_from_jid(user_iid.get_local(), to_str);
}
- else if (!iid.is_user && !iid.is_channel)
+ else if (iid.type == Iid::Type::Server)
{ // Message sent to the server JID
// Convert the message body into a raw IRC message
bridge->send_raw_message(iid.get_server(), body->get_inner());
}
}
}
- else if (iid.is_user)
+ else if (iid.type == Iid::Type::User)
this->send_invalid_user_error(to.local, from);
} catch (const IRCNotConnected& ex)
{
@@ -321,7 +321,7 @@ void BiboumiComponent::handle_iq(const Stanza& stanza)
std::string affiliation = child->get_tag("affiliation");
if (!nick.empty())
{
- Iid iid(to.local);
+ Iid iid(to.local, {});
if (role == "none")
{ // This is a kick
std::string reason;
@@ -345,15 +345,17 @@ void BiboumiComponent::handle_iq(const Stanza& stanza)
// Depending on the 'to' jid in the request, we use one adhoc
// command handler or an other
- Iid iid(to.local);
+ Iid iid(to.local, {});
AdhocCommandsHandler* adhoc_handler;
- if (!to.local.empty() && !iid.is_user && !iid.is_channel)
- adhoc_handler = &this->irc_server_adhoc_commands_handler;
- else if (!to.local.empty() && iid.is_channel)
- adhoc_handler = &this->irc_channel_adhoc_commands_handler;
- else
+ if (to.local.empty())
adhoc_handler = &this->adhoc_commands_handler;
-
+ else
+ {
+ if (iid.type == Iid::Type::Server)
+ adhoc_handler = &this->irc_server_adhoc_commands_handler;
+ else
+ adhoc_handler = &this->irc_channel_adhoc_commands_handler;
+ }
// Execute the command, if any, and get a result XmlNode that we
// insert in our response
XmlNode inner_node = adhoc_handler->handle_request(from, to_str, *query);
@@ -384,13 +386,12 @@ void BiboumiComponent::handle_iq(const Stanza& stanza)
}
else if ((query = stanza.get_child("query", VERSION_NS)))
{
- Iid iid(to.local);
- if (iid.is_user ||
- (iid.is_channel && !to.resource.empty()))
+ Iid iid(to.local, bridge);
+ if (iid.type != Iid::Type::Server && !to.resource.empty())
{
// Get the IRC user version
std::string target;
- if (iid.is_user)
+ if (iid.type == Iid::Type::User)
target = iid.get_local();
else
target = to.resource;
@@ -406,7 +407,7 @@ void BiboumiComponent::handle_iq(const Stanza& stanza)
}
else if ((query = stanza.get_child("query", DISCO_ITEMS_NS)))
{
- Iid iid(to.local);
+ Iid iid(to.local, bridge);
const std::string node = query->get_tag("node");
if (node == ADHOC_NS)
{
@@ -419,7 +420,7 @@ void BiboumiComponent::handle_iq(const Stanza& stanza)
this->adhoc_commands_handler);
stanza_error.disable();
}
- else if (!iid.is_user && !iid.is_channel)
+ else if (iid.type == Iid::Type::Server)
{ // Get the server's adhoc commands
this->send_adhoc_commands_list(id, from, to_str,
(Config::get("admin", "") ==
@@ -427,7 +428,7 @@ void BiboumiComponent::handle_iq(const Stanza& stanza)
this->irc_server_adhoc_commands_handler);
stanza_error.disable();
}
- else if (!iid.is_user && iid.is_channel)
+ else if (iid.type == Iid::Type::Channel)
{ // Get the channel's adhoc commands
this->send_adhoc_commands_list(id, from, to_str,
(Config::get("admin", "") ==
@@ -436,7 +437,7 @@ void BiboumiComponent::handle_iq(const Stanza& stanza)
stanza_error.disable();
}
}
- else if (node.empty() && !iid.is_user && !iid.is_channel)
+ else if (node.empty() && iid.type == Iid::Type::Server)
{ // Disco on an IRC server: get the list of channels
bridge->send_irc_channel_list_request(iid, id, from);
stanza_error.disable();
@@ -444,13 +445,13 @@ void BiboumiComponent::handle_iq(const Stanza& stanza)
}
else if ((query = stanza.get_child("ping", PING_NS)))
{
- Iid iid(to.local);
- if (iid.is_user)
+ Iid iid(to.local, bridge);
+ if (iid.type == Iid::Type::User)
{ // Ping any user (no check on the nick done ourself)
bridge->send_irc_user_ping_request(iid.get_server(),
iid.get_local(), id, from, to_str);
}
- else if (iid.is_channel && !to.resource.empty())
+ else if (iid.type == Iid::Type::Channel && !to.resource.empty())
{ // Ping a room participant (we check if the nick is in the room)
bridge->send_irc_participant_ping_request(iid,
to.resource, id, from, to_str);
@@ -481,7 +482,7 @@ void BiboumiComponent::handle_iq(const Stanza& stanza)
version = version_node->get_inner();
if (os_node)
os = os_node->get_inner();
- const Iid iid(to.local);
+ const Iid iid(to.local, bridge);
bridge->send_xmpp_version_to_irc(iid, name, version, os);
}
else
@@ -604,7 +605,7 @@ void BiboumiComponent::send_ping_request(const std::string& from,
"the response mismatches the 'from' of the request");
}
else
- bridge->send_irc_ping_result(from, id);
+ bridge->send_irc_ping_result({from, bridge}, id);
};
this->waiting_iq[id] = result_cb;
}