--- a/protocols/xmpp/meson.build Tue Dec 05 17:53:57 2023 -0600
+++ b/protocols/xmpp/meson.build Tue Dec 12 01:21:38 2023 -0600
@@ -1,9 +1,12 @@
+ 'purplexmppconnection.c', + 'purplexmppconnection.h', + 'purplexmppconstants.h', --- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/protocols/xmpp/purplexmppconnection.c Tue Dec 12 01:21:38 2023 -0600
@@ -0,0 +1,213 @@
+ * 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 <glib/gi18n-lib.h> +#include "purplexmppconnection.h" +#include "purplexmppconstants.h" +#include "purplexmppcore.h" +struct _PurpleXmppConnection { + PurpleConnection parent; + XemeConnection *xeme_connection; + XemeOutputStream *output; +G_DEFINE_DYNAMIC_TYPE(PurpleXmppConnection, purple_xmpp_connection, + PURPLE_TYPE_CONNECTION) +/****************************************************************************** + *****************************************************************************/ +purple_xmpp_connection_connect_cb(GObject *source, GAsyncResult *result, + PurpleXmppConnection *connection = data; + XemeOutputStream *output = NULL; + output = xeme_connection_connect_finish(XEME_CONNECTION(source), result, + purple_connection_take_error(PURPLE_CONNECTION(connection), error); + connection->output = output; + purple_connection_set_state(PURPLE_CONNECTION(connection), + PURPLE_CONNECTION_STATE_CONNECTED); +/****************************************************************************** + * PurpleConnection Implementation + *****************************************************************************/ +purple_xmpp_connection_connect(PurpleConnection *purple_connection, + PurpleXmppConnection *connection = NULL; + PurpleAccount *account = NULL; + XemeInputStream *input = NULL; + XemeTlsMode xeme_tls_mode = XEME_TLS_MODE_DIRECT_TLS; + GCancellable *cancellable = NULL; + GError *local_error = NULL; + GProxyResolver *resolver = NULL; + const char *resource = NULL; + const char *server = NULL; + const char *tls_mode = NULL; + const char *username = NULL; + guint16 port = PURPLE_XMPP_DEFAULT_PORT_TLS; + g_return_val_if_fail(PURPLE_XMPP_IS_CONNECTION(purple_connection), FALSE); + purple_connection_set_state(purple_connection, + PURPLE_CONNECTION_STATE_CONNECTING); + connection = PURPLE_XMPP_CONNECTION(purple_connection); + cancellable = purple_connection_get_cancellable(purple_connection); + account = purple_connection_get_account(purple_connection); + /* Figure out what proxy resolver to use. */ + resolver = purple_proxy_get_proxy_resolver(account, &local_error); + if(!G_IS_PROXY_RESOLVER(resolver) || local_error != NULL) { + if(local_error == NULL) { + local_error = g_error_new(PURPLE_XMPP_DOMAIN, 0, "unknown error"); + g_propagate_error(error, local_error); + g_clear_object(&resolver); + /* Grab some more information that we need. */ + username = purple_contact_info_get_username(PURPLE_CONTACT_INFO(account)); + connection->xeme_connection = xeme_connection_new(username); + /* If we have a resource, tell the xeme connection about it. */ + resource = purple_account_get_string(account, PURPLE_XMPP_OPTION_RESOURCE, + if(!purple_strempty(resource)) { + xeme_connection_set_resource(connection->xeme_connection, resource); + /* If we have a server, tell the xeme connection about it. */ + server = purple_account_get_string(account, PURPLE_XMPP_OPTION_SERVER, + if(!purple_strempty(server)) { + xeme_connection_set_server(connection->xeme_connection, server); + /* Set whatever port we have on our xeme connection. */ + port = purple_account_get_int(account, PURPLE_XMPP_OPTION_PORT, + PURPLE_XMPP_DEFAULT_PORT_TLS); + xeme_connection_set_port(connection->xeme_connection, port); + /* Figure out what if any TLS we're doing. This is initialized to direct + * tls above, so if we don't know which to use, that's what we'll end up + * using. Doing so should avoid possible accidental leaks. + tls_mode = purple_account_get_string(account, PURPLE_XMPP_OPTION_TLS_MODE, + PURPLE_XMPP_TLS_DIRECT); + if(purple_strequal(tls_mode, PURPLE_XMPP_TLS_DIRECT)) { + xeme_tls_mode = XEME_TLS_MODE_DIRECT_TLS; + } else if(purple_strequal(tls_mode, PURPLE_XMPP_TLS_STARTTLS)) { + xeme_tls_mode = XEME_TLS_MODE_START_TLS; + } else if(purple_strequal(tls_mode, PURPLE_XMPP_TLS_NONE)) { + xeme_tls_mode = XEME_TLS_MODE_NONE; + xeme_connection_set_tls_mode(connection->xeme_connection, xeme_tls_mode); + input = xeme_input_stream_new(); + /* Finally start connecting!! */ + xeme_connection_connect_async(connection->xeme_connection, input, resolver, + cancellable, purple_xmpp_connection_connect_cb, + g_clear_object(&input); +purple_xmpp_connection_disconnect(PurpleConnection *purple_connection, + PurpleXmppConnection *connection = NULL; + PurpleConnectionClass *parent_class = NULL; + g_return_val_if_fail(PURPLE_XMPP_IS_CONNECTION(purple_connection), FALSE); + connection = PURPLE_XMPP_CONNECTION(purple_connection); + /* Chain up to our parent's disconnect method. */ + parent_class = PURPLE_CONNECTION_CLASS(purple_xmpp_connection_parent_class); + parent_class->disconnect(purple_connection, error); + return xeme_connection_close(connection->xeme_connection, error); +/****************************************************************************** + * GObject Implementation + *****************************************************************************/ +purple_xmpp_connection_dispose(GObject *obj) { + PurpleXmppConnection *connection = PURPLE_XMPP_CONNECTION(obj); + g_clear_object(&connection->xeme_connection); + g_clear_object(&connection->output); + G_OBJECT_CLASS(purple_xmpp_connection_parent_class)->dispose(obj); +purple_xmpp_connection_init(G_GNUC_UNUSED PurpleXmppConnection *connection) { +purple_xmpp_connection_class_init(PurpleXmppConnectionClass *klass) { + GObjectClass *obj_class = G_OBJECT_CLASS(klass); + PurpleConnectionClass *connection_class = PURPLE_CONNECTION_CLASS(klass); + obj_class->dispose = purple_xmpp_connection_dispose; + connection_class->connect = purple_xmpp_connection_connect; + connection_class->disconnect = purple_xmpp_connection_disconnect; +purple_xmpp_connection_class_finalize(G_GNUC_UNUSED PurpleXmppConnectionClass *klass) { +/****************************************************************************** + *****************************************************************************/ +purple_xmpp_connection_register(GPluginNativePlugin *plugin) { + purple_xmpp_connection_register_type(G_TYPE_MODULE(plugin)); --- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/protocols/xmpp/purplexmppconnection.h Tue Dec 12 01:21:38 2023 -0600
@@ -0,0 +1,48 @@
+ * 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_XMPP_CONNECTION_H +#define PURPLE_XMPP_CONNECTION_H +#include <glib-object.h> +#include <gplugin-native.h> +#define PURPLE_XMPP_TYPE_CONNECTION (purple_xmpp_connection_get_type()) +G_DECLARE_FINAL_TYPE(PurpleXmppConnection, purple_xmpp_connection, PURPLE_XMPP, + CONNECTION, PurpleConnection) + * purple_xmpp_connection_register: (skip) + * @plugin: The GTypeModule + * Registers the dynamic type using @plugin. +G_GNUC_INTERNAL void purple_xmpp_connection_register(GPluginNativePlugin *plugin); +#endif /* PURPLE_XMPP_CONNECTION_H */ --- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/protocols/xmpp/purplexmppconstants.h Tue Dec 12 01:21:38 2023 -0600
@@ -0,0 +1,36 @@
+ * 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_XMPP_CONSTANTS_H +#define PURPLE_XMPP_CONSTANTS_H +#define PURPLE_XMPP_DEFAULT_PORT_CLEAR (5222) +#define PURPLE_XMPP_DEFAULT_PORT_TLS (5223) +#define PURPLE_XMPP_OPTION_RESOURCE ("resource") +#define PURPLE_XMPP_OPTION_SERVER ("server") +#define PURPLE_XMPP_OPTION_PORT ("port") +#define PURPLE_XMPP_OPTION_TLS_MODE ("tls-mode") +#define PURPLE_XMPP_OPTION_SASL_LOGIN_NAME ("sasl-login-name") +#define PURPLE_XMPP_OPTION_SASL_MECHANISMS ("sasl-mechanisms") +#define PURPLE_XMPP_OPTION_PLAIN_SASL_IN_CLEAR ("plain-sasl-in-clear") +#define PURPLE_XMPP_TLS_DIRECT ("direct") +#define PURPLE_XMPP_TLS_STARTTLS ("starttls") +#define PURPLE_XMPP_TLS_NONE ("none") +#endif /* PURPLE_XMPP_CONSTANTS_H */ --- a/protocols/xmpp/purplexmppcore.c Tue Dec 05 17:53:57 2023 -0600
+++ b/protocols/xmpp/purplexmppcore.c Tue Dec 12 01:21:38 2023 -0600
@@ -26,6 +26,7 @@
#include "purplexmppcore.h"
+#include "purplexmppconnection.h" #include "purplexmppprotocol.h"
/******************************************************************************
@@ -71,6 +72,7 @@
purple_xmpp_protocol_register(GPLUGIN_NATIVE_PLUGIN(plugin));
+ purple_xmpp_connection_register(GPLUGIN_NATIVE_PLUGIN(plugin)); xmpp_protocol = purple_xmpp_protocol_new();
--- a/protocols/xmpp/purplexmppprotocol.c Tue Dec 05 17:53:57 2023 -0600
+++ b/protocols/xmpp/purplexmppprotocol.c Tue Dec 12 01:21:38 2023 -0600
@@ -20,6 +20,9 @@
#include "purplexmppprotocol.h"
+#include "purplexmppconnection.h" +#include "purplexmppconstants.h" struct _PurpleXmppProtocol {
@@ -39,6 +42,59 @@
+purple_xmpp_protocol_get_account_options(G_GNUC_UNUSED PurpleProtocol *protocol) + PurpleAccountOption *option = NULL; + PurpleKeyValuePair *pair = NULL; + option = purple_account_option_string_new(_("Resource"), + PURPLE_XMPP_OPTION_RESOURCE, + options = g_list_append(options, option); + option = purple_account_option_string_new(_("Server"), + PURPLE_XMPP_OPTION_SERVER, NULL); + options = g_list_append(options, option); + option = purple_account_option_int_new(_("Port"), PURPLE_XMPP_OPTION_PORT, + PURPLE_XMPP_DEFAULT_PORT_TLS); + options = g_list_append(options, option); + pair = purple_key_value_pair_new(_("Direct TLS"), PURPLE_XMPP_TLS_DIRECT); + items = g_list_append(items, pair); + pair = purple_key_value_pair_new(_("STARTTLS"), PURPLE_XMPP_TLS_STARTTLS); + items = g_list_append(items, pair); + pair = purple_key_value_pair_new(_("None"), PURPLE_XMPP_TLS_NONE); + items = g_list_append(items, pair); + option = purple_account_option_list_new(_("TLS Mode"), + PURPLE_XMPP_OPTION_TLS_MODE, + options = g_list_append(options, option); + option = purple_account_option_string_new(_("SASL login name"), + PURPLE_XMPP_OPTION_SASL_LOGIN_NAME, + options = g_list_append(options, option); + option = purple_account_option_string_new(_("SASL mechanisms"), + PURPLE_XMPP_OPTION_SASL_MECHANISMS, + options = g_list_append(options, option); + option = purple_account_option_bool_new(_("Allow plaintext SASL auth over " + "unencrypted connection"), + PURPLE_XMPP_OPTION_PLAIN_SASL_IN_CLEAR, + options = g_list_append(options, option); purple_xmpp_protocol_status_types(G_GNUC_UNUSED PurpleProtocol *protocol,
G_GNUC_UNUSED PurpleAccount *account)
@@ -54,6 +110,20 @@
+static PurpleConnection * +purple_xmpp_protocol_create_connection(PurpleProtocol *protocol, + PurpleAccount *account, + G_GNUC_UNUSED GError **error) + PURPLE_XMPP_TYPE_CONNECTION, /******************************************************************************
*****************************************************************************/
@@ -77,7 +147,10 @@
PurpleProtocolClass *protocol_class = PURPLE_PROTOCOL_CLASS(klass);
protocol_class->get_user_splits = purple_xmpp_protocol_get_user_splits;
+ protocol_class->get_account_options = purple_xmpp_protocol_get_account_options; protocol_class->status_types = purple_xmpp_protocol_status_types;
+ protocol_class->create_connection = purple_xmpp_protocol_create_connection; /******************************************************************************
--- a/subprojects/xeme.wrap Tue Dec 05 17:53:57 2023 -0600
+++ b/subprojects/xeme.wrap Tue Dec 12 01:21:38 2023 -0600
@@ -1,4 +1,4 @@
url = https://keep.imfreedom.org/xeme/xeme/