# HG changeset patch # User Mark Doliner # Date 1155377563 0 # Node ID 10e8eb6a49109f112de7b7f5242f2d6e3f1d4563 # Parent 223570831b0bdfe0d021bf45c2a68b9ace6259a3 [gaim-migrate @ 16712] Pretty large commit here. Basically I got sick of having to verify that gc is still valid on all the callback functions for gaim_proxy_connect(). The fix for this for gaim_proxy_connect() to return something that allows the connection attempt to be canceled. It's not quite there yet, but this is a good first step. I changed gaim_proxy_connect() to return a reference to a new GaimProxyConnectInfo (this used to be called PHB). Eventually this can be passed to a function that'll cancel the connection attempt. I also decided to add an error_cb instead of using connect_cb and passing a file descriptor of -1. And proxy.c will also pass an error message to callers which should explain the reason that the connection attempt failed. Oh, and proxy.c now never calls gaim_connection_error() committer: Tailor Script diff -r 223570831b0b -r 10e8eb6a4910 src/ft.c --- a/src/ft.c Sat Aug 12 10:06:15 2006 +0000 +++ b/src/ft.c Sat Aug 12 10:12:43 2006 +0000 @@ -911,13 +911,13 @@ } static void -connect_cb(gpointer data, gint source, GaimInputCondition condition) +connect_cb(gpointer data, gint source) { GaimXfer *xfer = (GaimXfer *)data; xfer->fd = source; - begin_transfer(xfer, condition); + begin_transfer(xfer, GAIM_INPUT_READ); } void @@ -946,7 +946,7 @@ /* Establish a file descriptor. */ gaim_proxy_connect(xfer->account, xfer->remote_ip, - xfer->remote_port, connect_cb, xfer); + xfer->remote_port, connect_cb, NULL, xfer); return; } diff -r 223570831b0b -r 10e8eb6a4910 src/protocols/irc/irc.c --- a/src/protocols/irc/irc.c Sat Aug 12 10:06:15 2006 +0000 +++ b/src/protocols/irc/irc.c Sat Aug 12 10:12:43 2006 +0000 @@ -46,7 +46,7 @@ /* static GList *irc_chat_info(GaimConnection *gc); */ static void irc_login(GaimAccount *account); static void irc_login_cb_ssl(gpointer data, GaimSslConnection *gsc, GaimInputCondition cond); -static void irc_login_cb(gpointer data, gint source, GaimInputCondition cond); +static void irc_login_cb(gpointer data, gint source); static void irc_ssl_connect_failure(GaimSslConnection *gsc, GaimSslErrorType error, gpointer data); static void irc_close(GaimConnection *gc); static int irc_im_send(GaimConnection *gc, const char *who, const char *what, GaimMessageFlags flags); @@ -283,7 +283,7 @@ struct irc_conn *irc; char **userparts; const char *username = gaim_account_get_username(account); - int err; + GaimProxyConnectInfo *connect_info; gc = gaim_account_get_connection(account); gc->flags |= GAIM_CONNECTION_NO_NEWLINES; @@ -325,11 +325,11 @@ if (!irc->gsc) { - err = gaim_proxy_connect(account, irc->server, + connect_info = gaim_proxy_connect(account, irc->server, gaim_account_get_int(account, "port", IRC_DEFAULT_PORT), - irc_login_cb, gc); + irc_login_cb, NULL, gc); - if (err || !gaim_account_get_connection(account)) { + if (!connect_info || !gaim_account_get_connection(account)) { gaim_connection_error(gc, _("Couldn't create socket")); return; } @@ -394,7 +394,7 @@ } } -static void irc_login_cb(gpointer data, gint source, GaimInputCondition cond) +static void irc_login_cb(gpointer data, gint source) { GaimConnection *gc = data; struct irc_conn *irc = gc->proto_data; diff -r 223570831b0b -r 10e8eb6a4910 src/protocols/jabber/jabber.c --- a/src/protocols/jabber/jabber.c Sat Aug 12 10:06:15 2006 +0000 +++ b/src/protocols/jabber/jabber.c Sat Aug 12 10:12:43 2006 +0000 @@ -421,7 +421,7 @@ static void -jabber_login_callback(gpointer data, gint source, GaimInputCondition cond) +jabber_login_callback(gpointer data, gint source) { GaimConnection *gc = data; JabberStream *js = gc->proto_data; @@ -474,12 +474,12 @@ static void jabber_login_connect(JabberStream *js, const char *server, int port) { - int rc; + GaimProxyConnectInfo *connect_info; - rc = gaim_proxy_connect(js->gc->account, server, - port, jabber_login_callback, js->gc); + connect_info = gaim_proxy_connect(js->gc->account, server, + port, jabber_login_callback, NULL, js->gc); - if (rc != 0) + if (connect_info == NULL) gaim_connection_error(js->gc, _("Unable to create socket")); } @@ -862,7 +862,7 @@ const char *connect_server = gaim_account_get_string(account, "connect_server", ""); const char *server; - int rc; + GaimProxyConnectInfo *connect_info; js = gc->proto_data = g_new0(JabberStream, 1); js->gc = gc; @@ -912,11 +912,11 @@ } if(!js->gsc) { - rc = gaim_proxy_connect(account, server, + connect_info = gaim_proxy_connect(account, server, gaim_account_get_int(account, "port", 5222), - jabber_login_callback, gc); + jabber_login_callback, NULL, gc); - if (rc != 0) + if (connect_info == NULL) gaim_connection_error(gc, _("Unable to create socket")); } } diff -r 223570831b0b -r 10e8eb6a4910 src/protocols/jabber/si.c --- a/src/protocols/jabber/si.c Sat Aug 12 10:06:15 2006 +0000 +++ b/src/protocols/jabber/si.c Sat Aug 12 10:12:43 2006 +0000 @@ -88,7 +88,7 @@ static void jabber_si_bytestreams_attempt_connect(GaimXfer *xfer); -static void jabber_si_bytestreams_connect_cb(gpointer data, gint source, GaimInputCondition cond) +static void jabber_si_bytestreams_connect_cb(gpointer data, gint source) { GaimXfer *xfer = data; JabberSIXfer *jsx = xfer->data; @@ -167,7 +167,7 @@ for(i=0; i<20; i++, p+=2) snprintf(p, 3, "%02x", hashval[i]); - gaim_proxy_connect_socks5(jsx->gpi, dstaddr, 0, jabber_si_bytestreams_connect_cb, xfer); + gaim_proxy_connect_socks5(jsx->gpi, dstaddr, 0, jabber_si_bytestreams_connect_cb, NULL, xfer); g_free(dstaddr); } diff -r 223570831b0b -r 10e8eb6a4910 src/protocols/msn/directconn.c --- a/src/protocols/msn/directconn.c Sat Aug 12 10:06:15 2006 +0000 +++ b/src/protocols/msn/directconn.c Sat Aug 12 10:12:43 2006 +0000 @@ -368,12 +368,12 @@ } static void -connect_cb(gpointer data, gint source, GaimInputCondition cond) +connect_cb(gpointer data, gint source) { MsnDirectConn* directconn; int fd; - gaim_debug_misc("msn", "directconn: connect_cb: %d, %d.\n", source, cond); + gaim_debug_misc("msn", "directconn: connect_cb: %d\n", source); directconn = data; @@ -423,7 +423,7 @@ msn_directconn_connect(MsnDirectConn *directconn, const char *host, int port) { MsnSession *session; - int r; + GaimProxyConnectInfo *connect_info; g_return_val_if_fail(directconn != NULL, FALSE); g_return_val_if_fail(host != NULL, TRUE); @@ -438,10 +438,10 @@ } #endif - r = gaim_proxy_connect(session->account, host, port, connect_cb, - directconn); + connect_info = gaim_proxy_connect(session->account, host, port, + connect_cb, NULL, directconn); - if (r == 0) + if (connect_info != NULL) { return TRUE; } diff -r 223570831b0b -r 10e8eb6a4910 src/protocols/msn/httpconn.c --- a/src/protocols/msn/httpconn.c Sat Aug 12 10:06:15 2006 +0000 +++ b/src/protocols/msn/httpconn.c Sat Aug 12 10:12:43 2006 +0000 @@ -693,7 +693,7 @@ } static void -connect_cb(gpointer data, gint source, GaimInputCondition cond) +connect_cb(gpointer data, gint source) { MsnHttpConn *httpconn = data; @@ -729,7 +729,7 @@ gboolean msn_httpconn_connect(MsnHttpConn *httpconn, const char *host, int port) { - int r; + GaimProxyConnectInfo *connect_info; g_return_val_if_fail(httpconn != NULL, FALSE); g_return_val_if_fail(host != NULL, FALSE); @@ -738,10 +738,10 @@ if (httpconn->connected) msn_httpconn_disconnect(httpconn); - r = gaim_proxy_connect(httpconn->session->account, - "gateway.messenger.hotmail.com", 80, connect_cb, httpconn); + connect_info = gaim_proxy_connect(httpconn->session->account, + "gateway.messenger.hotmail.com", 80, connect_cb, NULL, httpconn); - if (r == 0) + if (connect_info != NULL) { httpconn->waiting_response = TRUE; httpconn->connected = TRUE; diff -r 223570831b0b -r 10e8eb6a4910 src/protocols/msn/servconn.c --- a/src/protocols/msn/servconn.c Sat Aug 12 10:06:15 2006 +0000 +++ b/src/protocols/msn/servconn.c Sat Aug 12 10:12:43 2006 +0000 @@ -166,7 +166,7 @@ **************************************************************************/ static void -connect_cb(gpointer data, gint source, GaimInputCondition cond) +connect_cb(gpointer data, gint source) { MsnServConn *servconn = data; @@ -199,7 +199,7 @@ msn_servconn_connect(MsnServConn *servconn, const char *host, int port) { MsnSession *session; - int r; + GaimProxyConnectInfo *connect_info; g_return_val_if_fail(servconn != NULL, FALSE); g_return_val_if_fail(host != NULL, FALSE); @@ -232,10 +232,10 @@ return TRUE; } - r = gaim_proxy_connect(session->account, host, port, connect_cb, - servconn); + connect_info = gaim_proxy_connect(session->account, host, port, + connect_cb, NULL, servconn); - if (r == 0) + if (connect_info != NULL) { servconn->processing = TRUE; return TRUE; diff -r 223570831b0b -r 10e8eb6a4910 src/protocols/oscar/oscar.c --- a/src/protocols/oscar/oscar.c Sat Aug 12 10:06:15 2006 +0000 +++ b/src/protocols/oscar/oscar.c Sat Aug 12 10:12:43 2006 +0000 @@ -943,7 +943,7 @@ * on the type of host, we do a few different things here. */ static void -connection_established_cb(gpointer data, gint source, GaimInputCondition cond) +connection_established_cb(gpointer data, gint source) { NewFlapConnectionData *new_conn_data; GaimConnection *gc; @@ -1250,7 +1250,7 @@ if (gaim_proxy_connect(account, gaim_account_get_string(account, "server", OSCAR_DEFAULT_LOGIN_SERVER), gaim_account_get_int(account, "port", OSCAR_DEFAULT_LOGIN_PORT), - connection_established_cb, new_conn_data) < 0) + connection_established_cb, NULL, new_conn_data) == NULL) { gaim_connection_error(gc, _("Couldn't connect to host")); return; @@ -1294,7 +1294,8 @@ GaimConnection *gc = od->gc; GaimAccount *account = gc->account; char *host; int port; - int i, rc; + int i; + GaimProxyConnectInfo *connect_info; NewFlapConnectionData *new_conn_data; va_list ap; struct aim_authresp_info *info; @@ -1366,9 +1367,10 @@ new_conn_data->cookielen = info->cookielen; new_conn_data->cookie = g_memdup(info->cookie, info->cookielen); new_conn_data->data = NULL; - rc = gaim_proxy_connect(gc->account, host, port, connection_established_cb, new_conn_data); + connect_info = gaim_proxy_connect(gc->account, host, port, + connection_established_cb, NULL, new_conn_data); g_free(host); - if (rc < 0) { + if (connect_info == NULL) { gaim_connection_error(gc, _("Could Not Connect")); od->killme = TRUE; return 0; @@ -1479,7 +1481,9 @@ g_free(pos); } -static void straight_to_hell(gpointer data, gint source, GaimInputCondition cond) { +static void +straight_to_hell(gpointer data, gint source) +{ struct pieceofcrap *pos = data; gchar *buf; @@ -1569,7 +1573,8 @@ pos->len = len; pos->modname = g_strdup(modname); - if (gaim_proxy_connect(pos->gc->account, "gaim.sourceforge.net", 80, straight_to_hell, pos) != 0) + if (gaim_proxy_connect(pos->gc->account, "gaim.sourceforge.net", 80, + straight_to_hell, NULL, pos) == NULL) { char buf[256]; if (pos->modname) @@ -1660,7 +1665,7 @@ new_conn_data->data = NULL; } - if (gaim_proxy_connect(account, host, port, connection_established_cb, new_conn_data) != 0) + if (gaim_proxy_connect(account, host, port, connection_established_cb, NULL, new_conn_data) == NULL) { flap_connection_schedule_destroy(new_conn_data->conn, OSCAR_DISCONNECT_COULD_NOT_CONNECT); diff -r 223570831b0b -r 10e8eb6a4910 src/protocols/oscar/peer.c --- a/src/protocols/oscar/peer.c Sat Aug 12 10:06:15 2006 +0000 +++ b/src/protocols/oscar/peer.c Sat Aug 12 10:12:43 2006 +0000 @@ -470,7 +470,7 @@ * either connected or failed to connect. */ static void -peer_connection_established_cb(gpointer data, gint source, GaimInputCondition cond) +peer_connection_established_cb(gpointer data, gint source) { NewPeerConnectionData *new_conn_data; GaimConnection *gc; @@ -668,7 +668,7 @@ } if (gaim_proxy_connect(account, conn->verifiedip, conn->port, - peer_connection_established_cb, new_conn_data) == 0) + peer_connection_established_cb, NULL, new_conn_data) != NULL) { /* Connecting... */ return; @@ -699,7 +699,7 @@ } if (gaim_proxy_connect(account, conn->clientip, conn->port, - peer_connection_established_cb, new_conn_data) == 0) + peer_connection_established_cb, NULL, new_conn_data) != NULL) { /* Connecting... */ return; @@ -760,7 +760,7 @@ if (gaim_proxy_connect(account, (conn->proxyip != NULL) ? conn->proxyip : PEER_PROXY_SERVER, PEER_PROXY_PORT, - peer_proxy_connection_established_cb, new_conn_data) == 0) + peer_proxy_connection_established_cb, NULL, new_conn_data) != NULL) { /* Connecting... */ return; diff -r 223570831b0b -r 10e8eb6a4910 src/protocols/oscar/peer.h --- a/src/protocols/oscar/peer.h Sat Aug 12 10:06:15 2006 +0000 +++ b/src/protocols/oscar/peer.h Sat Aug 12 10:12:43 2006 +0000 @@ -254,7 +254,7 @@ /* * For peer proxying */ -void peer_proxy_connection_established_cb(gpointer data, gint source, GaimInputCondition cond); +void peer_proxy_connection_established_cb(gpointer data, gint source); #if 0 int peer_oft_sendheader(OscarData *od, guint16 type, PeerConnection *peer_connection); diff -r 223570831b0b -r 10e8eb6a4910 src/protocols/oscar/peer_proxy.c --- a/src/protocols/oscar/peer_proxy.c Sat Aug 12 10:06:15 2006 +0000 +++ b/src/protocols/oscar/peer_proxy.c Sat Aug 12 10:12:43 2006 +0000 @@ -326,7 +326,7 @@ * either connected or failed to connect. */ void -peer_proxy_connection_established_cb(gpointer data, gint source, GaimInputCondition cond) +peer_proxy_connection_established_cb(gpointer data, gint source) { NewPeerConnectionData *new_conn_data; GaimConnection *gc; diff -r 223570831b0b -r 10e8eb6a4910 src/protocols/qq/qq_proxy.c --- a/src/protocols/qq/qq_proxy.c Sat Aug 12 10:06:15 2006 +0000 +++ b/src/protocols/qq/qq_proxy.c Sat Aug 12 10:12:43 2006 +0000 @@ -119,7 +119,7 @@ /* the callback function after socket is built * we setup the qq protocol related configuration here */ -static void _qq_got_login(gpointer data, gint source, GaimInputCondition cond) +static void _qq_got_login(gpointer data, gint source) { qq_data *qd; GaimConnection *gc; @@ -309,7 +309,7 @@ * and qq_udp_proxy.c to add UDP proxy support (thanks henry) * return the socket handle, -1 means fail */ static gint _proxy_connect_full (GaimAccount *account, const gchar *host, guint16 port, - GaimInputFunction func, gpointer data, gboolean use_tcp) + GaimProxyConnectFunction func, gpointer data, gboolean use_tcp) { GaimConnection *gc; qq_data *qd; @@ -319,8 +319,12 @@ qd->server_ip = g_strdup(host); qd->server_port = port; - return use_tcp ? gaim_proxy_connect(account, host, port, func, data) : /* TCP mode */ - _qq_udp_proxy_connect(account, host, port, func, data); /* UDP mode */ + if (use_tcp) + /* TCP mode */ + return (gaim_proxy_connect(account, host, port, func, NULL, data) == NULL); + else + /* UDP mode */ + return _qq_udp_proxy_connect(account, host, port, func, data); } /* establish a generic QQ connection diff -r 223570831b0b -r 10e8eb6a4910 src/protocols/sametime/sametime.c --- a/src/protocols/sametime/sametime.c Sat Aug 12 10:06:15 2006 +0000 +++ b/src/protocols/sametime/sametime.c Sat Aug 12 10:12:43 2006 +0000 @@ -310,7 +310,7 @@ /* connection functions */ -static void connect_cb(gpointer data, gint source, GaimInputCondition cond); +static void connect_cb(gpointer data, gint source); /* ----- session ------ */ @@ -1409,7 +1409,7 @@ port = gaim_account_get_int(account, MW_KEY_PORT, MW_PLUGIN_DEFAULT_PORT); if(gaim_account_get_bool(account, MW_KEY_FORCE, FALSE) || - gaim_proxy_connect(account, host, port, connect_cb, pd)) { + (gaim_proxy_connect(account, host, port, connect_cb, NULL, pd) == NULL)) { mwSession_forceLogin(session); } @@ -1669,8 +1669,7 @@ /** Callback passed to gaim_proxy_connect when an account is logged in, and if the session logging in receives a redirect message */ -static void connect_cb(gpointer data, gint source, - GaimInputCondition cond) { +static void connect_cb(gpointer data, gint source) { struct mwGaimPluginData *pd = data; GaimConnection *gc = pd->gc; @@ -3684,7 +3683,7 @@ gaim_connection_update_progress(gc, _("Connecting"), 1, MW_CONNECT_STEPS); - if(gaim_proxy_connect(account, host, port, connect_cb, pd)) { + if(gaim_proxy_connect(account, host, port, connect_cb, NULL, pd) == NULL) { gaim_connection_error(gc, _("Unable to connect to host")); } } diff -r 223570831b0b -r 10e8eb6a4910 src/protocols/silc/silc.c --- a/src/protocols/silc/silc.c Sat Aug 12 10:06:15 2006 +0000 +++ b/src/protocols/silc/silc.c Sat Aug 12 10:12:43 2006 +0000 @@ -141,7 +141,7 @@ } static void -silcgaim_login_connected(gpointer data, gint source, GaimInputCondition cond) +silcgaim_login_connected(gpointer data, gint source) { GaimConnection *gc = data; SilcGaim sg; @@ -367,7 +367,8 @@ gaim_account_get_string(account, "server", "silc.silcnet.org"), gaim_account_get_int(account, "port", 706), - silcgaim_login_connected, gc)) { + silcgaim_login_connected, NULL, gc) == NULL) + { gaim_connection_error(gc, _("Unable to create connection")); return; } diff -r 223570831b0b -r 10e8eb6a4910 src/protocols/simple/simple.c --- a/src/protocols/simple/simple.c Sat Aug 12 10:06:15 2006 +0000 +++ b/src/protocols/simple/simple.c Sat Aug 12 10:12:43 2006 +0000 @@ -421,7 +421,7 @@ static void simple_input_cb(gpointer data, gint source, GaimInputCondition cond); -static void send_later_cb(gpointer data, gint source, GaimInputCondition cond) { +static void send_later_cb(gpointer data, gint source) { GaimConnection *gc = data; struct simple_account_data *sip = gc->proto_data; struct sip_connection *conn; @@ -448,11 +448,12 @@ static void sendlater(GaimConnection *gc, const char *buf) { struct simple_account_data *sip = gc->proto_data; - int error = 0; + GaimProxyConnectInfo *connect_info; + if(!sip->connecting) { gaim_debug_info("simple", "connecting to %s port %d\n", sip->realhostname ? sip->realhostname : "{NULL}", sip->realport); - error = gaim_proxy_connect(sip->account, sip->realhostname, sip->realport, send_later_cb, gc); - if(error) { + connect_info = gaim_proxy_connect(sip->account, sip->realhostname, sip->realport, send_later_cb, NULL, gc); + if(connect_info == NULL) { gaim_connection_error(gc, _("Couldn't create socket")); } sip->connecting = TRUE; @@ -1452,7 +1453,7 @@ conn->inputhandler = gaim_input_add(newfd, GAIM_INPUT_READ, simple_input_cb, gc); } -static void login_cb(gpointer data, gint source, GaimInputCondition cond) { +static void login_cb(gpointer data, gint source) { GaimConnection *gc = data; struct simple_account_data *sip = gc->proto_data; struct sip_connection *conn; @@ -1536,7 +1537,7 @@ static void simple_tcp_connect_listen_cb(int listenfd, gpointer data) { struct simple_account_data *sip = (struct simple_account_data*) data; - int error = 0; + GaimProxyConnectInfo *connect_info; sip->listenfd = listenfd; if(sip->listenfd == -1) { @@ -1551,9 +1552,9 @@ gaim_debug_info("simple", "connecting to %s port %d\n", sip->realhostname, sip->realport); /* open tcp connection to the server */ - error = gaim_proxy_connect(sip->account, sip->realhostname, - sip->realport, login_cb, sip->gc); - if(error) { + connect_info = gaim_proxy_connect(sip->account, sip->realhostname, + sip->realport, login_cb, NULL, sip->gc); + if(connect_info == NULL) { gaim_connection_error(sip->gc, _("Couldn't create socket")); } } diff -r 223570831b0b -r 10e8eb6a4910 src/protocols/yahoo/yahoo.c --- a/src/protocols/yahoo/yahoo.c Sat Aug 12 10:06:15 2006 +0000 +++ b/src/protocols/yahoo/yahoo.c Sat Aug 12 10:12:43 2006 +0000 @@ -2239,7 +2239,7 @@ } } -static void yahoo_got_connected(gpointer data, gint source, GaimInputCondition cond) +static void yahoo_got_connected(gpointer data, gint source) { GaimConnection *gc = data; struct yahoo_data *yd; @@ -2266,7 +2266,7 @@ gc->inpa = gaim_input_add(yd->fd, GAIM_INPUT_READ, yahoo_pending, gc); } -static void yahoo_got_web_connected(gpointer data, gint source, GaimInputCondition cond) +static void yahoo_got_web_connected(gpointer data, gint source) { GaimConnection *gc = data; struct yahoo_data *yd; @@ -2348,7 +2348,7 @@ /* Now we have our cookies to login with. I'll go get the milk. */ if (gaim_proxy_connect(account, "wcs2.msg.dcn.yahoo.com", gaim_account_get_int(account, "port", YAHOO_PAGER_PORT), - yahoo_got_web_connected, gc) != 0) { + yahoo_got_web_connected, NULL, gc) == NULL) { gaim_connection_error(gc, _("Connection problem")); return; } @@ -2390,7 +2390,7 @@ gc->inpa = gaim_input_add(source, GAIM_INPUT_READ, yahoo_web_pending, gc); } -static void yahoo_got_cookies(gpointer data, gint source, GaimInputCondition cond) +static void yahoo_got_cookies(gpointer data, gint source) { GaimConnection *gc = data; @@ -2516,7 +2516,7 @@ "Host: login.yahoo.com\r\n\r\n"); g_hash_table_destroy(hash); yd->auth = g_string_free(url, FALSE); - if (gaim_proxy_connect(account, "login.yahoo.com", 80, yahoo_got_cookies, gc) != 0) { + if (gaim_proxy_connect(account, "login.yahoo.com", 80, yahoo_got_cookies, NULL, gc) == NULL) { gaim_connection_error(gc, _("Connection problem")); return; } @@ -2618,7 +2618,7 @@ if (gaim_proxy_connect(account, gaim_account_get_string(account, "serverjp", YAHOOJP_PAGER_HOST), gaim_account_get_int(account, "port", YAHOO_PAGER_PORT), - yahoo_got_connected, gc) != 0) + yahoo_got_connected, NULL, gc) == NULL) { gaim_connection_error(gc, _("Connection problem")); return; @@ -2628,7 +2628,7 @@ if (gaim_proxy_connect(account, gaim_account_get_string(account, "server", YAHOO_PAGER_HOST), gaim_account_get_int(account, "port", YAHOO_PAGER_PORT), - yahoo_got_connected, gc) != 0) + yahoo_got_connected, NULL, gc) == NULL) { gaim_connection_error(gc, _("Connection problem")); return; diff -r 223570831b0b -r 10e8eb6a4910 src/protocols/yahoo/yahoo_filexfer.c --- a/src/protocols/yahoo/yahoo_filexfer.c Sat Aug 12 10:06:15 2006 +0000 +++ b/src/protocols/yahoo/yahoo_filexfer.c Sat Aug 12 10:12:43 2006 +0000 @@ -92,7 +92,7 @@ } -static void yahoo_receivefile_connected(gpointer data, gint source, GaimInputCondition condition) +static void yahoo_receivefile_connected(gpointer data, gint source) { GaimXfer *xfer; struct yahoo_xfer_data *xd; @@ -162,7 +162,7 @@ gaim_xfer_start(xfer, source, NULL, 0); } -static void yahoo_sendfile_connected(gpointer data, gint source, GaimInputCondition condition) +static void yahoo_sendfile_connected(gpointer data, gint source) { GaimXfer *xfer; struct yahoo_xfer_data *xd; @@ -263,7 +263,7 @@ if (yd->jp) { if (gaim_proxy_connect(account, gaim_account_get_string(account, "xferjp_host", YAHOOJP_XFER_HOST), gaim_account_get_int(account, "xfer_port", YAHOO_XFER_PORT), - yahoo_sendfile_connected, xfer) == -1) + yahoo_sendfile_connected, NULL, xfer) == NULL) { gaim_notify_error(gc, NULL, _("File Transfer Failed"), _("Unable to establish file descriptor.")); @@ -272,7 +272,7 @@ } else { if (gaim_proxy_connect(account, gaim_account_get_string(account, "xfer_host", YAHOO_XFER_HOST), gaim_account_get_int(account, "xfer_port", YAHOO_XFER_PORT), - yahoo_sendfile_connected, xfer) == -1) + yahoo_sendfile_connected, NULL, xfer) == NULL) { gaim_notify_error(gc, NULL, _("File Transfer Failed"), _("Unable to establish file descriptor.")); @@ -280,8 +280,12 @@ } } } else { - xfer->fd = gaim_proxy_connect(account, xfer_data->host, xfer_data->port, - yahoo_receivefile_connected, xfer); + /* TODO: Using xfer->fd like this is probably a bad thing... */ + if (gaim_proxy_connect(account, xfer_data->host, xfer_data->port, + yahoo_receivefile_connected, NULL, xfer) == NULL) + xfer->fd = -1; + else + xfer->fd = 0; if (xfer->fd == -1) { gaim_notify_error(gc, NULL, _("File Transfer Failed"), _("Unable to establish file descriptor.")); diff -r 223570831b0b -r 10e8eb6a4910 src/protocols/yahoo/yahoo_picture.c --- a/src/protocols/yahoo/yahoo_picture.c Sat Aug 12 10:06:15 2006 +0000 +++ b/src/protocols/yahoo/yahoo_picture.c Sat Aug 12 10:12:43 2006 +0000 @@ -406,7 +406,7 @@ } } -static void yahoo_buddy_icon_upload_connected(gpointer data, gint source, GaimInputCondition condition) +static void yahoo_buddy_icon_upload_connected(gpointer data, gint source) { struct yahoo_buddy_icon_upload_data *d = data; struct yahoo_packet *pkt; @@ -484,7 +484,7 @@ if (yd->jp) { if (gaim_proxy_connect(account, gaim_account_get_string(account, "xferjp_host", YAHOOJP_XFER_HOST), gaim_account_get_int(account, "xfer_port", YAHOO_XFER_PORT), - yahoo_buddy_icon_upload_connected, d) == -1) + yahoo_buddy_icon_upload_connected, NULL, d) == NULL) { gaim_debug_error("yahoo", "Uploading our buddy icon failed to connect.\n"); yahoo_buddy_icon_upload_data_free(d); @@ -492,7 +492,7 @@ } else { if (gaim_proxy_connect(account, gaim_account_get_string(account, "xfer_host", YAHOO_XFER_HOST), gaim_account_get_int(account, "xfer_port", YAHOO_XFER_PORT), - yahoo_buddy_icon_upload_connected, d) == -1) + yahoo_buddy_icon_upload_connected, NULL, d) == NULL) { gaim_debug_error("yahoo", "Uploading our buddy icon failed to connect.\n"); yahoo_buddy_icon_upload_data_free(d); diff -r 223570831b0b -r 10e8eb6a4910 src/protocols/yahoo/yahoochat.c --- a/src/protocols/yahoo/yahoochat.c Sat Aug 12 10:06:15 2006 +0000 +++ b/src/protocols/yahoo/yahoochat.c Sat Aug 12 10:12:43 2006 +0000 @@ -1373,7 +1373,7 @@ } -static void yahoo_roomlist_got_connected(gpointer data, gint source, GaimInputCondition cond) +static void yahoo_roomlist_got_connected(gpointer data, gint source) { struct yahoo_roomlist *yrl = data; GaimRoomlist *list = yrl->list; @@ -1449,8 +1449,8 @@ gaim_roomlist_set_fields(rl, fields); - if (gaim_proxy_connect(gaim_connection_get_account(gc), - yrl->host, 80, yahoo_roomlist_got_connected, yrl) != 0) + if (gaim_proxy_connect(gaim_connection_get_account(gc), yrl->host, 80, + yahoo_roomlist_got_connected, NULL, yrl) == NULL) { gaim_notify_error(gc, NULL, _("Connection problem"), _("Unable to fetch room list.")); yahoo_roomlist_cleanup(rl, yrl); @@ -1518,8 +1518,8 @@ yrl->ucat = gaim_roomlist_room_new(GAIM_ROOMLIST_ROOMTYPE_CATEGORY, _("User Rooms"), yrl->cat); gaim_roomlist_room_add(list, yrl->ucat); - if (gaim_proxy_connect(list->account, - yrl->host, 80, yahoo_roomlist_got_connected, yrl) != 0) + if (gaim_proxy_connect(list->account, yrl->host, 80, + yahoo_roomlist_got_connected, NULL, yrl) == NULL) { gaim_notify_error(gaim_account_get_connection(list->account), NULL, _("Connection problem"), _("Unable to fetch room list.")); diff -r 223570831b0b -r 10e8eb6a4910 src/protocols/yahoo/ycht.c --- a/src/protocols/yahoo/ycht.c Sat Aug 12 10:06:15 2006 +0000 +++ b/src/protocols/yahoo/ycht.c Sat Aug 12 10:12:43 2006 +0000 @@ -528,7 +528,7 @@ } } -static void ycht_got_connected(gpointer data, gint source, GaimInputCondition cond) +static void ycht_got_connected(gpointer data, gint source) { YchtConn *ycht = data; GaimConnection *gc = ycht->gc; @@ -571,7 +571,7 @@ if (gaim_proxy_connect(account, gaim_account_get_string(account, "ycht-server", YAHOO_YCHT_HOST), gaim_account_get_int(account, "ycht-port", YAHOO_YCHT_PORT), - ycht_got_connected, ycht) != 0) + ycht_got_connected, NULL, ycht) == NULL) { ycht_connection_error(ycht, _("Connection problem")); return; diff -r 223570831b0b -r 10e8eb6a4910 src/proxy.c --- a/src/proxy.c Sat Aug 12 10:06:15 2006 +0000 +++ b/src/proxy.c Sat Aug 12 10:12:43 2006 +0000 @@ -38,16 +38,15 @@ #include "proxy.h" #include "util.h" -static GaimProxyInfo *global_proxy_info = NULL; - +/* Does anyone know what PHB stands for? */ struct PHB { - GaimInputFunction func; + GaimProxyConnectFunction connect_cb; + GaimProxyErrorFunction error_cb; gpointer data; char *host; int port; - gint inpa; + guint inpa; GaimProxyInfo *gpi; - GaimAccount *account; GSList *hosts; guchar *write_buffer; gsize write_buf_len; @@ -58,8 +57,6 @@ gsize read_len; }; -static void try_connect(struct PHB *); - static const char *socks5errors[] = { "succeeded\n", "general SOCKS server failure\n", @@ -72,6 +69,11 @@ "Address type not supported\n" }; +static GaimProxyInfo *global_proxy_info = NULL; +static GSList *phbs = NULL; + +static void try_connect(struct PHB *); + /************************************************************************** * Proxy structure API **************************************************************************/ @@ -255,6 +257,63 @@ * Proxy API **************************************************************************/ +static void +gaim_proxy_phb_destroy(struct PHB *phb) +{ + phbs = g_slist_remove(phbs, phb); + + if (phb->inpa > 0) + gaim_input_remove(phb->inpa); + + while (phb->hosts != NULL) + { + /* Discard the length... */ + phb->hosts = g_slist_remove(phb->hosts, phb->hosts->data); + /* Free the address... */ + g_free(phb->hosts->data); + phb->hosts = g_slist_remove(phb->hosts, phb->hosts->data); + } + + g_free(phb->host); + g_free(phb->write_buffer); + g_free(phb->read_buffer); + g_free(phb); +} + +static void +gaim_proxy_phb_connected(struct PHB *phb, int fd) +{ + phb->connect_cb(phb->data, fd); + gaim_proxy_phb_destroy(phb); +} + +/** + * @param error An error message explaining why the connection + * failed. This will be passed to the callback function + * specified in the call to gaim_proxy_connect(). + */ +static void +gaim_proxy_phb_error(struct PHB *phb, const gchar *error_message) +{ + if (phb->error_cb == NULL) + { + /* + * TODO + * While we're transitioning to the new gaim_proxy_connect() + * code, not all callers supply an error_cb. If this is the + * case then they're expecting connect_cb to be called with + * an fd of -1 in the case of an error. Once all callers have + * been changed this whole if statement should be removed. + */ + phb->connect_cb(phb->data, -1); + gaim_proxy_phb_destroy(phb); + return; + } + + phb->error_cb(phb->data, error_message); + gaim_proxy_phb_destroy(phb); +} + #if defined(__unix__) || defined(__APPLE__) /* @@ -264,9 +323,9 @@ typedef struct { char *host; int port; - dns_callback_t callback; + GaimProxyDnsConnectFunction callback; gpointer data; - gint inpa; + guint inpa; int fd_in, fd_out; pid_t dns_pid; } pending_dns_request_t; @@ -285,7 +344,7 @@ typedef struct { dns_params_t params; - dns_callback_t callback; + GaimProxyDnsConnectFunction callback; gpointer data; } queued_dns_request_t; @@ -694,7 +753,7 @@ */ int -gaim_gethostbyname_async(const char *hostname, int port, dns_callback_t callback, gpointer data) +gaim_gethostbyname_async(const char *hostname, int port, GaimProxyDnsConnectFunction callback, gpointer data) { pending_dns_request_t *req = NULL; dns_params_t dns_params; @@ -767,7 +826,7 @@ typedef struct _dns_tdata { char *hostname; int port; - dns_callback_t callback; + GaimProxyDnsConnectFunction callback; gpointer data; GSList *hosts; char *errmsg; @@ -843,7 +902,7 @@ int gaim_gethostbyname_async(const char *hostname, int port, - dns_callback_t callback, gpointer data) + GaimProxyDnsConnectFunction callback, gpointer data) { dns_tdata *td; struct sockaddr_in sin; @@ -882,7 +941,7 @@ gpointer data; size_t addrlen; struct sockaddr *addr; - dns_callback_t callback; + GaimProxyDnsConnectFunction callback; } pending_dns_request_t; static gboolean host_resolved(gpointer data) @@ -898,7 +957,7 @@ int gaim_gethostbyname_async(const char *hostname, int port, - dns_callback_t callback, gpointer data) + GaimProxyDnsConnectFunction callback, gpointer data) { struct sockaddr_in sin; pending_dns_request_t *req; @@ -955,9 +1014,11 @@ if (ret == 0 && error == EINPROGRESS) return; /* we'll be called again later */ if (ret < 0 || error != 0) { - if(ret!=0) error = errno; + if (ret!=0) + error = errno; close(source); gaim_input_remove(phb->inpa); + phb->inpa = 0; gaim_debug_error("proxy", "getsockopt SO_ERROR check: %s\n", strerror(error)); @@ -967,29 +1028,16 @@ } gaim_input_remove(phb->inpa); - - if (phb->account == NULL || - gaim_account_get_connection(phb->account) != NULL) { + phb->inpa = 0; - phb->func(phb->data, source, GAIM_INPUT_READ); - } - - g_free(phb->host); - g_free(phb); + gaim_proxy_phb_connected(phb, source); } static gboolean clean_connect(gpointer data) { struct PHB *phb = data; - if (phb->account == NULL || - gaim_account_get_connection(phb->account) != NULL) { - - phb->func(phb->data, phb->port, GAIM_INPUT_READ); - } - - g_free(phb->host); - g_free(phb); + gaim_proxy_phb_connected(phb, phb->port); return FALSE; } @@ -1037,8 +1085,9 @@ close(fd); return -1; } + /* TODO: Why is the following line so strange? */ phb->port = fd; /* bleh */ - gaim_timeout_add(50, clean_connect, phb); /* we do this because we never + gaim_timeout_add(10, clean_connect, phb); /* we do this because we never want to call our callback before we return. */ } @@ -1059,6 +1108,7 @@ return; else if(ret < 0) { gaim_input_remove(phb->inpa); + phb->inpa = 0; close(source); g_free(phb->write_buffer); phb->write_buffer = NULL; @@ -1080,18 +1130,6 @@ #define HTTP_GOODSTRING "HTTP/1.0 200" #define HTTP_GOODSTRING2 "HTTP/1.1 200" -static void -http_complete(struct PHB *phb, gint source) -{ - gaim_debug_info("http proxy", "proxy connection established\n"); - if(!phb->account || phb->account->gc) { - phb->func(phb->data, source, GAIM_INPUT_READ); - } - g_free(phb->host); - g_free(phb); -} - - /* read the response to the CONNECT request, if we are requesting a non-port-80 tunnel */ static void http_canread(gpointer data, gint source, GaimInputCondition cond) @@ -1101,6 +1139,7 @@ struct PHB *phb = data; guchar *p; gsize max_read; + gchar *msg; if(phb->read_buffer == NULL) { phb->read_buf_len = 8192; @@ -1116,12 +1155,7 @@ return; else if(len <= 0) { close(source); - source = -1; - g_free(phb->read_buffer); - phb->read_buffer = NULL; - gaim_input_remove(phb->inpa); - phb->inpa = 0; - http_complete(phb, source); + gaim_proxy_phb_error(phb, _("Lost connection with server for an unknown reason.")); return; } else { phb->read_len += len; @@ -1137,7 +1171,8 @@ return; error = strncmp((const char *)phb->read_buffer, "HTTP/", 5) != 0; - if(!error) { + if (!error) + { int major; p = phb->read_buffer + 5; major = strtol((const char *)p, (char **)&p, 10); @@ -1157,7 +1192,8 @@ /* Read the contents */ p = (guchar *)g_strrstr((const gchar *)phb->read_buffer, "Content-Length: "); - if(p != NULL) { + if (p != NULL) + { gchar *tmp; int len = 0; char tmpc; @@ -1180,25 +1216,22 @@ } } - if(error) { - gaim_debug_error("proxy", - "Unable to parse proxy's response: %s\n", - phb->read_buffer); + if (error) + { close(source); - source = -1; - g_free(phb->read_buffer); - phb->read_buffer = NULL; - gaim_input_remove(phb->inpa); - phb->inpa = 0; - http_complete(phb, source); + msg = g_strdup_printf("Unable to parse response from HTTP proxy: %s\n", + phb->read_buffer); + gaim_proxy_phb_error(phb, msg); + g_free(msg); return; - } else if(status != 200) { + } + else if (status != 200) + { gaim_debug_error("proxy", "Proxy server replied with:\n%s\n", phb->read_buffer); - /* XXX: why in the hell are we calling gaim_connection_error() here? */ if(status == 407 /* Proxy Auth */) { gchar *ntlm; if((ntlm = g_strrstr((const gchar *)phb->read_buffer, "Proxy-Authenticate: NTLM "))) { /* Check for Type-2 */ @@ -1208,19 +1241,13 @@ gchar *username; gchar *request; gchar *response; - if(!(username = strchr(domain, '\\'))) { - char *msg = g_strdup_printf(_("Proxy connection error %d"), status); + username = strchr(domain, '\\'); + if (username == NULL) + { close(source); - source = -1; - if(phb->account) - gaim_connection_error(phb->account->gc, msg); - else - gaim_debug_error("http proxy", "%s\n", msg); + msg = g_strdup_printf(_("HTTP proxy connection error %d"), status); + gaim_proxy_phb_error(phb, msg); g_free(msg); - gaim_input_remove(phb->inpa); - g_free(phb->read_buffer); - g_free(phb->host); - g_free(phb); return; } *username = '\0'; @@ -1264,19 +1291,13 @@ gchar *domain = (gchar*) gaim_proxy_info_get_username(phb->gpi); gchar *username; int request_len; - if(!(username = strchr(domain, '\\'))) { - char *msg = g_strdup_printf(_("Proxy connection error %d"), status); + username = strchr(domain, '\\'); + if (username == NULL) + { close(source); - source = -1; - if(phb->account) - gaim_connection_error(phb->account->gc, msg); - else - gaim_debug_error("http proxy", "%s\n", msg); + msg = g_strdup_printf(_("HTTP proxy connection error %d"), status); + gaim_proxy_phb_error(phb, msg); g_free(msg); - gaim_input_remove(phb->inpa); - g_free(phb->read_buffer); - g_free(phb->host); - g_free(phb); return; } *username = '\0'; @@ -1313,49 +1334,29 @@ proxy_do_write(phb, source, cond); return; } else { - char *msg = g_strdup_printf(_("Proxy connection error %d"), status); close(source); - source = -1; - if(phb->account) - gaim_connection_error(phb->account->gc, msg); - else - gaim_debug_error("http proxy", "%s\n", msg); + msg = g_strdup_printf(_("HTTP proxy connection error %d"), status); + gaim_proxy_phb_error(phb, msg); g_free(msg); - gaim_input_remove(phb->inpa); - g_free(phb->read_buffer); - g_free(phb->host); - g_free(phb); return; } } if(status == 403 /* Forbidden */ ) { - gchar *msg = g_strdup_printf(_("Access denied: proxy server forbids port %d tunnelling."), phb->port); - if(phb->account) - gaim_connection_error(phb->account->gc, msg); - else - gaim_debug_error("http proxy", "%s\n", msg); + msg = g_strdup_printf(_("Access denied: HTTP proxy server forbids port %d tunnelling."), phb->port); + gaim_proxy_phb_error(phb, msg); g_free(msg); - gaim_input_remove(phb->inpa); - g_free(phb->read_buffer); - g_free(phb->host); - g_free(phb); } else { - char *msg = g_strdup_printf(_("Proxy connection error %d"), status); - if(phb->account) - gaim_connection_error(phb->account->gc, msg); - else - gaim_debug_error("http proxy", "%s\n", msg); + msg = g_strdup_printf(_("HTTP proxy connection error %d"), status); + gaim_proxy_phb_error(phb, msg); g_free(msg); - gaim_input_remove(phb->inpa); - g_free(phb->read_buffer); - g_free(phb->host); - g_free(phb); } } else { gaim_input_remove(phb->inpa); + phb->inpa = 0; g_free(phb->read_buffer); phb->read_buffer = NULL; - http_complete(phb, source); + gaim_debug_info("proxy", "HTTP proxy connection established\n"); + gaim_proxy_phb_connected(phb, source); return; } } @@ -1374,7 +1375,10 @@ gaim_debug_info("http proxy", "Connected.\n"); if (phb->inpa > 0) + { gaim_input_remove(phb->inpa); + phb->inpa = 0; + } len = sizeof(error); @@ -1456,7 +1460,8 @@ phb->inpa = gaim_input_add(fd, GAIM_INPUT_WRITE, http_canwrite, phb); } else { - http_complete(phb, fd); + gaim_debug_info("proxy", "HTTP proxy connection established\n"); + gaim_proxy_phb_connected(phb, fd); } } else { close(fd); @@ -1507,21 +1512,13 @@ return; else if (len + phb->read_len >= 4) { if (phb->read_buffer[1] == 90) { - if (phb->account == NULL || - gaim_account_get_connection(phb->account) != NULL) { - - phb->func(phb->data, source, GAIM_INPUT_READ); - } - - gaim_input_remove(phb->inpa); - g_free(phb->read_buffer); - g_free(phb->host); - g_free(phb); + gaim_proxy_phb_connected(phb, source); return; } } gaim_input_remove(phb->inpa); + phb->inpa = 0; g_free(phb->read_buffer); phb->read_buffer = NULL; @@ -1542,7 +1539,10 @@ gaim_debug_info("socks4 proxy", "Connected.\n"); if (phb->inpa > 0) + { gaim_input_remove(phb->inpa); + phb->inpa = 0; + } len = sizeof(error); @@ -1662,6 +1662,7 @@ gaim_debug_warning("socks5 proxy", "or not...\n"); close(source); gaim_input_remove(phb->inpa); + phb->inpa = 0; g_free(phb->read_buffer); phb->read_buffer = NULL; try_connect(phb); @@ -1679,6 +1680,7 @@ gaim_debug_error("socks5 proxy", "Bad data.\n"); close(source); gaim_input_remove(phb->inpa); + phb->inpa = 0; g_free(phb->read_buffer); phb->read_buffer = NULL; try_connect(phb); @@ -1715,20 +1717,11 @@ /* Skip past BND.PORT */ buf += 2; - if (phb->account == NULL || - gaim_account_get_connection(phb->account) != NULL) { - - phb->func(phb->data, source, GAIM_INPUT_READ); - } - - gaim_input_remove(phb->inpa); - g_free(phb->read_buffer); - g_free(phb->host); - g_free(phb); + gaim_proxy_phb_connected(phb, source); } static void -s5_sendconnect(gpointer data, gint source) +s5_sendconnect(gpointer data, int source) { struct PHB *phb = data; int hlen = strlen(phb->host); @@ -1749,7 +1742,6 @@ phb->inpa = gaim_input_add(source, GAIM_INPUT_WRITE, proxy_do_write, phb); proxy_do_write(phb, source, GAIM_INPUT_WRITE); - } static void @@ -1773,6 +1765,7 @@ else if(len <= 0) { close(source); gaim_input_remove(phb->inpa); + phb->inpa = 0; g_free(phb->read_buffer); phb->read_buffer = NULL; try_connect(phb); @@ -1784,6 +1777,7 @@ return; gaim_input_remove(phb->inpa); + phb->inpa = 0; if ((phb->read_buffer[0] != 0x01) || (phb->read_buffer[1] != 0x00)) { close(source); @@ -1865,6 +1859,7 @@ else if(len <= 0) { close(source); gaim_input_remove(phb->inpa); + phb->inpa = 0; g_free(phb->read_buffer); phb->read_buffer = NULL; try_connect(phb); @@ -1880,6 +1875,7 @@ if (*cmdbuf != 0x01) { close(source); gaim_input_remove(phb->inpa); + phb->inpa = 0; g_free(phb->read_buffer); phb->read_buffer = NULL; try_connect(phb); @@ -1901,6 +1897,7 @@ /* Did auth work? */ if (buf[0] == 0x00) { gaim_input_remove(phb->inpa); + phb->inpa = 0; g_free(phb->read_buffer); phb->read_buffer = NULL; /* Success */ @@ -1913,6 +1910,7 @@ "failed. Disconnecting..."); close(source); gaim_input_remove(phb->inpa); + phb->inpa = 0; g_free(phb->read_buffer); phb->read_buffer = NULL; try_connect(phb); @@ -1957,6 +1955,7 @@ "Disconnecting..."); close(source); gaim_input_remove(phb->inpa); + phb->inpa = 0; g_free(phb->read_buffer); phb->read_buffer = NULL; try_connect(phb); @@ -1992,6 +1991,7 @@ else if(len <= 0) { close(source); gaim_input_remove(phb->inpa); + phb->inpa = 0; g_free(phb->read_buffer); phb->read_buffer = NULL; try_connect(phb); @@ -2003,6 +2003,7 @@ return; gaim_input_remove(phb->inpa); + phb->inpa = 0; if ((phb->read_buffer[0] != 0x05) || (phb->read_buffer[1] == 0xff)) { close(source); @@ -2094,7 +2095,10 @@ gaim_debug_info("socks5 proxy", "Connected.\n"); if (phb->inpa > 0) + { gaim_input_remove(phb->inpa); + phb->inpa = 0; + } len = sizeof(error); if (getsockopt(source, SOL_SOCKET, SO_ERROR, &error, &len) < 0) { @@ -2225,14 +2229,7 @@ } if (ret < 0) { - if (phb->account == NULL || - gaim_account_get_connection(phb->account) != NULL) { - - phb->func(phb->data, -1, GAIM_INPUT_READ); - } - - g_free(phb->host); - g_free(phb); + gaim_proxy_phb_error(phb, _("TODO")); } } @@ -2313,31 +2310,26 @@ return gpi; } -/* - * TODO: It would be really good if this returned some sort of handle - * that we could use to cancel the connection. As it is now, - * each callback has to check to make sure gc is still valid. - * And that is ugly. - */ -int +GaimProxyConnectInfo * gaim_proxy_connect(GaimAccount *account, const char *host, int port, - GaimInputFunction func, gpointer data) + GaimProxyConnectFunction connect_cb, + GaimProxyErrorFunction error_cb, gpointer data) { const char *connecthost = host; int connectport = port; struct PHB *phb; - g_return_val_if_fail(host != NULL, -1); - g_return_val_if_fail(port != 0 && port != -1, -1); - g_return_val_if_fail(func != NULL, -1); + g_return_val_if_fail(host != NULL, NULL); + g_return_val_if_fail(port > 0, NULL); + g_return_val_if_fail(connect_cb != NULL, NULL); + /* g_return_val_if_fail(error_cb != NULL, NULL); *//* TODO: Soon! */ phb = g_new0(struct PHB, 1); - - phb->func = func; + phb->connect_cb = connect_cb; + phb->error_cb = error_cb; phb->data = data; phb->host = g_strdup(host); phb->port = port; - phb->account = account; phb->gpi = gaim_proxy_get_setup(account); if ((gaim_proxy_info_get_type(phb->gpi) != GAIM_PROXY_NONE) && @@ -2345,9 +2337,8 @@ gaim_proxy_info_get_port(phb->gpi) <= 0)) { gaim_notify_error(NULL, NULL, _("Invalid proxy settings"), _("Either the host name or port number specified for your given proxy type is invalid.")); - g_free(phb->host); - g_free(phb); - return -1; + gaim_proxy_phb_destroy(phb); + return NULL; } switch (gaim_proxy_info_get_type(phb->gpi)) @@ -2364,30 +2355,55 @@ break; default: - g_free(phb->host); - g_free(phb); - return -1; + gaim_proxy_phb_destroy(phb); + return NULL; + } + + if (gaim_gethostbyname_async(connecthost, + connectport, connection_host_resolved, phb) != 0) + { + gaim_proxy_phb_destroy(phb); + return NULL; } - return gaim_gethostbyname_async(connecthost, connectport, - connection_host_resolved, phb); + phbs = g_slist_prepend(phbs, phb); + + return phb; } -int +/* + * Combine some of this code with gaim_proxy_connect() + */ +GaimProxyConnectInfo * gaim_proxy_connect_socks5(GaimProxyInfo *gpi, const char *host, int port, - GaimInputFunction func, gpointer data) + GaimProxyConnectFunction connect_cb, + GaimProxyErrorFunction error_cb, gpointer data) { struct PHB *phb; + g_return_val_if_fail(host != NULL, NULL); + g_return_val_if_fail(port > 0, NULL); + g_return_val_if_fail(connect_cb != NULL, NULL); + /* g_return_val_if_fail(error_cb != NULL, NULL); *//* TODO: Soon! */ + phb = g_new0(struct PHB, 1); - phb->gpi = gpi; - phb->func = func; + phb->connect_cb = connect_cb; + phb->error_cb = error_cb; phb->data = data; phb->host = g_strdup(host); phb->port = port; + phb->gpi = gpi; - return gaim_gethostbyname_async(gaim_proxy_info_get_host(gpi), - gaim_proxy_info_get_port(gpi), connection_host_resolved, phb); + if (gaim_gethostbyname_async(gaim_proxy_info_get_host(gpi), + gaim_proxy_info_get_port(gpi), connection_host_resolved, phb) != 0) + { + gaim_proxy_phb_destroy(phb); + return NULL; + } + + phbs = g_slist_prepend(phbs, phb); + + return phb; } @@ -2425,6 +2441,14 @@ gaim_proxy_info_set_password(info, value); } +void * +gaim_proxy_get_handle() +{ + static int handle; + + return &handle; +} + void gaim_proxy_init(void) { @@ -2459,10 +2483,9 @@ #endif } -void * -gaim_proxy_get_handle() +void +gaim_proxy_uninit(void) { - static int handle; - - return &handle; + while (phbs != NULL) + gaim_proxy_phb_destroy(phbs->data); } diff -r 223570831b0b -r 10e8eb6a4910 src/proxy.h --- a/src/proxy.h Sat Aug 12 10:06:15 2006 +0000 +++ b/src/proxy.h Sat Aug 12 10:12:43 2006 +0000 @@ -56,6 +56,17 @@ } GaimProxyInfo; +typedef struct PBH GaimProxyConnectInfo; + +typedef void (*GaimProxyConnectFunction)(gpointer data, gint source); +typedef void (*GaimProxyErrorFunction)(gpointer dat, const gchar *error_message); + +/** + * The "hosts" parameter is a linked list containing pairs of + * one size_t addrlen and one struct sockaddr *addr. + */ +typedef void (*GaimProxyDnsConnectFunction)(GSList *hosts, gpointer data, const char *error_message); + #include "account.h" @@ -69,13 +80,6 @@ /*@{*/ /** - * Get the handle for the proxy system. - * - * @return the handle to the proxy system - */ -void *gaim_proxy_get_handle(void); - -/** * Creates a proxy information structure. * * @return The proxy information structure. @@ -196,11 +200,23 @@ /*@{*/ /** + * Returns the proxy subsystem handle. + * + * @return The proxy subsystem handle. + */ +void *gaim_proxy_get_handle(void); + +/** * Initializes the proxy subsystem. */ void gaim_proxy_init(void); /** + * Uninitializes the proxy subsystem. + */ +void gaim_proxy_uninit(void); + +/** * Returns configuration of a proxy. * * @param account The account for which the configuration is needed. @@ -210,35 +226,50 @@ GaimProxyInfo *gaim_proxy_get_setup(GaimAccount *account); /** - * Makes a connection to the specified host and port. + * Makes a connection to the specified host and port. Note that this + * function name can be misleading--although it is called "proxy + * connect," it is used for establishing any outgoing TCP connection, + * whether through a proxy or not. * - * @param account The account making the connection. - * @param host The destination host. - * @param port The destination port. - * @param func The input handler function. - * @param data User-defined data. + * @param account The account making the connection. + * @param host The destination host. + * @param port The destination port. + * @param connect_cb The function to call when the connection is + * established. + * @param error_cb The function to call if there is an error while + * establishing the connection. + * @param data User-defined data. * - * @return Zero indicates the connection is pending. Any other value indicates failure. + * @return NULL if there was an error, or a reference to a data + * structure that can be used to cancel the pending + * connection, if needed. */ -int gaim_proxy_connect(GaimAccount *account, const char *host, int port, - GaimInputFunction func, gpointer data); +GaimProxyConnectInfo *gaim_proxy_connect(GaimAccount *account, + const char *host, int port, + GaimProxyConnectFunction connect_cb, + GaimProxyErrorFunction error_cb, gpointer data); /** * Makes a connection through a SOCKS5 proxy. * - * @param gpi The GaimProxyInfo specifying the proxy settings - * @param host The destination host. - * @param port The destination port. - * @param func The input handler function. - * @param data User-defined data. + * @param gpi The GaimProxyInfo specifying the proxy settings + * @param host The destination host. + * @param port The destination port. + * @param connect_cb The function to call when the connection is + * established. + * @param error_cb The function to call if there is an error while + * establishing the connection. + * @param data User-defined data. * - * @return Zero indicates the connection is pending. Any other value indicates failure. + * @return NULL if there was an error, or a reference to a data + * structure that can be used to cancel the pending + * connection, if needed. */ -int gaim_proxy_connect_socks5(GaimProxyInfo *gpi, const char *host, int port, - GaimInputFunction func, gpointer data); +GaimProxyConnectInfo *gaim_proxy_connect_socks5(GaimProxyInfo *gpi, + const char *host, int port, + GaimProxyConnectFunction connect_cb, + GaimProxyErrorFunction error_cb, gpointer data); -typedef void (*dns_callback_t)(GSList *hosts, gpointer data, - const char *error_message); /** * Do an async dns query * @@ -249,7 +280,7 @@ * * @return Zero indicates the connection is pending. Any other value indicates failure. */ -int gaim_gethostbyname_async(const char *hostname, int port, dns_callback_t callback, gpointer data); +int gaim_gethostbyname_async(const char *hostname, int port, GaimProxyDnsConnectFunction callback, gpointer data); /*@}*/ diff -r 223570831b0b -r 10e8eb6a4910 src/sslconn.c --- a/src/sslconn.c Sat Aug 12 10:06:15 2006 +0000 +++ b/src/sslconn.c Sat Aug 12 10:12:43 2006 +0000 @@ -69,7 +69,7 @@ { GaimSslConnection *gsc; GaimSslOps *ops; - int i; + GaimProxyConnectInfo *connect_info; g_return_val_if_fail(host != NULL, NULL); g_return_val_if_fail(port != 0 && port != -1, NULL); @@ -95,9 +95,9 @@ gsc->connect_cb = func; gsc->error_cb = error_func; - i = gaim_proxy_connect(account, host, port, ops->connect_cb, gsc); + connect_info = gaim_proxy_connect(account, host, port, ops->connect_cb, NULL, gsc); - if (i < 0) + if (connect_info == NULL) { g_free(gsc->host); g_free(gsc); diff -r 223570831b0b -r 10e8eb6a4910 src/upnp.c --- a/src/upnp.c Sat Aug 12 10:06:15 2006 +0000 +++ b/src/upnp.c Sat Aug 12 10:12:43 2006 +0000 @@ -780,15 +780,15 @@ } static void -looked_up_internal_ip_cb(gpointer data, gint sock, GaimInputCondition cond) +looked_up_internal_ip_cb(gpointer data, gint source) { - if (sock) { + if (source) { strncpy(control_info.internalip, - gaim_network_get_local_system_ip(sock), + gaim_network_get_local_system_ip(source), sizeof(control_info.internalip)); gaim_debug_info("upnp", "Local IP: %s\n", control_info.internalip); - close(sock); + close(source); } else gaim_debug_info("upnp", "Unable to look up local IP\n"); @@ -811,8 +811,8 @@ } if(gaim_proxy_connect(NULL, addressOfControl, port, - looked_up_internal_ip_cb, NULL) != 0) { - + looked_up_internal_ip_cb, NULL, NULL) == NULL) + { gaim_debug_error("upnp", "Get Local IP Connect Failed: Address: %s @@@ Port %d\n", addressOfControl, port); } diff -r 223570831b0b -r 10e8eb6a4910 src/util.c --- a/src/util.c Sat Aug 12 10:06:15 2006 +0000 +++ b/src/util.c Sat Aug 12 10:12:43 2006 +0000 @@ -3367,7 +3367,7 @@ } static void -url_fetch_connect_cb(gpointer url_data, gint source, GaimInputCondition cond) +url_fetch_connect_cb(gpointer url_data, gint source) { GaimFetchUrlData *gfud; @@ -3448,7 +3448,8 @@ &gfud->website.page, &gfud->website.user, &gfud->website.passwd); if (gaim_proxy_connect(NULL, gfud->website.address, - gfud->website.port, url_fetch_connect_cb, gfud) != 0) { + gfud->website.port, url_fetch_connect_cb, NULL, gfud) == NULL) + { destroy_fetch_url_data(gfud); cb(user_data, g_strdup(_("g003: Error opening connection.\n")), 0);