changeset 5681:46d7ad0dfa26

[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 <tailor@pidgin.im>
author Christian Hammond <chipx86@chipx86.com>
date Tue, 03 Jun 2003 02:00:33 +0000
parents 71cc0d5376c2
children cec7988f8ee7
files src/account.c src/account.h src/ft.c src/gaimrc.c src/gtkaccount.c src/gtkconv.c src/gtkprefs.c src/html.c src/prefs.c src/protocols/gg/gg.c src/protocols/gg/libgg.c src/protocols/irc/irc.c src/protocols/jabber/jabber.c src/protocols/msn/ft.c src/protocols/msn/servconn.c src/protocols/napster/napster.c src/protocols/oscar/oscar.c src/protocols/toc/toc.c src/protocols/yahoo/yahoo.c src/proxy.c src/proxy.h
diffstat 21 files changed, 871 insertions(+), 279 deletions(-) [+]
line wrap: on
line diff
--- 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)
--- 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.
--- 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;
 		}
--- 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);
+			}
 		}
 	}
 }
--- 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;
--- 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)
 {
--- 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;
--- 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);
--- 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) {
--- 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 <misiek@pld.ORG.PL>
  * 
@@ -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 "
--- 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 <wojtekka@irc.pl>,
@@ -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");
--- 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
 
--- 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;
--- 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);
--- 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)
--- 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) {
--- 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);
--- 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);
--- 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");
--- 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 <markster@marko.net>
+ * Copyright (C) 2003 Christian Hammond <chipx86@gnupdate.org>
  *
  * 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 <errno.h>
 #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);
+}
--- 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 <markster@marko.net>
+ * Copyright (C) 2003 Christian Hammond <chipx86@gnupdate.org>
  *
  * 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 <sys/types.h>
 /*this must happen before sys/socket.h or freebsd won't compile*/
 
 #ifndef _WIN32
-#include <sys/socket.h>
-#include <netdb.h>
-#include <netinet/in.h>
+# include <sys/socket.h>
+# include <netdb.h>
+# include <netinet/in.h>
 #else
-#include <winsock.h>
+# include <winsock.h>
 #endif
 
 #include <glib.h>
 
 #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_ */