Forward everything to all concerned XMPP resources
This commit is contained in:
+89
-17
@@ -156,9 +156,15 @@ IrcClient* Bridge::find_irc_client(const std::string& hostname)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Bridge::join_irc_channel(const Iid& iid, const std::string& nickname, const std::string& password)
|
bool Bridge::join_irc_channel(const Iid& iid, const std::string& nickname, const std::string& password,
|
||||||
|
const std::string& resource)
|
||||||
{
|
{
|
||||||
IrcClient* irc = this->make_irc_client(iid.get_server(), nickname);
|
const auto hostname = iid.get_server();
|
||||||
|
IrcClient* irc = this->make_irc_client(hostname, nickname);
|
||||||
|
this->add_resource_to_server(hostname, resource);
|
||||||
|
auto res_in_chan = this->is_resource_in_chan(ChannelKey{iid.get_local(), hostname}, resource);
|
||||||
|
if (!res_in_chan)
|
||||||
|
this->add_resource_to_chan(ChannelKey{iid.get_local(), hostname}, resource);
|
||||||
if (iid.get_local().empty())
|
if (iid.get_local().empty())
|
||||||
{ // Join the dummy channel
|
{ // Join the dummy channel
|
||||||
if (irc->is_welcomed())
|
if (irc->is_welcomed())
|
||||||
@@ -185,6 +191,8 @@ bool Bridge::join_irc_channel(const Iid& iid, const std::string& nickname, const
|
|||||||
{
|
{
|
||||||
irc->send_join_command(iid.get_local(), password);
|
irc->send_join_command(iid.get_local(), password);
|
||||||
return true;
|
return true;
|
||||||
|
} else if (!res_in_chan) {
|
||||||
|
this->generate_channel_join_for_resource(iid, resource);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -193,7 +201,8 @@ void Bridge::send_channel_message(const Iid& iid, const std::string& body)
|
|||||||
{
|
{
|
||||||
if (iid.get_server().empty())
|
if (iid.get_server().empty())
|
||||||
{
|
{
|
||||||
this->xmpp.send_stanza_error("message", this->user_jid, std::to_string(iid), "",
|
for (const auto& resource: this->resources_in_chan[ChannelKey{iid.get_local(), iid.get_server()}])
|
||||||
|
this->xmpp.send_stanza_error("message", this->user_jid + "/" + resource, std::to_string(iid), "",
|
||||||
"cancel", "remote-server-not-found",
|
"cancel", "remote-server-not-found",
|
||||||
std::to_string(iid) + " is not a valid channel name. "
|
std::to_string(iid) + " is not a valid channel name. "
|
||||||
"A correct room jid is of the form: #<chan>%<server>",
|
"A correct room jid is of the form: #<chan>%<server>",
|
||||||
@@ -226,8 +235,9 @@ void Bridge::send_channel_message(const Iid& iid, const std::string& body)
|
|||||||
irc->send_channel_message(iid.get_local(), action_prefix + line.substr(4) + "\01");
|
irc->send_channel_message(iid.get_local(), action_prefix + line.substr(4) + "\01");
|
||||||
else
|
else
|
||||||
irc->send_channel_message(iid.get_local(), line);
|
irc->send_channel_message(iid.get_local(), line);
|
||||||
|
for (const auto& resource: this->resources_in_chan[ChannelKey{iid.get_local(), iid.get_server()}])
|
||||||
this->xmpp.send_muc_message(std::to_string(iid), irc->get_own_nick(),
|
this->xmpp.send_muc_message(std::to_string(iid), irc->get_own_nick(),
|
||||||
this->make_xmpp_body(line), this->user_jid);
|
this->make_xmpp_body(line), this->user_jid + "/" + resource);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -554,8 +564,13 @@ void Bridge::send_message(const Iid& iid, const std::string& nick, const std::st
|
|||||||
{
|
{
|
||||||
const auto encoding = in_encoding_for(*this, iid);
|
const auto encoding = in_encoding_for(*this, iid);
|
||||||
if (muc)
|
if (muc)
|
||||||
|
{
|
||||||
|
for (const auto& resource: this->resources_in_chan[ChannelKey{iid.get_local(), iid.get_server()}])
|
||||||
|
{
|
||||||
this->xmpp.send_muc_message(std::to_string(iid), nick,
|
this->xmpp.send_muc_message(std::to_string(iid), nick,
|
||||||
this->make_xmpp_body(body, encoding), this->user_jid);
|
this->make_xmpp_body(body, encoding), this->user_jid + "/" + resource);
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
std::string target = std::to_string(iid);
|
std::string target = std::to_string(iid);
|
||||||
@@ -566,8 +581,11 @@ void Bridge::send_message(const Iid& iid, const std::string& nick, const std::st
|
|||||||
target = it->second;
|
target = it->second;
|
||||||
fulljid = true;
|
fulljid = true;
|
||||||
}
|
}
|
||||||
|
for (const auto& resource: this->resources_in_chan[ChannelKey{iid.get_local(), iid.get_server()}])
|
||||||
|
{
|
||||||
this->xmpp.send_message(target, this->make_xmpp_body(body, encoding),
|
this->xmpp.send_message(target, this->make_xmpp_body(body, encoding),
|
||||||
this->user_jid, "chat", fulljid);
|
this->user_jid + "/" + resource, "chat", fulljid);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -580,7 +598,8 @@ void Bridge::send_presence_error(const Iid& iid, const std::string& nick,
|
|||||||
|
|
||||||
void Bridge::send_muc_leave(Iid&& iid, std::string&& nick, const std::string& message, const bool self)
|
void Bridge::send_muc_leave(Iid&& iid, std::string&& nick, const std::string& message, const bool self)
|
||||||
{
|
{
|
||||||
this->xmpp.send_muc_leave(std::to_string(iid), std::move(nick), this->make_xmpp_body(message), this->user_jid, self);
|
for (const auto& resource: this->resources_in_chan[ChannelKey{iid.get_local(), iid.get_server()}])
|
||||||
|
this->xmpp.send_muc_leave(std::to_string(iid), std::move(nick), this->make_xmpp_body(message), this->user_jid + "/" + resource, self);
|
||||||
IrcClient* irc = this->find_irc_client(iid.get_server());
|
IrcClient* irc = this->find_irc_client(iid.get_server());
|
||||||
if (irc && irc->number_of_joined_channels() == 0)
|
if (irc && irc->number_of_joined_channels() == 0)
|
||||||
irc->send_quit_command("");
|
irc->send_quit_command("");
|
||||||
@@ -596,8 +615,9 @@ void Bridge::send_nick_change(Iid&& iid,
|
|||||||
std::string role;
|
std::string role;
|
||||||
std::tie(role, affiliation) = get_role_affiliation_from_irc_mode(user_mode);
|
std::tie(role, affiliation) = get_role_affiliation_from_irc_mode(user_mode);
|
||||||
|
|
||||||
|
for (const auto& resource: this->resources_in_chan[ChannelKey{iid.get_local(), iid.get_server()}])
|
||||||
this->xmpp.send_nick_change(std::to_string(iid),
|
this->xmpp.send_nick_change(std::to_string(iid),
|
||||||
old_nick, new_nick, affiliation, role, this->user_jid, self);
|
old_nick, new_nick, affiliation, role, this->user_jid + "/" + resource, self);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Bridge::send_xmpp_message(const std::string& from, const std::string& author, const std::string& msg)
|
void Bridge::send_xmpp_message(const std::string& from, const std::string& author, const std::string& msg)
|
||||||
@@ -614,7 +634,10 @@ void Bridge::send_xmpp_message(const std::string& from, const std::string& autho
|
|||||||
body = msg;
|
body = msg;
|
||||||
|
|
||||||
const auto encoding = in_encoding_for(*this, {from});
|
const auto encoding = in_encoding_for(*this, {from});
|
||||||
this->xmpp.send_message(from, this->make_xmpp_body(body, encoding), this->user_jid, "chat");
|
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");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Bridge::send_user_join(const std::string& hostname,
|
void Bridge::send_user_join(const std::string& hostname,
|
||||||
@@ -627,15 +650,21 @@ void Bridge::send_user_join(const std::string& hostname,
|
|||||||
std::string role;
|
std::string role;
|
||||||
std::tie(role, affiliation) = get_role_affiliation_from_irc_mode(user_mode);
|
std::tie(role, affiliation) = get_role_affiliation_from_irc_mode(user_mode);
|
||||||
|
|
||||||
|
for (const auto& resource: this->resources_in_chan[ChannelKey{chan_name, hostname}])
|
||||||
|
{
|
||||||
this->xmpp.send_user_join(chan_name + utils::empty_if_fixed_server("%" + hostname), user->nick, user->host,
|
this->xmpp.send_user_join(chan_name + utils::empty_if_fixed_server("%" + hostname), user->nick, user->host,
|
||||||
affiliation, role, this->user_jid, self);
|
affiliation, role, this->user_jid + "/" + resource, self);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Bridge::send_topic(const std::string& hostname, const std::string& chan_name, const std::string& topic, const std::string& who)
|
void Bridge::send_topic(const std::string& hostname, const std::string& chan_name, const std::string& topic, const std::string& who)
|
||||||
{
|
{
|
||||||
const auto encoding = in_encoding_for(*this, {chan_name + '%' + hostname});
|
const auto encoding = in_encoding_for(*this, {chan_name + '%' + hostname});
|
||||||
|
for (const auto& resource: this->resources_in_chan[ChannelKey{chan_name, hostname}])
|
||||||
|
{
|
||||||
this->xmpp.send_topic(chan_name + utils::empty_if_fixed_server(
|
this->xmpp.send_topic(chan_name + utils::empty_if_fixed_server(
|
||||||
"%" + hostname), this->make_xmpp_body(topic, encoding), this->user_jid, who);
|
"%" + hostname), this->make_xmpp_body(topic, encoding), this->user_jid + "/" + resource, who);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Bridge::get_own_nick(const Iid& iid)
|
std::string Bridge::get_own_nick(const Iid& iid)
|
||||||
@@ -653,12 +682,14 @@ size_t Bridge::active_clients() const
|
|||||||
|
|
||||||
void Bridge::kick_muc_user(Iid&& iid, const std::string& target, const std::string& reason, const std::string& author)
|
void Bridge::kick_muc_user(Iid&& iid, const std::string& target, const std::string& reason, const std::string& author)
|
||||||
{
|
{
|
||||||
this->xmpp.kick_user(std::to_string(iid), target, reason, author, this->user_jid);
|
for (const auto& resource: this->resources_in_chan[ChannelKey{iid.get_local(), iid.get_server()}])
|
||||||
|
this->xmpp.kick_user(std::to_string(iid), target, reason, author, this->user_jid + "/" + resource);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Bridge::send_nickname_conflict_error(const Iid& iid, const std::string& nickname)
|
void Bridge::send_nickname_conflict_error(const Iid& iid, const std::string& nickname)
|
||||||
{
|
{
|
||||||
this->xmpp.send_presence_error(std::to_string(iid), nickname, this->user_jid, "cancel", "conflict", "409", "");
|
for (const auto& resource: this->resources_in_chan[ChannelKey{iid.get_local(), iid.get_server()}])
|
||||||
|
this->xmpp.send_presence_error(std::to_string(iid), nickname, this->user_jid + "/" + resource, "cancel", "conflict", "409", "");
|
||||||
}
|
}
|
||||||
|
|
||||||
void Bridge::send_affiliation_role_change(const Iid& iid, const std::string& target, const char mode)
|
void Bridge::send_affiliation_role_change(const Iid& iid, const std::string& target, const char mode)
|
||||||
@@ -667,7 +698,8 @@ void Bridge::send_affiliation_role_change(const Iid& iid, const std::string& tar
|
|||||||
std::string affiliation;
|
std::string affiliation;
|
||||||
|
|
||||||
std::tie(role, affiliation) = get_role_affiliation_from_irc_mode(mode);
|
std::tie(role, affiliation) = get_role_affiliation_from_irc_mode(mode);
|
||||||
this->xmpp.send_affiliation_role_change(std::to_string(iid), target, affiliation, role, this->user_jid);
|
for (const auto& resource: this->resources_in_chan[ChannelKey{iid.get_local(), iid.get_server()}])
|
||||||
|
this->xmpp.send_affiliation_role_change(std::to_string(iid), target, affiliation, role, this->user_jid + "/" + resource);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Bridge::send_iq_version_request(const std::string& nick, const std::string& hostname)
|
void Bridge::send_iq_version_request(const std::string& nick, const std::string& hostname)
|
||||||
@@ -722,7 +754,7 @@ std::unordered_map<std::string, std::shared_ptr<IrcClient>>& Bridge::get_irc_cli
|
|||||||
return this->irc_clients;
|
return this->irc_clients;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Bridge::add_resource_to_chan(const std::string& channel, const std::string& resource)
|
void Bridge::add_resource_to_chan(const Bridge::ChannelKey& channel, const std::string& resource)
|
||||||
{
|
{
|
||||||
auto it = this->resources_in_chan.find(channel);
|
auto it = this->resources_in_chan.find(channel);
|
||||||
if (it == this->resources_in_chan.end())
|
if (it == this->resources_in_chan.end())
|
||||||
@@ -731,7 +763,7 @@ void Bridge::add_resource_to_chan(const std::string& channel, const std::string&
|
|||||||
it->second.insert(resource);
|
it->second.insert(resource);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Bridge::remove_resource_from_chan(const std::string& channel, const std::string& resource)
|
void Bridge::remove_resource_from_chan(const Bridge::ChannelKey& channel, const std::string& resource)
|
||||||
{
|
{
|
||||||
auto it = this->resources_in_chan.find(channel);
|
auto it = this->resources_in_chan.find(channel);
|
||||||
if (it != this->resources_in_chan.end())
|
if (it != this->resources_in_chan.end())
|
||||||
@@ -742,7 +774,7 @@ void Bridge::remove_resource_from_chan(const std::string& channel, const std::st
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Bridge::is_resource_in_chan(const std::string& channel, const std::string& resource) const
|
bool Bridge::is_resource_in_chan(const Bridge::ChannelKey& channel, const std::string& resource) const
|
||||||
{
|
{
|
||||||
auto it = this->resources_in_chan.find(channel);
|
auto it = this->resources_in_chan.find(channel);
|
||||||
if (it != this->resources_in_chan.end())
|
if (it != this->resources_in_chan.end())
|
||||||
@@ -750,3 +782,43 @@ bool Bridge::is_resource_in_chan(const std::string& channel, const std::string&
|
|||||||
return true;
|
return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Bridge::add_resource_to_server(const Bridge::IrcHostname& irc_hostname, const std::string& resource)
|
||||||
|
{
|
||||||
|
auto it = this->resources_in_server.find(irc_hostname);
|
||||||
|
if (it == this->resources_in_server.end())
|
||||||
|
this->resources_in_server[irc_hostname] = {resource};
|
||||||
|
else
|
||||||
|
it->second.insert(resource);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Bridge::remove_resource_from_server(const Bridge::IrcHostname& irc_hostname, const std::string& resource)
|
||||||
|
{
|
||||||
|
auto it = this->resources_in_server.find(irc_hostname);
|
||||||
|
if (it != this->resources_in_server.end())
|
||||||
|
{
|
||||||
|
it->second.erase(resource);
|
||||||
|
if (it->second.empty())
|
||||||
|
this->resources_in_server.erase(it);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Bridge::is_resource_in_server(const Bridge::IrcHostname& irc_hostname, const std::string& resource) const
|
||||||
|
{
|
||||||
|
auto it = this->resources_in_server.find(irc_hostname);
|
||||||
|
if (it != this->resources_in_server.end())
|
||||||
|
if (it->second.count(resource) == 1)
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Bridge::generate_channel_join_for_resource(const Iid& iid, const std::string& resource)
|
||||||
|
{
|
||||||
|
IrcClient* irc = this->get_irc_client(iid.get_server());
|
||||||
|
IrcChannel* channel = irc->get_channel(iid.get_local());
|
||||||
|
// Send the occupant list
|
||||||
|
for (const auto& user: channel->get_users())
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
+29
-8
@@ -65,7 +65,7 @@ public:
|
|||||||
* Try to join an irc_channel, does nothing and return true if the channel
|
* Try to join an irc_channel, does nothing and return true if the channel
|
||||||
* was already joined.
|
* was already joined.
|
||||||
*/
|
*/
|
||||||
bool join_irc_channel(const Iid& iid, const std::string& nickname, const std::string& password);
|
bool join_irc_channel(const Iid& iid, const std::string& nickname, const std::string& password, const std::string& resource);
|
||||||
|
|
||||||
void send_channel_message(const Iid& iid, const std::string& body);
|
void send_channel_message(const Iid& iid, const std::string& body);
|
||||||
void send_private_message(const Iid& iid, const std::string& body, const std::string& type="PRIVMSG");
|
void send_private_message(const Iid& iid, const std::string& body, const std::string& type="PRIVMSG");
|
||||||
@@ -195,11 +195,9 @@ public:
|
|||||||
std::unordered_map<std::string, std::shared_ptr<IrcClient>>& get_irc_clients();
|
std::unordered_map<std::string, std::shared_ptr<IrcClient>>& get_irc_clients();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Manage which resource is in which channel
|
* Manage which resource is connected to which IRC server
|
||||||
*/
|
*/
|
||||||
void add_resource_to_chan(const std::string& channel, const std::string& resource);
|
|
||||||
void remove_resource_from_chan(const std::string& channel, const std::string& resource);
|
|
||||||
bool is_resource_in_chan(const std::string& channel, const std::string& resource) const;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/**
|
/**
|
||||||
@@ -218,7 +216,7 @@ private:
|
|||||||
*/
|
*/
|
||||||
IrcClient* find_irc_client(const std::string& hostname);
|
IrcClient* find_irc_client(const std::string& hostname);
|
||||||
/**
|
/**
|
||||||
* The JID of the user associated with this bridge. Messages from/to this
|
* The bare JID of the user associated with this bridge. Messages from/to this
|
||||||
* JID are only managed by this bridge.
|
* JID are only managed by this bridge.
|
||||||
*/
|
*/
|
||||||
const std::string user_jid;
|
const std::string user_jid;
|
||||||
@@ -251,10 +249,33 @@ private:
|
|||||||
* response iq.
|
* response iq.
|
||||||
*/
|
*/
|
||||||
std::vector<irc_responder_callback_t> waiting_irc;
|
std::vector<irc_responder_callback_t> waiting_irc;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Keep track of which resource is in which channel.
|
* Resources to IRC channel/server mapping:
|
||||||
*/
|
*/
|
||||||
std::map<std::string, std::set<std::string>> resources_in_chan;
|
using Resource = std::string;
|
||||||
|
using ChannelName = std::string;
|
||||||
|
using IrcHostname = std::string;
|
||||||
|
using ChannelKey = std::tuple<ChannelName, IrcHostname>;
|
||||||
|
std::map<ChannelKey, std::set<Resource>> resources_in_chan;
|
||||||
|
std::map<IrcHostname, std::set<Resource>> resources_in_server;
|
||||||
|
/**
|
||||||
|
* Manage which resource is in which channel
|
||||||
|
*/
|
||||||
|
void add_resource_to_chan(const ChannelKey& channel_key, const std::string& resource);
|
||||||
|
void remove_resource_from_chan(const ChannelKey& channel_key, const std::string& resource);
|
||||||
|
bool is_resource_in_chan(const ChannelKey& channel_key, const std::string& resource) const;
|
||||||
|
|
||||||
|
void add_resource_to_server(const IrcHostname& irc_hostname, const std::string& resource);
|
||||||
|
void remove_resource_from_server(const IrcHostname& irc_hostname, const std::string& resource);
|
||||||
|
bool is_resource_in_server(const IrcHostname& irc_hostname, const std::string& resource) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate all the stanzas to be sent to this resource, simulating a join on this channel.
|
||||||
|
* This means sending the whole user list, the topic, etc
|
||||||
|
* TODO: send message history
|
||||||
|
*/
|
||||||
|
void generate_channel_join_for_resource(const Iid& iid, const std::string& resource);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct IRCNotConnected: public std::exception
|
struct IRCNotConnected: public std::exception
|
||||||
|
|||||||
@@ -31,6 +31,8 @@ public:
|
|||||||
IrcUser* find_user(const std::string& name) const;
|
IrcUser* find_user(const std::string& name) const;
|
||||||
void remove_user(const IrcUser* user);
|
void remove_user(const IrcUser* user);
|
||||||
void remove_all_users();
|
void remove_all_users();
|
||||||
|
const std::vector<std::unique_ptr<IrcUser>>& get_users() const
|
||||||
|
{ return this->users; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
std::unique_ptr<IrcUser> self;
|
std::unique_ptr<IrcUser> self;
|
||||||
|
|||||||
@@ -701,7 +701,7 @@ void IrcClient::empty_motd(const IrcMessage&)
|
|||||||
|
|
||||||
void IrcClient::on_empty_topic(const IrcMessage& message)
|
void IrcClient::on_empty_topic(const IrcMessage& message)
|
||||||
{
|
{
|
||||||
const std::string chan_name = utils::tolower(message.arguments[message.arguments.size() - 1]);
|
const std::string chan_name = utils::tolower(message.arguments[1]);
|
||||||
log_debug("empty topic for " << chan_name);
|
log_debug("empty topic for " << chan_name);
|
||||||
IrcChannel* channel = this->get_channel(chan_name);
|
IrcChannel* channel = this->get_channel(chan_name);
|
||||||
if (channel)
|
if (channel)
|
||||||
|
|||||||
@@ -105,26 +105,27 @@ void BiboumiComponent::clean()
|
|||||||
|
|
||||||
void BiboumiComponent::handle_presence(const Stanza& stanza)
|
void BiboumiComponent::handle_presence(const Stanza& stanza)
|
||||||
{
|
{
|
||||||
std::string from = stanza.get_tag("from");
|
std::string from_str = stanza.get_tag("from");
|
||||||
std::string id = stanza.get_tag("id");
|
std::string id = stanza.get_tag("id");
|
||||||
std::string to_str = stanza.get_tag("to");
|
std::string to_str = stanza.get_tag("to");
|
||||||
std::string type = stanza.get_tag("type");
|
std::string type = stanza.get_tag("type");
|
||||||
|
|
||||||
// Check for mandatory tags
|
// Check for mandatory tags
|
||||||
if (from.empty())
|
if (from_str.empty())
|
||||||
{
|
{
|
||||||
log_warning("Received an invalid presence stanza: tag 'from' is missing.");
|
log_warning("Received an invalid presence stanza: tag 'from' is missing.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (to_str.empty())
|
if (to_str.empty())
|
||||||
{
|
{
|
||||||
this->send_stanza_error("presence", from, this->served_hostname, id,
|
this->send_stanza_error("presence", from_str, this->served_hostname, id,
|
||||||
"modify", "bad-request", "Missing 'to' tag");
|
"modify", "bad-request", "Missing 'to' tag");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Bridge* bridge = this->get_user_bridge(from);
|
Bridge* bridge = this->get_user_bridge(from_str);
|
||||||
Jid to(to_str);
|
Jid to(to_str);
|
||||||
|
Jid from(from_str);
|
||||||
Iid iid(to.local);
|
Iid iid(to.local);
|
||||||
|
|
||||||
// An error stanza is sent whenever we exit this function without
|
// An error stanza is sent whenever we exit this function without
|
||||||
@@ -136,7 +137,7 @@ void BiboumiComponent::handle_presence(const Stanza& stanza)
|
|||||||
std::string error_type("cancel");
|
std::string error_type("cancel");
|
||||||
std::string error_name("internal-server-error");
|
std::string error_name("internal-server-error");
|
||||||
utils::ScopeGuard stanza_error([&](){
|
utils::ScopeGuard stanza_error([&](){
|
||||||
this->send_stanza_error("presence", from, to_str, id,
|
this->send_stanza_error("presence", from_str, to_str, id,
|
||||||
error_type, error_name, "");
|
error_type, error_name, "");
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -151,8 +152,8 @@ void BiboumiComponent::handle_presence(const Stanza& stanza)
|
|||||||
bridge->send_irc_nick_change(iid, to.resource);
|
bridge->send_irc_nick_change(iid, to.resource);
|
||||||
const XmlNode* x = stanza.get_child("x", MUC_NS);
|
const XmlNode* x = stanza.get_child("x", MUC_NS);
|
||||||
const XmlNode* password = x ? x->get_child("password", MUC_NS): nullptr;
|
const XmlNode* password = x ? x->get_child("password", MUC_NS): nullptr;
|
||||||
bridge->join_irc_channel(iid, to.resource,
|
bridge->join_irc_channel(iid, to.resource, password ? password->get_inner(): "",
|
||||||
password ? password->get_inner() : "");
|
from.resource);
|
||||||
}
|
}
|
||||||
else if (type == "unavailable")
|
else if (type == "unavailable")
|
||||||
{
|
{
|
||||||
@@ -164,12 +165,12 @@ void BiboumiComponent::handle_presence(const Stanza& stanza)
|
|||||||
{
|
{
|
||||||
// An user wants to join an invalid IRC channel, return a presence error to him
|
// An user wants to join an invalid IRC channel, return a presence error to him
|
||||||
if (type.empty())
|
if (type.empty())
|
||||||
this->send_invalid_room_error(to.local, to.resource, from);
|
this->send_invalid_room_error(to.local, to.resource, from_str);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (const IRCNotConnected& ex)
|
catch (const IRCNotConnected& ex)
|
||||||
{
|
{
|
||||||
this->send_stanza_error("presence", from, to_str, id,
|
this->send_stanza_error("presence", from_str, to_str, id,
|
||||||
"cancel", "remote-server-not-found",
|
"cancel", "remote-server-not-found",
|
||||||
"Not connected to IRC server "s + ex.hostname,
|
"Not connected to IRC server "s + ex.hostname,
|
||||||
true);
|
true);
|
||||||
|
|||||||
Reference in New Issue
Block a user