summaryrefslogtreecommitdiff
path: root/src/irc
diff options
context:
space:
mode:
Diffstat (limited to 'src/irc')
-rw-r--r--src/irc/iid.cpp5
-rw-r--r--src/irc/iid.hpp1
-rw-r--r--src/irc/irc_client.cpp49
-rw-r--r--src/irc/irc_client.hpp11
-rw-r--r--src/irc/irc_message.cpp6
-rw-r--r--src/irc/irc_user.cpp2
-rw-r--r--src/irc/irc_user.hpp2
7 files changed, 45 insertions, 31 deletions
diff --git a/src/irc/iid.cpp b/src/irc/iid.cpp
index d442013..6b07793 100644
--- a/src/irc/iid.cpp
+++ b/src/irc/iid.cpp
@@ -34,9 +34,10 @@ Iid::Iid(const std::string& iid, const Bridge *bridge)
void Iid::set_type(const std::set<char>& chantypes)
{
+ if (this->local.empty() && this->server.empty())
+ this->type = Iid::Type::None;
if (this->local.empty())
return;
-
if (chantypes.count(this->local[0]) == 1)
this->type = Iid::Type::Channel;
else
@@ -105,6 +106,8 @@ namespace std {
{
if (iid.type == Iid::Type::Server)
return iid.get_server();
+ else if (iid.get_local().empty() && iid.get_server().empty())
+ return {};
else
return iid.get_encoded_local() + iid.separator + iid.get_server();
}
diff --git a/src/irc/iid.hpp b/src/irc/iid.hpp
index 44861c1..81cf3ca 100644
--- a/src/irc/iid.hpp
+++ b/src/irc/iid.hpp
@@ -53,6 +53,7 @@ public:
Channel,
User,
Server,
+ None,
};
static constexpr char separator[]{"%"};
Iid(const std::string& iid, const std::set<char>& chantypes);
diff --git a/src/irc/irc_client.cpp b/src/irc/irc_client.cpp
index b0d3a47..48b105d 100644
--- a/src/irc/irc_client.cpp
+++ b/src/irc/irc_client.cpp
@@ -14,13 +14,13 @@
#include <sstream>
#include <iostream>
#include <stdexcept>
+#include <algorithm>
#include <cstring>
#include <chrono>
#include <string>
#include "biboumi.h"
-#include "louloulibs.h"
using namespace std::string_literals;
using namespace std::chrono_literals;
@@ -66,6 +66,7 @@ static const std::unordered_map<std::string,
{"433", {&IrcClient::on_nickname_conflict, {2, 0}}},
{"438", {&IrcClient::on_nickname_change_too_fast, {2, 0}}},
{"443", {&IrcClient::on_useronchannel, {3, 0}}},
+ {"475", {&IrcClient::on_channel_bad_key, {3, 0}}},
{"ERR_USERONCHANNEL", {&IrcClient::on_useronchannel, {3, 0}}},
{"001", {&IrcClient::on_welcome_message, {1, 0}}},
{"PART", {&IrcClient::on_part, {1, 0}}},
@@ -113,7 +114,6 @@ static const std::unordered_map<std::string,
{"472", {&IrcClient::on_generic_error, {2, 0}}},
{"473", {&IrcClient::on_generic_error, {2, 0}}},
{"474", {&IrcClient::on_generic_error, {2, 0}}},
- {"475", {&IrcClient::on_generic_error, {2, 0}}},
{"476", {&IrcClient::on_generic_error, {2, 0}}},
{"477", {&IrcClient::on_generic_error, {2, 0}}},
{"481", {&IrcClient::on_generic_error, {2, 0}}},
@@ -127,11 +127,11 @@ static const std::unordered_map<std::string,
{"502", {&IrcClient::on_generic_error, {2, 0}}},
};
-IrcClient::IrcClient(std::shared_ptr<Poller> poller, const std::string& hostname,
+IrcClient::IrcClient(std::shared_ptr<Poller>& poller, const std::string& hostname,
const std::string& nickname, const std::string& username,
const std::string& realname, const std::string& user_hostname,
Bridge& bridge):
- TCPSocketHandler(poller),
+ TCPClientSocketHandler(poller),
hostname(hostname),
user_hostname(user_hostname),
username(username),
@@ -338,7 +338,7 @@ void IrcClient::parse_in_buffer(const size_t)
if (pos == std::string::npos)
break ;
IrcMessage message(this->in_buf.substr(0, pos));
- this->in_buf = this->in_buf.substr(pos + 2, std::string::npos);
+ this->consume_in_buffer(pos + 2);
log_debug("IRC RECEIVING: (", this->get_hostname(), ") ", message);
// Call the standard callback (if any), associated with the command
@@ -450,7 +450,12 @@ void IrcClient::send_quit_command(const std::string& reason)
void IrcClient::send_join_command(const std::string& chan_name, const std::string& password)
{
if (this->welcomed == false)
- this->channels_to_join.emplace_back(chan_name, password);
+ {
+ const auto it = std::find_if(begin(this->channels_to_join), end(this->channels_to_join),
+ [&chan_name](const auto& pair) { return std::get<0>(pair) == chan_name; });
+ if (it == end(this->channels_to_join))
+ this->channels_to_join.emplace_back(chan_name, password);
+ }
else if (password.empty())
this->send_message(IrcMessage("JOIN", {chan_name}));
else
@@ -496,15 +501,7 @@ void IrcClient::send_private_message(const std::string& username, const std::str
void IrcClient::send_part_command(const std::string& chan_name, const std::string& status_message)
{
- IrcChannel* channel = this->get_channel(chan_name);
- if (channel->joined == true)
- {
- if (chan_name.empty())
- this->leave_dummy_channel(status_message);
- else
- this->send_message(IrcMessage("PART", {chan_name, status_message}));
- channel->parting = true;
- }
+ this->send_message(IrcMessage("PART", {chan_name, status_message}));
}
void IrcClient::send_mode_command(const std::string& chan_name, const std::vector<std::string>& arguments)
@@ -891,7 +888,7 @@ void IrcClient::on_part(const IrcMessage& message)
// channel pointer is now invalid
channel = nullptr;
}
- this->bridge.send_muc_leave(std::move(iid), std::move(nick), std::move(txt), self);
+ this->bridge.send_muc_leave(iid, std::move(nick), std::move(txt), self);
}
}
@@ -909,7 +906,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(std::move(iid), std::move(own_nick), leave_message, true);
+ this->bridge.send_muc_leave(iid, std::move(own_nick), leave_message, true);
}
this->channels.clear();
this->send_gateway_message("ERROR: "s + leave_message);
@@ -933,7 +930,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(std::move(iid), std::move(nick), txt, false);
+ this->bridge.send_muc_leave(iid, std::move(nick), txt, false);
}
}
}
@@ -1014,6 +1011,18 @@ void IrcClient::on_mode(const IrcMessage& message)
this->on_user_mode(message);
}
+void IrcClient::on_channel_bad_key(const IrcMessage& message)
+{
+ this->on_generic_error(message);
+ const std::string& nickname = message.arguments[0];
+ const std::string& channel = message.arguments[1];
+ std::string text;
+ if (message.arguments.size() > 2)
+ text = message.arguments[2];
+
+ this->bridge.send_presence_error({channel, this->hostname, Iid::Type::Channel}, nickname, "auth", "not-authorized", "", text);
+}
+
void IrcClient::on_channel_mode(const IrcMessage& message)
{
// For now, just transmit the modes so the user can know what happens
@@ -1143,14 +1152,14 @@ DummyIrcChannel& IrcClient::get_dummy_channel()
return this->dummy_channel;
}
-void IrcClient::leave_dummy_channel(const std::string& exit_message)
+void IrcClient::leave_dummy_channel(const std::string& exit_message, const std::string& resource)
{
if (!this->dummy_channel.joined)
return;
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);
+ this->bridge.send_muc_leave(Iid("%"s + this->hostname, this->chantypes), std::string(this->current_nick), exit_message, true, resource);
}
#ifdef BOTAN_FOUND
diff --git a/src/irc/irc_client.hpp b/src/irc/irc_client.hpp
index 1b4d892..8119201 100644
--- a/src/irc/irc_client.hpp
+++ b/src/irc/irc_client.hpp
@@ -5,7 +5,7 @@
#include <irc/irc_channel.hpp>
#include <irc/iid.hpp>
-#include <network/tcp_socket_handler.hpp>
+#include <network/tcp_client_socket_handler.hpp>
#include <network/resolver.hpp>
#include <unordered_map>
@@ -23,10 +23,10 @@ class Bridge;
* Represent one IRC client, i.e. an endpoint connected to a single IRC
* server, through a TCP socket, receiving and sending commands to it.
*/
-class IrcClient: public TCPSocketHandler
+class IrcClient: public TCPClientSocketHandler
{
public:
- explicit IrcClient(std::shared_ptr<Poller> poller, const std::string& hostname,
+ explicit IrcClient(std::shared_ptr<Poller>& poller, const std::string& hostname,
const std::string& nickname, const std::string& username,
const std::string& realname, const std::string& user_hostname,
Bridge& bridge);
@@ -52,7 +52,7 @@ public:
/**
* Close the connection, remove us from the poller
*/
- void on_connection_close(const std::string& error) override final;
+ void on_connection_close(const std::string& error_msg) override final;
/**
* Parse the data we have received so far and try to get one or more
* complete messages from it.
@@ -257,6 +257,7 @@ public:
void on_nick(const IrcMessage& message);
void on_kick(const IrcMessage& message);
void on_mode(const IrcMessage& message);
+ void on_channel_bad_key(const IrcMessage& message);
/**
* A mode towards our own user is received (note, that is different from a
* channel mode towards or own nick, see
@@ -282,7 +283,7 @@ public:
* Leave the dummy channel: forward a message to the user to indicate that
* he left it, and mark it as not joined.
*/
- void leave_dummy_channel(const std::string& exit_message);
+ void leave_dummy_channel(const std::string& exit_message, const std::string& resource);
const std::string& get_hostname() const { return this->hostname; }
std::string get_nick() const { return this->current_nick; }
diff --git a/src/irc/irc_message.cpp b/src/irc/irc_message.cpp
index 966a47c..14fdb0e 100644
--- a/src/irc/irc_message.cpp
+++ b/src/irc/irc_message.cpp
@@ -8,12 +8,12 @@ IrcMessage::IrcMessage(std::string&& line)
// optional prefix
if (line[0] == ':')
{
- pos = line.find(" ");
+ pos = line.find(' ');
this->prefix = line.substr(1, pos - 1);
line = line.substr(pos + 1, std::string::npos);
}
// command
- pos = line.find(" ");
+ pos = line.find(' ');
this->command = line.substr(0, pos);
line = line.substr(pos + 1, std::string::npos);
// arguments
@@ -24,7 +24,7 @@ IrcMessage::IrcMessage(std::string&& line)
this->arguments.emplace_back(line.substr(1, std::string::npos));
break ;
}
- pos = line.find(" ");
+ pos = line.find(' ');
this->arguments.emplace_back(line.substr(0, pos));
line = line.substr(pos + 1, std::string::npos);
} while (pos != std::string::npos);
diff --git a/src/irc/irc_user.cpp b/src/irc/irc_user.cpp
index 9fa3612..139015e 100644
--- a/src/irc/irc_user.cpp
+++ b/src/irc/irc_user.cpp
@@ -21,7 +21,7 @@ IrcUser::IrcUser(const std::string& name,
name_begin++;
}
- const std::string::size_type sep = name.find("!", name_begin);
+ const std::string::size_type sep = name.find('!', name_begin);
if (sep == std::string::npos)
this->nick = name.substr(name_begin);
else
diff --git a/src/irc/irc_user.hpp b/src/irc/irc_user.hpp
index c84030e..a4291d4 100644
--- a/src/irc/irc_user.hpp
+++ b/src/irc/irc_user.hpp
@@ -23,7 +23,7 @@ public:
void add_mode(const char mode);
void remove_mode(const char mode);
- char get_most_significant_mode(const std::vector<char>& sorted_user_modes) const;
+ char get_most_significant_mode(const std::vector<char>& modes) const;
std::string nick;
std::string host;