pidgin/pidgin

ebe4ff278b02
Parents 95c0077fe6bb
Children 3bc9948e9f3c
Use the parser on ircv3 messages and handle pings

Testing Done:
Connected to a local Ergo instance and verified ping/pongs were sent via ngrep and saw a whole of unhandled messages in the terminal.

Reviewed at https://reviews.imfreedom.org/r/1911/
--- a/libpurple/protocols/ircv3/meson.build Sat Oct 08 04:54:55 2022 -0500
+++ b/libpurple/protocols/ircv3/meson.build Sun Oct 09 00:41:50 2022 -0500
@@ -3,6 +3,8 @@
'purpleircv3connection.h',
'purpleircv3core.c',
'purpleircv3core.h',
+ 'purpleircv3messagehandlers.c',
+ 'purpleircv3messagehandlers.h',
'purpleircv3parser.c',
'purpleircv3parser.h',
'purpleircv3protocol.c',
--- a/libpurple/protocols/ircv3/purpleircv3connection.c Sat Oct 08 04:54:55 2022 -0500
+++ b/libpurple/protocols/ircv3/purpleircv3connection.c Sun Oct 09 00:41:50 2022 -0500
@@ -21,6 +21,7 @@
#include "purpleircv3connection.h"
#include "purpleircv3core.h"
+#include "purpleircv3parser.h"
enum {
PROP_0,
@@ -43,6 +44,8 @@
GDataInputStream *input;
PurpleQueuedOutputStream *output;
+
+ PurpleIRCv3Parser *parser;
};
G_DEFINE_DYNAMIC_TYPE(PurpleIRCv3Connection, purple_ircv3_connection,
@@ -108,6 +111,7 @@
purple_ircv3_connection_read_cb(GObject *source, GAsyncResult *result,
gpointer data)
{
+ PurpleIRCv3Connection *connection = NULL;
PurpleConnection *purple_connection = data;
GDataInputStream *istream = G_DATA_INPUT_STREAM(source);
GError *error = NULL;
@@ -133,9 +137,18 @@
return;
}
- g_message("received line: %s", line);
+ connection = g_object_get_data(G_OBJECT(purple_connection),
+ PURPLE_IRCV3_CONNECTION_KEY);
+ purple_ircv3_parser_parse(connection->parser, line, &error, connection);
g_free(line);
+
+ /* Call read_line_async again to continue reading lines. */
+ g_data_input_stream_read_line_async(connection->input,
+ G_PRIORITY_DEFAULT,
+ connection->cancellable,
+ purple_ircv3_connection_read_cb,
+ purple_connection);
}
static void
@@ -191,16 +204,25 @@
connection = g_object_get_data(G_OBJECT(purple_connection),
PURPLE_IRCV3_CONNECTION_KEY);
+ purple_connection_set_state(purple_connection,
+ PURPLE_CONNECTION_CONNECTED);
+
g_message("Successfully connected to %s", connection->server_name);
/* Save our connection and setup our input and outputs. */
connection->connection = conn;
+ /* Create our parser. */
+ connection->parser = purple_ircv3_parser_new();
+ purple_ircv3_parser_add_default_handlers(connection->parser);
+
ostream = g_io_stream_get_output_stream(G_IO_STREAM(conn));
connection->output = purple_queued_output_stream_new(ostream);
istream = g_io_stream_get_input_stream(G_IO_STREAM(conn));
connection->input = g_data_input_stream_new(istream);
+ g_data_input_stream_set_newline_type(G_DATA_INPUT_STREAM(connection->input),
+ G_DATA_STREAM_NEWLINE_TYPE_CR_LF);
/* Add our read callback. */
g_data_input_stream_read_line_async(connection->input,
@@ -266,6 +288,8 @@
g_clear_object(&connection->output);
g_clear_object(&connection->connection);
+ g_clear_object(&connection->parser);
+
G_OBJECT_CLASS(purple_ircv3_connection_parent_class)->dispose(obj);
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/libpurple/protocols/ircv3/purpleircv3messagehandlers.c Sun Oct 09 00:41:50 2022 -0500
@@ -0,0 +1,57 @@
+/*
+ * Purple - Internet Messaging Library
+ * Copyright (C) Pidgin Developers <devel@pidgin.im>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include "purpleircv3messagehandlers.h"
+
+#include "purpleircv3connection.h"
+
+gboolean
+purple_ircv3_messager_handler_fallback(GHashTable *tags, const char *source,
+ const char *command, guint n_params,
+ GStrv params, GError **error,
+ gpointer data)
+{
+ gchar *joined = g_strjoinv(" ", params);
+
+ g_message("-- unhandled message --");
+ g_message("source: %s", source);
+ g_message("command: %s", command);
+ g_message("params: %s", joined);
+ g_message("-- end of unhandled message --");
+
+ g_free(joined);
+
+ return TRUE;
+}
+
+gboolean
+purple_ircv3_messager_handler_ping(GHashTable *tags, const char *source,
+ const char *command, guint n_params,
+ GStrv params, GError **error,
+ gpointer data)
+{
+ PurpleIRCv3Connection *connection = data;
+
+ if(n_params == 1) {
+ purple_ircv3_connection_writef(connection, "PONG %s", params[0]);
+ } else {
+ purple_ircv3_connection_writef(connection, "PONG");
+ }
+
+ return TRUE;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/libpurple/protocols/ircv3/purpleircv3messagehandlers.h Sun Oct 09 00:41:50 2022 -0500
@@ -0,0 +1,60 @@
+/*
+ * Purple - Internet Messaging Library
+ * Copyright (C) Pidgin Developers <devel@pidgin.im>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
+ */
+
+#ifndef PURPLE_IRCV3_MESSAGE_HANDLERS_H
+#define PURPLE_IRCV3_MESSAGE_HANDLERS_H
+
+#include <glib.h>
+
+#include <purple.h>
+
+G_BEGIN_DECLS
+
+/**
+ * PurpleIRCv3MessageHandler:
+ * @tags: (element-type utf8 utf8): A [struct@GLib.HashTable] of tags for this
+ * message.
+ * @source: The source of the command.
+ * @command: The command or numeric of the message.
+ * @n_params: The number of parameters.
+ * @params: (array_length=n_params): The parameters of the message.
+ * @error: (nullable) (optional): A return address for a [type@GLib.Error].
+ * @data: The user data that was passed to [method@PurpleIRCv3.Parser.parse].
+ *
+ * Defines the type of a function that will be called to handle a message.
+ *
+ * Returns: %TRUE if the command was handled properly, otherwise %FALSE and
+ * @error may be set.
+ *
+ * Since: 3.0.0
+ */
+typedef gboolean (*PurpleIRCv3MessageHandler)(GHashTable *tags,
+ const char *source,
+ const char *command,
+ guint n_params,
+ GStrv params,
+ GError **error,
+ gpointer data);
+
+G_GNUC_INTERNAL gboolean purple_ircv3_messager_handler_fallback(GHashTable *tags, const char *source, const char *command, guint n_params, GStrv params, GError **error, gpointer data);
+
+G_GNUC_INTERNAL gboolean purple_ircv3_messager_handler_ping(GHashTable *tags, const char *source, const char *command, guint n_params, GStrv params, GError **error, gpointer data);
+
+G_END_DECLS
+
+#endif /* PURPLE_IRCV3_MESSAGE_HANDLERS_H */
--- a/libpurple/protocols/ircv3/purpleircv3parser.c Sat Oct 08 04:54:55 2022 -0500
+++ b/libpurple/protocols/ircv3/purpleircv3parser.c Sun Oct 09 00:41:50 2022 -0500
@@ -19,6 +19,7 @@
#include "purpleircv3parser.h"
#include "purpleircv3core.h"
+#include "purpleircv3messagehandlers.h"
struct _PurpleIRCv3Parser {
GObject parent;
@@ -166,6 +167,18 @@
return result;
}
+static void
+purple_ircv3_parser_add_handler(PurpleIRCv3Parser *parser,
+ const gchar *command,
+ PurpleIRCv3MessageHandler handler)
+{
+ g_return_if_fail(PURPLE_IRCV3_IS_PARSER(parser));
+ g_return_if_fail(command != NULL);
+ g_return_if_fail(handler != NULL);
+
+ g_hash_table_insert(parser->handlers, g_strdup(command), handler);
+}
+
/******************************************************************************
* Handlers
*****************************************************************************/
@@ -333,3 +346,14 @@
return result;
}
+
+void
+purple_ircv3_parser_add_default_handlers(PurpleIRCv3Parser *parser) {
+ g_return_if_fail(PURPLE_IRCV3_IS_PARSER(parser));
+
+ purple_ircv3_parser_set_fallback_handler(parser,
+ purple_ircv3_messager_handler_fallback);
+
+ purple_ircv3_parser_add_handler(parser, "PING",
+ purple_ircv3_messager_handler_ping);
+}
--- a/libpurple/protocols/ircv3/purpleircv3parser.h Sat Oct 08 04:54:55 2022 -0500
+++ b/libpurple/protocols/ircv3/purpleircv3parser.h Sun Oct 09 00:41:50 2022 -0500
@@ -24,15 +24,9 @@
#include <purple.h>
-G_BEGIN_DECLS
+#include "purpleircv3messagehandlers.h"
-typedef gboolean (*PurpleIRCv3MessageHandler)(GHashTable *tags,
- const gchar *source,
- const gchar *command,
- guint n_params,
- GStrv params,
- GError **error,
- gpointer data);
+G_BEGIN_DECLS
#define PURPLE_IRCV3_TYPE_PARSER (purple_ircv3_parser_get_type())
G_DECLARE_FINAL_TYPE(PurpleIRCv3Parser, purple_ircv3_parser, PURPLE_IRCV3,
@@ -74,6 +68,16 @@
*/
G_GNUC_INTERNAL gboolean purple_ircv3_parser_parse(PurpleIRCv3Parser *parser, const gchar *buffer, GError **error, gpointer data);
+/**
+ * purple_ircv3_parser_add_default_handlers:
+ * @parser: The instance.
+ *
+ * Adds all of the default handlers to @parser.
+ *
+ * Since: 3.0.0
+ */
+G_GNUC_INTERNAL void purple_ircv3_parser_add_default_handlers(PurpleIRCv3Parser *parser);
+
G_END_DECLS
#endif /* PURPLE_IRCV3_PARSER_H */