/pidgin/main: 69a42dcf5a74: Merged in CMaiku/pidgin (pull reques...
Gary Kramlich
grim at reaperworld.com
Sun May 15 11:11:27 EDT 2016
Changeset: 69a42dcf5a74ea61071aed1d7d90aff86dd1b96f
Author: Gary Kramlich <grim at reaperworld.com>
Date: 2016-05-15 10:11 -0500
Branch: default
URL: https://hg.pidgin.im/pidgin/main/rev/69a42dcf5a74
Description:
Merged in CMaiku/pidgin (pull request #41)
Port IRC to Gio
diffstat:
libpurple/Makefile.am | 2 +
libpurple/connection.c | 41 ++++
libpurple/connection.h | 21 ++
libpurple/protocols/irc/dcc_send.c | 11 +-
libpurple/protocols/irc/irc.c | 357 +++++++++++++-----------------------
libpurple/protocols/irc/irc.h | 14 +-
libpurple/queuedoutputstream.c | 151 +++++++++++++++
libpurple/queuedoutputstream.h | 109 +++++++++++
8 files changed, 468 insertions(+), 238 deletions(-)
diffs (truncated from 942 to 300 lines):
diff --git a/libpurple/Makefile.am b/libpurple/Makefile.am
--- a/libpurple/Makefile.am
+++ b/libpurple/Makefile.am
@@ -93,6 +93,7 @@ purple_coresources = \
protocol.c \
protocols.c \
purple-socket.c \
+ queuedoutputstream.c \
request.c \
request-datasheet.c \
roomlist.c \
@@ -172,6 +173,7 @@ purple_coreheaders = \
protocol.h \
protocols.h \
purple-socket.h \
+ queuedoutputstream.h \
request.h \
request-datasheet.h \
roomlist.h \
diff --git a/libpurple/connection.c b/libpurple/connection.c
--- a/libpurple/connection.c
+++ b/libpurple/connection.c
@@ -542,6 +542,47 @@ purple_connection_ssl_error (PurpleConne
purple_ssl_strerror(ssl_error));
}
+void
+purple_connection_g_error(PurpleConnection *pc, const GError *error,
+ const gchar *description)
+{
+ PurpleConnectionError reason;
+ gchar *tmp;
+
+ if (g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
+ /* Not a connection error. Ignore. */
+ return;
+ }
+
+ if (error->domain == G_TLS_ERROR) {
+ switch (error->code) {
+ case G_TLS_ERROR_UNAVAILABLE:
+ reason = PURPLE_CONNECTION_ERROR_NO_SSL_SUPPORT;
+ break;
+ case G_TLS_ERROR_NOT_TLS:
+ case G_TLS_ERROR_HANDSHAKE:
+ reason = PURPLE_CONNECTION_ERROR_ENCRYPTION_ERROR;
+ break;
+ case G_TLS_ERROR_BAD_CERTIFICATE:
+ case G_TLS_ERROR_CERTIFICATE_REQUIRED:
+ reason = PURPLE_CONNECTION_ERROR_CERT_OTHER_ERROR;
+ break;
+ case G_TLS_ERROR_EOF:
+ case G_TLS_ERROR_MISC:
+ default:
+ reason = PURPLE_CONNECTION_ERROR_NETWORK_ERROR;
+ }
+ } else if (error->domain == G_IO_ERROR) {
+ reason = PURPLE_CONNECTION_ERROR_NETWORK_ERROR;
+ } else {
+ reason = PURPLE_CONNECTION_ERROR_OTHER_ERROR;
+ }
+
+ tmp = g_strdup_printf(description, error->message);
+ purple_connection_error(pc, reason, tmp);
+ g_free(tmp);
+}
+
gboolean
purple_connection_error_is_fatal (PurpleConnectionError reason)
{
diff --git a/libpurple/connection.h b/libpurple/connection.h
--- a/libpurple/connection.h
+++ b/libpurple/connection.h
@@ -506,6 +506,27 @@ void
purple_connection_ssl_error (PurpleConnection *gc,
PurpleSslErrorType ssl_error);
+/*
+ * purple_connection_g_error
+ * @gc: Connection the error is associated with
+ * @error: Error information
+ * @description: Extra string which further explains the error.
+ * Substitutes a "%s" with the GError message.
+ *
+ * Closes a connection similar to purple_connection_error(), but
+ * takes a GError which is then converted to purple error codes.
+ *
+ * This function ignores G_IO_ERROR_CANCELLED, returning without
+ * closing the connection. This can be used as a shortcut when
+ * cancelling connections, as this is commonly done when shutting
+ * down a connection. If G_IO_ERROR_CANCELLED needs to be caught,
+ * do so with g_error_matches() prior to calling this function.
+ */
+void
+purple_connection_g_error(PurpleConnection *pc,
+ const GError *error,
+ const gchar *description);
+
/**
* purple_connection_error_is_fatal:
*
diff --git a/libpurple/protocols/irc/dcc_send.c b/libpurple/protocols/irc/dcc_send.c
--- a/libpurple/protocols/irc/dcc_send.c
+++ b/libpurple/protocols/irc/dcc_send.c
@@ -279,6 +279,8 @@ irc_dccsend_network_listen_cb(int sock,
struct irc_xfer_send_data *xd;
PurpleConnection *gc;
struct irc_conn *irc;
+ GSocket *gsock;
+ int fd = -1;
const char *arg[2];
char *tmp;
struct in_addr addr;
@@ -317,7 +319,14 @@ irc_dccsend_network_listen_cb(int sock,
/* Send the intended recipient the DCC request */
arg[0] = purple_xfer_get_remote_user(xfer);
- inet_aton(purple_network_get_my_ip(irc->fd), &addr);
+
+ /* Fetching this fd here assumes it won't be modified */
+ gsock = g_socket_connection_get_socket(irc->conn);
+ if (gsock != NULL) {
+ fd = g_socket_get_fd(gsock);
+ }
+
+ inet_aton(purple_network_get_my_ip(fd), &addr);
arg[1] = tmp = g_strdup_printf("\001DCC SEND \"%s\" %u %hu %" G_GOFFSET_FORMAT "\001",
purple_xfer_get_filename(xfer), ntohl(addr.s_addr),
port, purple_xfer_get_size(xfer));
diff --git a/libpurple/protocols/irc/irc.c b/libpurple/protocols/irc/irc.c
--- a/libpurple/protocols/irc/irc.c
+++ b/libpurple/protocols/irc/irc.c
@@ -32,6 +32,7 @@
#include "notify.h"
#include "protocol.h"
#include "plugins.h"
+#include "tls-certificate.h"
#include "util.h"
#include "version.h"
@@ -46,15 +47,12 @@ static GList *irc_status_types(PurpleAcc
static GList *irc_get_actions(PurpleConnection *gc);
/* static GList *irc_chat_info(PurpleConnection *gc); */
static void irc_login(PurpleAccount *account);
-static void irc_login_cb_ssl(gpointer data, PurpleSslConnection *gsc, PurpleInputCondition cond);
-static void irc_login_cb(gpointer data, gint source, const gchar *error_message);
-static void irc_ssl_connect_failure(PurpleSslConnection *gsc, PurpleSslErrorType error, gpointer data);
+static void irc_login_cb(GObject *source, GAsyncResult *res, gpointer user_data);
static void irc_close(PurpleConnection *gc);
static int irc_im_send(PurpleConnection *gc, PurpleMessage *msg);
static int irc_chat_send(PurpleConnection *gc, int id, PurpleMessage *msg);
static void irc_chat_join (PurpleConnection *gc, GHashTable *data);
-static void irc_input_cb(gpointer data, gint source, PurpleInputCondition cond);
-static void irc_input_cb_ssl(gpointer data, PurpleSslConnection *gsc, PurpleInputCondition cond);
+static void irc_read_input(struct irc_conn *irc);
static guint irc_nick_hash(const char *nick);
static gboolean irc_nick_equal(const char *nick1, const char *nick2);
@@ -87,19 +85,6 @@ static void irc_view_motd(PurpleProtocol
g_free(body);
}
-static int do_send(struct irc_conn *irc, const char *buf, gsize len)
-{
- int ret;
-
- if (irc->gsc) {
- ret = purple_ssl_write(irc->gsc, buf, len);
- } else {
- ret = write(irc->fd, buf, len);
- }
-
- return ret;
-}
-
static int irc_send_raw(PurpleConnection *gc, const char *buf, int len)
{
struct irc_conn *irc = purple_connection_get_protocol_data(gc);
@@ -111,44 +96,21 @@ static int irc_send_raw(PurpleConnection
}
static void
-irc_send_cb(gpointer data, gint source, PurpleInputCondition cond)
+irc_flush_cb(GObject *source, GAsyncResult *res, gpointer data)
{
- struct irc_conn *irc = data;
- int ret, writelen;
- const gchar *buffer = NULL;
+ PurpleConnection *gc = data;
+ gboolean result;
+ GError *error = NULL;
- writelen = purple_circular_buffer_get_max_read(irc->outbuf);
+ result = g_output_stream_flush_finish(G_OUTPUT_STREAM(source),
+ res, &error);
- if (writelen == 0) {
- purple_input_remove(irc->writeh);
- irc->writeh = 0;
+ if (!result) {
+ purple_connection_g_error(gc, error,
+ _("Lost connection with server: %s"));
+ g_clear_error(&error);
return;
}
-
- buffer = purple_circular_buffer_get_output(irc->outbuf);
-
- ret = do_send(irc, buffer, writelen);
-
- if (ret < 0 && errno == EAGAIN)
- return;
- else if (ret <= 0) {
- PurpleConnection *gc = purple_account_get_connection(irc->account);
- gchar *tmp = g_strdup_printf(_("Lost connection with server: %s"),
- g_strerror(errno));
- purple_connection_error (gc,
- PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp);
- g_free(tmp);
- return;
- }
-
- purple_circular_buffer_mark_read(irc->outbuf, ret);
-
-#if 0
- /* We *could* try to write more if we wrote it all */
- if (ret == write_len) {
- irc_send_cb(data, source, cond);
- }
-#endif
}
int irc_send(struct irc_conn *irc, const char *buf)
@@ -158,43 +120,29 @@ int irc_send(struct irc_conn *irc, const
int irc_send_len(struct irc_conn *irc, const char *buf, int buflen)
{
- int ret;
char *tosend= g_strdup(buf);
+ int len;
+ GBytes *data;
purple_signal_emit(_irc_protocol, "irc-sending-text", purple_account_get_connection(irc->account), &tosend);
if (tosend == NULL)
return 0;
- /* If we're not buffering writes, try to send immediately */
- if (!irc->writeh)
- ret = do_send(irc, tosend, buflen);
- else {
- ret = -1;
- errno = EAGAIN;
+ len = strlen(tosend);
+ data = g_bytes_new_take(tosend, len);
+ purple_queued_output_stream_push_bytes(irc->output, data);
+ g_bytes_unref(data);
+
+ if (!g_output_stream_has_pending(G_OUTPUT_STREAM(irc->output))) {
+ /* Connection idle. Flush data. */
+ g_output_stream_flush_async(G_OUTPUT_STREAM(irc->output),
+ G_PRIORITY_DEFAULT, irc->cancellable,
+ irc_flush_cb,
+ purple_account_get_connection(irc->account));
}
- /* purple_debug(PURPLE_DEBUG_MISC, "irc", "sent%s: %s",
- irc->gsc ? " (ssl)" : "", tosend); */
- if (ret <= 0 && errno != EAGAIN) {
- PurpleConnection *gc = purple_account_get_connection(irc->account);
- gchar *tmp = g_strdup_printf(_("Lost connection with server: %s"),
- g_strerror(errno));
- purple_connection_error (gc,
- PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp);
- g_free(tmp);
- } else if (ret < buflen) {
- if (ret < 0)
- ret = 0;
- if (!irc->writeh)
- irc->writeh = purple_input_add(
- irc->gsc ? irc->gsc->fd : irc->fd,
- PURPLE_INPUT_WRITE, irc_send_cb, irc);
- purple_circular_buffer_append(irc->outbuf, tosend + ret,
- buflen - ret);
- }
- g_free(tosend);
- return ret;
+ return len;
}
/* XXX I don't like messing directly with these buddies */
@@ -337,6 +285,8 @@ static void irc_login(PurpleAccount *acc
struct irc_conn *irc;
char **userparts;
const char *username = purple_account_get_username(account);
+ GSocketClient *client;
+ GProxyResolver *resolver;
gc = purple_account_get_connection(account);
purple_connection_set_flags(gc, PURPLE_CONNECTION_FLAG_NO_NEWLINES |
More information about the Commits
mailing list