/pidgin/main: 69a42dcf5a74: Merged in CMaiku/pidgin (pull reques...
Gary Kramlich <[email protected]>
| Newsgroups | gmane.comp.gnome.gaim.cvs |
|---|---|
| Message-ID | <[email protected]> |
Changeset: 69a42dcf5a74ea61071aed1d7d90aff86dd1b96f Author: Gary Kramlich <[email protected]> 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 | _______________________________________________ Commits mailing list [email protected] https://pidgin.im/cgi-bin/mailman/listinfo/commits