# HG changeset patch # User Mark Doliner # Date 1155793630 0 # Node ID c8ebbc0110f413efd0566df5bf7aa4ee7578d51d # Parent ff3db5cdeb9f5620ceec3cf593813989d8258c36 [gaim-migrate @ 16808] gaim_ssl_connect's are now cancelable (without crashing, anyway) This was relatively easy, because the PRPLs already keep a reference to the GaimSslConnection. I just needed to update the core ssl code to keep track of the GaimProxyConnectInfo, and to call gaim_proxy_connect_cancel() when gaim_ssl_close() is called committer: Tailor Script diff -r ff3db5cdeb9f -r c8ebbc0110f4 plugins/ssl/ssl-nss.c --- a/plugins/ssl/ssl-nss.c Thu Aug 17 04:45:11 2006 +0000 +++ b/plugins/ssl/ssl-nss.c Thu Aug 17 05:47:10 2006 +0000 @@ -237,16 +237,13 @@ } static void -ssl_nss_connect_cb(gpointer data, gint source, GaimInputCondition cond) +ssl_nss_connect(GaimSslConnection *gsc) { - GaimSslConnection *gsc = (GaimSslConnection *)data; GaimSslNssData *nss_data = g_new0(GaimSslNssData, 1); PRSocketOptionData socket_opt; gsc->private_data = nss_data; - gsc->fd = source; - nss_data->fd = PR_ImportTCPSocket(gsc->fd); if (nss_data->fd == NULL) @@ -359,7 +356,7 @@ { ssl_nss_init, ssl_nss_uninit, - ssl_nss_connect_cb, + ssl_nss_connect, ssl_nss_close, ssl_nss_read, ssl_nss_write diff -r ff3db5cdeb9f -r c8ebbc0110f4 src/protocols/irc/irc.c --- a/src/protocols/irc/irc.c Thu Aug 17 04:45:11 2006 +0000 +++ b/src/protocols/irc/irc.c Thu Aug 17 05:47:10 2006 +0000 @@ -450,7 +450,7 @@ g_free(irc->inbuf); if (irc->gsc) { gaim_ssl_close(irc->gsc); - } else if (irc->fd > 0) { + } else if (irc->fd >= 0) { close(irc->fd); } if (irc->timer) diff -r ff3db5cdeb9f -r c8ebbc0110f4 src/sslconn.c --- a/src/sslconn.c Thu Aug 17 04:45:11 2006 +0000 +++ b/src/sslconn.c Thu Aug 17 05:47:10 2006 +0000 @@ -45,10 +45,14 @@ gaim_plugin_load(plugin); ops = gaim_ssl_get_ops(); - if (ops != NULL && ops->init != NULL) - return ops->init(); - else + if ((ops == NULL) || (ops->init == NULL) || (ops->uninit == NULL) || + (ops->connect == NULL) || (ops->close == NULL) || + (ops->read == NULL) || (ops->write == NULL)) + { return FALSE; + } + + return ops->init(); } gboolean @@ -62,25 +66,42 @@ #endif } +static void +gaim_ssl_connect_cb(gpointer data, gint source, const gchar *error_message) +{ + GaimSslConnection *gsc; + GaimSslOps *ops; + + gsc = data; + gsc->connect_info = NULL; + + if (source < 0) + { + if (gsc->error_cb != NULL) + gsc->error_cb(gsc, GAIM_SSL_CONNECT_FAILED, gsc->connect_cb_data); + + gaim_ssl_close(gsc); + return; + } + + gsc->fd = source; + + ops = gaim_ssl_get_ops(); + ops->connect(gsc); +} + GaimSslConnection * gaim_ssl_connect(GaimAccount *account, const char *host, int port, GaimSslInputFunction func, GaimSslErrorFunction error_func, void *data) { GaimSslConnection *gsc; - GaimSslOps *ops; - GaimProxyConnectInfo *connect_info; g_return_val_if_fail(host != NULL, NULL); g_return_val_if_fail(port != 0 && port != -1, NULL); g_return_val_if_fail(func != NULL, NULL); g_return_val_if_fail(gaim_ssl_is_supported(), NULL); - ops = gaim_ssl_get_ops(); - - g_return_val_if_fail(ops != NULL, NULL); - g_return_val_if_fail(ops->connect_cb != NULL, NULL); - if (!_ssl_initialized) { if (!ssl_init()) @@ -89,15 +110,16 @@ gsc = g_new0(GaimSslConnection, 1); + gsc->fd = -1; gsc->host = g_strdup(host); gsc->port = port; gsc->connect_cb_data = data; gsc->connect_cb = func; gsc->error_cb = error_func; - connect_info = gaim_proxy_connect(account, host, port, ops->connect_cb, gsc); + gsc->connect_info = gaim_proxy_connect(account, host, port, gaim_ssl_connect_cb, gsc); - if (connect_info == NULL) + if (gsc->connect_info == NULL) { g_free(gsc->host); g_free(gsc); @@ -141,11 +163,6 @@ g_return_val_if_fail(func != NULL, NULL); g_return_val_if_fail(gaim_ssl_is_supported(), NULL); - ops = gaim_ssl_get_ops(); - - g_return_val_if_fail(ops != NULL, NULL); - g_return_val_if_fail(ops->connect_cb != NULL, NULL); - if (!_ssl_initialized) { if (!ssl_init()) @@ -157,8 +174,10 @@ gsc->connect_cb_data = data; gsc->connect_cb = func; gsc->error_cb = error_func; + gsc->fd = fd; - ops->connect_cb(gsc, fd, GAIM_INPUT_READ); + ops = gaim_ssl_get_ops(); + ops->connect(gsc); return (GaimSslConnection *)gsc; } @@ -171,14 +190,15 @@ g_return_if_fail(gsc != NULL); ops = gaim_ssl_get_ops(); + (ops->close)(gsc); - if (gsc->inpa) + if (gsc->connect_info != NULL) + gaim_proxy_connect_cancel(gsc->connect_info); + + if (gsc->inpa > 0) gaim_input_remove(gsc->inpa); - if (ops != NULL && ops->close != NULL) - (ops->close)(gsc); - - if (gsc->fd != -1) + if (gsc->fd >= 0) close(gsc->fd); g_free(gsc->host); @@ -195,11 +215,7 @@ g_return_val_if_fail(len > 0, 0); ops = gaim_ssl_get_ops(); - - if (ops != NULL && (ops->read) != NULL) - return (ops->read)(gsc, data, len); - - return 0; + return (ops->read)(gsc, data, len); } size_t @@ -212,11 +228,7 @@ g_return_val_if_fail(len > 0, 0); ops = gaim_ssl_get_ops(); - - if (ops != NULL && (ops->write) != NULL) - return (ops->write)(gsc, data, len); - - return 0; + return (ops->write)(gsc, data, len); } void @@ -245,9 +257,7 @@ return; ops = gaim_ssl_get_ops(); - - if (ops != NULL && ops->uninit != NULL) - ops->uninit(); + ops->uninit(); _ssl_initialized = FALSE; } diff -r ff3db5cdeb9f -r c8ebbc0110f4 src/sslconn.h --- a/src/sslconn.h Thu Aug 17 04:45:11 2006 +0000 +++ b/src/sslconn.h Thu Aug 17 05:47:10 2006 +0000 @@ -54,6 +54,7 @@ int fd; int inpa; + GaimProxyConnectInfo *connect_info; void *private_data; }; @@ -61,13 +62,13 @@ /** * SSL implementation operations structure. * - * Every SSL implementation must provide one of these and register it. + * Every SSL implementation must provide all of these and register it. */ typedef struct { gboolean (*init)(void); void (*uninit)(void); - GaimInputFunction connect_cb; + void (*connect)(GaimSslConnection *gsc); void (*close)(GaimSslConnection *gsc); size_t (*read)(GaimSslConnection *gsc, void *data, size_t len); size_t (*write)(GaimSslConnection *gsc, const void *data, size_t len);