Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/dequis/purple-facebook.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Ruprecht <cmaiku@gmail.com>2016-09-29 23:56:14 +0300
committerdequis <dx@dxzone.com.ar>2016-11-21 15:41:07 +0300
commit067af3febef217fd164f9ef26a05457768de65d0 (patch)
tree9e953c1e395e0461a12b255947f437c6c38521b7
parenta065b18b31e8ff1ea04056652106bdc245d95c8f (diff)
VERSION: update to 56d191003b34
-rw-r--r--ChangeLog3
-rw-r--r--VERSION2
-rw-r--r--patches/04-revert-gio.patch533
3 files changed, 537 insertions, 1 deletions
diff --git a/ChangeLog b/ChangeLog
index 5564bcd..98551d9 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,6 @@
+purple-facebook-56d191003b34 (2016-09-15):
+ - Update backport to handle Gio port
+
purple-facebook-2a8f41535c8f (2016-08-12):
- Update backport to handle blistnodetypes.[ch] to buddy.[ch] rename
diff --git a/VERSION b/VERSION
index e9ee61f..714caa5 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-2a8f41535c8f
+56d191003b34
diff --git a/patches/04-revert-gio.patch b/patches/04-revert-gio.patch
new file mode 100644
index 0000000..1c5874e
--- /dev/null
+++ b/patches/04-revert-gio.patch
@@ -0,0 +1,533 @@
+diff -r 56d191003b34 -r 5a63c26f21fd libpurple/protocols/facebook/facebook.c
+--- a/libpurple/protocols/facebook/facebook.c Thu Sep 15 13:31:06 2016 -0500
++++ b/libpurple/protocols/facebook/facebook.c Wed Sep 14 14:53:12 2016 -0500
+@@ -332,8 +332,8 @@
+
+ gc = fb_data_get_connection(fata);
+
+- if (error->domain == G_IO_ERROR) {
+- purple_connection_g_error(gc, error);
++ if (error->domain == FB_MQTT_SSL_ERROR) {
++ purple_connection_ssl_error(gc, error->code);
+ return;
+ }
+
+diff -r 56d191003b34 -r 5a63c26f21fd libpurple/protocols/facebook/mqtt.c
+--- a/libpurple/protocols/facebook/mqtt.c Thu Sep 15 13:31:06 2016 -0500
++++ b/libpurple/protocols/facebook/mqtt.c Wed Sep 14 14:53:12 2016 -0500
+@@ -28,8 +28,7 @@
+ #include "account.h"
+ #include "eventloop.h"
+ #include "glibcompat.h"
+-#include "purple-gio.h"
+-#include "queuedoutputstream.h"
++#include "sslconn.h"
+
+ #include "marshal.h"
+ #include "mqtt.h"
+@@ -38,17 +37,17 @@
+ struct _FbMqttPrivate
+ {
+ PurpleConnection *gc;
+- GIOStream *conn;
+- GBufferedInputStream *input;
+- PurpleQueuedOutputStream *output;
+- GCancellable *cancellable;
++ PurpleSslConnection *gsc;
+ gboolean connected;
+ guint16 mid;
+
+ GByteArray *rbuf;
++ GByteArray *wbuf;
+ gsize remz;
+
+ gint tev;
++ gint rev;
++ gint wev;
+ };
+
+ struct _FbMqttMessagePrivate
+@@ -66,8 +65,6 @@
+ G_DEFINE_TYPE(FbMqtt, fb_mqtt, G_TYPE_OBJECT);
+ G_DEFINE_TYPE(FbMqttMessage, fb_mqtt_message, G_TYPE_OBJECT);
+
+-static void fb_mqtt_read_packet(FbMqtt *mqtt);
+-
+ static void
+ fb_mqtt_dispose(GObject *obj)
+ {
+@@ -76,6 +73,7 @@
+
+ fb_mqtt_close(mqtt);
+ g_byte_array_free(priv->rbuf, TRUE);
++ g_byte_array_free(priv->wbuf, TRUE);
+ }
+
+ static void
+@@ -163,6 +161,7 @@
+ mqtt->priv = priv;
+
+ priv->rbuf = g_byte_array_new();
++ priv->wbuf = g_byte_array_new();
+ }
+
+ static void
+@@ -206,6 +205,18 @@
+ return q;
+ }
+
++GQuark
++fb_mqtt_ssl_error_quark(void)
++{
++ static GQuark q = 0;
++
++ if (G_UNLIKELY(q == 0)) {
++ q = g_quark_from_static_string("fb-mqtt-ssl-error-quark");
++ }
++
++ return q;
++}
++
+ FbMqtt *
+ fb_mqtt_new(PurpleConnection *gc)
+ {
+@@ -229,47 +240,33 @@
+ g_return_if_fail(FB_IS_MQTT(mqtt));
+ priv = mqtt->priv;
+
++ if (priv->wev > 0) {
++ purple_input_remove(priv->wev);
++ priv->wev = 0;
++ }
++
++ if (priv->rev > 0) {
++ purple_input_remove(priv->rev);
++ priv->rev = 0;
++ }
++
+ if (priv->tev > 0) {
+ purple_timeout_remove(priv->tev);
+ priv->tev = 0;
+ }
+
+- if (priv->cancellable != NULL) {
+- g_cancellable_cancel(priv->cancellable);
+- g_clear_object(&priv->cancellable);
++ if (priv->gsc != NULL) {
++ purple_ssl_close(priv->gsc);
++ priv->gsc = NULL;
+ }
+
+- if (priv->conn != NULL) {
+- purple_gio_graceful_close(priv->conn,
+- G_INPUT_STREAM(priv->input),
+- G_OUTPUT_STREAM(priv->output));
+- g_clear_object(&priv->input);
+- g_clear_object(&priv->output);
+- g_clear_object(&priv->conn);
++ if (priv->wbuf->len > 0) {
++ fb_util_debug_warning("Closing with unwritten data");
+ }
+
+ priv->connected = FALSE;
+ g_byte_array_set_size(priv->rbuf, 0);
+-}
+-
+-static void
+-fb_mqtt_take_error(FbMqtt *mqtt, GError *err, const gchar *prefix)
+-{
+- if (g_error_matches(err, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
+- /* Return as cancelled means the connection is closing */
+- g_error_free(err);
+- return;
+- }
+-
+- /* Now we can check for programming errors */
+- g_return_if_fail(FB_IS_MQTT(mqtt));
+-
+- if (prefix != NULL) {
+- g_prefix_error(&err, "%s: ", prefix);
+- }
+-
+- g_signal_emit_by_name(mqtt, "error", err);
+- g_error_free(err);
++ g_byte_array_set_size(priv->wbuf, 0);
+ }
+
+ void
+@@ -347,130 +344,74 @@
+ }
+
+ static void
+-fb_mqtt_cb_fill(GObject *source, GAsyncResult *res, gpointer data)
+-{
+- GBufferedInputStream *input = G_BUFFERED_INPUT_STREAM(source);
+- FbMqtt *mqtt = data;
+- gssize ret;
+- GError *err = NULL;
+-
+- ret = g_buffered_input_stream_fill_finish(input, res, &err);
+-
+- if (ret < 1) {
+- if (ret == 0) {
+- err = g_error_new_literal(G_IO_ERROR,
+- G_IO_ERROR_CONNECTION_CLOSED,
+- _("Connection closed"));
+- }
+-
+- fb_mqtt_take_error(mqtt, err, _("Failed to read fixed header"));
+- return;
+- }
+-
+- fb_mqtt_read_packet(mqtt);
+-}
+-
+-static void
+-fb_mqtt_cb_read_packet(GObject *source, GAsyncResult *res, gpointer data)
++fb_mqtt_cb_read(gpointer data, gint fd, PurpleInputCondition cond)
+ {
+ FbMqtt *mqtt = data;
+- FbMqttPrivate *priv;
+- gssize ret;
+ FbMqttMessage *msg;
+- GError *err = NULL;
++ FbMqttPrivate *priv = mqtt->priv;
++ gint res;
++ guint mult;
++ guint8 buf[1024];
++ guint8 byte;
++ gsize size;
++ gssize rize;
+
+- ret = g_input_stream_read_finish(G_INPUT_STREAM(source), res, &err);
++ if (priv->remz < 1) {
++ /* Reset the read buffer */
++ g_byte_array_set_size(priv->rbuf, 0);
+
+- if (ret < 1) {
+- if (ret == 0) {
+- err = g_error_new_literal(G_IO_ERROR,
+- G_IO_ERROR_CONNECTION_CLOSED,
+- _("Connection closed"));
++ res = purple_ssl_read(priv->gsc, &byte, sizeof byte);
++ g_byte_array_append(priv->rbuf, &byte, sizeof byte);
++
++ if (res != sizeof byte) {
++ fb_mqtt_error(mqtt, FB_MQTT_ERROR_GENERAL,
++ _("Failed to read fixed header"));
++ return;
+ }
+
+- fb_mqtt_take_error(mqtt, err, _("Failed to read packet data"));
+- return;
+- }
+-
+- priv = mqtt->priv;
+- priv->remz -= ret;
++ mult = 1;
+
+- if (priv->remz > 0) {
+- g_input_stream_read_async(G_INPUT_STREAM(source),
+- priv->rbuf->data +
+- priv->rbuf->len - priv->remz, priv->remz,
+- G_PRIORITY_DEFAULT, priv->cancellable,
+- fb_mqtt_cb_read_packet, mqtt);
+- return;
++ do {
++ res = purple_ssl_read(priv->gsc, &byte, sizeof byte);
++ g_byte_array_append(priv->rbuf, &byte, sizeof byte);
++
++ if (res != sizeof byte) {
++ fb_mqtt_error(mqtt, FB_MQTT_ERROR_GENERAL,
++ _("Failed to read packet size"));
++ return;
++ }
++
++ priv->remz += (byte & 127) * mult;
++ mult *= 128;
++ } while ((byte & 128) != 0);
+ }
+
+- msg = fb_mqtt_message_new_bytes(priv->rbuf);
++ if (priv->remz > 0) {
++ size = MIN(priv->remz, sizeof buf);
++ rize = purple_ssl_read(priv->gsc, buf, size);
+
+- if (G_UNLIKELY(msg == NULL)) {
+- fb_mqtt_error(mqtt, FB_MQTT_ERROR_GENERAL,
+- _("Failed to parse message"));
+- return;
++ if (rize < 1) {
++ fb_mqtt_error(mqtt, FB_MQTT_ERROR_GENERAL,
++ _("Failed to read packet data"));
++ return;
++ }
++
++ g_byte_array_append(priv->rbuf, buf, rize);
++ priv->remz -= rize;
+ }
+
+- fb_mqtt_read(mqtt, msg);
+- g_object_unref(msg);
+-
+- /* Read another packet if connection wasn't reset in fb_mqtt_read() */
+- if (fb_mqtt_connected(mqtt, FALSE)) {
+- fb_mqtt_read_packet(mqtt);
+- }
+-}
++ if (priv->remz < 1) {
++ msg = fb_mqtt_message_new_bytes(priv->rbuf);
++ priv->remz = 0;
+
+-static void
+-fb_mqtt_read_packet(FbMqtt *mqtt)
+-{
+- FbMqttPrivate *priv = mqtt->priv;
+- const guint8 const *buf;
+- gsize count = 0;
+- gsize pos;
+- guint mult = 1;
+- guint8 byte;
+- gsize size = 0;
+-
+- buf = g_buffered_input_stream_peek_buffer(priv->input, &count);
+-
+- /* Start at 1 to skip the first byte */
+- pos = 1;
+-
+- do {
+- if (pos >= count) {
+- /* Not enough data yet, try again later */
+- size = 0;
+- break;
++ if (G_UNLIKELY(msg == NULL)) {
++ fb_mqtt_error(mqtt, FB_MQTT_ERROR_GENERAL,
++ _("Failed to parse message"));
++ return;
+ }
+
+- byte = *(buf + pos++);
+-
+- size += (byte & 127) * mult;
+- mult *= 128;
+- } while ((byte & 128) != 0);
+-
+- if (size > 0) {
+- /* Add header to size */
+- size += pos;
+-
+- g_byte_array_set_size(priv->rbuf, size);
+- priv->remz = size;
+-
+- /* TODO: Use g_input_stream_read_all_async() when available. */
+- /* TODO: Alternately, it would be nice to let the
+- * FbMqttMessage directly use the GBufferedInputStream
+- * buffer instead of copying it, provided it's consumed
+- * before the next read.
+- */
+- g_input_stream_read_async(G_INPUT_STREAM(priv->input),
+- priv->rbuf->data, priv->rbuf->len,
+- G_PRIORITY_DEFAULT, priv->cancellable,
+- fb_mqtt_cb_read_packet, mqtt);
+- } else {
+- g_buffered_input_stream_fill_async(priv->input, -1,
+- G_PRIORITY_DEFAULT, priv->cancellable,
+- fb_mqtt_cb_fill, mqtt);
++ fb_mqtt_read(mqtt, msg);
++ g_object_unref(msg);
+ }
+ }
+
+@@ -578,16 +519,27 @@
+ }
+
+ static void
+-fb_mqtt_cb_flush(GObject *source, GAsyncResult *res, gpointer data)
++fb_mqtt_cb_write(gpointer data, gint fd, PurpleInputCondition cond)
+ {
+ FbMqtt *mqtt = data;
+- GError *err = NULL;
++ FbMqttPrivate *priv = mqtt->priv;
++ gssize wize;
+
+- if (!g_output_stream_flush_finish(G_OUTPUT_STREAM(source),
+- res, &err)) {
+- fb_mqtt_take_error(mqtt, err, _("Failed to write data"));
++ wize = purple_ssl_write(priv->gsc, priv->wbuf->data, priv->wbuf->len);
++
++ if (wize < 0) {
++ fb_mqtt_error(mqtt, FB_MQTT_ERROR_GENERAL,
++ _("Failed to write data"));
+ return;
+ }
++
++ if (wize > 0) {
++ g_byte_array_remove_range(priv->wbuf, 0, wize);
++ }
++
++ if (priv->wbuf->len < 1) {
++ priv->wev = 0;
++ }
+ }
+
+ void
+@@ -596,7 +548,6 @@
+ const GByteArray *bytes;
+ FbMqttMessagePrivate *mriv;
+ FbMqttPrivate *priv;
+- GBytes *gbytes;
+
+ g_return_if_fail(FB_IS_MQTT(mqtt));
+ g_return_if_fail(FB_IS_MQTT_MESSAGE(msg));
+@@ -615,46 +566,46 @@
+ "Writing %d (flags: 0x%0X)",
+ mriv->type, mriv->flags);
+
+- /* TODO: Would be nice to refactor this to not require copying bytes */
+- gbytes = g_bytes_new(bytes->data, bytes->len);
+- purple_queued_output_stream_push_bytes(priv->output, gbytes);
+- g_bytes_unref(gbytes);
++ g_byte_array_append(priv->wbuf, bytes->data, bytes->len);
++ fb_mqtt_cb_write(mqtt, priv->gsc->fd, PURPLE_INPUT_WRITE);
+
+- if (!g_output_stream_has_pending(G_OUTPUT_STREAM(priv->output))) {
+- g_output_stream_flush_async(G_OUTPUT_STREAM(priv->output),
+- G_PRIORITY_DEFAULT, priv->cancellable,
+- fb_mqtt_cb_flush, mqtt);
++ if (priv->wev > 0) {
++ priv->wev = purple_input_add(priv->gsc->fd,
++ PURPLE_INPUT_WRITE,
++ fb_mqtt_cb_write, mqtt);
+ }
+ }
+
+ static void
+-fb_mqtt_cb_open(GObject *source, GAsyncResult *res, gpointer data)
++fb_mqtt_cb_open(gpointer data, PurpleSslConnection *ssl,
++ PurpleInputCondition cond)
+ {
+ FbMqtt *mqtt = data;
+- FbMqttPrivate *priv;
+- GSocketConnection *conn;
+- GError *err = NULL;
+-
+- conn = g_socket_client_connect_to_host_finish(G_SOCKET_CLIENT(source),
+- res, &err);
+-
+- if (conn == NULL) {
+- fb_mqtt_take_error(mqtt, err, NULL);
+- return;
+- }
++ FbMqttPrivate *priv = mqtt->priv;
+
+ fb_mqtt_timeout_clear(mqtt);
++ priv->rev = purple_input_add(priv->gsc->fd, PURPLE_INPUT_READ,
++ fb_mqtt_cb_read, mqtt);
++ g_signal_emit_by_name(mqtt, "open");
++}
+
+- priv = mqtt->priv;
+- priv->conn = G_IO_STREAM(conn);
+- priv->input = G_BUFFERED_INPUT_STREAM(g_buffered_input_stream_new(
+- g_io_stream_get_input_stream(priv->conn)));
+- priv->output = purple_queued_output_stream_new(
+- g_io_stream_get_output_stream(priv->conn));
++static void
++fb_mqtt_cb_open_error(PurpleSslConnection *ssl, PurpleSslErrorType error,
++ gpointer data)
++{
++ const gchar *str;
++ FbMqtt *mqtt = data;
++ FbMqttPrivate *priv = mqtt->priv;
++ GError *err;
+
+- fb_mqtt_read_packet(mqtt);
++ str = purple_ssl_strerror(error);
++ err = g_error_new_literal(FB_MQTT_SSL_ERROR, error, str);
+
+- g_signal_emit_by_name(mqtt, "open");
++ /* Do not call purple_ssl_close() from the error_func */
++ priv->gsc = NULL;
++
++ g_signal_emit_by_name(mqtt, "error", err);
++ g_error_free(err);
+ }
+
+ void
+@@ -662,29 +613,20 @@
+ {
+ FbMqttPrivate *priv;
+ PurpleAccount *acc;
+- GSocketClient *client;
+- GError *err = NULL;
+
+ g_return_if_fail(FB_IS_MQTT(mqtt));
+ priv = mqtt->priv;
+
+ acc = purple_connection_get_account(priv->gc);
+ fb_mqtt_close(mqtt);
++ priv->gsc = purple_ssl_connect(acc, host, port, fb_mqtt_cb_open,
++ fb_mqtt_cb_open_error, mqtt);
+
+- client = purple_gio_socket_client_new(acc, &err);
+-
+- if (client == NULL) {
+- fb_mqtt_take_error(mqtt, err, NULL);
++ if (priv->gsc == NULL) {
++ fb_mqtt_cb_open_error(NULL, 0, mqtt);
+ return;
+ }
+
+- priv->cancellable = g_cancellable_new();
+-
+- g_socket_client_set_tls(client, TRUE);
+- g_socket_client_connect_to_host_async(client, host, port,
+- priv->cancellable, fb_mqtt_cb_open, mqtt);
+- g_object_unref(client);
+-
+ fb_mqtt_timeout(mqtt);
+ }
+
+@@ -720,7 +662,7 @@
+
+ g_return_val_if_fail(FB_IS_MQTT(mqtt), FALSE);
+ priv = mqtt->priv;
+- connected = (priv->conn != NULL) && priv->connected;
++ connected = (priv->gsc != NULL) && priv->connected;
+
+ if (!connected && error) {
+ fb_mqtt_error(mqtt, FB_MQTT_ERROR_GENERAL,
+diff -r 56d191003b34 -r 5a63c26f21fd libpurple/protocols/facebook/mqtt.h
+--- a/libpurple/protocols/facebook/mqtt.h Thu Sep 15 13:31:06 2016 -0500
++++ b/libpurple/protocols/facebook/mqtt.h Wed Sep 14 14:53:12 2016 -0500
+@@ -107,6 +107,13 @@
+ */
+ #define FB_MQTT_ERROR fb_mqtt_error_quark()
+
++/**
++ * FB_MQTT_SSL_ERROR:
++ *
++ * The #GQuark of the domain of MQTT SSL errors.
++ */
++#define FB_MQTT_SSL_ERROR fb_mqtt_ssl_error_quark()
++
+ typedef struct _FbMqtt FbMqtt;
+ typedef struct _FbMqttClass FbMqttClass;
+ typedef struct _FbMqttPrivate FbMqttPrivate;
+@@ -291,6 +298,16 @@
+ fb_mqtt_error_quark(void);
+
+ /**
++ * fb_mqtt_ssl_error_quark:
++ *
++ * Gets the #GQuark of the domain of MQTT SSL errors.
++ *
++ * Returns: The #GQuark of the domain.
++ */
++GQuark
++fb_mqtt_ssl_error_quark(void);
++
++/**
+ * fb_mqtt_new:
+ * @gc: The #PurpleConnection.
+ *