From 87aaacdb420341bf3619922332d58b95249971bc Mon Sep 17 00:00:00 2001 From: Florent Le Coz Date: Sun, 3 Nov 2013 00:22:32 +0100 Subject: Rename libirc and libxmpp to irc and xmpp --- src/irc/irc_client.hpp | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 src/irc/irc_client.hpp (limited to 'src/irc/irc_client.hpp') diff --git a/src/irc/irc_client.hpp b/src/irc/irc_client.hpp new file mode 100644 index 0000000..e380f5b --- /dev/null +++ b/src/irc/irc_client.hpp @@ -0,0 +1,60 @@ +#ifndef IRC_CLIENT_INCLUDED +# define IRC_CLIENT_INCLUDED + +#include + +#include + +#include + +/** + * Represent one IRC client, i.e. an endpoint connected to a single IRC + * server, through a TCP socket, receiving and sending commands to it. + * + * TODO: TLS support, maybe, but that's not high priority + */ +class IrcClient: public SocketHandler +{ +public: + explicit IrcClient(); + ~IrcClient(); + /** + * Called when successfully connected to the server + */ + void on_connected(); + /** + * Close the connection, remove us from the poller + */ + void on_connection_close(); + /** + * Parse the data we have received so far and try to get one or more + * complete messages from it. + */ + void parse_in_buffer(); + /** + * Serialize the given message into a line, and send that into the socket + * (actually, into our out_buf and signal the poller that we want to wach + * for send events to be ready) + */ + void send_message(IrcMessage&& message); + /** + * Send the USER irc command + */ + void send_user_command(const std::string& username, const std::string& realname); + /** + * Send the NICK irc command + */ + void send_nick_command(const std::string& username); + /** + * Send the JOIN irc command + */ + void send_join_command(const std::string& chan_name); + +private: + IrcClient(const IrcClient&) = delete; + IrcClient(IrcClient&&) = delete; + IrcClient& operator=(const IrcClient&) = delete; + IrcClient& operator=(IrcClient&&) = delete; +}; + +#endif // IRC_CLIENT_INCLUDED -- cgit v1.2.3 From bf7b05ef72bbdac97704d262ddfe418908267535 Mon Sep 17 00:00:00 2001 From: Florent Le Coz Date: Wed, 6 Nov 2013 20:51:05 +0100 Subject: Implement the Bridge class to translate between the two protocols MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add all useful classes as well: Jid, Iid, IrcChannel, IrcUser etc to properly keep the informations about what we receive from the IRC server. Only handle the MUC join stanza, and send the list of users in the IRC channel to the XMPP user, and the IRC channel’s topic, for now. --- src/irc/irc_client.hpp | 60 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 59 insertions(+), 1 deletion(-) (limited to 'src/irc/irc_client.hpp') diff --git a/src/irc/irc_client.hpp b/src/irc/irc_client.hpp index e380f5b..db1b83b 100644 --- a/src/irc/irc_client.hpp +++ b/src/irc/irc_client.hpp @@ -2,11 +2,16 @@ # define IRC_CLIENT_INCLUDED #include +#include +#include #include +#include #include +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. @@ -16,8 +21,12 @@ class IrcClient: public SocketHandler { public: - explicit IrcClient(); + explicit IrcClient(const std::string& hostname, const std::string& username, Bridge* bridge); ~IrcClient(); + /** + * Connect to the IRC server + */ + void start(); /** * Called when successfully connected to the server */ @@ -31,12 +40,20 @@ public: * complete messages from it. */ void parse_in_buffer(); + /** + * Return the channel with this name, create it if it does not yet exist + */ + IrcChannel* get_channel(const std::string& name); /** * Serialize the given message into a line, and send that into the socket * (actually, into our out_buf and signal the poller that we want to wach * for send events to be ready) */ void send_message(IrcMessage&& message); + /** + * Send the PONG irc command + */ + void send_pong_command(); /** * Send the USER irc command */ @@ -49,8 +66,49 @@ public: * Send the JOIN irc command */ void send_join_command(const std::string& chan_name); + /** + * Forward the server message received from IRC to the XMPP component + */ + void forward_server_message(const IrcMessage& message); + /** + * Forward the join of an other user into an IRC channel, and save the + * IrcUsers in the IrcChannel + */ + void set_and_forward_user_list(const IrcMessage& message); + /** + * Remember our nick and host, when we are joined to the channel. The list + * of user comes after so we do not send the self-presence over XMPP yet. + */ + void on_self_channel_join(const IrcMessage& message); + /** + * Save the topic in the IrcChannel + */ + void on_topic_received(const IrcMessage& message); + /** + * The channel has been completely joined (self presence, topic, all names + * received etc), send the self presence and topic to the XMPP user. + */ + void on_channel_completely_joined(const IrcMessage& message); private: + /** + * The hostname of the server we are connected to. + */ + const std::string hostname; + /** + * The user name used in the USER irc command + */ + const std::string username; + /** + * Raw pointer because the bridge owns us. + */ + Bridge* bridge; + + /** + * The list of joined channels, indexed by name + */ + std::unordered_map> channels; + IrcClient(const IrcClient&) = delete; IrcClient(IrcClient&&) = delete; IrcClient& operator=(const IrcClient&) = delete; -- cgit v1.2.3 From a418b6ed5d70f0e61e71bb1adce2a693ade89e30 Mon Sep 17 00:00:00 2001 From: Florent Le Coz Date: Thu, 7 Nov 2013 01:53:09 +0100 Subject: Send and receive messages Also correctly respond to PING with the id, escape some XML content, but not always --- src/irc/irc_client.hpp | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) (limited to 'src/irc/irc_client.hpp') diff --git a/src/irc/irc_client.hpp b/src/irc/irc_client.hpp index db1b83b..50f3781 100644 --- a/src/irc/irc_client.hpp +++ b/src/irc/irc_client.hpp @@ -44,6 +44,10 @@ public: * Return the channel with this name, create it if it does not yet exist */ IrcChannel* get_channel(const std::string& name); + /** + * Return our own nick + */ + std::string get_own_nick() const; /** * Serialize the given message into a line, and send that into the socket * (actually, into our out_buf and signal the poller that we want to wach @@ -53,7 +57,7 @@ public: /** * Send the PONG irc command */ - void send_pong_command(); + void send_pong_command(const IrcMessage& message); /** * Send the USER irc command */ @@ -66,6 +70,11 @@ public: * Send the JOIN irc command */ void send_join_command(const std::string& chan_name); + /** + * Send a PRIVMSG command for a channel + * Return true if the message was actually sent + */ + bool send_channel_message(const std::string& chan_name, const std::string& body); /** * Forward the server message received from IRC to the XMPP component */ @@ -80,6 +89,10 @@ public: * of user comes after so we do not send the self-presence over XMPP yet. */ void on_self_channel_join(const IrcMessage& message); + /** + * When a channel message is received + */ + void on_channel_message(const IrcMessage& message); /** * Save the topic in the IrcChannel */ @@ -89,6 +102,10 @@ public: * received etc), send the self presence and topic to the XMPP user. */ void on_channel_completely_joined(const IrcMessage& message); + /** + * When a message 001 is received, join the rooms we wanted to join, and set our actual nickname + */ + void on_welcome_message(const IrcMessage& message); private: /** @@ -99,15 +116,26 @@ private: * The user name used in the USER irc command */ const std::string username; + /** + * Our current nickname on the server + */ + std::string current_nick; /** * Raw pointer because the bridge owns us. */ Bridge* bridge; - /** * The list of joined channels, indexed by name */ std::unordered_map> channels; + /** + * A list of chan we want to join, but we need a response 001 from + * the server before sending the actual JOIN commands. So we just keep the + * channel names in a list, and send the JOIN commands for each of them + * whenever the WELCOME message is received. + */ + std::vector channels_to_join; + bool welcomed; IrcClient(const IrcClient&) = delete; IrcClient(IrcClient&&) = delete; -- cgit v1.2.3 From 7c671499350e22f8bfba2f72b9827aa5b200f7b0 Mon Sep 17 00:00:00 2001 From: Florent Le Coz Date: Sat, 9 Nov 2013 23:17:48 +0100 Subject: Implement part and join, both ways --- src/irc/irc_client.hpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'src/irc/irc_client.hpp') diff --git a/src/irc/irc_client.hpp b/src/irc/irc_client.hpp index 50f3781..e58ffbc 100644 --- a/src/irc/irc_client.hpp +++ b/src/irc/irc_client.hpp @@ -75,6 +75,10 @@ public: * Return true if the message was actually sent */ bool send_channel_message(const std::string& chan_name, const std::string& body); + /** + * Send the PART irc command + */ + void send_part_command(const std::string& chan_name, const std::string& status_message); /** * Forward the server message received from IRC to the XMPP component */ @@ -88,7 +92,7 @@ public: * Remember our nick and host, when we are joined to the channel. The list * of user comes after so we do not send the self-presence over XMPP yet. */ - void on_self_channel_join(const IrcMessage& message); + void on_channel_join(const IrcMessage& message); /** * When a channel message is received */ @@ -106,6 +110,10 @@ public: * When a message 001 is received, join the rooms we wanted to join, and set our actual nickname */ void on_welcome_message(const IrcMessage& message); + /** + * When a PART message is received + */ + void on_part(const IrcMessage& message); private: /** -- cgit v1.2.3 From 0bb7ee0127a625ca8b6c25d9f593bfaa3d5af84b Mon Sep 17 00:00:00 2001 From: Florent Le Coz Date: Sun, 10 Nov 2013 05:08:50 +0100 Subject: Handle IRC QUIT command --- src/irc/irc_client.hpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/irc/irc_client.hpp') diff --git a/src/irc/irc_client.hpp b/src/irc/irc_client.hpp index e58ffbc..33ab894 100644 --- a/src/irc/irc_client.hpp +++ b/src/irc/irc_client.hpp @@ -114,6 +114,10 @@ public: * When a PART message is received */ void on_part(const IrcMessage& message); + /** + * When a QUIT message is received + */ + void on_quit(const IrcMessage& message); private: /** -- cgit v1.2.3 From 10d528717723a72dd3240c634980a461cf9fa2df Mon Sep 17 00:00:00 2001 From: Florent Le Coz Date: Sun, 10 Nov 2013 06:33:04 +0100 Subject: Handle private messages, both ways --- src/irc/irc_client.hpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/irc/irc_client.hpp') diff --git a/src/irc/irc_client.hpp b/src/irc/irc_client.hpp index 33ab894..bb51a4e 100644 --- a/src/irc/irc_client.hpp +++ b/src/irc/irc_client.hpp @@ -75,6 +75,10 @@ public: * Return true if the message was actually sent */ bool send_channel_message(const std::string& chan_name, const std::string& body); + /** + * Send a PRIVMSG command for an user + */ + void send_private_message(const std::string& username, const std::string& body); /** * Send the PART irc command */ -- cgit v1.2.3 From 096a4e3bafe6e2d238e4592f57f22f19f363fcbd Mon Sep 17 00:00:00 2001 From: Florent Le Coz Date: Mon, 11 Nov 2013 00:24:34 +0100 Subject: Handle nick changes, both ways --- src/irc/irc_client.hpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'src/irc/irc_client.hpp') diff --git a/src/irc/irc_client.hpp b/src/irc/irc_client.hpp index bb51a4e..d9ea069 100644 --- a/src/irc/irc_client.hpp +++ b/src/irc/irc_client.hpp @@ -44,6 +44,10 @@ public: * Return the channel with this name, create it if it does not yet exist */ IrcChannel* get_channel(const std::string& name); + /** + * Returns true if the channel is joined + */ + bool is_channel_joined(const std::string& name); /** * Return our own nick */ @@ -67,7 +71,7 @@ public: */ void send_nick_command(const std::string& username); /** - * Send the JOIN irc command + * Send the JOIN irc command. */ void send_join_command(const std::string& chan_name); /** @@ -118,6 +122,10 @@ public: * When a PART message is received */ void on_part(const IrcMessage& message); + /** + * When a NICK message is received + */ + void on_nick(const IrcMessage& message); /** * When a QUIT message is received */ -- cgit v1.2.3 From 5817a95b5ee89480788832be35679dfcd2ed833b Mon Sep 17 00:00:00 2001 From: Florent Le Coz Date: Tue, 12 Nov 2013 23:43:43 +0100 Subject: Basic handling of modes, both ways --- src/irc/irc_client.hpp | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) (limited to 'src/irc/irc_client.hpp') diff --git a/src/irc/irc_client.hpp b/src/irc/irc_client.hpp index d9ea069..722f850 100644 --- a/src/irc/irc_client.hpp +++ b/src/irc/irc_client.hpp @@ -87,6 +87,10 @@ public: * Send the PART irc command */ void send_part_command(const std::string& chan_name, const std::string& status_message); + /** + * Send the MODE irc command + */ + void send_mode_command(const std::string& chan_name, const std::vector& arguments); /** * Forward the server message received from IRC to the XMPP component */ @@ -118,17 +122,20 @@ public: * When a message 001 is received, join the rooms we wanted to join, and set our actual nickname */ void on_welcome_message(const IrcMessage& message); - /** - * When a PART message is received - */ void on_part(const IrcMessage& message); + void on_nick(const IrcMessage& message); + void on_mode(const IrcMessage& message); /** - * When a NICK message is received + * A mode towards our own user is received (note, that is different from a + * channel mode towards or own nick, see + * http://tools.ietf.org/html/rfc2812#section-3.1.5 VS #section-3.2.3) */ - void on_nick(const IrcMessage& message); + void on_user_mode(const IrcMessage& message); /** - * When a QUIT message is received + * A mode towards a channel. Note that this can change the mode of the + * channel itself or an IrcUser in it. */ + void on_channel_mode(const IrcMessage& message); void on_quit(const IrcMessage& message); private: -- cgit v1.2.3 From 3cfaab9a2debe03829b1ff26fe94e775e1d18e0a Mon Sep 17 00:00:00 2001 From: Florent Le Coz Date: Tue, 12 Nov 2013 23:47:00 +0100 Subject: Map irc commands to callbacks, in a clean way --- src/irc/irc_client.hpp | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) (limited to 'src/irc/irc_client.hpp') diff --git a/src/irc/irc_client.hpp b/src/irc/irc_client.hpp index 722f850..07ff02c 100644 --- a/src/irc/irc_client.hpp +++ b/src/irc/irc_client.hpp @@ -167,11 +167,33 @@ private: */ std::vector channels_to_join; bool welcomed; - IrcClient(const IrcClient&) = delete; IrcClient(IrcClient&&) = delete; IrcClient& operator=(const IrcClient&) = delete; IrcClient& operator=(IrcClient&&) = delete; }; +/** + * Define a map of functions to be called for each IRC command we can + * handle. + */ +typedef void (IrcClient::*irc_callback_t)(const IrcMessage&); + +static const std::unordered_map irc_callbacks = { + {"NOTICE", &IrcClient::forward_server_message}, + {"375", &IrcClient::forward_server_message}, + {"372", &IrcClient::forward_server_message}, + {"JOIN", &IrcClient::on_channel_join}, + {"PRIVMSG", &IrcClient::on_channel_message}, + {"353", &IrcClient::set_and_forward_user_list}, + {"332", &IrcClient::on_topic_received}, + {"366", &IrcClient::on_channel_completely_joined}, + {"001", &IrcClient::on_welcome_message}, + {"PART", &IrcClient::on_part}, + {"QUIT", &IrcClient::on_quit}, + {"NICK", &IrcClient::on_nick}, + {"MODE", &IrcClient::on_mode}, + {"PING", &IrcClient::send_pong_command}, +}; + #endif // IRC_CLIENT_INCLUDED -- cgit v1.2.3 From 0859801230f999889d0f7356864888e8c5936cda Mon Sep 17 00:00:00 2001 From: Florent Le Coz Date: Wed, 13 Nov 2013 01:24:36 +0100 Subject: Handle KICK in irc channel, both ways --- src/irc/irc_client.hpp | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src/irc/irc_client.hpp') diff --git a/src/irc/irc_client.hpp b/src/irc/irc_client.hpp index 07ff02c..3b22fa0 100644 --- a/src/irc/irc_client.hpp +++ b/src/irc/irc_client.hpp @@ -91,6 +91,10 @@ public: * Send the MODE irc command */ void send_mode_command(const std::string& chan_name, const std::vector& arguments); + /** + * Send the KICK irc command + */ + void send_kick_command(const std::string& chan_name, const std::string& target, const std::string& reason); /** * Forward the server message received from IRC to the XMPP component */ @@ -124,6 +128,7 @@ public: void on_welcome_message(const IrcMessage& message); void on_part(const IrcMessage& message); void on_nick(const IrcMessage& message); + void on_kick(const IrcMessage& message); void on_mode(const IrcMessage& message); /** * A mode towards our own user is received (note, that is different from a @@ -194,6 +199,7 @@ static const std::unordered_map irc_callbacks = { {"NICK", &IrcClient::on_nick}, {"MODE", &IrcClient::on_mode}, {"PING", &IrcClient::send_pong_command}, + {"KICK", &IrcClient::on_kick}, }; #endif // IRC_CLIENT_INCLUDED -- cgit v1.2.3 From 1e122d3342ef4336f17bd5606be7101748627415 Mon Sep 17 00:00:00 2001 From: Florent Le Coz Date: Sun, 17 Nov 2013 11:35:43 +0100 Subject: Send the motd as one single big message We append each line to a string, and when the MOTD is complete, we send that string at once. --- src/irc/irc_client.hpp | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) (limited to 'src/irc/irc_client.hpp') diff --git a/src/irc/irc_client.hpp b/src/irc/irc_client.hpp index 3b22fa0..aa420f4 100644 --- a/src/irc/irc_client.hpp +++ b/src/irc/irc_client.hpp @@ -99,6 +99,18 @@ public: * Forward the server message received from IRC to the XMPP component */ void forward_server_message(const IrcMessage& message); + /** + * Just empty the motd we kept as a string + */ + void empty_motd(const IrcMessage& message); + /** + * Send the MOTD string as one single "big" message + */ + void send_motd(const IrcMessage& message); + /** + * Append this line to the MOTD + */ + void on_motd_line(const IrcMessage& message); /** * Forward the join of an other user into an IRC channel, and save the * IrcUsers in the IrcChannel @@ -172,6 +184,11 @@ private: */ std::vector channels_to_join; bool welcomed; + /** + * Each motd line received is appended to this string, which we send when + * the motd is completely received + */ + std::string motd; IrcClient(const IrcClient&) = delete; IrcClient(IrcClient&&) = delete; IrcClient& operator=(const IrcClient&) = delete; @@ -186,8 +203,12 @@ typedef void (IrcClient::*irc_callback_t)(const IrcMessage&); static const std::unordered_map irc_callbacks = { {"NOTICE", &IrcClient::forward_server_message}, - {"375", &IrcClient::forward_server_message}, - {"372", &IrcClient::forward_server_message}, + {"RPL_MOTDSTART", &IrcClient::empty_motd}, + {"375", &IrcClient::empty_motd}, + {"RPL_MOTD", &IrcClient::on_motd_line}, + {"372", &IrcClient::on_motd_line}, + {"RPL_MOTDEND", &IrcClient::send_motd}, + {"376", &IrcClient::send_motd}, {"JOIN", &IrcClient::on_channel_join}, {"PRIVMSG", &IrcClient::on_channel_message}, {"353", &IrcClient::set_and_forward_user_list}, -- cgit v1.2.3 From 12a18ca748a27111bb24a7f6518f831494e5ca47 Mon Sep 17 00:00:00 2001 From: Florent Le Coz Date: Thu, 21 Nov 2013 19:38:31 +0100 Subject: TIL override and final --- src/irc/irc_client.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/irc/irc_client.hpp') diff --git a/src/irc/irc_client.hpp b/src/irc/irc_client.hpp index aa420f4..4749cac 100644 --- a/src/irc/irc_client.hpp +++ b/src/irc/irc_client.hpp @@ -30,16 +30,16 @@ public: /** * Called when successfully connected to the server */ - void on_connected(); + void on_connected() override final; /** * Close the connection, remove us from the poller */ - void on_connection_close(); + void on_connection_close() override final; /** * Parse the data we have received so far and try to get one or more * complete messages from it. */ - void parse_in_buffer(); + void parse_in_buffer() override final; /** * Return the channel with this name, create it if it does not yet exist */ -- cgit v1.2.3 From 3afb63a650b8b925ce1ba722dd42b7418f623713 Mon Sep 17 00:00:00 2001 From: Florent Le Coz Date: Sat, 21 Dec 2013 21:04:41 +0100 Subject: Shutdown cleanly on SIGINT --- src/irc/irc_client.hpp | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src/irc/irc_client.hpp') diff --git a/src/irc/irc_client.hpp b/src/irc/irc_client.hpp index 4749cac..4038cdf 100644 --- a/src/irc/irc_client.hpp +++ b/src/irc/irc_client.hpp @@ -95,6 +95,10 @@ public: * Send the KICK irc command */ void send_kick_command(const std::string& chan_name, const std::string& target, const std::string& reason); + /** + * Send the QUIT irc command + */ + void send_quit_command(); /** * Forward the server message received from IRC to the XMPP component */ @@ -139,6 +143,7 @@ public: */ void on_welcome_message(const IrcMessage& message); void on_part(const IrcMessage& message); + void on_error(const IrcMessage& message); void on_nick(const IrcMessage& message); void on_kick(const IrcMessage& message); void on_mode(const IrcMessage& message); @@ -216,6 +221,7 @@ static const std::unordered_map irc_callbacks = { {"366", &IrcClient::on_channel_completely_joined}, {"001", &IrcClient::on_welcome_message}, {"PART", &IrcClient::on_part}, + {"ERROR", &IrcClient::on_error}, {"QUIT", &IrcClient::on_quit}, {"NICK", &IrcClient::on_nick}, {"MODE", &IrcClient::on_mode}, -- cgit v1.2.3 From 9df757fc6737b59f56d5b808ef48baba760b142e Mon Sep 17 00:00:00 2001 From: Florent Le Coz Date: Thu, 26 Dec 2013 14:57:13 +0100 Subject: Handle topic changes --- src/irc/irc_client.hpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src/irc/irc_client.hpp') diff --git a/src/irc/irc_client.hpp b/src/irc/irc_client.hpp index 4038cdf..99ee6c0 100644 --- a/src/irc/irc_client.hpp +++ b/src/irc/irc_client.hpp @@ -218,6 +218,7 @@ static const std::unordered_map irc_callbacks = { {"PRIVMSG", &IrcClient::on_channel_message}, {"353", &IrcClient::set_and_forward_user_list}, {"332", &IrcClient::on_topic_received}, + {"TOPIC", &IrcClient::on_topic_received}, {"366", &IrcClient::on_channel_completely_joined}, {"001", &IrcClient::on_welcome_message}, {"PART", &IrcClient::on_part}, -- cgit v1.2.3 From 483e17020dc4f19223001ab36da0dc48a15a0d3e Mon Sep 17 00:00:00 2001 From: Florent Le Coz Date: Fri, 27 Dec 2013 11:49:28 +0100 Subject: Be verbose about the connection status, and some errors --- src/irc/irc_client.hpp | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'src/irc/irc_client.hpp') diff --git a/src/irc/irc_client.hpp b/src/irc/irc_client.hpp index 99ee6c0..e695e53 100644 --- a/src/irc/irc_client.hpp +++ b/src/irc/irc_client.hpp @@ -99,6 +99,12 @@ public: * Send the QUIT irc command */ void send_quit_command(); + /** + * Send a message to the gateway user, not generated by the IRC server, + * but that might be useful because we want to be verbose (for example we + * might want to notify the user about the connexion state) + */ + void send_gateway_message(const std::string& message, const std::string& from=""); /** * Forward the server message received from IRC to the XMPP component */ @@ -138,6 +144,14 @@ public: * received etc), send the self presence and topic to the XMPP user. */ void on_channel_completely_joined(const IrcMessage& message); + /** + * We tried to set an invalid nickname + */ + void on_erroneous_nickname(const IrcMessage& message); + /** + * Handles most errors from the server by just forwarding the message to the user. + */ + void on_generic_error(const IrcMessage& message); /** * When a message 001 is received, join the rooms we wanted to join, and set our actual nickname */ @@ -208,6 +222,8 @@ typedef void (IrcClient::*irc_callback_t)(const IrcMessage&); static const std::unordered_map irc_callbacks = { {"NOTICE", &IrcClient::forward_server_message}, + {"002", &IrcClient::forward_server_message}, + {"003", &IrcClient::forward_server_message}, {"RPL_MOTDSTART", &IrcClient::empty_motd}, {"375", &IrcClient::empty_motd}, {"RPL_MOTD", &IrcClient::on_motd_line}, @@ -220,6 +236,8 @@ static const std::unordered_map irc_callbacks = { {"332", &IrcClient::on_topic_received}, {"TOPIC", &IrcClient::on_topic_received}, {"366", &IrcClient::on_channel_completely_joined}, + {"432", &IrcClient::on_erroneous_nickname}, + {"461", &IrcClient::on_generic_error}, {"001", &IrcClient::on_welcome_message}, {"PART", &IrcClient::on_part}, {"ERROR", &IrcClient::on_error}, -- cgit v1.2.3 From 43cc60e4a9e2859fdf67c89e58ee18cf7571f186 Mon Sep 17 00:00:00 2001 From: Florent Le Coz Date: Fri, 27 Dec 2013 15:34:58 +0100 Subject: Handle nickname conflicts by sending the correct XMPP error presence --- src/irc/irc_client.hpp | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src/irc/irc_client.hpp') diff --git a/src/irc/irc_client.hpp b/src/irc/irc_client.hpp index e695e53..eced4b6 100644 --- a/src/irc/irc_client.hpp +++ b/src/irc/irc_client.hpp @@ -148,6 +148,11 @@ public: * We tried to set an invalid nickname */ void on_erroneous_nickname(const IrcMessage& message); + /** + * When the IRC servers denies our nickname because of a conflict. Send a + * presence conflict from all channels, because the name is server-wide. + */ + void on_nickname_conflict(const IrcMessage& message); /** * Handles most errors from the server by just forwarding the message to the user. */ @@ -237,6 +242,7 @@ static const std::unordered_map irc_callbacks = { {"TOPIC", &IrcClient::on_topic_received}, {"366", &IrcClient::on_channel_completely_joined}, {"432", &IrcClient::on_erroneous_nickname}, + {"433", &IrcClient::on_nickname_conflict}, {"461", &IrcClient::on_generic_error}, {"001", &IrcClient::on_welcome_message}, {"PART", &IrcClient::on_part}, -- cgit v1.2.3 From a075517824da7e82e1be7b67d615834851482861 Mon Sep 17 00:00:00 2001 From: Florent Le Coz Date: Fri, 27 Dec 2013 17:42:48 +0100 Subject: Basic isupport support CHANMODES and PREFIX only --- src/irc/irc_client.hpp | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'src/irc/irc_client.hpp') diff --git a/src/irc/irc_client.hpp b/src/irc/irc_client.hpp index eced4b6..a0258ee 100644 --- a/src/irc/irc_client.hpp +++ b/src/irc/irc_client.hpp @@ -8,7 +8,9 @@ #include #include +#include #include +#include class Bridge; @@ -109,6 +111,11 @@ public: * Forward the server message received from IRC to the XMPP component */ void forward_server_message(const IrcMessage& message); + /** + * When receiving the isupport informations. See + * http://www.irc.org/tech_docs/draft-brocklesby-irc-isupport-03.txt + */ + void on_isupport_message(const IrcMessage& message); /** * Just empty the motd we kept as a string */ @@ -208,11 +215,24 @@ private: */ std::vector channels_to_join; bool welcomed; + /** + * See http://www.irc.org/tech_docs/draft-brocklesby-irc-isupport-03.txt section 3.3 + * We store the possible chanmodes in this object. + * chanmodes[0] contains modes of type A, [1] of type B etc + */ + std::vector chanmodes; /** * Each motd line received is appended to this string, which we send when * the motd is completely received */ std::string motd; + /** + * See http://www.irc.org/tech_docs/draft-brocklesby-irc-isupport-03.txt section 3.14 + * The example given would be transformed into + * modes_to_prefix = {{'a', '&'}, {'b', '*'}} + */ + std::map prefix_to_mode; + IrcClient(const IrcClient&) = delete; IrcClient(IrcClient&&) = delete; IrcClient& operator=(const IrcClient&) = delete; @@ -229,6 +249,7 @@ static const std::unordered_map irc_callbacks = { {"NOTICE", &IrcClient::forward_server_message}, {"002", &IrcClient::forward_server_message}, {"003", &IrcClient::forward_server_message}, + {"005", &IrcClient::on_isupport_message}, {"RPL_MOTDSTART", &IrcClient::empty_motd}, {"375", &IrcClient::empty_motd}, {"RPL_MOTD", &IrcClient::on_motd_line}, -- cgit v1.2.3 From e840704b58a984351971e8034e74f5e9fdfaf114 Mon Sep 17 00:00:00 2001 From: Florent Le Coz Date: Sat, 4 Jan 2014 01:30:03 +0100 Subject: Convert received modes into roles and affiliations --- src/irc/irc_client.hpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'src/irc/irc_client.hpp') diff --git a/src/irc/irc_client.hpp b/src/irc/irc_client.hpp index a0258ee..96ded44 100644 --- a/src/irc/irc_client.hpp +++ b/src/irc/irc_client.hpp @@ -229,9 +229,14 @@ private: /** * See http://www.irc.org/tech_docs/draft-brocklesby-irc-isupport-03.txt section 3.14 * The example given would be transformed into - * modes_to_prefix = {{'a', '&'}, {'b', '*'}} + * modes_to_prefix = {{'&', 'a'}, {'*', 'b'}} */ std::map prefix_to_mode; + /** + * Available user modes, sorted from most significant to least significant + * (for example 'ahov' is a common order). + */ + std::vector sorted_user_modes; IrcClient(const IrcClient&) = delete; IrcClient(IrcClient&&) = delete; -- cgit v1.2.3 From fbec16f1a208881ea49923287aae27978d79681e Mon Sep 17 00:00:00 2001 From: Florent Le Coz Date: Sat, 4 Jan 2014 01:53:50 +0100 Subject: Possibility to change a channel's topic --- src/irc/irc_client.hpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src/irc/irc_client.hpp') diff --git a/src/irc/irc_client.hpp b/src/irc/irc_client.hpp index 96ded44..a058b19 100644 --- a/src/irc/irc_client.hpp +++ b/src/irc/irc_client.hpp @@ -97,6 +97,7 @@ public: * Send the KICK irc command */ void send_kick_command(const std::string& chan_name, const std::string& target, const std::string& reason); + void send_topic_command(const std::string& chan_name, const std::string& topic); /** * Send the QUIT irc command */ -- cgit v1.2.3 From 274859c096b25444d475d1319e9296a868ec258c Mon Sep 17 00:00:00 2001 From: Florent Le Coz Date: Sat, 8 Feb 2014 08:22:42 +0100 Subject: Handle most generic error IRC messages --- src/irc/irc_client.hpp | 50 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-) (limited to 'src/irc/irc_client.hpp') diff --git a/src/irc/irc_client.hpp b/src/irc/irc_client.hpp index a058b19..7380a8d 100644 --- a/src/irc/irc_client.hpp +++ b/src/irc/irc_client.hpp @@ -270,7 +270,6 @@ static const std::unordered_map irc_callbacks = { {"366", &IrcClient::on_channel_completely_joined}, {"432", &IrcClient::on_erroneous_nickname}, {"433", &IrcClient::on_nickname_conflict}, - {"461", &IrcClient::on_generic_error}, {"001", &IrcClient::on_welcome_message}, {"PART", &IrcClient::on_part}, {"ERROR", &IrcClient::on_error}, @@ -279,6 +278,55 @@ static const std::unordered_map irc_callbacks = { {"MODE", &IrcClient::on_mode}, {"PING", &IrcClient::send_pong_command}, {"KICK", &IrcClient::on_kick}, + + {"401", &IrcClient::on_generic_error}, + {"402", &IrcClient::on_generic_error}, + {"403", &IrcClient::on_generic_error}, + {"404", &IrcClient::on_generic_error}, + {"405", &IrcClient::on_generic_error}, + {"406", &IrcClient::on_generic_error}, + {"407", &IrcClient::on_generic_error}, + {"408", &IrcClient::on_generic_error}, + {"409", &IrcClient::on_generic_error}, + {"410", &IrcClient::on_generic_error}, + {"411", &IrcClient::on_generic_error}, + {"412", &IrcClient::on_generic_error}, + {"414", &IrcClient::on_generic_error}, + {"421", &IrcClient::on_generic_error}, + {"422", &IrcClient::on_generic_error}, + {"423", &IrcClient::on_generic_error}, + {"424", &IrcClient::on_generic_error}, + {"431", &IrcClient::on_generic_error}, + {"436", &IrcClient::on_generic_error}, + {"441", &IrcClient::on_generic_error}, + {"442", &IrcClient::on_generic_error}, + {"443", &IrcClient::on_generic_error}, + {"444", &IrcClient::on_generic_error}, + {"446", &IrcClient::on_generic_error}, + {"451", &IrcClient::on_generic_error}, + {"461", &IrcClient::on_generic_error}, + {"462", &IrcClient::on_generic_error}, + {"463", &IrcClient::on_generic_error}, + {"464", &IrcClient::on_generic_error}, + {"465", &IrcClient::on_generic_error}, + {"467", &IrcClient::on_generic_error}, + {"470", &IrcClient::on_generic_error}, + {"471", &IrcClient::on_generic_error}, + {"472", &IrcClient::on_generic_error}, + {"473", &IrcClient::on_generic_error}, + {"474", &IrcClient::on_generic_error}, + {"475", &IrcClient::on_generic_error}, + {"476", &IrcClient::on_generic_error}, + {"477", &IrcClient::on_generic_error}, + {"481", &IrcClient::on_generic_error}, + {"482", &IrcClient::on_generic_error}, + {"483", &IrcClient::on_generic_error}, + {"484", &IrcClient::on_generic_error}, + {"485", &IrcClient::on_generic_error}, + {"487", &IrcClient::on_generic_error}, + {"491", &IrcClient::on_generic_error}, + {"501", &IrcClient::on_generic_error}, + {"502", &IrcClient::on_generic_error}, }; #endif // IRC_CLIENT_INCLUDED -- cgit v1.2.3 From 190c4ff1762e5e762e913f98033369ed75ed5291 Mon Sep 17 00:00:00 2001 From: Florent Le Coz Date: Thu, 20 Feb 2014 02:19:50 +0100 Subject: QUIT the irc server when the last channel is left --- src/irc/irc_client.hpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src/irc/irc_client.hpp') diff --git a/src/irc/irc_client.hpp b/src/irc/irc_client.hpp index 7380a8d..5cd1403 100644 --- a/src/irc/irc_client.hpp +++ b/src/irc/irc_client.hpp @@ -101,7 +101,7 @@ public: /** * Send the QUIT irc command */ - void send_quit_command(); + void send_quit_command(const std::string& reason); /** * Send a message to the gateway user, not generated by the IRC server, * but that might be useful because we want to be verbose (for example we @@ -186,6 +186,10 @@ public: */ void on_channel_mode(const IrcMessage& message); void on_quit(const IrcMessage& message); + /** + * Return the number of joined channels + */ + size_t number_of_joined_channels() const; private: /** -- cgit v1.2.3 From 99aba5667d0d7ba6657f9c175a9342126bc4b0f2 Mon Sep 17 00:00:00 2001 From: Florent Le Coz Date: Sat, 22 Feb 2014 21:42:24 +0100 Subject: Connection to servers does not block the process anymore --- src/irc/irc_client.hpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/irc/irc_client.hpp') diff --git a/src/irc/irc_client.hpp b/src/irc/irc_client.hpp index 5cd1403..28a1424 100644 --- a/src/irc/irc_client.hpp +++ b/src/irc/irc_client.hpp @@ -29,6 +29,10 @@ public: * Connect to the IRC server */ void start(); + /** + * Called when the connection to the server cannot be established + */ + void on_connection_failed(const std::string& reason) override final; /** * Called when successfully connected to the server */ -- cgit v1.2.3 From 86d4347af8532ef85472e47c01d645fa5ad1b3b1 Mon Sep 17 00:00:00 2001 From: Florent Le Coz Date: Fri, 28 Feb 2014 01:14:38 +0100 Subject: Avoid unnecessary copies by recv()ing data directly into the expat buffer --- src/irc/irc_client.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/irc/irc_client.hpp') diff --git a/src/irc/irc_client.hpp b/src/irc/irc_client.hpp index 28a1424..908db8e 100644 --- a/src/irc/irc_client.hpp +++ b/src/irc/irc_client.hpp @@ -45,7 +45,7 @@ public: * Parse the data we have received so far and try to get one or more * complete messages from it. */ - void parse_in_buffer() override final; + void parse_in_buffer(const size_t) override final; /** * Return the channel with this name, create it if it does not yet exist */ -- cgit v1.2.3 From 020325dbb071f1735bceb80de9f982aefcd2de47 Mon Sep 17 00:00:00 2001 From: Florent Le Coz Date: Sun, 13 Apr 2014 15:37:56 +0200 Subject: [WIP] DummyIrcChannel --- src/irc/irc_client.hpp | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'src/irc/irc_client.hpp') diff --git a/src/irc/irc_client.hpp b/src/irc/irc_client.hpp index 908db8e..960d36f 100644 --- a/src/irc/irc_client.hpp +++ b/src/irc/irc_client.hpp @@ -194,6 +194,14 @@ public: * Return the number of joined channels */ size_t number_of_joined_channels() const; + /** + * Get a reference to the unique dummy channel + */ + DummyIrcChannel& get_dummy_channel(); + + const std::string& get_hostname() const { return this->hostname; } + std::string get_nick() const { return this->current_nick; } + bool is_welcomed() const { return this->welcomed; } private: /** @@ -216,6 +224,11 @@ private: * The list of joined channels, indexed by name */ std::unordered_map> channels; + /** + * A single channel with a iid of the form "hostname" (normal channel have + * an iid of the form "chan%hostname". + */ + DummyIrcChannel dummy_channel; /** * A list of chan we want to join, but we need a response 001 from * the server before sending the actual JOIN commands. So we just keep the @@ -223,6 +236,10 @@ private: * whenever the WELCOME message is received. */ std::vector channels_to_join; + /** + * This flag indicates that the server is completely joined (connection + * has been established, we are authentified and we have a nick) + */ bool welcomed; /** * See http://www.irc.org/tech_docs/draft-brocklesby-irc-isupport-03.txt section 3.3 -- cgit v1.2.3 From 5739d418e2b35dfc038fe1a12f8b5c7eeeed6868 Mon Sep 17 00:00:00 2001 From: Florent Le Coz Date: Tue, 15 Apr 2014 04:56:50 +0200 Subject: Better way to leave the dummy room --- src/irc/irc_client.hpp | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src/irc/irc_client.hpp') diff --git a/src/irc/irc_client.hpp b/src/irc/irc_client.hpp index 960d36f..811d416 100644 --- a/src/irc/irc_client.hpp +++ b/src/irc/irc_client.hpp @@ -198,6 +198,11 @@ public: * Get a reference to the unique dummy channel */ DummyIrcChannel& get_dummy_channel(); + /** + * 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); const std::string& get_hostname() const { return this->hostname; } std::string get_nick() const { return this->current_nick; } -- cgit v1.2.3 From 77a84fd2d99bcffd562f09c8235e5bcd365accb1 Mon Sep 17 00:00:00 2001 From: Florent Le Coz Date: Fri, 25 Apr 2014 00:35:57 +0200 Subject: NOTICE from channels are displayed in the channel, with a green "[notice]" --- src/irc/irc_client.hpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src/irc/irc_client.hpp') diff --git a/src/irc/irc_client.hpp b/src/irc/irc_client.hpp index 811d416..849190a 100644 --- a/src/irc/irc_client.hpp +++ b/src/irc/irc_client.hpp @@ -147,6 +147,10 @@ public: * When a channel message is received */ void on_channel_message(const IrcMessage& message); + /** + * A notice is received + */ + void on_notice(const IrcMessage& message); /** * Save the topic in the IrcChannel */ @@ -282,7 +286,7 @@ private: typedef void (IrcClient::*irc_callback_t)(const IrcMessage&); static const std::unordered_map irc_callbacks = { - {"NOTICE", &IrcClient::forward_server_message}, + {"NOTICE", &IrcClient::on_notice}, {"002", &IrcClient::forward_server_message}, {"003", &IrcClient::forward_server_message}, {"005", &IrcClient::on_isupport_message}, -- cgit v1.2.3 From 579ca4bdb6b8806d821daa2ee47d60260b64f0f8 Mon Sep 17 00:00:00 2001 From: Florent Le Coz Date: Wed, 7 May 2014 02:02:47 +0200 Subject: Forward iq version results to IRC --- src/irc/irc_client.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/irc/irc_client.hpp') diff --git a/src/irc/irc_client.hpp b/src/irc/irc_client.hpp index 849190a..a2e2afe 100644 --- a/src/irc/irc_client.hpp +++ b/src/irc/irc_client.hpp @@ -88,7 +88,7 @@ public: /** * Send a PRIVMSG command for an user */ - void send_private_message(const std::string& username, const std::string& body); + void send_private_message(const std::string& username, const std::string& body, const std::string& type); /** * Send the PART irc command */ -- cgit v1.2.3 From 5507adbe9473f4b41e52d16498f14850773e5e45 Mon Sep 17 00:00:00 2001 From: Florent Le Coz Date: Tue, 27 May 2014 01:01:44 +0200 Subject: SocketHandlers own the poller and add themself into it only when the socket is created MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We want to call socket() with the parameters provided by getaddrinfo, so we can’t addd the fd into the poller immediately. We need to wait the connection attempt, and then the SocketHandler can call add_socket_handler itself, if the connection succeeds, or is in progress. --- src/irc/irc_client.hpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/irc/irc_client.hpp') diff --git a/src/irc/irc_client.hpp b/src/irc/irc_client.hpp index a2e2afe..e70ee33 100644 --- a/src/irc/irc_client.hpp +++ b/src/irc/irc_client.hpp @@ -8,6 +8,7 @@ #include #include +#include #include #include #include @@ -23,7 +24,7 @@ class Bridge; class IrcClient: public SocketHandler { public: - explicit IrcClient(const std::string& hostname, const std::string& username, Bridge* bridge); + explicit IrcClient(std::shared_ptr poller, const std::string& hostname, const std::string& username, Bridge* bridge); ~IrcClient(); /** * Connect to the IRC server -- cgit v1.2.3 From 796af0531e0f5eb5fa2b800370338ede120a867d Mon Sep 17 00:00:00 2001 From: Florent Le Coz Date: Tue, 27 May 2014 02:17:25 +0200 Subject: Add support for CHANTYPES isupport element, to know the prefixes of channels --- src/irc/irc_client.hpp | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src/irc/irc_client.hpp') diff --git a/src/irc/irc_client.hpp b/src/irc/irc_client.hpp index e70ee33..e6fb393 100644 --- a/src/irc/irc_client.hpp +++ b/src/irc/irc_client.hpp @@ -12,6 +12,7 @@ #include #include #include +#include class Bridge; @@ -257,6 +258,11 @@ private: * chanmodes[0] contains modes of type A, [1] of type B etc */ std::vector chanmodes; + /** + * See http://www.irc.org/tech_docs/draft-brocklesby-irc-isupport-03.txt + * section 3.5 + */ + std::set chantypes; /** * Each motd line received is appended to this string, which we send when * the motd is completely received -- cgit v1.2.3 From c2311b2893f3db755b67c43e5ad60cef66b10ab2 Mon Sep 17 00:00:00 2001 From: Florent Le Coz Date: Fri, 30 May 2014 16:08:23 +0200 Subject: Send (every 240s) a PING command to all connected irc servers fix #2452 --- src/irc/irc_client.hpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src/irc/irc_client.hpp') diff --git a/src/irc/irc_client.hpp b/src/irc/irc_client.hpp index e6fb393..2f28c95 100644 --- a/src/irc/irc_client.hpp +++ b/src/irc/irc_client.hpp @@ -70,6 +70,7 @@ public: * Send the PONG irc command */ void send_pong_command(const IrcMessage& message); + void send_ping_command(); /** * Send the USER irc command */ -- cgit v1.2.3 From 23f32ba39ebe5e9bbdfc4dd00d9914c0f0447ef4 Mon Sep 17 00:00:00 2001 From: Florent Le Coz Date: Sun, 18 May 2014 20:23:08 +0200 Subject: Implement TLS support using Botan For now, it tries two TLS ports and then connects to the non-tls port. In the future we would like the user to be able to configure that. fix #2435 --- src/irc/irc_client.hpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'src/irc/irc_client.hpp') diff --git a/src/irc/irc_client.hpp b/src/irc/irc_client.hpp index 2f28c95..7dff1db 100644 --- a/src/irc/irc_client.hpp +++ b/src/irc/irc_client.hpp @@ -11,6 +11,7 @@ #include #include #include +#include #include #include @@ -19,8 +20,6 @@ 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. - * - * TODO: TLS support, maybe, but that's not high priority */ class IrcClient: public SocketHandler { @@ -280,6 +279,12 @@ private: * (for example 'ahov' is a common order). */ std::vector sorted_user_modes; + /** + * A list of ports to which we will try to connect, in reverse. Each port + * is associated with a boolean telling if we should use TLS or not if the + * connection succeeds on that port. + */ + std::stack> ports_to_try; IrcClient(const IrcClient&) = delete; IrcClient(IrcClient&&) = delete; -- cgit v1.2.3 From 04d999168ac4629f5e49939f3659b32b2da2563d Mon Sep 17 00:00:00 2001 From: Florent Le Coz Date: Wed, 2 Jul 2014 03:01:09 +0200 Subject: Add a level of inheritance above SocketHandler SocketHandler has been renamed to TCPSocketHandler SocketHandler is now a simple interface with a few methods, used only by Poller. This way we can inherite from the new SocketHandler class, to handle other types of sockets, and still make them manageable by the poller without any change in the Poller class. --- src/irc/irc_client.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/irc/irc_client.hpp') diff --git a/src/irc/irc_client.hpp b/src/irc/irc_client.hpp index 7dff1db..afa6437 100644 --- a/src/irc/irc_client.hpp +++ b/src/irc/irc_client.hpp @@ -5,7 +5,7 @@ #include #include -#include +#include #include #include @@ -21,7 +21,7 @@ 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 SocketHandler +class IrcClient: public TCPSocketHandler { public: explicit IrcClient(std::shared_ptr poller, const std::string& hostname, const std::string& username, Bridge* bridge); -- cgit v1.2.3 From 11a31db2d5bcc158bb8902e74f192dbc82827f53 Mon Sep 17 00:00:00 2001 From: Florent Le Coz Date: Tue, 15 Jul 2014 15:39:25 +0200 Subject: Send the reason of the connection close to the user --- src/irc/irc_client.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/irc/irc_client.hpp') diff --git a/src/irc/irc_client.hpp b/src/irc/irc_client.hpp index afa6437..88d2d72 100644 --- a/src/irc/irc_client.hpp +++ b/src/irc/irc_client.hpp @@ -41,7 +41,7 @@ public: /** * Close the connection, remove us from the poller */ - void on_connection_close() override final; + void on_connection_close(const std::string& error) override final; /** * Parse the data we have received so far and try to get one or more * complete messages from it. -- cgit v1.2.3 From 41e8a3ba9b57e67aec5d0d30112338664afbd6e4 Mon Sep 17 00:00:00 2001 From: Florent Le Coz Date: Fri, 8 Aug 2014 00:47:05 +0200 Subject: Send a proper error on IRC message 438 (nickname change too fast) fix #2576 --- src/irc/irc_client.hpp | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src/irc/irc_client.hpp') diff --git a/src/irc/irc_client.hpp b/src/irc/irc_client.hpp index 88d2d72..9bef04a 100644 --- a/src/irc/irc_client.hpp +++ b/src/irc/irc_client.hpp @@ -171,6 +171,10 @@ public: * presence conflict from all channels, because the name is server-wide. */ void on_nickname_conflict(const IrcMessage& message); + /** + * Idem, but for when the user changes their nickname too quickly + */ + void on_nickname_change_too_fast(const IrcMessage& message); /** * Handles most errors from the server by just forwarding the message to the user. */ @@ -317,6 +321,7 @@ static const std::unordered_map irc_callbacks = { {"366", &IrcClient::on_channel_completely_joined}, {"432", &IrcClient::on_erroneous_nickname}, {"433", &IrcClient::on_nickname_conflict}, + {"438", &IrcClient::on_nickname_change_too_fast}, {"001", &IrcClient::on_welcome_message}, {"PART", &IrcClient::on_part}, {"ERROR", &IrcClient::on_error}, -- cgit v1.2.3 From b79dbefbe71824d8d42c5034a6900644a0850c4c Mon Sep 17 00:00:00 2001 From: Florent Le Coz Date: Mon, 12 Jan 2015 22:50:06 +0100 Subject: If we sent a message to a user, their notices are considered private messages fix #2882 --- src/irc/irc_client.hpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/irc/irc_client.hpp') diff --git a/src/irc/irc_client.hpp b/src/irc/irc_client.hpp index 9bef04a..70d7955 100644 --- a/src/irc/irc_client.hpp +++ b/src/irc/irc_client.hpp @@ -289,6 +289,10 @@ private: * connection succeeds on that port. */ std::stack> ports_to_try; + /** + * A set of (lowercase) nicknames to which we sent a private message. + */ + std::set nicks_to_treat_as_private; IrcClient(const IrcClient&) = delete; IrcClient(IrcClient&&) = delete; -- cgit v1.2.3 From e4fcbd3030f033c24102db9f6b6abfb540332c9d Mon Sep 17 00:00:00 2001 From: Emmanuel Gil Peyrot Date: Wed, 14 Jan 2015 12:38:46 +0100 Subject: Add support for password-protected IRC rooms. --- src/irc/irc_client.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/irc/irc_client.hpp') diff --git a/src/irc/irc_client.hpp b/src/irc/irc_client.hpp index 70d7955..29da868 100644 --- a/src/irc/irc_client.hpp +++ b/src/irc/irc_client.hpp @@ -81,7 +81,7 @@ public: /** * Send the JOIN irc command. */ - void send_join_command(const std::string& chan_name); + void send_join_command(const std::string& chan_name, const std::string& password = ""); /** * Send a PRIVMSG command for a channel * Return true if the message was actually sent -- cgit v1.2.3 From 60569993b4532caffd8b1a6646292efbbd933585 Mon Sep 17 00:00:00 2001 From: Florent Le Coz Date: Wed, 14 Jan 2015 13:48:34 +0100 Subject: Make the password work when we join our first channel on that server Because we need to wait for the welcome message, when we connect to the server, before sending the JOIN command, we need to also save the value of the password to reuse it when we actually send the JOIN command --- src/irc/irc_client.hpp | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'src/irc/irc_client.hpp') diff --git a/src/irc/irc_client.hpp b/src/irc/irc_client.hpp index 29da868..578fce2 100644 --- a/src/irc/irc_client.hpp +++ b/src/irc/irc_client.hpp @@ -8,6 +8,7 @@ #include #include +#include #include #include #include @@ -81,7 +82,7 @@ public: /** * Send the JOIN irc command. */ - void send_join_command(const std::string& chan_name, const std::string& password = ""); + void send_join_command(const std::string& chan_name, const std::string& password); /** * Send a PRIVMSG command for a channel * Return true if the message was actually sent @@ -245,12 +246,13 @@ private: */ DummyIrcChannel dummy_channel; /** - * A list of chan we want to join, but we need a response 001 from - * the server before sending the actual JOIN commands. So we just keep the - * channel names in a list, and send the JOIN commands for each of them - * whenever the WELCOME message is received. + * A list of chan we want to join (tuples with the channel name and the + * password, if any), but we need a response 001 from the server before + * sending the actual JOIN commands. So we just keep the channel names in + * a list, and send the JOIN commands for each of them whenever the + * WELCOME message is received. */ - std::vector channels_to_join; + std::vector> channels_to_join; /** * This flag indicates that the server is completely joined (connection * has been established, we are authentified and we have a nick) -- cgit v1.2.3 From c01befb054075ab414fd602859e5999a138aa5bf Mon Sep 17 00:00:00 2001 From: Florent Le Coz Date: Thu, 26 Feb 2015 05:02:08 +0100 Subject: Implement room discovery using the LIST irc command ref #2472 --- src/irc/irc_client.hpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/irc/irc_client.hpp') diff --git a/src/irc/irc_client.hpp b/src/irc/irc_client.hpp index 578fce2..86edbab 100644 --- a/src/irc/irc_client.hpp +++ b/src/irc/irc_client.hpp @@ -104,6 +104,10 @@ public: * Send the KICK irc command */ void send_kick_command(const std::string& chan_name, const std::string& target, const std::string& reason); + /** + * Send the LIST irc command + */ + void send_list_command(); void send_topic_command(const std::string& chan_name, const std::string& topic); /** * Send the QUIT irc command -- cgit v1.2.3 From ffcce28c7711ff69e46445c466bd439362e3d0d4 Mon Sep 17 00:00:00 2001 From: Florent Le Coz Date: Tue, 24 Mar 2015 04:34:05 +0100 Subject: Do not log a warning when we receive a PONG command --- src/irc/irc_client.hpp | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src/irc/irc_client.hpp') diff --git a/src/irc/irc_client.hpp b/src/irc/irc_client.hpp index 86edbab..03951be 100644 --- a/src/irc/irc_client.hpp +++ b/src/irc/irc_client.hpp @@ -70,6 +70,11 @@ public: * Send the PONG irc command */ void send_pong_command(const IrcMessage& message); + /** + * Do nothing when we receive a PONG command (but also do not log that no + * handler exist) + */ + void on_pong(const IrcMessage& message); void send_ping_command(); /** * Send the USER irc command @@ -339,6 +344,7 @@ static const std::unordered_map irc_callbacks = { {"NICK", &IrcClient::on_nick}, {"MODE", &IrcClient::on_mode}, {"PING", &IrcClient::send_pong_command}, + {"PONG", &IrcClient::on_pong}, {"KICK", &IrcClient::on_kick}, {"401", &IrcClient::on_generic_error}, -- cgit v1.2.3 From 0a6b673b14efc4f623ea445045e6fc60e9842a25 Mon Sep 17 00:00:00 2001 From: Florent Le Coz Date: Thu, 7 May 2015 17:01:17 +0200 Subject: Support raw IRC messages Messages received on an IRC server JID are forwarded as raw IRC messages. fix #2486 --- src/irc/irc_client.hpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src/irc/irc_client.hpp') diff --git a/src/irc/irc_client.hpp b/src/irc/irc_client.hpp index 03951be..08021c1 100644 --- a/src/irc/irc_client.hpp +++ b/src/irc/irc_client.hpp @@ -66,6 +66,7 @@ public: * for send events to be ready) */ void send_message(IrcMessage&& message); + void send_raw(const std::string& txt); /** * Send the PONG irc command */ -- cgit v1.2.3 From 163ace553f3e65dcf9f97070faa5dbab0d31bac0 Mon Sep 17 00:00:00 2001 From: Florent Le Coz Date: Thu, 7 May 2015 17:17:01 +0200 Subject: Handle all unknown IRC command by forwarding the arguments as a message body MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This way, the users can receive the result of any IRC command (although not parsed nor formatted in anyway) when biboumi doesn’t support it fix #2884 --- src/irc/irc_client.hpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src/irc/irc_client.hpp') diff --git a/src/irc/irc_client.hpp b/src/irc/irc_client.hpp index 08021c1..4ab0fcb 100644 --- a/src/irc/irc_client.hpp +++ b/src/irc/irc_client.hpp @@ -211,6 +211,7 @@ public: */ void on_channel_mode(const IrcMessage& message); void on_quit(const IrcMessage& message); + void on_unknown_message(const IrcMessage& message); /** * Return the number of joined channels */ -- cgit v1.2.3 From fa466f33f4c8009e69fe0ebf31c7eef1c394377b Mon Sep 17 00:00:00 2001 From: Florent Le Coz Date: Tue, 19 May 2015 06:00:07 +0200 Subject: Ignore commands that flood the user with private messages when listing chans ref #2472 --- src/irc/irc_client.hpp | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'src/irc/irc_client.hpp') diff --git a/src/irc/irc_client.hpp b/src/irc/irc_client.hpp index 4ab0fcb..0d1604d 100644 --- a/src/irc/irc_client.hpp +++ b/src/irc/irc_client.hpp @@ -151,6 +151,23 @@ public: * IrcUsers in the IrcChannel */ void set_and_forward_user_list(const IrcMessage& message); + /** + * Signal the start of the LIST response. The RFC says its obsolete and + * “not used”, but I we receive it on some servers, so just ignore it. + */ + void on_rpl_liststart(const IrcMessage& message); + /** + * A single LIST response line (one channel) + * + * The command is handled in a wait_irc callback. This general handler is + * empty and just used to avoid sending a message stanza for each received + * channel. + */ + void on_rpl_list(const IrcMessage& message); + /** + * Signal the end of the LIST response, ignore. + */ + void on_rpl_listend(const IrcMessage& message); /** * Remember our nick and host, when we are joined to the channel. The list * of user comes after so we do not send the self-presence over XMPP yet. @@ -324,6 +341,12 @@ static const std::unordered_map irc_callbacks = { {"002", &IrcClient::forward_server_message}, {"003", &IrcClient::forward_server_message}, {"005", &IrcClient::on_isupport_message}, + {"RPL_LISTSTART", &IrcClient::on_rpl_liststart}, + {"321", &IrcClient::on_rpl_liststart}, + {"RPL_LIST", &IrcClient::on_rpl_list}, + {"322", &IrcClient::on_rpl_list}, + {"RPL_LISTEND", &IrcClient::on_rpl_listend}, + {"323", &IrcClient::on_rpl_listend}, {"RPL_MOTDSTART", &IrcClient::empty_motd}, {"375", &IrcClient::empty_motd}, {"RPL_MOTD", &IrcClient::on_motd_line}, -- cgit v1.2.3 From 4cfcc79114d89096219039104674d35ca1aba5ca Mon Sep 17 00:00:00 2001 From: Florent Le Coz Date: Sun, 6 Sep 2015 18:55:48 +0200 Subject: Check the number of argument of every IRC command received from the server Each IrcClient callback has a max and min size of argument, we call the callback only if the parsed message has a correct number of arguments, otherwise it is ignored (with a warning logged). --- src/irc/irc_client.hpp | 167 +++++++++++++++++++++++++------------------------ 1 file changed, 84 insertions(+), 83 deletions(-) (limited to 'src/irc/irc_client.hpp') diff --git a/src/irc/irc_client.hpp b/src/irc/irc_client.hpp index 0d1604d..a3f69a0 100644 --- a/src/irc/irc_client.hpp +++ b/src/irc/irc_client.hpp @@ -336,90 +336,91 @@ private: */ typedef void (IrcClient::*irc_callback_t)(const IrcMessage&); -static const std::unordered_map irc_callbacks = { - {"NOTICE", &IrcClient::on_notice}, - {"002", &IrcClient::forward_server_message}, - {"003", &IrcClient::forward_server_message}, - {"005", &IrcClient::on_isupport_message}, - {"RPL_LISTSTART", &IrcClient::on_rpl_liststart}, - {"321", &IrcClient::on_rpl_liststart}, - {"RPL_LIST", &IrcClient::on_rpl_list}, - {"322", &IrcClient::on_rpl_list}, - {"RPL_LISTEND", &IrcClient::on_rpl_listend}, - {"323", &IrcClient::on_rpl_listend}, - {"RPL_MOTDSTART", &IrcClient::empty_motd}, - {"375", &IrcClient::empty_motd}, - {"RPL_MOTD", &IrcClient::on_motd_line}, - {"372", &IrcClient::on_motd_line}, - {"RPL_MOTDEND", &IrcClient::send_motd}, - {"376", &IrcClient::send_motd}, - {"JOIN", &IrcClient::on_channel_join}, - {"PRIVMSG", &IrcClient::on_channel_message}, - {"353", &IrcClient::set_and_forward_user_list}, - {"332", &IrcClient::on_topic_received}, - {"TOPIC", &IrcClient::on_topic_received}, - {"366", &IrcClient::on_channel_completely_joined}, - {"432", &IrcClient::on_erroneous_nickname}, - {"433", &IrcClient::on_nickname_conflict}, - {"438", &IrcClient::on_nickname_change_too_fast}, - {"001", &IrcClient::on_welcome_message}, - {"PART", &IrcClient::on_part}, - {"ERROR", &IrcClient::on_error}, - {"QUIT", &IrcClient::on_quit}, - {"NICK", &IrcClient::on_nick}, - {"MODE", &IrcClient::on_mode}, - {"PING", &IrcClient::send_pong_command}, - {"PONG", &IrcClient::on_pong}, - {"KICK", &IrcClient::on_kick}, +static const std::unordered_map>> irc_callbacks = { + {"NOTICE", {&IrcClient::on_notice, {2, 0}}}, + {"002", {&IrcClient::forward_server_message, {2, 0}}}, + {"003", {&IrcClient::forward_server_message, {2, 0}}}, + {"005", {&IrcClient::on_isupport_message, {0, 0}}}, + {"RPL_LISTSTART", {&IrcClient::on_rpl_liststart, {0, 0}}}, + {"321", {&IrcClient::on_rpl_liststart, {0, 0}}}, + {"RPL_LIST", {&IrcClient::on_rpl_list, {0, 0}}}, + {"322", {&IrcClient::on_rpl_list, {0, 0}}}, + {"RPL_LISTEND", {&IrcClient::on_rpl_listend, {0, 0}}}, + {"323", {&IrcClient::on_rpl_listend, {0, 0}}}, + {"RPL_MOTDSTART", {&IrcClient::empty_motd, {0, 0}}}, + {"375", {&IrcClient::empty_motd, {0, 0}}}, + {"RPL_MOTD", {&IrcClient::on_motd_line, {2, 0}}}, + {"372", {&IrcClient::on_motd_line, {2, 0}}}, + {"RPL_MOTDEND", {&IrcClient::send_motd, {0, 0}}}, + {"376", {&IrcClient::send_motd, {0, 0}}}, + {"JOIN", {&IrcClient::on_channel_join, {1, 0}}}, + {"PRIVMSG", {&IrcClient::on_channel_message, {2, 0}}}, + {"353", {&IrcClient::set_and_forward_user_list, {4, 0}}}, + {"332", {&IrcClient::on_topic_received, {2, 0}}}, + {"TOPIC", {&IrcClient::on_topic_received, {2, 0}}}, + {"366", {&IrcClient::on_channel_completely_joined, {2, 0}}}, + {"432", {&IrcClient::on_erroneous_nickname, {2, 0}}}, + {"433", {&IrcClient::on_nickname_conflict, {2, 0}}}, + {"438", {&IrcClient::on_nickname_change_too_fast, {2, 0}}}, + {"001", {&IrcClient::on_welcome_message, {1, 0}}}, + {"PART", {&IrcClient::on_part, {1, 0}}}, + {"ERROR", {&IrcClient::on_error, {1, 0}}}, + {"QUIT", {&IrcClient::on_quit, {0, 0}}}, + {"NICK", {&IrcClient::on_nick, {1, 0}}}, + {"MODE", {&IrcClient::on_mode, {1, 0}}}, + {"PING", {&IrcClient::send_pong_command, {1, 0}}}, + {"PONG", {&IrcClient::on_pong, {0, 0}}}, + {"KICK", {&IrcClient::on_kick, {3, 0}}}, - {"401", &IrcClient::on_generic_error}, - {"402", &IrcClient::on_generic_error}, - {"403", &IrcClient::on_generic_error}, - {"404", &IrcClient::on_generic_error}, - {"405", &IrcClient::on_generic_error}, - {"406", &IrcClient::on_generic_error}, - {"407", &IrcClient::on_generic_error}, - {"408", &IrcClient::on_generic_error}, - {"409", &IrcClient::on_generic_error}, - {"410", &IrcClient::on_generic_error}, - {"411", &IrcClient::on_generic_error}, - {"412", &IrcClient::on_generic_error}, - {"414", &IrcClient::on_generic_error}, - {"421", &IrcClient::on_generic_error}, - {"422", &IrcClient::on_generic_error}, - {"423", &IrcClient::on_generic_error}, - {"424", &IrcClient::on_generic_error}, - {"431", &IrcClient::on_generic_error}, - {"436", &IrcClient::on_generic_error}, - {"441", &IrcClient::on_generic_error}, - {"442", &IrcClient::on_generic_error}, - {"443", &IrcClient::on_generic_error}, - {"444", &IrcClient::on_generic_error}, - {"446", &IrcClient::on_generic_error}, - {"451", &IrcClient::on_generic_error}, - {"461", &IrcClient::on_generic_error}, - {"462", &IrcClient::on_generic_error}, - {"463", &IrcClient::on_generic_error}, - {"464", &IrcClient::on_generic_error}, - {"465", &IrcClient::on_generic_error}, - {"467", &IrcClient::on_generic_error}, - {"470", &IrcClient::on_generic_error}, - {"471", &IrcClient::on_generic_error}, - {"472", &IrcClient::on_generic_error}, - {"473", &IrcClient::on_generic_error}, - {"474", &IrcClient::on_generic_error}, - {"475", &IrcClient::on_generic_error}, - {"476", &IrcClient::on_generic_error}, - {"477", &IrcClient::on_generic_error}, - {"481", &IrcClient::on_generic_error}, - {"482", &IrcClient::on_generic_error}, - {"483", &IrcClient::on_generic_error}, - {"484", &IrcClient::on_generic_error}, - {"485", &IrcClient::on_generic_error}, - {"487", &IrcClient::on_generic_error}, - {"491", &IrcClient::on_generic_error}, - {"501", &IrcClient::on_generic_error}, - {"502", &IrcClient::on_generic_error}, + {"401", {&IrcClient::on_generic_error, {2, 0}}}, + {"402", {&IrcClient::on_generic_error, {2, 0}}}, + {"403", {&IrcClient::on_generic_error, {2, 0}}}, + {"404", {&IrcClient::on_generic_error, {2, 0}}}, + {"405", {&IrcClient::on_generic_error, {2, 0}}}, + {"406", {&IrcClient::on_generic_error, {2, 0}}}, + {"407", {&IrcClient::on_generic_error, {2, 0}}}, + {"408", {&IrcClient::on_generic_error, {2, 0}}}, + {"409", {&IrcClient::on_generic_error, {2, 0}}}, + {"410", {&IrcClient::on_generic_error, {2, 0}}}, + {"411", {&IrcClient::on_generic_error, {2, 0}}}, + {"412", {&IrcClient::on_generic_error, {2, 0}}}, + {"414", {&IrcClient::on_generic_error, {2, 0}}}, + {"421", {&IrcClient::on_generic_error, {2, 0}}}, + {"422", {&IrcClient::on_generic_error, {2, 0}}}, + {"423", {&IrcClient::on_generic_error, {2, 0}}}, + {"424", {&IrcClient::on_generic_error, {2, 0}}}, + {"431", {&IrcClient::on_generic_error, {2, 0}}}, + {"436", {&IrcClient::on_generic_error, {2, 0}}}, + {"441", {&IrcClient::on_generic_error, {2, 0}}}, + {"442", {&IrcClient::on_generic_error, {2, 0}}}, + {"443", {&IrcClient::on_generic_error, {2, 0}}}, + {"444", {&IrcClient::on_generic_error, {2, 0}}}, + {"446", {&IrcClient::on_generic_error, {2, 0}}}, + {"451", {&IrcClient::on_generic_error, {2, 0}}}, + {"461", {&IrcClient::on_generic_error, {2, 0}}}, + {"462", {&IrcClient::on_generic_error, {2, 0}}}, + {"463", {&IrcClient::on_generic_error, {2, 0}}}, + {"464", {&IrcClient::on_generic_error, {2, 0}}}, + {"465", {&IrcClient::on_generic_error, {2, 0}}}, + {"467", {&IrcClient::on_generic_error, {2, 0}}}, + {"470", {&IrcClient::on_generic_error, {2, 0}}}, + {"471", {&IrcClient::on_generic_error, {2, 0}}}, + {"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}}}, + {"482", {&IrcClient::on_generic_error, {2, 0}}}, + {"483", {&IrcClient::on_generic_error, {2, 0}}}, + {"484", {&IrcClient::on_generic_error, {2, 0}}}, + {"485", {&IrcClient::on_generic_error, {2, 0}}}, + {"487", {&IrcClient::on_generic_error, {2, 0}}}, + {"491", {&IrcClient::on_generic_error, {2, 0}}}, + {"501", {&IrcClient::on_generic_error, {2, 0}}}, + {"502", {&IrcClient::on_generic_error, {2, 0}}}, }; #endif // IRC_CLIENT_INCLUDED -- cgit v1.2.3 From 532228a3cefd92fe43ad0f52149b7f0f5ab5cb79 Mon Sep 17 00:00:00 2001 From: Florent Le Coz Date: Fri, 18 Sep 2015 22:02:01 +0200 Subject: =?UTF-8?q?Send=20a=20PASS=20IRC=20command=20if=20the=20=E2=80=9Cp?= =?UTF-8?q?ass=E2=80=9D=20config=20is=20sot=20by=20a=20user,=20on=20an=20I?= =?UTF-8?q?RC=20server?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fix #3068 --- src/irc/irc_client.hpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src/irc/irc_client.hpp') diff --git a/src/irc/irc_client.hpp b/src/irc/irc_client.hpp index a3f69a0..4e61d14 100644 --- a/src/irc/irc_client.hpp +++ b/src/irc/irc_client.hpp @@ -85,6 +85,7 @@ public: * Send the NICK irc command */ void send_nick_command(const std::string& username); + void send_pass_command(const std::string& password); /** * Send the JOIN irc command. */ -- cgit v1.2.3 From 6512f830fa2baa85a7c688843ebd42eb528e2ad6 Mon Sep 17 00:00:00 2001 From: Florent Le Coz Date: Mon, 12 Oct 2015 16:35:50 +0200 Subject: The realname is also saved as an IrcClient member --- src/irc/irc_client.hpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'src/irc/irc_client.hpp') diff --git a/src/irc/irc_client.hpp b/src/irc/irc_client.hpp index 4e61d14..a6b51ce 100644 --- a/src/irc/irc_client.hpp +++ b/src/irc/irc_client.hpp @@ -254,9 +254,13 @@ private: */ const std::string hostname; /** - * The user name used in the USER irc command + * The username used in the USER irc command */ - const std::string username; + std::string username; + /** + * The realname used in the USER irc command + */ + std::string realname; /** * Our current nickname on the server */ -- cgit v1.2.3 From 1aa2c2d857037f3274297527ca3971a75203d39c Mon Sep 17 00:00:00 2001 From: Florent Le Coz Date: Mon, 12 Oct 2015 17:14:29 +0200 Subject: Introduce the realname_from_jid option MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When set to true, the realname and username are extracted (by default) from the user’s JID fix #3136 --- src/irc/irc_client.hpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/irc/irc_client.hpp') diff --git a/src/irc/irc_client.hpp b/src/irc/irc_client.hpp index a6b51ce..7a04164 100644 --- a/src/irc/irc_client.hpp +++ b/src/irc/irc_client.hpp @@ -25,7 +25,9 @@ class Bridge; class IrcClient: public TCPSocketHandler { public: - explicit IrcClient(std::shared_ptr poller, const std::string& hostname, const std::string& username, Bridge* bridge); + explicit IrcClient(std::shared_ptr poller, const std::string& hostname, + const std::string& nickname, const std::string& username, + const std::string& realname, Bridge* bridge); ~IrcClient(); /** * Connect to the IRC server -- cgit v1.2.3 From 34fc1d4010d23be947c00fc956f2bdded2374cee Mon Sep 17 00:00:00 2001 From: Florent Le Coz Date: Sat, 31 Oct 2015 06:17:35 +0100 Subject: Implement a basic webirc support See https://kiwiirc.com/docs/webirc fix #3135 --- src/irc/irc_client.hpp | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) (limited to 'src/irc/irc_client.hpp') diff --git a/src/irc/irc_client.hpp b/src/irc/irc_client.hpp index 7a04164..885ec84 100644 --- a/src/irc/irc_client.hpp +++ b/src/irc/irc_client.hpp @@ -6,6 +6,7 @@ #include #include +#include #include #include @@ -27,7 +28,8 @@ class IrcClient: public TCPSocketHandler public: explicit IrcClient(std::shared_ptr poller, const std::string& hostname, const std::string& nickname, const std::string& username, - const std::string& realname, Bridge* bridge); + const std::string& realname, const std::string& user_hostname, + Bridge* bridge); ~IrcClient(); /** * Connect to the IRC server @@ -88,6 +90,7 @@ public: */ void send_nick_command(const std::string& username); void send_pass_command(const std::string& password); + void send_webirc_command(const std::string& password, const std::string& user_ip); /** * Send the JOIN irc command. */ @@ -250,11 +253,18 @@ public: std::string get_nick() const { return this->current_nick; } bool is_welcomed() const { return this->welcomed; } + const Resolver& get_resolver() const; + private: /** * The hostname of the server we are connected to. */ const std::string hostname; + /** + * The hostname of the user. This is used in the USER and the WEBIRC + * commands, but only the one in WEBIRC will be used by the IRC server. + */ + const std::string user_hostname; /** * The username used in the USER irc command */ @@ -330,6 +340,11 @@ private: * A set of (lowercase) nicknames to which we sent a private message. */ std::set nicks_to_treat_as_private; + /** + * DNS resolver, used to resolve the hostname of the user if we are using + * the WebIRC protocole. + */ + Resolver dns_resolver; IrcClient(const IrcClient&) = delete; IrcClient(IrcClient&&) = delete; -- cgit v1.2.3 From 6fb4cf5e4db2babad567524df6be3e2798a0fb63 Mon Sep 17 00:00:00 2001 From: Florent Le Coz Date: Sat, 31 Oct 2015 06:23:51 +0100 Subject: Do not forget to implement a method --- src/irc/irc_client.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/irc/irc_client.hpp') diff --git a/src/irc/irc_client.hpp b/src/irc/irc_client.hpp index 885ec84..cdae0aa 100644 --- a/src/irc/irc_client.hpp +++ b/src/irc/irc_client.hpp @@ -253,7 +253,7 @@ public: std::string get_nick() const { return this->current_nick; } bool is_welcomed() const { return this->welcomed; } - const Resolver& get_resolver() const; + const Resolver& get_resolver() const { return this->dns_resolver; } private: /** -- cgit v1.2.3 From e8386bd14e9783f0bef39bdf577545522e33e719 Mon Sep 17 00:00:00 2001 From: Florent Le Coz Date: Tue, 3 Nov 2015 16:56:38 +0100 Subject: Provide an adhoc option to let user pass the cert verif for some IRC servers --- src/irc/irc_client.hpp | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/irc/irc_client.hpp') diff --git a/src/irc/irc_client.hpp b/src/irc/irc_client.hpp index cdae0aa..733fc92 100644 --- a/src/irc/irc_client.hpp +++ b/src/irc/irc_client.hpp @@ -52,6 +52,9 @@ public: * complete messages from it. */ void parse_in_buffer(const size_t) override final; +#ifdef BOTAN_FOUND + virtual bool abort_on_invalid_cert() const override final; +#endif /** * Return the channel with this name, create it if it does not yet exist */ -- cgit v1.2.3 From 7e2427148e9023483f266cd3ac4e167d50320796 Mon Sep 17 00:00:00 2001 From: Florent Le Coz Date: Mon, 21 Dec 2015 20:45:40 +0100 Subject: =?UTF-8?q?Use=20references=20instead=20of=20raw=20pointer,=20to?= =?UTF-8?q?=20store=20the=20=E2=80=9Cparent=E2=80=9D=20object?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In Bridge and IrcClient --- src/irc/irc_client.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/irc/irc_client.hpp') diff --git a/src/irc/irc_client.hpp b/src/irc/irc_client.hpp index 733fc92..7c2a43f 100644 --- a/src/irc/irc_client.hpp +++ b/src/irc/irc_client.hpp @@ -29,7 +29,7 @@ public: explicit IrcClient(std::shared_ptr poller, const std::string& hostname, const std::string& nickname, const std::string& username, const std::string& realname, const std::string& user_hostname, - Bridge* bridge); + Bridge& bridge); ~IrcClient(); /** * Connect to the IRC server @@ -281,9 +281,9 @@ private: */ std::string current_nick; /** - * Raw pointer because the bridge owns us. + * To communicate back with the bridge */ - Bridge* bridge; + Bridge& bridge; /** * The list of joined channels, indexed by name */ -- cgit v1.2.3 From 0a352e557d2a0760601847a97c562759fb04d529 Mon Sep 17 00:00:00 2001 From: Florent Le Coz Date: Tue, 2 Feb 2016 17:41:38 +0100 Subject: Move the irc callbacks into the cpp file --- src/irc/irc_client.hpp | 93 -------------------------------------------------- 1 file changed, 93 deletions(-) (limited to 'src/irc/irc_client.hpp') diff --git a/src/irc/irc_client.hpp b/src/irc/irc_client.hpp index 7c2a43f..628f547 100644 --- a/src/irc/irc_client.hpp +++ b/src/irc/irc_client.hpp @@ -355,97 +355,4 @@ private: IrcClient& operator=(IrcClient&&) = delete; }; -/** - * Define a map of functions to be called for each IRC command we can - * handle. - */ -typedef void (IrcClient::*irc_callback_t)(const IrcMessage&); - -static const std::unordered_map>> irc_callbacks = { - {"NOTICE", {&IrcClient::on_notice, {2, 0}}}, - {"002", {&IrcClient::forward_server_message, {2, 0}}}, - {"003", {&IrcClient::forward_server_message, {2, 0}}}, - {"005", {&IrcClient::on_isupport_message, {0, 0}}}, - {"RPL_LISTSTART", {&IrcClient::on_rpl_liststart, {0, 0}}}, - {"321", {&IrcClient::on_rpl_liststart, {0, 0}}}, - {"RPL_LIST", {&IrcClient::on_rpl_list, {0, 0}}}, - {"322", {&IrcClient::on_rpl_list, {0, 0}}}, - {"RPL_LISTEND", {&IrcClient::on_rpl_listend, {0, 0}}}, - {"323", {&IrcClient::on_rpl_listend, {0, 0}}}, - {"RPL_MOTDSTART", {&IrcClient::empty_motd, {0, 0}}}, - {"375", {&IrcClient::empty_motd, {0, 0}}}, - {"RPL_MOTD", {&IrcClient::on_motd_line, {2, 0}}}, - {"372", {&IrcClient::on_motd_line, {2, 0}}}, - {"RPL_MOTDEND", {&IrcClient::send_motd, {0, 0}}}, - {"376", {&IrcClient::send_motd, {0, 0}}}, - {"JOIN", {&IrcClient::on_channel_join, {1, 0}}}, - {"PRIVMSG", {&IrcClient::on_channel_message, {2, 0}}}, - {"353", {&IrcClient::set_and_forward_user_list, {4, 0}}}, - {"332", {&IrcClient::on_topic_received, {2, 0}}}, - {"TOPIC", {&IrcClient::on_topic_received, {2, 0}}}, - {"366", {&IrcClient::on_channel_completely_joined, {2, 0}}}, - {"432", {&IrcClient::on_erroneous_nickname, {2, 0}}}, - {"433", {&IrcClient::on_nickname_conflict, {2, 0}}}, - {"438", {&IrcClient::on_nickname_change_too_fast, {2, 0}}}, - {"001", {&IrcClient::on_welcome_message, {1, 0}}}, - {"PART", {&IrcClient::on_part, {1, 0}}}, - {"ERROR", {&IrcClient::on_error, {1, 0}}}, - {"QUIT", {&IrcClient::on_quit, {0, 0}}}, - {"NICK", {&IrcClient::on_nick, {1, 0}}}, - {"MODE", {&IrcClient::on_mode, {1, 0}}}, - {"PING", {&IrcClient::send_pong_command, {1, 0}}}, - {"PONG", {&IrcClient::on_pong, {0, 0}}}, - {"KICK", {&IrcClient::on_kick, {3, 0}}}, - - {"401", {&IrcClient::on_generic_error, {2, 0}}}, - {"402", {&IrcClient::on_generic_error, {2, 0}}}, - {"403", {&IrcClient::on_generic_error, {2, 0}}}, - {"404", {&IrcClient::on_generic_error, {2, 0}}}, - {"405", {&IrcClient::on_generic_error, {2, 0}}}, - {"406", {&IrcClient::on_generic_error, {2, 0}}}, - {"407", {&IrcClient::on_generic_error, {2, 0}}}, - {"408", {&IrcClient::on_generic_error, {2, 0}}}, - {"409", {&IrcClient::on_generic_error, {2, 0}}}, - {"410", {&IrcClient::on_generic_error, {2, 0}}}, - {"411", {&IrcClient::on_generic_error, {2, 0}}}, - {"412", {&IrcClient::on_generic_error, {2, 0}}}, - {"414", {&IrcClient::on_generic_error, {2, 0}}}, - {"421", {&IrcClient::on_generic_error, {2, 0}}}, - {"422", {&IrcClient::on_generic_error, {2, 0}}}, - {"423", {&IrcClient::on_generic_error, {2, 0}}}, - {"424", {&IrcClient::on_generic_error, {2, 0}}}, - {"431", {&IrcClient::on_generic_error, {2, 0}}}, - {"436", {&IrcClient::on_generic_error, {2, 0}}}, - {"441", {&IrcClient::on_generic_error, {2, 0}}}, - {"442", {&IrcClient::on_generic_error, {2, 0}}}, - {"443", {&IrcClient::on_generic_error, {2, 0}}}, - {"444", {&IrcClient::on_generic_error, {2, 0}}}, - {"446", {&IrcClient::on_generic_error, {2, 0}}}, - {"451", {&IrcClient::on_generic_error, {2, 0}}}, - {"461", {&IrcClient::on_generic_error, {2, 0}}}, - {"462", {&IrcClient::on_generic_error, {2, 0}}}, - {"463", {&IrcClient::on_generic_error, {2, 0}}}, - {"464", {&IrcClient::on_generic_error, {2, 0}}}, - {"465", {&IrcClient::on_generic_error, {2, 0}}}, - {"467", {&IrcClient::on_generic_error, {2, 0}}}, - {"470", {&IrcClient::on_generic_error, {2, 0}}}, - {"471", {&IrcClient::on_generic_error, {2, 0}}}, - {"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}}}, - {"482", {&IrcClient::on_generic_error, {2, 0}}}, - {"483", {&IrcClient::on_generic_error, {2, 0}}}, - {"484", {&IrcClient::on_generic_error, {2, 0}}}, - {"485", {&IrcClient::on_generic_error, {2, 0}}}, - {"487", {&IrcClient::on_generic_error, {2, 0}}}, - {"491", {&IrcClient::on_generic_error, {2, 0}}}, - {"501", {&IrcClient::on_generic_error, {2, 0}}}, - {"502", {&IrcClient::on_generic_error, {2, 0}}}, -}; - #endif // IRC_CLIENT_INCLUDED -- cgit v1.2.3 From 464261d4ed462f5d74507fe4d17bc5f76b5f726d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Mon, 11 Apr 2016 17:14:39 +0200 Subject: Support RPL_NOTPIC and 005 --- src/irc/irc_client.hpp | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'src/irc/irc_client.hpp') diff --git a/src/irc/irc_client.hpp b/src/irc/irc_client.hpp index 628f547..5efecc6 100644 --- a/src/irc/irc_client.hpp +++ b/src/irc/irc_client.hpp @@ -143,6 +143,10 @@ public: * http://www.irc.org/tech_docs/draft-brocklesby-irc-isupport-03.txt */ void on_isupport_message(const IrcMessage& message); + /** + * Does nothing yet. Isn’t that duplicating features from 005? + */ + void on_server_myinfo(const IrcMessage& message); /** * Just empty the motd we kept as a string */ @@ -194,6 +198,10 @@ public: * Save the topic in the IrcChannel */ void on_topic_received(const IrcMessage& message); + /** + * Empty the topic + */ + void on_empty_topic(const IrcMessage& message); /** * The channel has been completely joined (self presence, topic, all names * received etc), send the self presence and topic to the XMPP user. -- cgit v1.2.3 From 04d28f968b227067e77e365d317fc251d3c965f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Tue, 19 Apr 2016 02:43:26 +0200 Subject: Forward the topic authors, handle the author from 333 messages fix #2 --- src/irc/irc_client.hpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/irc/irc_client.hpp') diff --git a/src/irc/irc_client.hpp b/src/irc/irc_client.hpp index 5efecc6..ceaa860 100644 --- a/src/irc/irc_client.hpp +++ b/src/irc/irc_client.hpp @@ -198,6 +198,10 @@ public: * Save the topic in the IrcChannel */ void on_topic_received(const IrcMessage& message); + /** + * Save the topic author in the IrcChannel + */ + void on_topic_who_time_received(const IrcMessage& message); /** * Empty the topic */ -- cgit v1.2.3 From af42073830087d97385e507f27f601e8769541b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Wed, 4 May 2016 14:16:40 +0200 Subject: Style fix Move all constructors at the top of classes --- src/irc/irc_client.hpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'src/irc/irc_client.hpp') diff --git a/src/irc/irc_client.hpp b/src/irc/irc_client.hpp index ceaa860..7af097c 100644 --- a/src/irc/irc_client.hpp +++ b/src/irc/irc_client.hpp @@ -31,6 +31,12 @@ public: const std::string& realname, const std::string& user_hostname, Bridge& bridge); ~IrcClient(); + + IrcClient(const IrcClient&) = delete; + IrcClient(IrcClient&&) = delete; + IrcClient& operator=(const IrcClient&) = delete; + IrcClient& operator=(IrcClient&&) = delete; + /** * Connect to the IRC server */ @@ -360,11 +366,6 @@ private: * the WebIRC protocole. */ Resolver dns_resolver; - - IrcClient(const IrcClient&) = delete; - IrcClient(IrcClient&&) = delete; - IrcClient& operator=(const IrcClient&) = delete; - IrcClient& operator=(IrcClient&&) = delete; }; #endif // IRC_CLIENT_INCLUDED -- cgit v1.2.3 From 2d11a5f49454717c404b25825f18e696281207d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Wed, 8 Jun 2016 01:32:39 +0200 Subject: Support multiple nick session, except for IQs ref #2556 --- src/irc/irc_client.hpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/irc/irc_client.hpp') diff --git a/src/irc/irc_client.hpp b/src/irc/irc_client.hpp index 7af097c..f075ce6 100644 --- a/src/irc/irc_client.hpp +++ b/src/irc/irc_client.hpp @@ -276,6 +276,8 @@ public: const Resolver& get_resolver() const { return this->dns_resolver; } + const std::vector& get_sorted_user_modes() const { return sorted_user_modes; } + private: /** * The hostname of the server we are connected to. -- cgit v1.2.3 From 849c50f9f33d5a391f623272b007810c816aca68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Wed, 15 Jun 2016 15:47:05 +0200 Subject: Save our own host, as reported by the server --- src/irc/irc_client.hpp | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'src/irc/irc_client.hpp') diff --git a/src/irc/irc_client.hpp b/src/irc/irc_client.hpp index f075ce6..718d8a7 100644 --- a/src/irc/irc_client.hpp +++ b/src/irc/irc_client.hpp @@ -217,6 +217,10 @@ public: * received etc), send the self presence and topic to the XMPP user. */ void on_channel_completely_joined(const IrcMessage& message); + /** + * Save our own host, as reported by the server + */ + void on_own_host_received(const IrcMessage& message); /** * We tried to set an invalid nickname */ @@ -283,6 +287,12 @@ private: * The hostname of the server we are connected to. */ const std::string hostname; + /** + * Our own host, as reported by the IRC server. + * By default (and if it is not overridden by the server), it is a + * meaningless string, with the maximum allowed size + */ + std::string own_host{63, '*'}; /** * The hostname of the user. This is used in the USER and the WEBIRC * commands, but only the one in WEBIRC will be used by the IRC server. -- cgit v1.2.3 From 81f8f45b371d1a0ef72c2768fbd1f9188fe83616 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Mon, 4 Jul 2016 17:53:53 +0200 Subject: Replace all include guards by #pragma once MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It’s $CURRENT_YEAR --- src/irc/irc_client.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/irc/irc_client.hpp') diff --git a/src/irc/irc_client.hpp b/src/irc/irc_client.hpp index 718d8a7..fc3918e 100644 --- a/src/irc/irc_client.hpp +++ b/src/irc/irc_client.hpp @@ -1,5 +1,5 @@ -#ifndef IRC_CLIENT_INCLUDED -# define IRC_CLIENT_INCLUDED +#pragma once + #include #include @@ -380,4 +380,4 @@ private: Resolver dns_resolver; }; -#endif // IRC_CLIENT_INCLUDED + -- cgit v1.2.3