# HG changeset patch # User Christian Hammond # Date 1054605633 0 # Node ID 46d7ad0dfa264d6eff3ed74fb28f98c4692cf21f # Parent 71cc0d5376c2eefa65e6bdcfe8bd4e1346fa2360 [gaim-migrate @ 6100] Rewrote the proxy code. It should now work with the new prefs, and it has a namespace and API too! committer: Tailor Script diff -r 71cc0d5376c2 -r 46d7ad0dfa26 src/account.c --- a/src/account.c Mon Jun 02 22:30:25 2003 +0000 +++ b/src/account.c Tue Jun 03 02:00:33 2003 +0000 @@ -298,6 +298,16 @@ } void +gaim_account_set_proxy_info(GaimAccount *account, GaimProxyInfo *info) +{ + g_return_if_fail(account != NULL); + + account->proxy_info = info; + + schedule_accounts_save(); +} + +void gaim_account_set_int(GaimAccount *account, const char *name, int value) { GaimAccountSetting *setting; @@ -433,6 +443,14 @@ return account->check_mail; } +GaimProxyInfo * +gaim_account_get_proxy_info(const GaimAccount *account) +{ + g_return_val_if_fail(account != NULL, NULL); + + return account->proxy_info; +} + int gaim_account_get_int(const GaimAccount *account, const char *name, int default_value) diff -r 71cc0d5376c2 -r 46d7ad0dfa26 src/account.h --- a/src/account.h Mon Jun 02 22:30:25 2003 +0000 +++ b/src/account.h Tue Jun 03 02:00:33 2003 +0000 @@ -26,6 +26,7 @@ typedef struct _GaimAccount GaimAccount; #include "connection.h" +#include "proxy.h" #include "prpl.h" struct _GaimAccount @@ -47,7 +48,7 @@ GHashTable *settings; /**< Protocol-specific settings. */ - struct gaim_proxy_info *gpi; /**< Proxy information. */ + GaimProxyInfo *proxy_info; /**< Proxy information. */ GSList *permit; /**< Permit list. */ GSList *deny; /**< Deny list. */ @@ -160,6 +161,14 @@ void gaim_account_set_check_mail(GaimAccount *account, gboolean value); /** + * Sets the account's proxy information. + * + * @param account The account. + * @param info The proxy information. + */ +void gaim_account_set_proxy_info(GaimAccount *account, GaimProxyInfo *info); + +/** * Sets a protocol-specific integer setting for an account. * * @param account The account. @@ -280,6 +289,15 @@ gboolean gaim_account_get_check_mail(const GaimAccount *account); /** + * Returns the account's proxy information. + * + * @param account The account. + * + * @return The proxy information. + */ +GaimProxyInfo *gaim_account_get_proxy_info(const GaimAccount *account); + +/** * Returns a protocol-specific integer setting for an account. * * @param account The account. diff -r 71cc0d5376c2 -r 46d7ad0dfa26 src/ft.c --- a/src/ft.c Mon Jun 02 22:30:25 2003 +0000 +++ b/src/ft.c Tue Jun 03 02:00:33 2003 +0000 @@ -602,8 +602,8 @@ xfer->remote_port = port; /* Establish a file descriptor. */ - proxy_connect(xfer->account, xfer->remote_ip, xfer->remote_port, - connect_cb, xfer); + gaim_proxy_connect(xfer->account, xfer->remote_ip, + xfer->remote_port, connect_cb, xfer); return; } diff -r 71cc0d5376c2 -r 46d7ad0dfa26 src/gaimrc.c --- a/src/gaimrc.c Mon Jun 02 22:30:25 2003 +0000 +++ b/src/gaimrc.c Tue Jun 03 02:00:33 2003 +0000 @@ -660,16 +660,15 @@ if (strcmp(p->option, "proxy_opts")) return account; - if(atoi(p->value[0]) != PROXY_USE_GLOBAL) { - account->gpi = g_new0(struct gaim_proxy_info, 1); - account->gpi->proxytype = atoi(p->value[0]); - g_snprintf(account->gpi->proxyhost, sizeof(account->gpi->proxyhost), - "%s", p->value[1]); - account->gpi->proxyport = atoi(p->value[2]); - g_snprintf(account->gpi->proxyuser, sizeof(account->gpi->proxyuser), - "%s", p->value[3]); - g_snprintf(account->gpi->proxypass, sizeof(account->gpi->proxypass), - "%s", p->value[4]); + if(atoi(p->value[0]) != GAIM_PROXY_USE_GLOBAL) { + GaimProxyInfo *info; + + info = gaim_proxy_info_new(); + gaim_proxy_info_set_type(info, atoi(p->value[0])); + gaim_proxy_info_set_host(info, p->value[1]); + gaim_proxy_info_set_port(info, atoi(p->value[2])); + gaim_proxy_info_set_username(info, p->value[3]); + gaim_proxy_info_set_password(info, p->value[4]); } return account; @@ -1143,6 +1142,8 @@ static gboolean gaimrc_parse_proxy_uri(const char *proxy) { + GaimProxyInfo *info; + char *c, *d; char buffer[2048]; @@ -1221,27 +1222,20 @@ } /* NOTE: HTTP_PROXY takes precendence. */ - if (host[0]) - strcpy(global_proxy_info.proxyhost, host); - else - *global_proxy_info.proxyhost = '\0'; + info = gaim_global_proxy_get_info(); - if (user[0]) - strcpy(global_proxy_info.proxyuser, user); - else - *global_proxy_info.proxyuser = '\0'; + if (*host) gaim_proxy_info_set_host(info, host); + if (*user) gaim_proxy_info_set_username(info, user); + if (*pass) gaim_proxy_info_set_password(info, pass); - if (pass[0]) - strcpy(global_proxy_info.proxypass, pass); - else - *global_proxy_info.proxypass = '\0'; - - global_proxy_info.proxyport = port; + gaim_proxy_info_set_port(info, port); gaim_debug(GAIM_DEBUG_MISC, "gaimrc", "Host: '%s', User: '%s', Password: '%s', Port: %d\n", - global_proxy_info.proxyhost, global_proxy_info.proxyuser, - global_proxy_info.proxypass, global_proxy_info.proxyport); + gaim_proxy_info_get_host(info), + gaim_proxy_info_get_username(info), + gaim_proxy_info_get_password(info), + gaim_proxy_info_get_port(info)); return TRUE; } @@ -1251,9 +1245,11 @@ char buf[2048]; struct parse parse_buffer; struct parse *p; + GaimProxyInfo *info; + + info = gaim_global_proxy_get_info(); buf[0] = 0; - global_proxy_info.proxyhost[0] = 0; gaim_debug(GAIM_DEBUG_MISC, "gaimrc", "gaimrc_read_proxy\n"); while (buf[0] != '}') { @@ -1266,78 +1262,60 @@ p = parse_line(buf, &parse_buffer); if (!strcmp(p->option, "host")) { - g_snprintf(global_proxy_info.proxyhost, - sizeof(global_proxy_info.proxyhost), "%s", p->value[0]); + gaim_proxy_info_set_host(info, p->value[0]); gaim_debug(GAIM_DEBUG_MISC, "gaimrc", - "Set proxyhost %s\n", global_proxy_info.proxyhost); + "Set proxyhost %s\n", p->value[0]); } else if (!strcmp(p->option, "port")) { - global_proxy_info.proxyport = atoi(p->value[0]); + gaim_proxy_info_set_port(info, atoi(p->value[0])); } else if (!strcmp(p->option, "type")) { - global_proxy_info.proxytype = atoi(p->value[0]); + gaim_proxy_info_set_type(info, atoi(p->value[0])); } else if (!strcmp(p->option, "user")) { - g_snprintf(global_proxy_info.proxyuser, - sizeof(global_proxy_info.proxyuser), "%s", p->value[0]); + gaim_proxy_info_set_username(info, p->value[0]); } else if (!strcmp(p->option, "pass")) { - g_snprintf(global_proxy_info.proxypass, - sizeof(global_proxy_info.proxypass), "%s", p->value[0]); + gaim_proxy_info_set_password(info, p->value[0]); } } - if (global_proxy_info.proxyhost[0]) - proxy_info_is_from_gaimrc = 1; + + if (gaim_proxy_info_get_host(info) != NULL) + gaim_global_proxy_set_from_prefs(TRUE); else { + const char *host; gboolean getVars = TRUE; - proxy_info_is_from_gaimrc = 0; - if (g_getenv("HTTP_PROXY")) - g_snprintf(global_proxy_info.proxyhost, - sizeof(global_proxy_info.proxyhost), "%s", - g_getenv("HTTP_PROXY")); - else if (g_getenv("http_proxy")) - g_snprintf(global_proxy_info.proxyhost, - sizeof(global_proxy_info.proxyhost), "%s", - g_getenv("http_proxy")); - else if (g_getenv("HTTPPROXY")) - g_snprintf(global_proxy_info.proxyhost, - sizeof(global_proxy_info.proxyhost), "%s", - g_getenv("HTTPPROXY")); + if ((host = g_getenv("HTTP_PROXY")) != NULL || + (host = g_getenv("http_proxy")) != NULL || + (host = g_getenv("HTTPPROXY")) != NULL) { - if (*global_proxy_info.proxyhost != '\0') - getVars = !gaimrc_parse_proxy_uri(global_proxy_info.proxyhost); + gaim_proxy_info_set_host(info, host); + } + + if (gaim_proxy_info_get_host(info) != NULL) + getVars = !gaimrc_parse_proxy_uri(gaim_proxy_info_get_host(info)); if (getVars) { - if (g_getenv("HTTP_PROXY_PORT")) - global_proxy_info.proxyport = atoi(g_getenv("HTTP_PROXY_PORT")); - else if (g_getenv("http_proxy_port")) - global_proxy_info.proxyport = atoi(g_getenv("http_proxy_port")); - else if (g_getenv("HTTPPROXYPORT")) - global_proxy_info.proxyport = atoi(g_getenv("HTTPPROXYPORT")); + const char *port_str, *user, *pass; + + if ((port_str = g_getenv("HTTP_PROXY_PORT")) != NULL || + (port_str = g_getenv("http_proxy_port")) != NULL || + (port_str = g_getenv("HTTPPROXYPORT")) != NULL) { + + gaim_proxy_info_set_port(info, atoi(port_str)); + } - if (g_getenv("HTTP_PROXY_USER")) - g_snprintf(global_proxy_info.proxyuser, - sizeof(global_proxy_info.proxyuser), "%s", - g_getenv("HTTP_PROXY_USER")); - else if (g_getenv("http_proxy_user")) - g_snprintf(global_proxy_info.proxyuser, - sizeof(global_proxy_info.proxyuser), "%s", - g_getenv("http_proxy_user")); - else if (g_getenv("HTTPPROXYUSER")) - g_snprintf(global_proxy_info.proxyuser, - sizeof(global_proxy_info.proxyuser), "%s", - g_getenv("HTTPPROXYUSER")); + if ((user = g_getenv("HTTP_PROXY_USER")) != NULL || + (user = g_getenv("http_proxy_user")) != NULL || + (user = g_getenv("HTTPPROXYUSER")) != NULL) { + + gaim_proxy_info_set_username(info, user); + } - if (g_getenv("HTTP_PROXY_PASS")) - g_snprintf(global_proxy_info.proxypass, - sizeof(global_proxy_info.proxypass), "%s", - g_getenv("HTTP_PROXY_PASS")); - else if (g_getenv("http_proxy_pass")) - g_snprintf(global_proxy_info.proxypass, - sizeof(global_proxy_info.proxypass), "%s", - g_getenv("http_proxy_pass")); - else if (g_getenv("HTTPPROXYPASS")) - g_snprintf(global_proxy_info.proxypass, - sizeof(global_proxy_info.proxypass), "%s", - g_getenv("HTTPPROXYPASS")); + if ((pass = g_getenv("HTTP_PROXY_PASS")) != NULL || + (pass = g_getenv("http_proxy_pass")) != NULL || + (pass = g_getenv("HTTPPROXYPASS")) != NULL) { + + gaim_proxy_info_set_password(info, pass); + } } } } diff -r 71cc0d5376c2 -r 46d7ad0dfa26 src/gtkaccount.c --- a/src/gtkaccount.c Mon Jun 02 22:30:25 2003 +0000 +++ b/src/gtkaccount.c Tue Jun 03 02:00:33 2003 +0000 @@ -99,6 +99,9 @@ GtkWidget *protocol_frame; GtkWidget *register_check; + /* Proxy Options */ + GtkWidget *proxy_frame; + GtkSizeGroup *sg; } AccountPrefsDialog; @@ -490,6 +493,14 @@ } static void +__add_proxy_options_frame(AccountPrefsDialog *dialog, GtkWidget *parent) +{ + if (dialog->proxy_frame != NULL) + gtk_widget_destroy(dialog->proxy_frame); + +} + +static void __show_account_prefs(AccountPrefsDialogType type, GaimAccount *account) { AccountPrefsDialog *dialog; diff -r 71cc0d5376c2 -r 46d7ad0dfa26 src/gtkconv.c --- a/src/gtkconv.c Mon Jun 02 22:30:25 2003 +0000 +++ b/src/gtkconv.c Tue Jun 03 02:00:33 2003 +0000 @@ -5297,7 +5297,7 @@ gaim_conversation_foreach(gaim_gtkconv_update_buddy_icon); } -void +static void chat_button_type_pref_cb(const char *name, GaimPrefType type, gpointer value, gpointer data) { diff -r 71cc0d5376c2 -r 46d7ad0dfa26 src/gtkprefs.c --- a/src/gtkprefs.c Mon Jun 02 22:30:25 2003 +0000 +++ b/src/gtkprefs.c Tue Jun 03 02:00:33 2003 +0000 @@ -393,16 +393,19 @@ static void proxy_print_option(GtkEntry *entry, int entrynum) { + GaimProxyInfo *info = gaim_global_proxy_get_info(); + if (entrynum == PROXYHOST) - g_snprintf(global_proxy_info.proxyhost, sizeof(global_proxy_info.proxyhost), "%s", gtk_entry_get_text(entry)); + gaim_proxy_info_set_host(info, gtk_entry_get_text(entry)); else if (entrynum == PROXYPORT) - global_proxy_info.proxyport = atoi(gtk_entry_get_text(entry)); + gaim_proxy_info_set_port(info, atoi(gtk_entry_get_text(entry))); else if (entrynum == PROXYUSER) - g_snprintf(global_proxy_info.proxyuser, sizeof(global_proxy_info.proxyuser), "%s", gtk_entry_get_text(entry)); + gaim_proxy_info_set_username(info, gtk_entry_get_text(entry)); else if (entrynum == PROXYPASS) - g_snprintf(global_proxy_info.proxypass, sizeof(global_proxy_info.proxypass), "%s", gtk_entry_get_text(entry)); - proxy_info_is_from_gaimrc = 1; /* If the user specifies it, we want - to save it */ + gaim_proxy_info_set_password(info, gtk_entry_get_text(entry)); + + /* If the user specifies it, we want to save it. */ + gaim_global_proxy_set_from_prefs(TRUE); } /* OK, Apply and Cancel */ @@ -1127,6 +1130,7 @@ GtkWidget *label; GtkWidget *hbox; GtkWidget *table; + GaimProxyInfo *proxy_info; ret = gtk_vbox_new(FALSE, 18); gtk_container_set_border_width (GTK_CONTAINER (ret), 12); @@ -1143,8 +1147,13 @@ vbox = gaim_gtk_make_frame(ret, _("Proxy Server")); prefs_proxy_frame = vbox; - if (global_proxy_info.proxytype == PROXY_NONE) + proxy_info = gaim_global_proxy_get_info(); + + if (proxy_info == NULL || + gaim_proxy_info_get_type(proxy_info) == GAIM_PROXY_NONE) { + gtk_widget_set_sensitive(GTK_WIDGET(vbox), FALSE); + } table = gtk_table_new(2, 4, FALSE); gtk_container_set_border_width(GTK_CONTAINER(table), 5); @@ -1162,7 +1171,10 @@ gtk_table_attach(GTK_TABLE(table), entry, 1, 2, 0, 1, GTK_FILL, 0, 0, 0); g_signal_connect(G_OBJECT(entry), "changed", G_CALLBACK(proxy_print_option), (void *)PROXYHOST); - gtk_entry_set_text(GTK_ENTRY(entry), global_proxy_info.proxyhost); + + if (proxy_info != NULL && gaim_proxy_info_get_host(proxy_info)) + gtk_entry_set_text(GTK_ENTRY(entry), + gaim_proxy_info_get_host(proxy_info)); hbox = gtk_hbox_new(TRUE, 5); gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); @@ -1177,9 +1189,11 @@ g_signal_connect(G_OBJECT(entry), "changed", G_CALLBACK(proxy_print_option), (void *)PROXYPORT); - if (global_proxy_info.proxyport) { + if (proxy_info != NULL && gaim_proxy_info_get_port(proxy_info) != 0) { char buf[128]; - g_snprintf(buf, sizeof(buf), "%d", global_proxy_info.proxyport); + g_snprintf(buf, sizeof(buf), "%d", + gaim_proxy_info_get_port(proxy_info)); + gtk_entry_set_text(GTK_ENTRY(entry), buf); } @@ -1192,7 +1206,10 @@ gtk_table_attach(GTK_TABLE(table), entry, 1, 2, 2, 3, GTK_FILL, 0, 0, 0); g_signal_connect(G_OBJECT(entry), "changed", G_CALLBACK(proxy_print_option), (void *)PROXYUSER); - gtk_entry_set_text(GTK_ENTRY(entry), global_proxy_info.proxyuser); + + if (proxy_info != NULL && gaim_proxy_info_get_username(proxy_info) != NULL) + gtk_entry_set_text(GTK_ENTRY(entry), + gaim_proxy_info_get_username(proxy_info)); hbox = gtk_hbox_new(TRUE, 5); gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); @@ -1207,7 +1224,10 @@ gtk_entry_set_visibility(GTK_ENTRY(entry), FALSE); g_signal_connect(G_OBJECT(entry), "changed", G_CALLBACK(proxy_print_option), (void *)PROXYPASS); - gtk_entry_set_text(GTK_ENTRY(entry), global_proxy_info.proxypass); + + if (proxy_info != NULL && gaim_proxy_info_get_password(proxy_info) != NULL) + gtk_entry_set_text(GTK_ENTRY(entry), + gaim_proxy_info_get_password(proxy_info)); gtk_widget_show_all(ret); return ret; diff -r 71cc0d5376c2 -r 46d7ad0dfa26 src/html.c --- a/src/html.c Mon Jun 02 22:30:25 2003 +0000 +++ b/src/html.c Tue Jun 03 02:00:33 2003 +0000 @@ -314,8 +314,9 @@ gunk->website = parse_url(url); gunk->full = full; - if ((sock = proxy_connect(NULL, gunk->website->address, gunk->website->port, - grab_url_callback, gunk)) < 0) { + if ((sock = gaim_proxy_connect(NULL, gunk->website->address, + gunk->website->port, grab_url_callback, + gunk)) < 0) { g_free(gunk->website); g_free(gunk->url); g_free(gunk); diff -r 71cc0d5376c2 -r 46d7ad0dfa26 src/prefs.c --- a/src/prefs.c Mon Jun 02 22:30:25 2003 +0000 +++ b/src/prefs.c Tue Jun 03 02:00:33 2003 +0000 @@ -137,10 +137,6 @@ gaim_prefs_add_bool("/core/conversations/im/show_login", TRUE); gaim_prefs_add_bool("/core/conversations/im/send_typing", TRUE); - /* Proxy */ - gaim_prefs_add_none("/core/proxy"); - gaim_prefs_add_string("/core/proxy/type", "none"); - /* Sound */ gaim_prefs_add_none("/core/sound"); gaim_prefs_add_bool("/core/sound/use_sys_default", TRUE); @@ -150,6 +146,8 @@ gaim_prefs_add_bool("/core/sound/use_custom", FALSE); gaim_prefs_add_string("/core/sound/command", ""); gaim_prefs_add_bool("/core/sound/while_away", FALSE); + + gaim_proxy_init(); } static char *pref_full_name(struct gaim_pref *pref) { diff -r 71cc0d5376c2 -r 46d7ad0dfa26 src/protocols/gg/gg.c --- a/src/protocols/gg/gg.c Mon Jun 02 22:30:25 2003 +0000 +++ b/src/protocols/gg/gg.c Tue Jun 03 02:00:33 2003 +0000 @@ -1,6 +1,6 @@ /* * gaim - Gadu-Gadu Protocol Plugin - * $Id: gg.c 6059 2003-06-01 23:31:46Z chipx86 $ + * $Id: gg.c 6100 2003-06-03 02:00:33Z chipx86 $ * * Copyright (C) 2001 Arkadiusz Mi¶kiewicz * @@ -450,7 +450,7 @@ } /* If we are GG_STATE_CONNECTING_GG then we still need to connect, as - we could not use proxy_connect in libgg.c */ + we could not use gaim_proxy_connect in libgg.c */ switch( gd->sess->state ) { case GG_STATE_CONNECTING_GG: { @@ -462,7 +462,7 @@ ip.s_addr = gd->sess->server_ip; - if (proxy_connect(gc->account, inet_ntoa(ip), gd->sess->port, login_callback, gc) < 0) { + if (gaim_proxy_connect(gc->account, inet_ntoa(ip), gd->sess->port, login_callback, gc) < 0) { g_snprintf(buf, sizeof(buf), _("Connect to %s failed"), inet_ntoa(ip)); gaim_connection_error(gc, buf); return; @@ -544,7 +544,7 @@ return; } - gg_login() sucks for me, so I'm using proxy_connect() + gg_login() sucks for me, so I'm using gaim_proxy_connect() */ gd->sess->uin = (uin_t) strtol(account->username, (char **)NULL, 10); @@ -552,7 +552,7 @@ gd->sess->state = GG_STATE_CONNECTING; gd->sess->check = GG_CHECK_WRITE; gd->sess->async = 1; - if (proxy_connect(account, GG_APPMSG_HOST, GG_APPMSG_PORT, login_callback, gc) < 0) { + if (gaim_proxy_connect(account, GG_APPMSG_HOST, GG_APPMSG_PORT, login_callback, gc) < 0) { g_snprintf(buf, sizeof(buf), _("Connect to %s failed"), GG_APPMSG_HOST); gaim_connection_error(gc, buf); return; @@ -989,7 +989,7 @@ g_free(u); g_free(p); - if (proxy_connect(gc->account, GG_PUBDIR_HOST, GG_PUBDIR_PORT, http_req_callback, hi) < 0) { + if (gaim_proxy_connect(gc->account, GG_PUBDIR_HOST, GG_PUBDIR_PORT, http_req_callback, hi) < 0) { gaim_notify_error(gc, NULL, _("Unable to import Gadu-Gadu buddy list"), _("Gaim was unable to connect to the Gadu-Gadu " @@ -1059,7 +1059,7 @@ } } - if (proxy_connect(gc->account, GG_PUBDIR_HOST, GG_PUBDIR_PORT, http_req_callback, he) < 0) { + if (gaim_proxy_connect(gc->account, GG_PUBDIR_HOST, GG_PUBDIR_PORT, http_req_callback, he) < 0) { gaim_notify_error(gc, NULL, _("Couldn't export buddy list"), _("Gaim was unable to connect to the buddy " @@ -1082,7 +1082,7 @@ he->host = GG_PUBDIR_HOST; he->request = g_strdup_printf("FmNum=%s&Pass=%s&Delete=1", u, p); - if (proxy_connect(gc->account, GG_PUBDIR_HOST, GG_PUBDIR_PORT, http_req_callback, he) < 0) { + if (gaim_proxy_connect(gc->account, GG_PUBDIR_HOST, GG_PUBDIR_PORT, http_req_callback, he) < 0) { gaim_notify_error(gc, NULL, _("Unable to delete Gadu-Gadu buddy list"), _("Gaim was unable to connect to the buddy " @@ -1131,7 +1131,7 @@ g_free(enew_city); } - if (proxy_connect(gc->account, GG_PUBDIR_HOST, GG_PUBDIR_PORT, http_req_callback, srch) < 0) { + if (gaim_proxy_connect(gc->account, GG_PUBDIR_HOST, GG_PUBDIR_PORT, http_req_callback, srch) < 0) { gaim_notify_error(gc, NULL, _("Unable to access directory"), _("Gaim was unable to search the Directory " @@ -1165,7 +1165,7 @@ g_free(enew); g_free(eold); - if (proxy_connect(gc->account, GG_REGISTER_HOST, GG_REGISTER_PORT, http_req_callback, hpass) < 0) { + if (gaim_proxy_connect(gc->account, GG_REGISTER_HOST, GG_REGISTER_PORT, http_req_callback, hpass) < 0) { gaim_notify_error(gc, NULL, _("Unable to change Gadu-Gadu password"), _("Gaim was unable to change your password " @@ -1243,7 +1243,7 @@ } else srch->request = g_strdup_printf("Mode=3&UserId=%s", who); - if (proxy_connect(gc->account, GG_PUBDIR_HOST, GG_PUBDIR_PORT, http_req_callback, srch) < 0) { + if (gaim_proxy_connect(gc->account, GG_PUBDIR_HOST, GG_PUBDIR_PORT, http_req_callback, srch) < 0) { gaim_notify_error(gc, NULL, _("Unable to access user profile."), _("Gaim was unable to access this user's " diff -r 71cc0d5376c2 -r 46d7ad0dfa26 src/protocols/gg/libgg.c --- a/src/protocols/gg/libgg.c Mon Jun 02 22:30:25 2003 +0000 +++ b/src/protocols/gg/libgg.c Tue Jun 03 02:00:33 2003 +0000 @@ -1,4 +1,4 @@ -/* $Id: libgg.c 4552 2003-01-11 19:59:27Z seanegan $ */ +/* $Id: libgg.c 6100 2003-06-03 02:00:33Z chipx86 $ */ /* * (C) Copyright 2001 Wojtek Kaniewski , @@ -72,7 +72,7 @@ #ifdef __GNUC__ __attribute__ ((unused)) #endif -= "$Id: libgg.c 4552 2003-01-11 19:59:27Z seanegan $"; += "$Id: libgg.c 6100 2003-06-03 02:00:33Z chipx86 $"; #endif @@ -861,7 +861,7 @@ switch (sess->state) { #ifndef _WIN32 /* Apparantly we will never be in this state as long as we are - using proxy_connect instead of gg_login - Herman */ + using gaim_proxy_connect instead of gg_login - Herman */ case GG_STATE_RESOLVING: { struct in_addr a; @@ -1048,7 +1048,7 @@ a.s_addr = inet_addr(host); sess->server_ip = a.s_addr; #if 0 - /* We need to watch this non-blocking socket so lets use proxy_connect + /* We need to watch this non-blocking socket so lets use gaim_proxy_connect in gg.c - Herman */ if((sess->fd = gg_connect(&a, port, sess->assync)) == -1) { gg_debug(GG_DEBUG_MISC, "-- connection failed, trying https connection\n"); diff -r 71cc0d5376c2 -r 46d7ad0dfa26 src/protocols/irc/irc.c --- a/src/protocols/irc/irc.c Mon Jun 02 22:30:25 2003 +0000 +++ b/src/protocols/irc/irc.c Tue Jun 03 02:00:33 2003 +0000 @@ -1242,7 +1242,7 @@ static void dcc_chat_init(struct dcc_chat *data) { if (g_list_find(gaim_connections_get_all(), data->gc)) { - proxy_connect(data->gc->account, data->ip_address, data->port, dcc_chat_callback, data); + gaim_proxy_connect(data->gc->account, data->ip_address, data->port, dcc_chat_callback, data); } else { g_free(data); } @@ -1960,7 +1960,7 @@ idata->str = g_string_new(""); idata->fd = -1; - rc = proxy_connect(account, idata->server, + rc = gaim_proxy_connect(account, idata->server, gaim_account_get_int(account, "port", 6667), irc_login_callback, gc); @@ -2755,7 +2755,7 @@ struct irc_file_transfer *ift = find_ift_by_xfer(gc, xfer); ift->xfer = xfer; - proxy_connect(gc->account, ift->ip, ift->port, dcc_recv_callback, ift); + gaim_proxy_connect(gc->account, ift->ip, ift->port, dcc_recv_callback, ift); } #endif diff -r 71cc0d5376c2 -r 46d7ad0dfa26 src/protocols/jabber/jabber.c --- a/src/protocols/jabber/jabber.c Mon Jun 02 22:30:25 2003 +0000 +++ b/src/protocols/jabber/jabber.c Tue Jun 03 02:00:33 2003 +0000 @@ -828,7 +828,7 @@ XML_SetElementHandler(gjc->parser, startElement, endElement); XML_SetCharacterDataHandler(gjc->parser, charData); - rc = proxy_connect(account, server, port, gjab_connected, GJ_GC(gjc)); + rc = gaim_proxy_connect(account, server, port, gjab_connected, GJ_GC(gjc)); if (!account->gc || (rc != 0)) { STATE_EVT(JCONN_STATE_OFF) return; diff -r 71cc0d5376c2 -r 46d7ad0dfa26 src/protocols/msn/ft.c --- a/src/protocols/msn/ft.c Mon Jun 02 22:30:25 2003 +0000 +++ b/src/protocols/msn/ft.c Tue Jun 03 02:00:33 2003 +0000 @@ -506,7 +506,7 @@ strncpy(ip_s, ip, sizeof(ip_s)); - if (proxy_connect(xfer->account, ip_s, atoi(port_s), + if (gaim_proxy_connect(xfer->account, ip_s, atoi(port_s), msn_msnftp_connect, xfer) != 0) { gaim_xfer_cancel_remote(xfer); diff -r 71cc0d5376c2 -r 46d7ad0dfa26 src/protocols/msn/servconn.c --- a/src/protocols/msn/servconn.c Mon Jun 02 22:30:25 2003 +0000 +++ b/src/protocols/msn/servconn.c Tue Jun 03 02:00:33 2003 +0000 @@ -198,7 +198,7 @@ g_return_val_if_fail(servconn->server != NULL, FALSE); g_return_val_if_fail(!servconn->connected, TRUE); - i = proxy_connect(servconn->session->account, servconn->server, + i = gaim_proxy_connect(servconn->session->account, servconn->server, servconn->port, __connect_cb, servconn); if (i == 0) diff -r 71cc0d5376c2 -r 46d7ad0dfa26 src/protocols/napster/napster.c --- a/src/protocols/napster/napster.c Mon Jun 02 22:30:25 2003 +0000 +++ b/src/protocols/napster/napster.c Tue Jun 03 02:00:33 2003 +0000 @@ -504,7 +504,7 @@ gaim_connection_update_progress(gc, _("Connecting"), 1, NAPSTER_CONNECT_STEPS); gc->proto_data = g_new0(struct nap_data, 1); - if (proxy_connect(account, + if (gaim_proxy_connect(account, gaim_account_get_string(account, "server", NAP_SERVER), gaim_account_get_int(account, "port", NAP_PORT), nap_login_connect, gc) != 0) { diff -r 71cc0d5376c2 -r 46d7ad0dfa26 src/protocols/oscar/oscar.c --- a/src/protocols/oscar/oscar.c Mon Jun 02 22:30:25 2003 +0000 +++ b/src/protocols/oscar/oscar.c Tue Jun 03 02:00:33 2003 +0000 @@ -683,7 +683,7 @@ aim_conn_addhandler(sess, conn, 0x0017, 0x0003, gaim_parse_auth_resp, 0); conn->status |= AIM_CONN_STATUS_INPROGRESS; - if (proxy_connect(account, gaim_account_get_string(account, "server", FAIM_LOGIN_SERVER), + if (gaim_proxy_connect(account, gaim_account_get_string(account, "server", FAIM_LOGIN_SERVER), gaim_account_get_int(account, "port", FAIM_LOGIN_PORT), oscar_login_connect, gc) < 0) { gaim_connection_error(gc, _("Couldn't connect to host")); @@ -862,7 +862,7 @@ if (oft_info->conn) { oft_info->conn->subtype = AIM_CONN_SUBTYPE_OFT_SENDFILE; aim_conn_addhandler(od->sess, oft_info->conn, AIM_CB_FAM_OFT, AIM_CB_OFT_PROMPT, oscar_sendfile_prompt, 0); - oft_info->conn->fd = xfer->fd = proxy_connect(gaim_connection_get_account(gc), xfer->remote_ip, xfer->remote_port, + oft_info->conn->fd = xfer->fd = gaim_proxy_connect(gaim_connection_get_account(gc), xfer->remote_ip, xfer->remote_port, oscar_sendfile_connected, xfer); if (xfer->fd == -1) { gaim_notify_error(gc, NULL, _("File Transfer Aborted"), @@ -1161,7 +1161,7 @@ } host = g_strndup(info->bosip, i); bosconn->status |= AIM_CONN_STATUS_INPROGRESS; - rc = proxy_connect(gc->account, host, port, oscar_bos_connect, gc); + rc = gaim_proxy_connect(gc->account, host, port, oscar_bos_connect, gc); g_free(host); if (rc < 0) { gaim_connection_error(gc, _("Could Not Connect")); @@ -1316,7 +1316,7 @@ pos->len = len; pos->modname = modname ? g_strdup(modname) : NULL; - if (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, pos) != 0) { char buf[256]; if (pos->modname) g_free(pos->modname); @@ -1613,7 +1613,7 @@ aim_conn_addhandler(sess, tstconn, 0x0007, 0x0007, gaim_account_confirm, 0); tstconn->status |= AIM_CONN_STATUS_INPROGRESS; - if (proxy_connect(account, host, port, oscar_auth_connect, gc) != 0) { + if (gaim_proxy_connect(account, host, port, oscar_auth_connect, gc) != 0) { aim_conn_kill(sess, &tstconn); gaim_debug(GAIM_DEBUG_ERROR, "oscar", "unable to reconnect with authorizer\n"); @@ -1635,7 +1635,7 @@ aim_conn_addhandler(sess, tstconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNINITDONE, conninitdone_chatnav, 0); tstconn->status |= AIM_CONN_STATUS_INPROGRESS; - if (proxy_connect(account, host, port, oscar_chatnav_connect, gc) != 0) { + if (gaim_proxy_connect(account, host, port, oscar_chatnav_connect, gc) != 0) { aim_conn_kill(sess, &tstconn); gaim_debug(GAIM_DEBUG_ERROR, "oscar", "unable to connect to chatnav server\n"); @@ -1669,7 +1669,7 @@ ccon->show = extract_name(redir->chat.room); ccon->conn->status |= AIM_CONN_STATUS_INPROGRESS; - if (proxy_connect(account, host, port, oscar_chat_connect, ccon) != 0) { + if (gaim_proxy_connect(account, host, port, oscar_chat_connect, ccon) != 0) { aim_conn_kill(sess, &tstconn); gaim_debug(GAIM_DEBUG_ERROR, "oscar", "unable to connect to chat server\n"); @@ -1696,7 +1696,7 @@ aim_conn_addhandler(sess, tstconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNINITDONE, conninitdone_icon, 0); tstconn->status |= AIM_CONN_STATUS_INPROGRESS; - if (proxy_connect(account, host, port, oscar_icon_connect, gc) != 0) { + if (gaim_proxy_connect(account, host, port, oscar_icon_connect, gc) != 0) { aim_conn_kill(sess, &tstconn); gaim_debug(GAIM_DEBUG_ERROR, "oscar", "unable to connect to icon server\n"); @@ -1717,7 +1717,7 @@ aim_conn_addhandler(sess, tstconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNINITDONE, conninitdone_email, 0); tstconn->status |= AIM_CONN_STATUS_INPROGRESS; - if (proxy_connect(account, host, port, oscar_email_connect, gc) != 0) { + if (gaim_proxy_connect(account, host, port, oscar_email_connect, gc) != 0) { aim_conn_kill(sess, &tstconn); gaim_debug(GAIM_DEBUG_ERROR, "oscar", "unable to connect to email server\n"); @@ -1935,7 +1935,7 @@ } /* - * This is the gaim callback passed to proxy_connect when connecting to another AIM + * This is the gaim callback passed to gaim_proxy_connect when connecting to another AIM * user in order to transfer a file. */ static void oscar_sendfile_connected(gpointer data, gint source, GaimInputCondition condition) { @@ -2116,7 +2116,7 @@ } host = g_strndup(d->ip, i); dim->conn->status |= AIM_CONN_STATUS_INPROGRESS; - rc = proxy_connect(gc->account, host, port, oscar_odc_callback, dim); + rc = gaim_proxy_connect(gc->account, host, port, oscar_odc_callback, dim); g_free(host); if (rc < 0) { aim_conn_kill(od->sess, &dim->conn); diff -r 71cc0d5376c2 -r 46d7ad0dfa26 src/protocols/toc/toc.c --- a/src/protocols/toc/toc.c Mon Jun 02 22:30:25 2003 +0000 +++ b/src/protocols/toc/toc.c Tue Jun 03 02:00:33 2003 +0000 @@ -192,7 +192,7 @@ gaim_connection_update_progress(gc, buf, 1, TOC_CONNECT_STEPS); debug_printf("* Client connects to TOC\n"); - if (proxy_connect(account, + if (gaim_proxy_connect(account, gaim_account_get_string(account, "server", TOC_HOST), gaim_account_get_int(account, "port", TOC_PORT), toc_login_callback, gc) != 0 || !account->gc) { @@ -1683,7 +1683,7 @@ g_snprintf(buf, sizeof(buf), "toc_rvous_accept %s %s %s", ft->user, ft->cookie, FILE_SEND_UID); sflap_send(ft->gc, buf, -1, TYPE_DATA); - if (proxy_connect(account, ft->ip, ft->port, toc_send_file_connect, ft) != 0) { + if (gaim_proxy_connect(account, ft->ip, ft->port, toc_send_file_connect, ft) != 0) { gaim_notify_error(ft->gc, NULL, _("Could not connect for transfer."), NULL); g_free(ft->filename); @@ -1895,7 +1895,7 @@ g_snprintf(buf2, sizeof(buf2), "toc_rvous_accept %s %s %s", ft->user, ft->cookie, FILE_GET_UID); sflap_send(ft->gc, buf2, -1, TYPE_DATA); - if (proxy_connect(account, ft->ip, ft->port, toc_get_file_connect, ft) < 0) { + if (gaim_proxy_connect(account, ft->ip, ft->port, toc_get_file_connect, ft) < 0) { gaim_notify_error(ft->gc, NULL, _("Could not connect for transfer."), NULL); fclose(ft->file); diff -r 71cc0d5376c2 -r 46d7ad0dfa26 src/protocols/yahoo/yahoo.c --- a/src/protocols/yahoo/yahoo.c Mon Jun 02 22:30:25 2003 +0000 +++ b/src/protocols/yahoo/yahoo.c Tue Jun 03 02:00:33 2003 +0000 @@ -997,7 +997,7 @@ yd->hash = g_hash_table_new(g_str_hash, g_str_equal); yd->games = g_hash_table_new(g_str_hash, g_str_equal); - if (proxy_connect(account, gaim_account_get_string(account, "server", YAHOO_PAGER_HOST), + 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) { gaim_connection_error(gc, "Connection problem"); diff -r 71cc0d5376c2 -r 46d7ad0dfa26 src/proxy.c --- a/src/proxy.c Mon Jun 02 22:30:25 2003 +0000 +++ b/src/proxy.c Tue Jun 03 02:00:33 2003 +0000 @@ -1,7 +1,11 @@ -/* +/** + * @file proxy.c Proxy API + * @ingroup core + * * gaim * * Copyright (C) 1998-1999, Mark Spencer + * Copyright (C) 2003 Christian Hammond * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -47,6 +51,7 @@ #include #include "gaim.h" #include "proxy.h" +#include "prefs.h" #ifdef _WIN32 #include "win32dep.h" @@ -55,7 +60,8 @@ #define GAIM_READ_COND (G_IO_IN | G_IO_HUP | G_IO_ERR) #define GAIM_WRITE_COND (G_IO_OUT | G_IO_HUP | G_IO_ERR | G_IO_NVAL) -struct gaim_proxy_info global_proxy_info; +static GaimProxyInfo *global_proxy_info = NULL; +static gboolean global_proxy_info_from_prefs = FALSE; struct PHB { GaimInputFunction func; @@ -63,7 +69,7 @@ char *host; int port; gint inpa; - struct gaim_proxy_info *gpi; + GaimProxyInfo *gpi; GaimAccount *account; }; @@ -71,8 +77,143 @@ GaimInputFunction function; guint result; gpointer data; + } GaimIOClosure; +/************************************************************************** + * Proxy structure API + **************************************************************************/ +GaimProxyInfo * +gaim_proxy_info_new(void) +{ + return g_new0(GaimProxyInfo, 1); +} + +void +gaim_proxy_info_destroy(GaimProxyInfo *info) +{ + g_return_if_fail(info != NULL); + + if (info->host != NULL) g_free(info->host); + if (info->username != NULL) g_free(info->username); + if (info->password != NULL) g_free(info->password); + + g_free(info); +} + +void +gaim_proxy_info_set_type(GaimProxyInfo *info, GaimProxyType type) +{ + g_return_if_fail(info != NULL); + + info->type = type; +} + +void +gaim_proxy_info_set_host(GaimProxyInfo *info, const char *host) +{ + g_return_if_fail(info != NULL); + + if (info->host != NULL) + g_free(info->host); + + info->host = (host == NULL ? NULL : g_strdup(host)); +} + +void +gaim_proxy_info_set_port(GaimProxyInfo *info, int port) +{ + g_return_if_fail(info != NULL); + + info->port = port; +} + +void +gaim_proxy_info_set_username(GaimProxyInfo *info, const char *username) +{ + g_return_if_fail(info != NULL); + + if (info->username != NULL) + g_free(info->username); + + info->username = (username == NULL ? NULL : g_strdup(username)); +} + +void +gaim_proxy_info_set_password(GaimProxyInfo *info, const char *password) +{ + g_return_if_fail(info != NULL); + + if (info->password != NULL) + g_free(info->password); + + info->password = (password == NULL ? NULL : g_strdup(password)); +} + +GaimProxyType +gaim_proxy_info_get_type(const GaimProxyInfo *info) +{ + g_return_val_if_fail(info != NULL, GAIM_PROXY_NONE); + + return info->type; +} + +const char * +gaim_proxy_info_get_host(const GaimProxyInfo *info) +{ + g_return_val_if_fail(info != NULL, NULL); + + return info->host; +} + +int +gaim_proxy_info_get_port(const GaimProxyInfo *info) +{ + g_return_val_if_fail(info != NULL, 0); + + return info->port; +} + +const char * +gaim_proxy_info_get_username(const GaimProxyInfo *info) +{ + g_return_val_if_fail(info != NULL, NULL); + + return info->username; +} + +const char * +gaim_proxy_info_get_password(const GaimProxyInfo *info) +{ + g_return_val_if_fail(info != NULL, NULL); + + return info->password; +} + +/************************************************************************** + * Global Proxy API + **************************************************************************/ +void +gaim_global_proxy_set_from_prefs(gboolean from_prefs) +{ + global_proxy_info_from_prefs = from_prefs; +} + +GaimProxyInfo * +gaim_global_proxy_get_info(void) +{ + return global_proxy_info; +} + +gboolean +gaim_global_proxy_is_from_prefs(void) +{ + return global_proxy_info_from_prefs; +} + +/************************************************************************** + * Proxy API + **************************************************************************/ static void gaim_io_destroy(gpointer data) { g_free(data); @@ -579,7 +720,9 @@ return FALSE; } -int gaim_gethostbyname_async(const char *hostname, int port, dns_callback_t callback, gpointer data) +int +gaim_gethostbyname_async(const char *hostname, int port, + dns_callback_t callback, gpointer data) { struct sockaddr_in sin; pending_dns_request_t *req; @@ -610,7 +753,8 @@ #endif -static void no_one_calls(gpointer data, gint source, GaimInputCondition cond) +static void +no_one_calls(gpointer data, gint source, GaimInputCondition cond) { struct PHB *phb = data; unsigned int len; @@ -626,8 +770,13 @@ if(ret==0) errno = error; close(source); gaim_input_remove(phb->inpa); - if(!phb->account || phb->account->gc) + + 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); @@ -635,10 +784,16 @@ "getsockopt SO_ERROR check: %s\n", strerror(errno)); return; } + fcntl(source, F_SETFL, 0); gaim_input_remove(phb->inpa); - if(!phb->account || phb->account->gc) + + if (phb->account == NULL || + gaim_account_get_connection(phb->account) != NULL) { + phb->func(phb->data, source, GAIM_INPUT_READ); + } + g_free(phb->host); g_free(phb); } @@ -647,8 +802,12 @@ { struct PHB *phb = data; - if(!phb->account || phb->account->gc) + 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); @@ -656,7 +815,8 @@ } -static int proxy_connect_none(struct PHB *phb, struct sockaddr *addr, socklen_t addrlen) +static int +proxy_connect_none(struct PHB *phb, struct sockaddr *addr, socklen_t addrlen) { int fd = -1; @@ -675,13 +835,15 @@ gaim_debug(GAIM_DEBUG_WARNING, "proxy", "Connect would have blocked.\n"); phb->inpa = gaim_input_add(fd, GAIM_INPUT_WRITE, no_one_calls, phb); - } else { + } + else { gaim_debug(GAIM_DEBUG_ERROR, "proxy", "Connect failed (errno %d)\n", errno); close(fd); return -1; } - } else { + } + else { unsigned int len; int error = ETIMEDOUT; gaim_debug(GAIM_DEBUG_MISC, "proxy", "Connect didn't block.\n"); @@ -704,7 +866,8 @@ #define HTTP_GOODSTRING "HTTP/1.0 200" #define HTTP_GOODSTRING2 "HTTP/1.1 200" -static void http_canread(gpointer data, gint source, GaimInputCondition cond) +static void +http_canread(gpointer data, gint source, GaimInputCondition cond) { int nlc = 0; int pos = 0; @@ -721,7 +884,7 @@ nlc = 0; } inputline[pos] = '\0'; - + error = strncmp(inputline, "HTTP/", 5) != 0; if(!error) { p = inputline + 5; @@ -744,7 +907,8 @@ "Unable to parse proxy's response: %s\n", inputline); close(source); source=-1; - } else if(status!=200) { + } + else if(status!=200) { gaim_debug(GAIM_DEBUG_ERROR, "proxy", "Proxy server replied: (%s)\n", p); close(source); @@ -758,7 +922,8 @@ return; } -static void http_canwrite(gpointer data, gint source, GaimInputCondition cond) +static void +http_canwrite(gpointer data, gint source, GaimInputCondition cond) { char request[8192]; int request_len = 0; @@ -770,25 +935,38 @@ if (phb->inpa > 0) gaim_input_remove(phb->inpa); + len = sizeof(error); + if (getsockopt(source, SOL_SOCKET, SO_ERROR, &error, &len) < 0) { close(source); - if(!phb->account || phb->account->gc) + + 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); return; } - request_len = g_snprintf(request, sizeof(request), "CONNECT %s:%d HTTP/1.1\r\nHost: %s:%d\r\n", phb->host, phb->port, - phb->host, phb->port); + request_len = g_snprintf(request, sizeof(request), + "CONNECT %s:%d HTTP/1.1\r\nHost: %s:%d\r\n", + phb->host, phb->port, phb->host, phb->port); - if (phb->gpi->proxyuser) { + if (gaim_proxy_info_get_username(phb->gpi) != NULL) { char *t1, *t2; - t1 = g_strdup_printf("%s:%s", phb->gpi->proxyuser, phb->gpi->proxypass); + t1 = g_strdup_printf("%s:%s", + gaim_proxy_info_get_username(phb->gpi), + gaim_proxy_info_get_password(phb->gpi)); + t2 = tobase64(t1, strlen(t1)); g_free(t1); g_return_if_fail(request_len < sizeof(request)); - request_len += g_snprintf(request + request_len, sizeof(request) - request_len, "Proxy-Authorization: Basic %s\r\n", t2); + request_len += g_snprintf(request + request_len, + sizeof(request) - request_len, + "Proxy-Authorization: Basic %s\r\n", t2); g_free(t2); } @@ -798,8 +976,13 @@ if (write(source, request, request_len) < 0) { close(source); - if(!phb->account || phb->account->gc) + + 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); return; @@ -808,14 +991,16 @@ phb->inpa = gaim_input_add(source, GAIM_INPUT_READ, http_canread, phb); } -static int proxy_connect_http(struct PHB *phb, struct sockaddr *addr, socklen_t addrlen) +static int +proxy_connect_http(struct PHB *phb, struct sockaddr *addr, socklen_t addrlen) { int fd = -1; gaim_debug(GAIM_DEBUG_INFO, "http proxy", "Connecting to %s:%d via %s:%d using HTTP\n", - phb->host, phb->port, phb->gpi->proxyhost, - phb->gpi->proxyport); + phb->host, phb->port, + gaim_proxy_info_get_host(phb->gpi), + gaim_proxy_info_get_port(phb->gpi)); if ((fd = socket(addr->sa_family, SOCK_STREAM, 0)) < 0) { return -1; @@ -827,12 +1012,14 @@ if ((errno == EINPROGRESS) || (errno == EINTR)) { gaim_debug(GAIM_DEBUG_WARNING, "http proxy", "Connect would have blocked.\n"); - phb->inpa = gaim_input_add(fd, GAIM_INPUT_WRITE, http_canwrite, phb); + phb->inpa = gaim_input_add(fd, GAIM_INPUT_WRITE, + http_canwrite, phb); } else { close(fd); return -1; } - } else { + } + else { unsigned int len; int error = ETIMEDOUT; @@ -851,7 +1038,8 @@ return fd; } -static void s4_canread(gpointer data, gint source, GaimInputCondition cond) +static void +s4_canread(gpointer data, gint source, GaimInputCondition cond) { unsigned char packet[12]; struct PHB *phb = data; @@ -861,21 +1049,31 @@ memset(packet, 0, sizeof(packet)); if (read(source, packet, 9) >= 4 && packet[1] == 90) { - if(!phb->account || phb->account->gc) - phb->func(phb->data, source, GAIM_INPUT_READ); + 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); return; } close(source); - if(!phb->account || phb->account->gc) + + 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); } -static void s4_canwrite(gpointer data, gint source, GaimInputCondition cond) +static void +s4_canwrite(gpointer data, gint source, GaimInputCondition cond) { unsigned char packet[12]; struct hostent *hp; @@ -887,11 +1085,18 @@ if (phb->inpa > 0) gaim_input_remove(phb->inpa); + len = sizeof(error); + if (getsockopt(source, SOL_SOCKET, SO_ERROR, &error, &len) < 0) { close(source); - if(!phb->account || phb->account->gc) + + 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); return; @@ -901,8 +1106,13 @@ /* XXX does socks4 not support host name lookups by the proxy? */ if (!(hp = gethostbyname(phb->host))) { close(source); - if(!phb->account || phb->account->gc) + + 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); return; @@ -920,8 +1130,13 @@ if (write(source, packet, 9) != 9) { close(source); - if(!phb->account || phb->account->gc) + + 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); return; @@ -930,26 +1145,29 @@ phb->inpa = gaim_input_add(source, GAIM_INPUT_READ, s4_canread, phb); } -static int proxy_connect_socks4(struct PHB *phb, struct sockaddr *addr, socklen_t addrlen) +static int +proxy_connect_socks4(struct PHB *phb, struct sockaddr *addr, socklen_t addrlen) { int fd = -1; gaim_debug(GAIM_DEBUG_INFO, "socks4 proxy", "Connecting to %s:%d via %s:%d using SOCKS4\n", - phb->host, phb->port, phb->gpi->proxyhost, - phb->gpi->proxyport); + phb->host, phb->port, + gaim_proxy_info_get_host(phb->gpi), + gaim_proxy_info_get_port(phb->gpi)); - if ((fd = socket(addr->sa_family, SOCK_STREAM, 0)) < 0) { + if ((fd = socket(addr->sa_family, SOCK_STREAM, 0)) < 0) return -1; - } fcntl(fd, F_SETFL, O_NONBLOCK); + if (connect(fd, addr, addrlen) < 0) { if ((errno == EINPROGRESS) || (errno == EINTR)) { gaim_debug(GAIM_DEBUG_WARNING, "socks4 proxy", "Connect would have blocked.\n"); phb->inpa = gaim_input_add(fd, GAIM_INPUT_WRITE, s4_canwrite, phb); - } else { + } + else { close(fd); return -1; } @@ -961,10 +1179,12 @@ "Connect didn't block.\n"); len = sizeof(error); + if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &len) < 0) { close(fd); return -1; } + fcntl(fd, F_SETFL, 0); s4_canwrite(phb, fd, GAIM_INPUT_WRITE); } @@ -972,7 +1192,8 @@ return fd; } -static void s5_canread_again(gpointer data, gint source, GaimInputCondition cond) +static void +s5_canread_again(gpointer data, gint source, GaimInputCondition cond) { unsigned char buf[512]; struct PHB *phb = data; @@ -983,8 +1204,13 @@ if (read(source, buf, 10) < 10) { gaim_debug(GAIM_DEBUG_WARNING, "socks5 proxy", "or not...\n"); close(source); - if(!phb->account || phb->account->gc) + + 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); return; @@ -992,21 +1218,30 @@ if ((buf[0] != 0x05) || (buf[1] != 0x00)) { gaim_debug(GAIM_DEBUG_ERROR, "socks5 proxy", "Bad data.\n"); close(source); - if(!phb->account || phb->account->gc) + + 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); return; } - if(!phb->account || phb->account->gc) + if (phb->account == NULL || + gaim_account_get_connection(phb->account) != NULL) { + phb->func(phb->data, source, GAIM_INPUT_READ); + } + g_free(phb->host); g_free(phb); - return; } -static void s5_sendconnect(gpointer data, gint source) +static void +s5_sendconnect(gpointer data, gint source) { unsigned char buf[512]; struct PHB *phb = data; @@ -1023,8 +1258,13 @@ if (write(source, buf, (5 + strlen(phb->host) + 2)) < (5 + strlen(phb->host) + 2)) { close(source); - if(!phb->account || phb->account->gc) + + 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); return; @@ -1033,7 +1273,8 @@ phb->inpa = gaim_input_add(source, GAIM_INPUT_READ, s5_canread_again, phb); } -static void s5_readauth(gpointer data, gint source, GaimInputCondition cond) +static void +s5_readauth(gpointer data, gint source, GaimInputCondition cond) { unsigned char buf[512]; struct PHB *phb = data; @@ -1043,8 +1284,13 @@ if (read(source, buf, 2) < 2) { close(source); - if(!phb->account || phb->account->gc) + + 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); return; @@ -1052,8 +1298,13 @@ if ((buf[0] != 0x01) || (buf[1] != 0x00)) { close(source); - if(!phb->account || phb->account->gc) + + 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); return; @@ -1062,7 +1313,8 @@ s5_sendconnect(phb, source); } -static void s5_canread(gpointer data, gint source, GaimInputCondition cond) +static void +s5_canread(gpointer data, gint source, GaimInputCondition cond) { unsigned char buf[512]; struct PHB *phb = data; @@ -1072,8 +1324,13 @@ if (read(source, buf, 2) < 2) { close(source); - if(!phb->account || phb->account->gc) + + 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); return; @@ -1081,37 +1338,53 @@ if ((buf[0] != 0x05) || (buf[1] == 0xff)) { close(source); - if(!phb->account || phb->account->gc) + + 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); return; } if (buf[1] == 0x02) { - unsigned int i = strlen(phb->gpi->proxyuser), j = strlen(phb->gpi->proxypass); + unsigned int i, j; + + i = strlen(gaim_proxy_info_get_username(phb->gpi)); + j = strlen(gaim_proxy_info_get_password(phb->gpi)); + buf[0] = 0x01; /* version 1 */ buf[1] = i; - memcpy(buf + 2, phb->gpi->proxyuser, i); + memcpy(buf + 2, gaim_proxy_info_get_username(phb->gpi), i); buf[2 + i] = j; - memcpy(buf + 2 + i + 1, phb->gpi->proxypass, j); + memcpy(buf + 2 + i + 1, gaim_proxy_info_get_password(phb->gpi), j); if (write(source, buf, 3 + i + j) < 3 + i + j) { close(source); - if(!phb->account || phb->account->gc) + + 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); return; } phb->inpa = gaim_input_add(source, GAIM_INPUT_READ, s5_readauth, phb); - } else { + } + else { s5_sendconnect(phb, source); } } -static void s5_canwrite(gpointer data, gint source, GaimInputCondition cond) +static void +s5_canwrite(gpointer data, gint source, GaimInputCondition cond) { unsigned char buf[512]; int i; @@ -1123,11 +1396,16 @@ if (phb->inpa > 0) gaim_input_remove(phb->inpa); + len = sizeof(error); if (getsockopt(source, SOL_SOCKET, SO_ERROR, &error, &len) < 0) { close(source); - if(!phb->account || phb->account->gc) + 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); return; @@ -1136,12 +1414,14 @@ i = 0; buf[0] = 0x05; /* SOCKS version 5 */ - if (phb->gpi->proxyuser[0]) { + + if (gaim_proxy_info_get_username(phb->gpi) != NULL) { buf[1] = 0x02; /* two methods */ buf[2] = 0x00; /* no authentication */ buf[3] = 0x02; /* username/password authentication */ i = 4; - } else { + } + else { buf[1] = 0x01; buf[2] = 0x00; i = 3; @@ -1150,8 +1430,13 @@ if (write(source, buf, i) < i) { gaim_debug(GAIM_DEBUG_ERROR, "socks5 proxy", "Unable to write\n"); close(source); - if(!phb->account || phb->account->gc) + + 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); return; @@ -1160,40 +1445,48 @@ phb->inpa = gaim_input_add(source, GAIM_INPUT_READ, s5_canread, phb); } -static int proxy_connect_socks5(struct PHB *phb, struct sockaddr *addr, socklen_t addrlen) +static int +proxy_connect_socks5(struct PHB *phb, struct sockaddr *addr, socklen_t addrlen) { int fd = -1; gaim_debug(GAIM_DEBUG_INFO, "socks5 proxy", "Connecting to %s:%d via %s:%d using SOCKS5\n", - phb->host, phb->port, phb->gpi->proxyhost, - phb->gpi->proxyport); + phb->host, phb->port, + gaim_proxy_info_get_host(phb->gpi), + gaim_proxy_info_get_port(phb->gpi)); - if ((fd = socket(addr->sa_family, SOCK_STREAM, 0)) < 0) { + if ((fd = socket(addr->sa_family, SOCK_STREAM, 0)) < 0) return -1; - } fcntl(fd, F_SETFL, O_NONBLOCK); + if (connect(fd, addr, addrlen) < 0) { if ((errno == EINPROGRESS) || (errno == EINTR)) { gaim_debug(GAIM_DEBUG_WARNING, "socks5 proxy", "Connect would have blocked.\n"); + phb->inpa = gaim_input_add(fd, GAIM_INPUT_WRITE, s5_canwrite, phb); - } else { + } + else { close(fd); return -1; } - } else { + } + else { unsigned int len; int error = ETIMEDOUT; gaim_debug(GAIM_DEBUG_MISC, "socks5 proxy", "Connect didn't block.\n"); + len = sizeof(error); + if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &len) < 0) { close(fd); return -1; } + fcntl(fd, F_SETFL, 0); s5_canwrite(phb, fd, GAIM_INPUT_WRITE); } @@ -1201,86 +1494,154 @@ return fd; } -static void connection_host_resolved(GSList *hosts, gpointer data, const char *error_message) +static void +connection_host_resolved(GSList *hosts, gpointer data, + const char *error_message) { struct PHB *phb = (struct PHB*)data; size_t addrlen; struct sockaddr *addr; int ret = -1; - while(hosts) { + while (hosts) { addrlen = GPOINTER_TO_INT(hosts->data); hosts = hosts->next; addr = hosts->data; hosts = hosts->next; - switch(phb->gpi->proxytype) + switch (gaim_proxy_info_get_type(phb->gpi)) { - case PROXY_NONE: + case GAIM_PROXY_NONE: ret = proxy_connect_none(phb, addr, addrlen); break; - case PROXY_HTTP: + + case GAIM_PROXY_HTTP: ret = proxy_connect_http(phb, addr, addrlen); break; - case PROXY_SOCKS4: + + case GAIM_PROXY_SOCKS4: ret = proxy_connect_socks4(phb, addr, addrlen); break; - case PROXY_SOCKS5: + + case GAIM_PROXY_SOCKS5: ret = proxy_connect_socks5(phb, addr, addrlen); break; + + default: + break; } + if (ret > 0) break; } - if(ret < 0) { - if(!phb->account || phb->account->gc) + + 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); } } int -proxy_connect(GaimAccount *account, const char *host, int port, GaimInputFunction func, gpointer data) +gaim_proxy_connect(GaimAccount *account, const char *host, int port, + GaimInputFunction func, gpointer data) { const char *connecthost = host; int connectport = port; struct PHB *phb = g_new0(struct PHB, 1); - if(!account || !account->gpi) - phb->gpi = &global_proxy_info; + + 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); + + if (account == NULL || gaim_account_get_proxy_info(account) == NULL) + phb->gpi = gaim_global_proxy_get_info(); else - phb->gpi = account->gpi; + phb->gpi = gaim_account_get_proxy_info(account); + phb->func = func; phb->data = data; phb->host = g_strdup(host); phb->port = port; phb->account = account; - if (!host || !port || (port == -1) || !func) { - if(host) - g_free(phb->host); - g_free(phb); - return -1; + if ((gaim_proxy_info_get_type(phb->gpi) != GAIM_PROXY_NONE) && + (gaim_proxy_info_get_host(phb->gpi) == NULL || + gaim_proxy_info_get_port(phb->gpi) == 0 || + gaim_proxy_info_get_port(phb->gpi) == -1)) { + + gaim_proxy_info_set_type(phb->gpi, GAIM_PROXY_NONE); } - if ((phb->gpi->proxytype!=PROXY_NONE) && (!phb->gpi->proxyhost || !phb->gpi->proxyhost[0] || !phb->gpi->proxyport || (phb->gpi->proxyport == -1))) - phb->gpi->proxytype=PROXY_NONE; - - switch(phb->gpi->proxytype) + switch (gaim_proxy_info_get_type(phb->gpi)) { - case PROXY_NONE: + case GAIM_PROXY_NONE: break; - case PROXY_HTTP: - case PROXY_SOCKS4: - case PROXY_SOCKS5: - connecthost=phb->gpi->proxyhost; - connectport=phb->gpi->proxyport; + + case GAIM_PROXY_HTTP: + case GAIM_PROXY_SOCKS4: + case GAIM_PROXY_SOCKS5: + connecthost = gaim_proxy_info_get_host(phb->gpi); + connectport = gaim_proxy_info_get_port(phb->gpi); break; + default: g_free(phb->host); g_free(phb); return -1; } - - return gaim_gethostbyname_async(connecthost, connectport, connection_host_resolved, phb); + + return gaim_gethostbyname_async(connecthost, connectport, + connection_host_resolved, phb); +} + + +static void +proxy_pref_cb(const char *name, GaimPrefType type, gpointer value, + gpointer data) +{ + GaimProxyInfo *info = gaim_global_proxy_get_info(); + + if (!strcmp(name, "/core/proxy/type")) + gaim_proxy_info_set_type(info, GPOINTER_TO_INT(value)); + else if (!strcmp(name, "/core/proxy/host")) + gaim_proxy_info_set_host(info, value); + else if (!strcmp(name, "/core/proxy/port")) + gaim_proxy_info_set_port(info, GPOINTER_TO_INT(value)); + else if (!strcmp(name, "/core/proxy/username")) + gaim_proxy_info_set_username(info, value); + else if (!strcmp(name, "/core/proxy/password")) + gaim_proxy_info_set_password(info, value); } + +void +gaim_proxy_init(void) +{ + /* Initialize a default proxy info struct. */ + global_proxy_info = gaim_proxy_info_new(); + + /* Proxy */ + gaim_prefs_add_none("/core/proxy"); + gaim_prefs_add_string("/core/proxy/type", "none"); + gaim_prefs_add_string("/core/proxy/host", ""); + gaim_prefs_add_int("/core/proxy/port", 0); + gaim_prefs_add_string("/core/proxy/username", ""); + gaim_prefs_add_string("/core/proxy/password", ""); + + /* Setup callbacks for the preferences. */ + gaim_prefs_connect_callback("/core/proxy/type", + proxy_pref_cb, NULL); + gaim_prefs_connect_callback("/core/proxy/host", + proxy_pref_cb, NULL); + gaim_prefs_connect_callback("/core/proxy/port", + proxy_pref_cb, NULL); + gaim_prefs_connect_callback("/core/proxy/username", + proxy_pref_cb, NULL); + gaim_prefs_connect_callback("/core/proxy/password", + proxy_pref_cb, NULL); +} diff -r 71cc0d5376c2 -r 46d7ad0dfa26 src/proxy.h --- a/src/proxy.h Mon Jun 02 22:30:25 2003 +0000 +++ b/src/proxy.h Tue Jun 03 02:00:33 2003 +0000 @@ -1,10 +1,11 @@ /** - * @file proxy.h Proxy functions + * @file proxy.h Proxy API * @ingroup core * * gaim * * Copyright (C) 1998-1999, Mark Spencer + * Copyright (C) 2003 Christian Hammond * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -20,57 +21,243 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -/* this is the export part of the proxy.c file. it does a little - prototype-ing stuff and redefine some net function to mask them - with some kind of transparent layer */ - -#ifndef _PROXY_H_ -#define _PROXY_H_ +#ifndef _GAIM_PROXY_H_ +#define _GAIM_PROXY_H_ #include /*this must happen before sys/socket.h or freebsd won't compile*/ #ifndef _WIN32 -#include -#include -#include +# include +# include +# include #else -#include +# include #endif #include #include "core.h" +#include "account.h" -typedef enum { - PROXY_USE_GLOBAL = -1, - PROXY_NONE = 0, - PROXY_HTTP, - PROXY_SOCKS4, - PROXY_SOCKS5, -} proxytype_t; +/** + * A type of proxy connection. + */ +typedef enum +{ + GAIM_PROXY_USE_GLOBAL = -1, /**< Use the global proxy information. */ + GAIM_PROXY_NONE = 0, /**< No proxy. */ + GAIM_PROXY_HTTP, /**< HTTP proxy. */ + GAIM_PROXY_SOCKS4, /**< SOCKS 4 proxy. */ + GAIM_PROXY_SOCKS5, /**< SOCKS 5 proxy. */ + +} GaimProxyType; -struct gaim_proxy_info { - int proxytype; - char proxyhost[128]; - proxytype_t proxyport; - char proxyuser[128]; - char proxypass[128]; -}; +/** + * An input condition. + */ +typedef enum +{ + GAIM_INPUT_READ = 1 << 0, + GAIM_INPUT_WRITE = 1 << 1 + +} GaimInputCondition; -extern struct gaim_proxy_info global_proxy_info; -extern guint proxy_info_is_from_gaimrc; +/** + * Information on proxy settings. + */ +typedef struct +{ + GaimProxyType type; /**< The proxy type. */ -typedef enum { - GAIM_INPUT_READ = 1 << 0, - GAIM_INPUT_WRITE = 1 << 1 -} GaimInputCondition; + char *host; /**< The host. */ + int port; /**< The port number. */ + char *username; /**< The username. */ + char *password; /**< The password. */ + +} GaimProxyInfo; + typedef void (*GaimInputFunction)(gpointer, gint, GaimInputCondition); -extern gint gaim_input_add(int, GaimInputCondition, GaimInputFunction, gpointer); -extern void gaim_input_remove(gint); +/**************************************************************************/ +/** @name Proxy structure API */ +/**************************************************************************/ +/*@{*/ + +/** + * Creates a proxy information structure. + * + * @return The proxy information structure. + */ +GaimProxyInfo *gaim_proxy_info_new(void); + +/** + * Destroys a proxy information structure. + * + * @param proxy The proxy information structure to destroy. + */ +void gaim_proxy_info_destroy(GaimProxyInfo *info); + +/** + * Sets the type of proxy. + * + * @param proxy The proxy information. + * @param type The proxy type. + */ +void gaim_proxy_info_set_type(GaimProxyInfo *info, GaimProxyType type); + +/** + * Sets the proxy host. + * + * @param proxy The proxy information. + * @param host The host. + */ +void gaim_proxy_info_set_host(GaimProxyInfo *info, const char *host); + +/** + * Sets the proxy port. + * + * @param proxy The proxy information. + * @param port The port. + */ +void gaim_proxy_info_set_port(GaimProxyInfo *info, int port); + +/** + * Sets the proxy username. + * + * @param proxy The proxy information. + * @param username The username. + */ +void gaim_proxy_info_set_username(GaimProxyInfo *info, const char *username); + +/** + * Sets the proxy password. + * + * @param proxy The proxy information. + * @param password The password. + */ +void gaim_proxy_info_set_password(GaimProxyInfo *info, const char *password); + +/** + * Returns the proxy's type. + * + * @param The proxy information. + * + * @return The type. + */ +GaimProxyType gaim_proxy_info_get_type(const GaimProxyInfo *info); + +/** + * Returns the proxy's host. + * + * @param The proxy information. + * + * @return The host. + */ +const char *gaim_proxy_info_get_host(const GaimProxyInfo *info); + +/** + * Returns the proxy's port. + * + * @param The proxy information. + * + * @return The port. + */ +int gaim_proxy_info_get_port(const GaimProxyInfo *info); -extern int proxy_connect(GaimAccount *account, const char *host, int port, GaimInputFunction func, gpointer data); +/** + * Returns the proxy's username. + * + * @param The proxy information. + * + * @return The username. + */ +const char *gaim_proxy_info_get_username(const GaimProxyInfo *info); + +/** + * Returns the proxy's password. + * + * @param The proxy information. + * + * @return The password. + */ +const char *gaim_proxy_info_get_password(const GaimProxyInfo *info); + +/*@}*/ + +/**************************************************************************/ +/** @name Global Proxy API */ +/**************************************************************************/ +/*@{*/ + +/** + * Sets whether or not the global proxy information is from preferences. + * + * @param from_prefs @c TRUE if the info is from preferences. + */ +void gaim_global_proxy_set_from_prefs(gboolean from_prefs); + +/** + * Returns gaim's global proxy information. + * + * @return The global proxy information. + */ +GaimProxyInfo *gaim_global_proxy_get_info(void); + +/** + * Returns whether or not the current global proxy information is from + * preferences. + * + * @return @c TRUE if the info is from preferences. + */ +gboolean gaim_global_proxy_is_from_prefs(void); -#endif /* _PROXY_H_ */ +/*@}*/ + +/**************************************************************************/ +/** @name Proxy API */ +/**************************************************************************/ +/*@{*/ + +/** + * Initializes the proxy subsystem. + */ +void gaim_proxy_init(void); + +/** + * Adds an input handler. + * + * @param source The input source. + * @param cond The condition type. + * @param func The callback function for data. + * @param user_data User-specified data. + * + * @return The resulting handle. + */ +gint gaim_input_add(int source, GaimInputCondition cond, + GaimInputFunction func, gpointer user_data); + +/** + * Removes an input handler. + * + * @param handle The handle of the input handler. + */ +void gaim_input_remove(gint handle); + +/** + * Makes a connection to the specified host and port. + * + * @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. + * + * @return The socket handle. + */ +int gaim_proxy_connect(GaimAccount *account, const char *host, int port, + GaimInputFunction func, gpointer data); + +/*@}*/ + +#endif /* _GAIM_PROXY_H_ */