Index: Makefile
===================================================================
--- Makefile	(revision fef6116e89bb0651c72454effbb51e04e9e1b8dc)
+++ Makefile	(revision 3f9440db856c1b1cde54eb919543cfc23ea09983)
@@ -10,7 +10,7 @@
 
 # Program variables
-objects = account.o bitlbee.o conf.o crypting.o help.o ipc.o irc.o irc_commands.o log.o nick.o query.o root_commands.o set.o storage.o $(STORAGE_OBJS) unix.o user.o
+objects = account.o bitlbee.o conf.o crypting.o help.o ini.o ipc.o irc.o irc_commands.o log.o nick.o query.o root_commands.o set.o storage.o storage_text.o unix.o url.o user.o util.o
 headers = account.h bitlbee.h commands.h conf.h config.h crypting.h help.h ini.h ipc.h irc.h log.h nick.h query.h set.h sock.h storage.h url.h user.h protocols/http_client.h protocols/md5.h protocols/nogaim.h protocols/proxy.h protocols/sha.h protocols/ssl_client.h
-subdirs = protocols lib
+subdirs = protocols
 
 # Expansion of variables
@@ -42,5 +42,5 @@
 
 distclean: clean $(subdirs)
-	rm -f Makefile.settings config.h bitlbee.pc
+	rm -f Makefile.settings config.h
 	find . -name 'DEADJOE' -o -name '*.orig' -o -name '*.rej' -o -name '*~' -exec rm -f {} \;
 
Index: account.c
===================================================================
--- account.c	(revision fef6116e89bb0651c72454effbb51e04e9e1b8dc)
+++ account.c	(revision 3f9440db856c1b1cde54eb919543cfc23ea09983)
@@ -28,15 +28,12 @@
 #include "account.h"
 
-char *set_eval_account( set_t *set, char *value );
-
 account_t *account_add( irc_t *irc, struct prpl *prpl, char *user, char *pass )
 {
 	account_t *a;
-	set_t *s;
 	
 	if( irc->accounts )
 	{
 		for( a = irc->accounts; a->next; a = a->next );
-		a = a->next = g_new0( account_t, 1 );
+		a = a->next = g_new0 ( account_t, 1 );
 	}
 	else
@@ -48,62 +45,7 @@
 	a->user = g_strdup( user );
 	a->pass = g_strdup( pass );
-	a->auto_connect = 1;
 	a->irc = irc;
 	
-	s = set_add( &a->set, "auto_connect", NULL, set_eval_account, a );
-	s->flags |= ACC_SET_NOSAVE;
-	
-	s = set_add( &a->set, "password", NULL, set_eval_account, a );
-	s->flags |= ACC_SET_NOSAVE;
-	
-	s = set_add( &a->set, "server", NULL, set_eval_account, a );
-	s->flags |= ACC_SET_NOSAVE | ACC_SET_OFFLINE_ONLY;
-	
-	s = set_add( &a->set, "username", NULL, set_eval_account, a );
-	s->flags |= ACC_SET_NOSAVE | ACC_SET_OFFLINE_ONLY;
-	set_setstr( &a->set, "username", user );
-	
 	return( a );
-}
-
-char *set_eval_account( set_t *set, char *value )
-{
-	account_t *acc = set->data;
-	
-	/* Double-check: We refuse to edit on-line accounts. */
-	if( set->flags & ACC_SET_OFFLINE_ONLY && acc->gc )
-		return NULL;
-	
-	if( strcmp( set->key, "username" ) == 0 )
-	{
-		g_free( acc->user );
-		acc->user = g_strdup( value );
-		return value;
-	}
-	else if( strcmp( set->key, "password" ) == 0 )
-	{
-		g_free( acc->pass );
-		acc->pass = g_strdup( value );
-		return NULL;	/* password shouldn't be visible in plaintext! */
-	}
-	else if( strcmp( set->key, "server" ) == 0 )
-	{
-		g_free( acc->server );
-		if( *value )
-			acc->server = g_strdup( value );
-		else
-			acc->server = NULL;
-		return value;
-	}
-	else if( strcmp( set->key, "auto_connect" ) == 0 )
-	{
-		if( !is_bool( value ) )
-			return NULL;
-		
-		acc->auto_connect = bool2int( value );
-		return value;
-	}
-	
-	return NULL;
 }
 
@@ -187,7 +129,4 @@
 			}
 			
-			while( a->set )
-				set_del( &a->set, a->set->key );
-			
 			g_free( a->user );
 			g_free( a->pass );
@@ -203,4 +142,6 @@
 void account_on( irc_t *irc, account_t *a )
 {
+	struct aim_user *u;
+	
 	if( a->gc )
 	{
@@ -211,6 +152,15 @@
 	cancel_auto_reconnect( a );
 	
+	u = g_new0 ( struct aim_user, 1 );
+	u->irc = irc;
+	u->prpl = a->prpl;
+	strncpy( u->username, a->user, sizeof( u->username ) - 1 );
+	strncpy( u->password, a->pass, sizeof( u->password ) - 1 );
+	if( a->server) strncpy( u->proto_opt[0], a->server, sizeof( u->proto_opt[0] ) - 1 );
+	
+	a->gc = (struct gaim_connection *) u; /* Bit hackish :-/ */
 	a->reconnect = 0;
-	a->prpl->login( a );
+	
+	a->prpl->login( u );
 }
 
Index: account.h
===================================================================
--- account.h	(revision fef6116e89bb0651c72454effbb51e04e9e1b8dc)
+++ account.h	(revision 3f9440db856c1b1cde54eb919543cfc23ea09983)
@@ -34,8 +34,5 @@
 	char *server;
 	
-	int auto_connect;
 	int reconnect;
-	
-	set_t *set;
 	
 	struct irc *irc;
@@ -50,6 +47,3 @@
 void account_off( irc_t *irc, account_t *a );
 
-#define ACC_SET_NOSAVE		1
-#define ACC_SET_OFFLINE_ONLY	2
-
 #endif
Index: bitlbee.c
===================================================================
--- bitlbee.c	(revision fef6116e89bb0651c72454effbb51e04e9e1b8dc)
+++ bitlbee.c	(revision 3f9440db856c1b1cde54eb919543cfc23ea09983)
@@ -291,8 +291,4 @@
 			irc_t *irc;
 			
-			/* Since we're fork()ing here, let's make sure we won't
-			   get the same random numbers as the parent/siblings. */
-			srand( time( NULL ) ^ getpid() );
-			
 			/* Close the listening socket, we're a client. */
 			close( global.listen_socket );
Index: bitlbee.h
===================================================================
--- bitlbee.h	(revision fef6116e89bb0651c72454effbb51e04e9e1b8dc)
+++ bitlbee.h	(revision 3f9440db856c1b1cde54eb919543cfc23ea09983)
@@ -130,5 +130,5 @@
 #include "query.h"
 #include "sock.h"
-#include "misc.h"
+#include "util.h"
 #include "proxy.h"
 
Index: conf.c
===================================================================
--- conf.c	(revision fef6116e89bb0651c72454effbb51e04e9e1b8dc)
+++ conf.c	(revision 3f9440db856c1b1cde54eb919543cfc23ea09983)
@@ -34,5 +34,5 @@
 #include "ipc.h"
 
-#include "proxy.h"
+#include "protocols/proxy.h"
 
 char *CONF_FILE;
@@ -55,6 +55,5 @@
 	conf->nofork = 0;
 	conf->verbose = 0;
-	conf->primary_storage = "xml";
-	conf->migrate_storage = g_strsplit( "text", ",", -1 );
+	conf->primary_storage = "text";
 	conf->runmode = RUNMODE_INETD;
 	conf->authmode = AUTHMODE_OPEN;
@@ -323,5 +322,5 @@
 		if( g_strcasecmp( ini->section, "defaults" ) == 0 )
 		{
-			set_t *s = set_find( &irc->set, ini->key );
+			set_t *s = set_find( irc, ini->key );
 			
 			if( s )
Index: configure
===================================================================
--- configure	(revision fef6116e89bb0651c72454effbb51e04e9e1b8dc)
+++ configure	(revision 3f9440db856c1b1cde54eb919543cfc23ea09983)
@@ -31,5 +31,4 @@
 
 events=glib
-ldap=auto
 ssl=auto
 
@@ -67,6 +66,4 @@
 
 --ipv6=0/1	IPv6 socket support			$ipv6
-
---ldap=0/1/auto	LDAP support				$ldap
 
 --events=...	Event handler (glib, libevent)		$events
@@ -144,20 +141,18 @@
 fi
 
-echo CFLAGS+=-I`pwd` -I`pwd`/lib -I`pwd`/protocols -I. >> Makefile.settings
+echo CFLAGS+=-I`pwd` -I`pwd`/protocols -I. >> Makefile.settings
 
 echo CFLAGS+=-DHAVE_CONFIG_H >> Makefile.settings
 
 if [ -n "$CC" ]; then
-	CC=$CC
+	echo "CC=$CC" >> Makefile.settings;
 elif type gcc > /dev/null 2> /dev/null; then
-	CC=gcc
+	echo "CC=gcc" >> Makefile.settings;
 elif type cc > /dev/null 2> /dev/null; then
-	CC=cc
+	echo "CC=cc" >> Makefile.settings;
 else
 	echo 'Cannot find a C compiler, aborting.'
 	exit 1;
 fi
-
-echo "CC=$CC" >> Makefile.settings;
 
 if [ -n "$LD" ]; then
@@ -237,103 +232,63 @@
 }
 
-detect_ldap()
-{
-	TMPFILE=`mktemp`
-	if $CC -o $TMPFILE -shared -lldap 2>/dev/null >/dev/null; then
-		cat<<EOF>>Makefile.settings
-EFLAGS+=-lldap
-CFLAGS+=
-EOF
-		ldap=1
-		rm -f $TMPFILE
-		ret=1
+if [ "$msn" = 1 -o "$jabber" = 1 ]; then
+	if [ "$ssl" = "auto" ]; then
+		detect_gnutls
+		if [ "$ret" = "0" ]; then
+			detect_nss
+		fi;
+	elif [ "$ssl" = "gnutls" ]; then
+		detect_gnutls;
+	elif [ "$ssl" = "nss" ]; then
+		detect_nss;
+	elif [ "$ssl" = "openssl" ]; then
+		echo
+		echo 'No detection code exists for OpenSSL. Make sure that you have a complete'
+		echo 'install of OpenSSL (including devel/header files) before reporting'
+		echo 'compilation problems.'
+		echo
+		echo 'Also, keep in mind that the OpenSSL is, according to some people, not'
+		echo 'completely GPL-compatible. Using GnuTLS or NSS is recommended and better'
+		echo 'supported by us. However, on many BSD machines, OpenSSL can be considered'
+		echo 'part of the operating system, which makes it GPL-compatible.'
+		echo
+		echo 'For more info, see: http://www.openssl.org/support/faq.html#LEGAL2'
+		echo '                    http://www.gnome.org/~markmc/openssl-and-the-gpl.html'
+		echo
+		echo 'Please note that distributing a BitlBee binary which links to OpenSSL is'
+		echo 'probably illegal. If you want to create and distribute a binary BitlBee'
+		echo 'package, you really should use GnuTLS or NSS instead.'
+		echo
+		echo 'Also, the OpenSSL license requires us to say this:'
+		echo ' *    "This product includes software developed by the OpenSSL Project'
+		echo ' *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"'
+		
+		echo 'EFLAGS+=-lssl -lcrypto' >> Makefile.settings
+		
+		ret=1;
+	elif [ "$ssl" = "bogus" ]; then
+		echo
+		echo 'Using bogus SSL code. This will not make the MSN module work, but it will'
+		echo 'allow you to use the Jabber module - although without working SSL support.'
+		
+		ret=1;
 	else
-		ldap=0
-		ret=0
-	fi
-}
-
-if [ "$ssl" = "auto" ]; then
-	detect_gnutls
-	if [ "$ret" = "0" ]; then
-		detect_nss
-	fi
-elif [ "$ssl" = "gnutls" ]; then
-	detect_gnutls
-elif [ "$ssl" = "nss" ]; then
-	detect_nss
-elif [ "$ssl" = "openssl" ]; then
-	echo
-	echo 'No detection code exists for OpenSSL. Make sure that you have a complete'
-	echo 'install of OpenSSL (including devel/header files) before reporting'
-	echo 'compilation problems.'
-	echo
-	echo 'Also, keep in mind that the OpenSSL is, according to some people, not'
-	echo 'completely GPL-compatible. Using GnuTLS or NSS is recommended and better'
-	echo 'supported by us. However, on many BSD machines, OpenSSL can be considered'
-	echo 'part of the operating system, which makes it GPL-compatible.'
-	echo
-	echo 'For more info, see: http://www.openssl.org/support/faq.html#LEGAL2'
-	echo '                    http://www.gnome.org/~markmc/openssl-and-the-gpl.html'
-	echo
-	echo 'Please note that distributing a BitlBee binary which links to OpenSSL is'
-	echo 'probably illegal. If you want to create and distribute a binary BitlBee'
-	echo 'package, you really should use GnuTLS or NSS instead.'
-	echo
-	echo 'Also, the OpenSSL license requires us to say this:'
-	echo ' *    "This product includes software developed by the OpenSSL Project'
-	echo ' *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"'
-	
-	echo 'EFLAGS+=-lssl -lcrypto' >> Makefile.settings
-	
-	ret=1
-elif [ "$ssl" = "bogus" ]; then
-	echo
-	echo 'Using bogus SSL code. This means some features have to be disabled.'
-	
-	## Yes, you, at the console! How can you authenticate if you don't have any SSL!?
-	if [ "$msn" = "1" ]; then
-		echo
-		echo 'Real SSL support is necessary for MSN authentication, will build without'
-		echo 'MSN protocol support.'
-		msn=0
+		echo
+		echo 'ERROR: Unknown SSL library specified.'
+		exit 1;
 	fi
 	
-	ret=1
-else
-	echo
-	echo 'ERROR: Unknown SSL library specified.'
-	exit 1
-fi
-
-if [ "$ret" = "0" ]; then
-	echo
-	echo 'ERROR: Could not find a suitable SSL library (GnuTLS, libnss or OpenSSL).'
-	echo '       Please note that this script doesn'\''t have detection code for OpenSSL,'
-	echo '       so if you want to use that, you have to select it by hand. If you don'\''t'
-	echo '       need SSL support, you can select the "bogus" SSL library. (--ssl=bogus)'
+	if [ "$ret" = "0" ]; then
+		echo
+		echo 'ERROR: Could not find a suitable SSL library (GnuTLS, libnss or OpenSSL).'
+		echo '       This is necessary for MSN and full Jabber support. To continue,'
+		echo '       install a suitable SSL library or disable MSN support (--msn=0).'
+		echo '       If you want Jabber without SSL support you can try --ssl=bogus.'
+		
+		exit 1;
+	fi;
 	
-	exit 1
-fi;
-
-echo 'SSL_CLIENT=ssl_'$ssl'.o' >> Makefile.settings
-
-STORAGES="text xml"
-
-if [ "$ldap" = "auto" ]; then
-	detect_ldap
-fi
-
-if [ "$ldap" = 0 ]; then
-	echo "#undef WITH_LDAP" >> config.h
-elif [ "$ldap" = 1 ]; then
-	echo "#define WITH_LDAP 1" >> config.h
-	STORAGES="$STORAGES ldap"
-fi
-
-for i in $STORAGES; do
-	STORAGE_OBJS="$STORAGE_OBJS storage_$i.o"
-done
-echo "STORAGE_OBJS="$STORAGE_OBJS >> Makefile.settings
+	echo 'SSL_CLIENT=ssl_'$ssl'.o' >> Makefile.settings
+fi
 
 if [ "$strip" = 0 ]; then
@@ -349,4 +304,6 @@
 	elif type strip > /dev/null 2> /dev/null; then
 		echo "STRIP=strip" >> Makefile.settings;
+	elif /bin/test -x /usr/ccs/bin/strip; then
+		echo "STRIP=/usr/ccs/bin/strip" >> Makefile.settings;
 	else
 		echo
@@ -427,5 +384,5 @@
 if [ "$protocols" = "PROTOCOLS = " ]; then
 	echo "WARNING: You haven't selected any communication protocol to compile!"
-	echo "         BitlBee will run, but you will be unable to connect to IM servers!"
+	echo "         Bitlbee will run, but you will be unable to connect to IM servers!"
 fi
 
@@ -462,22 +419,27 @@
 
 if [ "$debug" = "1" ]; then
-	echo '  Debugging enabled.'
-else
-	echo '  Debugging disabled.'
+	echo '  Debugging enabled.';
+else
+	echo '  Debugging disabled.';
 fi
 
 if [ "$strip" = "1" ]; then
-	echo '  Binary stripping enabled.'
-else
-	echo '  Binary stripping disabled.'
-fi
-
-echo '  Using event handler: '$events
-echo '  Using SSL library: '$ssl
-echo '  Building with these storage backends: '$STORAGES
+	echo '  Binary stripping enabled.';
+else
+	echo '  Binary stripping disabled.';
+fi
+
+echo '  Using event handler: '$events;
+echo '  Using SSL library: '$ssl;
+
+#if [ "$flood" = "0" ]; then
+#	echo '  Flood protection disabled.';
+#else
+#	echo '  Flood protection enabled.';
+#fi
 
 if [ -n "$protocols" ]; then
-	echo '  Building with these protocols:' $protocols
-else
-	echo '  Building without IM-protocol support. We wish you a lot of fun...'
-fi
+	echo '  Building with these protocols:' $protocols;
+else
+	echo '  Building without IM-protocol support. We wish you a lot of fun...';
+fi
Index: c/bitlbee.schema
===================================================================
--- doc/bitlbee.schema	(revision fef6116e89bb0651c72454effbb51e04e9e1b8dc)
+++ 	(revision )
@@ -1,62 +1,0 @@
-## LDAP Schema file for BitlBee
-## Copyright (C) 2006 Jelmer Vernooij <jelmer@samba.org>
-##
-## We need the following object classes and related attributes:
-##
-## bitlBeeBuddy:
-##  - nick
-##  - handle
-
-## each bitlBeeNick has zero or more bitlBeeAccount subentries
-## and bitlBeeAccount entries contain zero or more bitlBeeBuddy entries
-
-## The admin needs to setup the LDAP server to:
-## - allow anonymous users to auth against bitlBeeNick objects on the 
-##   password field
-## - allow anonymous users to create new objects that start with nick=
-## - allow read/write for a user that is authenticated only to his/her own 
-##   object and subentries
-
-##  - userid 
-##  - userPassword
-##  - setting (multiple values)
-##  depends: top, account
-
-attributetype ( 1.3.6.1.4.1.25873.2.1.1 NAME 'bitlBeeAutoConnect'
-	DESC 'Autoconnect setting'
-	EQUALITY booleanMatch
-	SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )
-
-attributetype ( 1.3.6.1.4.1.25873.2.1.2 NAME 'bitlBeeAccountNo'
-	DESC 'Account number'
-	EQUALITY integerMatch
-	SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
-
-objectclass ( 1.3.6.1.4.1.25873.2.2.3 NAME 'bitlBeeAccount' SUP account STRUCTURAL
-	DESC 'BitlBee User Account '
-	MUST ( userid, userPassword )
-	MAY ( ) )
-
-## bitlBeeAccount:
-##  - accountNo 1.3.6.1.4.1.1466.115.121.1.27
-##  - protocol (msn, oscar, jabber, yahoo, ...)
-##  - username
-##  - password
-##  - server name
-##  - autoconnect (true/false) 1.3.6.1.4.1.1466.115.121.1.7
-##  depends: top
-
-objectclass ( 1.3.6.1.4.1.25873.2.2.1 NAME 'bitlBeeIMAccount' SUP account STRUCTURAL
-	DESC 'BitlBee IM Account '
-	MUST ( bitlBeeAccountNo, userid, userPassword )
-	MAY ( host, bitlBeeAutoconnect ) )
-
-objectclass ( 1.3.6.1.4.1.25873.2.2.2 NAME 'bitlBeeSetting' SUP top STRUCTURAL
-	DESC 'BitlBee Configuration Setting'
-	MUST ( bitlBeeSettingName )
-	MAY ( bitlBeeSettingValue ) )
-
-objectclass ( 1.3.6.1.4.1.25873.2.2.3 NAME 'bitlBeeBuddy' SUP top STRUCTURAL
-	DESC 'BitlBee Nick Mapping'
-	MUST ( bitlBeeBuddyHandle )
-	MAY ( ircNick ) )
Index: ini.c
===================================================================
--- ini.c	(revision 3f9440db856c1b1cde54eb919543cfc23ea09983)
+++ ini.c	(revision 3f9440db856c1b1cde54eb919543cfc23ea09983)
@@ -0,0 +1,90 @@
+  /********************************************************************\
+  * BitlBee -- An IRC to other IM-networks gateway                     *
+  *                                                                    *
+  * Copyright 2002-2005 Wilmer van der Gaast and others                *
+  \********************************************************************/
+
+/* INI file reading code						*/
+
+/*
+  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
+  the Free Software Foundation; either version 2 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License with
+  the Debian GNU/Linux distribution in /usr/share/common-licenses/GPL;
+  if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+  Suite 330, Boston, MA  02111-1307  USA
+*/
+#define BITLBEE_CORE
+#include "bitlbee.h"
+
+ini_t *ini_open( char *file )
+{
+	ini_t *ini = g_new0( ini_t, 1 );
+	
+	if( ( ini->fp = fopen( file, "r" ) ) == NULL )
+	{
+		g_free( ini );
+		return( NULL );
+	}
+	
+	return( ini );
+}
+
+int ini_read( ini_t *file )
+{
+	char key[MAX_STRING], s[MAX_STRING], *t;
+	int i;
+	
+	while( !feof( file->fp ) )
+	{
+		*s = 0;
+		fscanf( file->fp, "%127[^\n#]s", s );
+		fscanf( file->fp, "%*[^\n]s" );
+		fgetc( file->fp );		/* Skip newline		*/
+		file->line ++;
+		if( strchr( s, '=' ) )
+		{
+			sscanf( s, "%[^ =]s", key );
+			if( ( t = strchr( key, '.' ) ) )
+			{
+				*t = 0;
+				strcpy( file->section, key );
+				t ++;
+			}
+			else
+			{
+				strcpy( file->section, file->c_section );
+				t = key;
+			}
+			sscanf( t, "%s", file->key );
+			t = strchr( s, '=' ) + 1;
+			for( i = 0; t[i] == ' '; i ++ );
+			strcpy( file->value, &t[i] );
+			for( i = strlen( file->value ) - 1; file->value[i] == 32; i -- )
+				file->value[i] = 0;
+			
+			return( 1 );
+		}
+		else if( ( t = strchr( s, '[' ) ) )
+		{
+			strcpy( file->c_section, t + 1 );
+			t = strchr( file->c_section, ']' );
+			*t = 0;
+		}
+	}
+	return( 0 );
+}
+
+void ini_close( ini_t *file )
+{
+	fclose( file->fp );
+	g_free( file );
+}
Index: ini.h
===================================================================
--- ini.h	(revision 3f9440db856c1b1cde54eb919543cfc23ea09983)
+++ ini.h	(revision 3f9440db856c1b1cde54eb919543cfc23ea09983)
@@ -0,0 +1,43 @@
+  /********************************************************************\
+  * BitlBee -- An IRC to other IM-networks gateway                     *
+  *                                                                    *
+  * Copyright 2002-2004 Wilmer van der Gaast and others                *
+  \********************************************************************/
+
+/* INI file reading code						*/
+
+/*
+  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
+  the Free Software Foundation; either version 2 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License with
+  the Debian GNU/Linux distribution in /usr/share/common-licenses/GPL;
+  if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+  Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#ifndef _INI_H
+#define _INI_H
+
+typedef struct
+{
+	FILE *fp;
+	int line;
+	char c_section[MAX_STRING];
+	char section[MAX_STRING];
+	char key[MAX_STRING];
+	char value[MAX_STRING];
+} ini_t;
+
+ini_t *ini_open( char *file );
+int ini_read( ini_t *file );
+void ini_close( ini_t *file );
+
+#endif
Index: irc.c
===================================================================
--- irc.c	(revision fef6116e89bb0651c72454effbb51e04e9e1b8dc)
+++ irc.c	(revision 3f9440db856c1b1cde54eb919543cfc23ea09983)
@@ -33,9 +33,8 @@
 GSList *irc_connection_list = NULL;
 
-static char *passchange( irc_t *irc, void *set, char *value )
-{
-	irc_setpass( irc, value );
-	irc_usermsg( irc, "Password successfully changed" );
-	return NULL;
+static char *passchange (irc_t *irc, void *set, char *value) 
+{
+	irc_setpass (irc, value);
+	return (NULL);
 }
 
@@ -121,24 +120,24 @@
 	irc_connection_list = g_slist_append( irc_connection_list, irc );
 	
-	set_add( &irc->set, "away_devoice", "true",  set_eval_away_devoice, irc );
-	set_add( &irc->set, "auto_connect", "true", set_eval_bool, irc );
-	set_add( &irc->set, "auto_reconnect", "false", set_eval_bool, irc );
-	set_add( &irc->set, "auto_reconnect_delay", "300", set_eval_int, irc );
-	set_add( &irc->set, "buddy_sendbuffer", "false", set_eval_bool, irc );
-	set_add( &irc->set, "buddy_sendbuffer_delay", "200", set_eval_int, irc );
-	set_add( &irc->set, "charset", "iso8859-1", set_eval_charset, irc );
-	set_add( &irc->set, "debug", "false", set_eval_bool, irc );
-	set_add( &irc->set, "default_target", "root", NULL, irc );
-	set_add( &irc->set, "display_namechanges", "false", set_eval_bool, irc );
-	set_add( &irc->set, "handle_unknown", "root", NULL, irc );
-	set_add( &irc->set, "lcnicks", "true", set_eval_bool, irc );
-	set_add( &irc->set, "ops", "both", set_eval_ops, irc );
-	set_add( &irc->set, "password", NULL, passchange, irc );
-	set_add( &irc->set, "private", "true", set_eval_bool, irc );
-	set_add( &irc->set, "query_order", "lifo", NULL, irc );
-	set_add( &irc->set, "save_on_quit", "true", set_eval_bool, irc );
-	set_add( &irc->set, "strip_html", "true", NULL, irc );
-	set_add( &irc->set, "to_char", ": ", set_eval_to_char, irc );
-	set_add( &irc->set, "typing_notice", "false", set_eval_bool, irc );
+	set_add( irc, "away_devoice", "true",  set_eval_away_devoice );
+	set_add( irc, "auto_connect", "true", set_eval_bool );
+	set_add( irc, "auto_reconnect", "false", set_eval_bool );
+	set_add( irc, "auto_reconnect_delay", "300", set_eval_int );
+	set_add( irc, "buddy_sendbuffer", "false", set_eval_bool );
+	set_add( irc, "buddy_sendbuffer_delay", "200", set_eval_int );
+	set_add( irc, "charset", "iso8859-1", set_eval_charset );
+	set_add( irc, "debug", "false", set_eval_bool );
+	set_add( irc, "default_target", "root", NULL );
+	set_add( irc, "display_namechanges", "false", set_eval_bool );
+	set_add( irc, "handle_unknown", "root", NULL );
+	set_add( irc, "lcnicks", "true", set_eval_bool );
+	set_add( irc, "ops", "both", set_eval_ops );
+	set_add( irc, "private", "true", set_eval_bool );
+	set_add( irc, "query_order", "lifo", NULL );
+	set_add( irc, "save_on_quit", "true", set_eval_bool );
+	set_add( irc, "strip_html", "true", NULL );
+	set_add( irc, "to_char", ": ", set_eval_to_char );
+	set_add( irc, "typing_notice", "false", set_eval_bool );
+	set_add( irc, "password", NULL, passchange);
 	
 	conf_loaddefaults( irc );
@@ -212,5 +211,5 @@
 	log_message( LOGLVL_INFO, "Destroying connection with fd %d", irc->fd );
 	
-	if( irc->status & USTATUS_IDENTIFIED && set_getint( &irc->set, "save_on_quit" ) ) 
+	if( irc->status & USTATUS_IDENTIFIED && set_getint( irc, "save_on_quit" ) ) 
 		if( storage_save( irc, TRUE ) != STORAGE_OK )
 			irc_usermsg( irc, "Error while saving settings!" );
@@ -330,8 +329,9 @@
 void irc_setpass (irc_t *irc, const char *pass) 
 {
-	g_free (irc->password);
+	if (irc->password) g_free (irc->password);
 	
 	if (pass) {
 		irc->password = g_strdup (pass);
+		irc_usermsg (irc, "Password successfully changed");
 	} else {
 		irc->password = NULL;
@@ -364,5 +364,5 @@
 			}
 			
-			if( ( cs = set_getstr( &irc->set, "charset" ) ) && ( g_strcasecmp( cs, "utf-8" ) != 0 ) )
+			if( ( cs = set_getstr( irc, "charset" ) ) && ( g_strcasecmp( cs, "utf-8" ) != 0 ) )
 			{
 				conv[IRC_MAX_LINE] = 0;
@@ -584,5 +584,5 @@
 	
 	strip_newlines( line );
-	if( ( cs = set_getstr( &irc->set, "charset" ) ) && ( g_strcasecmp( cs, "utf-8" ) != 0 ) )
+	if( ( cs = set_getstr( irc, "charset" ) ) && ( g_strcasecmp( cs, "utf-8" ) != 0 ) )
 	{
 		char conv[IRC_MAX_LINE+1];
@@ -666,5 +666,5 @@
 			}
 			
-			if( u->gc && !u->away && set_getbool( &irc->set, "away_devoice" ) )
+			if( u->gc && !u->away && set_getint( irc, "away_devoice" ) )
 				strcat( namelist, "+" );
 			
@@ -676,5 +676,5 @@
 	{
 		GList *l;
-		char *ops = set_getstr( &irc->set, "ops" );
+		char *ops = set_getstr( irc, "ops" );
 		
 		/* root and the user aren't in the channel userlist but should
@@ -924,11 +924,11 @@
 {
 	char *nick, *s;
-	char reason[128];
+	char reason[64];
 	
 	if( u->gc && u->gc->flags & OPT_LOGGING_OUT )
 	{
-		if( u->gc->acc->server )
+		if( u->gc->user->proto_opt[0][0] )
 			g_snprintf( reason, sizeof( reason ), "%s %s", irc->myhost,
-			            u->gc->acc->server );
+			            u->gc->user->proto_opt[0] );
 		else if( ( s = strchr( u->gc->username, '@' ) ) )
 			g_snprintf( reason, sizeof( reason ), "%s %s", irc->myhost,
@@ -936,5 +936,5 @@
 		else
 			g_snprintf( reason, sizeof( reason ), "%s %s.%s", irc->myhost,
-			            u->gc->acc->prpl->name, irc->myhost );
+			            u->gc->prpl->name, irc->myhost );
 		
 		/* proto_opt might contain garbage after the : */
@@ -1012,5 +1012,5 @@
 		else if( g_strncasecmp( s + 1, "TYPING", 6 ) == 0 )
 		{
-			if( u && u->gc && u->gc->acc->prpl->send_typing && strlen( s ) >= 10 )
+			if( u && u->gc && u->gc->prpl->send_typing && strlen( s ) >= 10 )
 			{
 				time_t current_typing_notice = time( NULL );
@@ -1018,5 +1018,5 @@
 				if( current_typing_notice - u->last_typing_notice >= 5 )
 				{
-					u->gc->acc->prpl->send_typing( u->gc, u->handle, s[8] == '1' );
+					u->gc->prpl->send_typing( u->gc, u->handle, s[8] == '1' );
 					u->last_typing_notice = current_typing_notice;
 				}
@@ -1051,5 +1051,5 @@
 		}
 	}
-	else if( c && c->gc && c->gc->acc && c->gc->acc->prpl )
+	else if( c && c->gc && c->gc->prpl )
 	{
 		return( bim_chat_msg( c->gc, c->id, s ) );
@@ -1083,5 +1083,5 @@
 	if( !u || !u->gc ) return;
 	
-	if( set_getint( &irc->set, "buddy_sendbuffer" ) && set_getint( &irc->set, "buddy_sendbuffer_delay" ) > 0 )
+	if( set_getint( irc, "buddy_sendbuffer" ) && set_getint( irc, "buddy_sendbuffer_delay" ) > 0 )
 	{
 		int delay;
@@ -1110,5 +1110,5 @@
 		strcat( u->sendbuf, "\n" );
 		
-		delay = set_getint( &irc->set, "buddy_sendbuffer_delay" );
+		delay = set_getint( irc, "buddy_sendbuffer_delay" );
 		if( delay <= 5 )
 			delay *= 1000;
@@ -1175,5 +1175,5 @@
 		int len = strlen( irc->nick) + 3;
 		prefix = g_new (char, len );
-		g_snprintf( prefix, len, "%s%s", irc->nick, set_getstr( &irc->set, "to_char" ) );
+		g_snprintf( prefix, len, "%s%s", irc->nick, set_getstr( irc, "to_char" ) );
 		prefix[len-1] = 0;
 	}
Index: irc_commands.c
===================================================================
--- irc_commands.c	(revision fef6116e89bb0651c72454effbb51e04e9e1b8dc)
+++ irc_commands.c	(revision 3f9440db856c1b1cde54eb919543cfc23ea09983)
@@ -150,8 +150,8 @@
 		irc_part( irc, u, c->channel );
 		
-		if( c->gc )
+		if( c->gc && c->gc->prpl )
 		{
 			c->joined = 0;
-			c->gc->acc->prpl->chat_leave( c->gc, c->id );
+			c->gc->prpl->chat_leave( c->gc, c->id );
 		}
 	}
@@ -173,9 +173,9 @@
 			user_t *u = user_find( irc, cmd[1] + 1 );
 			
-			if( u && u->gc && u->gc->acc->prpl->chat_open )
+			if( u && u->gc && u->gc->prpl && u->gc->prpl->chat_open )
 			{
 				irc_reply( irc, 403, "%s :Initializing groupchat in a different channel", cmd[1] );
 				
-				if( !u->gc->acc->prpl->chat_open( u->gc, u->handle ) )
+				if( !u->gc->prpl->chat_open( u->gc, u->handle ) )
 				{
 					irc_usermsg( irc, "Could not open a groupchat with %s.", u->nick );
@@ -205,7 +205,7 @@
 	
 	if( u && c && ( u->gc == c->gc ) )
-		if( c->gc && c->gc->acc->prpl->chat_invite )
-		{
-			c->gc->acc->prpl->chat_invite( c->gc, c->id, "", u->handle );
+		if( c->gc && c->gc->prpl && c->gc->prpl->chat_invite )
+		{
+			c->gc->prpl->chat_invite( c->gc, c->id, "", u->handle );
 			irc_reply( irc, 341, "%s %s", nick, channel );
 			return;
@@ -230,5 +230,5 @@
 		{
 			unsigned int i;
-			char *t = set_getstr( &irc->set, "default_target" );
+			char *t = set_getstr( irc, "default_target" );
 			
 			if( g_strcasecmp( t, "last" ) == 0 && irc->last_target )
@@ -477,6 +477,6 @@
 		
 		if( u->gc )
-			irc_reply( irc, 312, "%s %s.%s :%s network", u->nick, u->gc->acc->user,
-			           *u->gc->acc->server ? u->gc->acc->server : "", u->gc->acc->prpl->name );
+			irc_reply( irc, 312, "%s %s.%s :%s network", u->nick, u->gc->user->username,
+			           *u->gc->user->proto_opt[0] ? u->gc->user->proto_opt[0] : "", u->gc->prpl->name );
 		else
 			irc_reply( irc, 312, "%s %s :%s", u->nick, irc->myhost, IRCD_INFO );
Index: b/Makefile
===================================================================
--- lib/Makefile	(revision fef6116e89bb0651c72454effbb51e04e9e1b8dc)
+++ 	(revision )
@@ -1,37 +1,0 @@
-###########################
-## Makefile for BitlBee  ##
-##                       ##
-## Copyright 2006 Lintux ##
-###########################
-
-### DEFINITIONS
-
--include ../Makefile.settings
-
-# [SH] Program variables
-objects = base64.o $(EVENT_HANDLER) http_client.o ini.o md5.o misc.o proxy.o rc4.o sha.o $(SSL_CLIENT) url.o
-
-CFLAGS += -Wall
-LFLAGS += -r
-
-# [SH] Phony targets
-all: lib.o
-
-.PHONY: all clean distclean
-
-clean: $(subdirs)
-	rm -f *.o $(OUTFILE) core
-
-distclean: clean $(subdirs)
-
-### MAIN PROGRAM
-
-lib.o: $(objects) $(subdirs)
-	@echo '*' Linking lib.o
-	@$(LD) $(LFLAGS) $(objects) -o lib.o
-
-$(objects): ../Makefile.settings Makefile
-
-$(objects): %.o: %.c
-	@echo '*' Compiling $<
-	@$(CC) -c $(CFLAGS) $< -o $@
Index: b/base64.c
===================================================================
--- lib/base64.c	(revision fef6116e89bb0651c72454effbb51e04e9e1b8dc)
+++ 	(revision )
@@ -1,153 +1,0 @@
-/***************************************************************************\
-*                                                                           *
-*  BitlBee - An IRC to IM gateway                                           *
-*  Base64 handling functions. encode_real() is mostly based on the y64 en-  *
-*  coder from libyahoo2. Moving it to a new file because it's getting big.  *
-*                                                                           *
-*  Copyright 2006 Wilmer van der Gaast <wilmer@gaast.net>                   *
-*                                                                           *
-*  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     *
-*  the Free Software Foundation; either version 2 of the License, or        *
-*  (at your option) any later version.                                      *
-*                                                                           *
-*  This program is distributed in the hope that it will be useful,          *
-*  but WITHOUT ANY WARRANTY; without even the implied warranty of           *
-*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            *
-*  GNU General Public License for more details.                             *
-*                                                                           *
-*  You should have received a copy of the GNU General Public License along  *
-*  with this program; if not, write to the Free Software Foundation, Inc.,  *
-*  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.              *
-*                                                                           *
-\***************************************************************************/
-
-#include <glib.h>
-#include <string.h>
-#include "base64.h"
-
-static const char real_b64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
-
-char *tobase64(const char *text)
-{
-	return base64_encode(text, strlen(text));
-}
-
-char *base64_encode(const char *in, int len)
-{
-	char *out;
-	
-	out = g_malloc((len + 2)    /* the == padding */
-	                    / 3     /* every 3-byte block */
-	                    * 4     /* becomes a 4-byte one */
-	                    + 1);   /* and of course, ASCIIZ! */
-	
-	base64_encode_real((unsigned char*) in, len, (unsigned char*) out, real_b64);
-	
-	return out;
-}
-
-int base64_encode_real(const unsigned char *in, int inlen, unsigned char *out, const char *b64digits)
-{
-	int outlen = 0;
-	
-	for (; inlen >= 3; inlen -= 3)
-	{
-		out[outlen++] = b64digits[in[0] >> 2];
-		out[outlen++] = b64digits[((in[0]<<4) & 0x30) | (in[1]>>4)];
-		out[outlen++] = b64digits[((in[1]<<2) & 0x3c) | (in[2]>>6)];
-		out[outlen++] = b64digits[in[2] & 0x3f];
-		in += 3;
-	}
-	if (inlen > 0)
-	{
-		out[outlen++] = b64digits[in[0] >> 2];
-		if (inlen > 1)
-		{
-			out[outlen++] = b64digits[((in[0]<<4) & 0x30) | (in[1]>>4)];
-			out[outlen++] = b64digits[((in[1]<<2) & 0x3c)];
-		}
-		else
-		{
-			out[outlen++] = b64digits[((in[0]<<4) & 0x30)];
-			out[outlen++] = b64digits[64];
-		}
-		out[outlen++] = b64digits[64];
-	}
-	out[outlen] = 0;
-	
-	return outlen;
-}
-
-/* Just a simple wrapper, but usually not very convenient because of zero
-   termination. */
-char *frombase64(const char *in)
-{
-	unsigned char *out;
-	
-	base64_decode(in, &out);
-	
-	return (char*) out;
-}
-
-/* FIXME: Lookup table stuff is not threadsafe! (But for now BitlBee is not threaded.) */
-int base64_decode(const char *in, unsigned char **out)
-{
-	static char b64rev[256] = { 0 };
-	int len, i;
-	
-	/* Create a reverse-lookup for the Base64 sequence. */
-	if( b64rev[0] == 0 )
-	{
-		memset( b64rev, 0xff, 256 );
-		for( i = 0; i <= 64; i ++ )
-			b64rev[(int)real_b64[i]] = i;
-	}
-	
-	len = strlen( in );
-	*out = g_malloc( ( len + 6 ) / 4 * 3 );
-	len = base64_decode_real( (unsigned char*) in, *out, b64rev );
-	*out = g_realloc( *out, len + 1 );
-	out[0][len] = 0;	/* Zero termination can't hurt. */
-	
-	return len;
-}
-
-int base64_decode_real(const unsigned char *in, unsigned char *out, char *b64rev)
-{
-	int i, outlen = 0;
-	
-	for( i = 0; in[i]; i += 4 )
-	{
-		int sx;
-		
-		sx = b64rev[(int)in[i+0]];
-		if( sx >= 64 )
-			break;
-		out[outlen] = ( sx << 2 ) & 0xfc;
-		
-		sx = b64rev[(int)in[i+1]];
-		if( sx >= 64 )
-			break;
-		out[outlen] |= ( sx >> 4 ) & 0x03;
-		outlen ++;
-		out[outlen] = ( sx << 4 ) & 0xf0;
-		
-		sx = b64rev[(int)in[i+2]];
-		if( sx >= 64 )
-			break;
-		out[outlen] |= ( sx >> 2 ) & 0x0f;
-		outlen ++;
-		out[outlen] = ( sx << 6 ) & 0xc0;
-		
-		sx = b64rev[(int)in[i+3]];
-		if( sx >= 64 )
-			break;
-		out[outlen] |= sx;
-		outlen ++;
-	}
-	
-	/* If sx > 64 the base64 string was damaged. Should we ignore this? */
-	
-	return outlen;
-}
Index: b/base64.h
===================================================================
--- lib/base64.h	(revision fef6116e89bb0651c72454effbb51e04e9e1b8dc)
+++ 	(revision )
@@ -1,33 +1,0 @@
-/***************************************************************************\
-*                                                                           *
-*  BitlBee - An IRC to IM gateway                                           *
-*  Base64 handling functions. encode_real() is mostly based on the y64 en-  *
-*  coder from libyahoo2. Moving it to a new file because it's getting big.  *
-*                                                                           *
-*  Copyright 2006 Wilmer van der Gaast <wilmer@gaast.net>                   *
-*                                                                           *
-*  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     *
-*  the Free Software Foundation; either version 2 of the License, or        *
-*  (at your option) any later version.                                      *
-*                                                                           *
-*  This program is distributed in the hope that it will be useful,          *
-*  but WITHOUT ANY WARRANTY; without even the implied warranty of           *
-*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            *
-*  GNU General Public License for more details.                             *
-*                                                                           *
-*  You should have received a copy of the GNU General Public License along  *
-*  with this program; if not, write to the Free Software Foundation, Inc.,  *
-*  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.              *
-*                                                                           *
-\***************************************************************************/
-
-#include <glib.h>
-#include <gmodule.h>
-
-G_MODULE_EXPORT char *tobase64( const char *text );
-G_MODULE_EXPORT char *base64_encode( const char *in, int len );
-G_MODULE_EXPORT int base64_encode_real( const unsigned char *in, int inlen, unsigned char *out, const char *b64digits );
-G_MODULE_EXPORT char *frombase64( const char *in );
-G_MODULE_EXPORT int base64_decode( const char *in, unsigned char **out );
-G_MODULE_EXPORT int base64_decode_real( const unsigned char *in, unsigned char *out, char *b64reverse );
Index: b/events.h
===================================================================
--- lib/events.h	(revision fef6116e89bb0651c72454effbb51e04e9e1b8dc)
+++ 	(revision )
@@ -1,66 +1,0 @@
-/*
- * nogaim
- *
- * Copyright (C) 2006 Wilmer van der Gaast and others
- *
- * 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
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- */
-
-/*
- * Split off the event handling things from proxy.[ch] (and adding timer
- * stuff. This to allow BitlBee to use other libs than GLib for event
- * handling.
- */
-
-
-#ifndef _EVENTS_H_
-#define _EVENTS_H_
-
-#include <sys/types.h>
-#ifndef _WIN32
-#include <sys/socket.h>
-#include <netdb.h>
-#include <netinet/in.h>
-#endif
-#include <glib.h>
-#include <gmodule.h>
-
-typedef enum {
-	GAIM_INPUT_READ = 1 << 1,
-	GAIM_INPUT_WRITE = 1 << 2
-} b_input_condition;
-typedef gboolean (*b_event_handler)(gpointer data, gint fd, b_input_condition cond);
-
-#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)
-#define GAIM_ERR_COND   (G_IO_HUP | G_IO_ERR | G_IO_NVAL)
-
-// #define event_debug( x... ) printf( x )
-#define event_debug( x... )
-
-G_MODULE_EXPORT void b_main_init();
-G_MODULE_EXPORT void b_main_run();
-G_MODULE_EXPORT void b_main_quit();
-
-G_MODULE_EXPORT gint b_input_add(int fd, b_input_condition cond, b_event_handler func, gpointer data);
-G_MODULE_EXPORT gint b_timeout_add(gint timeout, b_event_handler func, gpointer data);
-G_MODULE_EXPORT void b_event_remove(gint id);
-
-#ifdef EVENTS_LIBEVENT
-G_MODULE_EXPORT void closesocket(int fd);
-#endif
-
-#endif /* _EVENTS_H_ */
Index: b/events_glib.c
===================================================================
--- lib/events_glib.c	(revision fef6116e89bb0651c72454effbb51e04e9e1b8dc)
+++ 	(revision )
@@ -1,137 +1,0 @@
-  /********************************************************************\
-  * BitlBee -- An IRC to other IM-networks gateway                     *
-  *                                                                    *
-  * Copyright 2002-2006 Wilmer van der Gaast and others                *
-  \********************************************************************/
-
-/*
- * Event handling (using GLib)
- */
-
-/*
-  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
-  the Free Software Foundation; either version 2 of the License, or
-  (at your option) any later version.
-
-  This program is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-  GNU General Public License for more details.
-
-  You should have received a copy of the GNU General Public License with
-  the Debian GNU/Linux distribution in /usr/share/common-licenses/GPL;
-  if not, write to the Free Software Foundation, Inc., 59 Temple Place,
-  Suite 330, Boston, MA  02111-1307  USA
-*/
-
-#define BITLBEE_CORE
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-#ifndef _WIN32
-#include <sys/socket.h>
-#include <netdb.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <unistd.h>
-#else
-#include "sock.h"
-#define ETIMEDOUT WSAETIMEDOUT
-#define EINPROGRESS WSAEINPROGRESS
-#endif
-#include <fcntl.h>
-#include <errno.h>
-#include "proxy.h"
-
-typedef struct _GaimIOClosure {
-	b_event_handler function;
-	guint result;
-	gpointer data;
-} GaimIOClosure;
-
-static GMainLoop *loop;
-
-void b_main_init()
-{
-	loop = g_main_new( FALSE );
-}
-
-void b_main_run()
-{
-	g_main_run( loop );
-}
-
-void b_main_quit()
-{
-	g_main_quit( loop );
-}
-
-static gboolean gaim_io_invoke(GIOChannel *source, GIOCondition condition, gpointer data)
-{
-	GaimIOClosure *closure = data;
-	b_input_condition gaim_cond = 0;
-	gboolean st;
-
-	if (condition & GAIM_READ_COND)
-		gaim_cond |= GAIM_INPUT_READ;
-	if (condition & GAIM_WRITE_COND)
-		gaim_cond |= GAIM_INPUT_WRITE;
-	
-	event_debug( "gaim_io_invoke( %d, %d, 0x%x )\n", g_io_channel_unix_get_fd(source), condition, data );
-
-	st = closure->function(closure->data, g_io_channel_unix_get_fd(source), gaim_cond);
-	
-	if( !st )
-		event_debug( "Returned FALSE, cancelling.\n" );
-	
-	return st;
-}
-
-static void gaim_io_destroy(gpointer data)
-{
-	event_debug( "gaim_io_destroy( 0x%x )\n", data );
-	g_free(data);
-}
-
-gint b_input_add(gint source, b_input_condition condition, b_event_handler function, gpointer data)
-{
-	GaimIOClosure *closure = g_new0(GaimIOClosure, 1);
-	GIOChannel *channel;
-	GIOCondition cond = 0;
-	
-	closure->function = function;
-	closure->data = data;
-	
-	if (condition & GAIM_INPUT_READ)
-		cond |= GAIM_READ_COND;
-	if (condition & GAIM_INPUT_WRITE)
-		cond |= GAIM_WRITE_COND;
-	
-	channel = g_io_channel_unix_new(source);
-	closure->result = g_io_add_watch_full(channel, G_PRIORITY_DEFAULT, cond,
-					      gaim_io_invoke, closure, gaim_io_destroy);
-	
-	event_debug( "b_input_add( %d, %d, 0x%x, 0x%x ) = %d (0x%x)\n", source, condition, function, data, closure->result, closure );
-	
-	g_io_channel_unref(channel);
-	return closure->result;
-}
-
-gint b_timeout_add(gint timeout, b_event_handler func, gpointer data)
-{
-	gint st = g_timeout_add(timeout, func, data);
-	
-	event_debug( "b_timeout_add( %d, %d, %d ) = %d\n", timeout, func, data, st );
-	
-	return st;
-}
-
-void b_event_remove(gint tag)
-{
-	event_debug( "b_event_remove( %d )\n", tag );
-	
-	if (tag > 0)
-		g_source_remove(tag);
-}
Index: b/events_libevent.c
===================================================================
--- lib/events_libevent.c	(revision fef6116e89bb0651c72454effbb51e04e9e1b8dc)
+++ 	(revision )
@@ -1,247 +1,0 @@
-  /********************************************************************\
-  * BitlBee -- An IRC to other IM-networks gateway                     *
-  *                                                                    *
-  * Copyright 2002-2006 Wilmer van der Gaast and others                *
-  \********************************************************************/
-
-/*
- * Event handling (using libevent)
- */
-
-/*
-  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
-  the Free Software Foundation; either version 2 of the License, or
-  (at your option) any later version.
-
-  This program is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-  GNU General Public License for more details.
-
-  You should have received a copy of the GNU General Public License with
-  the Debian GNU/Linux distribution in /usr/share/common-licenses/GPL;
-  if not, write to the Free Software Foundation, Inc., 59 Temple Place,
-  Suite 330, Boston, MA  02111-1307  USA
-*/
-
-#define BITLBEE_CORE
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include "proxy.h"
-
-#include <sys/time.h>
-#include <event.h>
-
-static guint id_next;
-static GHashTable *id_hash;
-static int quitting = 0;
-
-/* Since libevent doesn't handle two event handlers for one fd-condition
-   very well (which happens sometimes when BitlBee changes event handlers
-   for a combination), let's buid some indexes so we can delete them here
-   already, just in time. */
-static GHashTable *read_hash;
-static GHashTable *write_hash;
-
-struct b_event_data
-{
-	guint id;
-	struct event evinfo;
-	gint timeout;
-	b_event_handler function;
-	void *data;
-};
-
-void b_main_init()
-{
-	event_init();
-	
-	id_next = 1;
-	id_hash = g_hash_table_new( g_int_hash, g_int_equal );
-	read_hash = g_hash_table_new( g_int_hash, g_int_equal );
-	write_hash = g_hash_table_new( g_int_hash, g_int_equal );
-}
-
-void b_main_run()
-{
-	event_dispatch();
-}
-
-void b_main_quit()
-{
-	struct timeval tv;
-	
-	/* libevent sometimes generates events before really quitting,
-	   we want to stop them. */
-	quitting = 1;
-	
-	memset( &tv, 0, sizeof( struct timeval ) );
-	event_loopexit( &tv );
-}
-
-static void b_event_passthrough( int fd, short event, void *data )
-{
-	struct b_event_data *b_ev = data;
-	b_input_condition cond = 0;
-	int id;
-	
-	if( fd >= 0 )
-	{
-		if( event & EV_READ )
-			cond |= GAIM_INPUT_READ;
-		if( event & EV_WRITE )
-			cond |= GAIM_INPUT_WRITE;
-	}
-	
-	event_debug( "b_event_passthrough( %d, %d, 0x%x ) (%d)\n", fd, event, (int) data, b_ev->id );
-	
-	/* Since the called function might cancel this handler already
-	   (which free()s b_ev, we have to remember the ID here. */
-	id = b_ev->id;
-	
-	if( quitting )
-	{
-		b_event_remove( id );
-		return;
-	}
-	
-	if( !b_ev->function( b_ev->data, fd, cond ) )
-	{
-		event_debug( "Handler returned FALSE: " );
-		b_event_remove( id );
-	}
-	else if( fd == -1 )
-	{
-		struct timeval tv;
-		
-		tv.tv_sec = b_ev->timeout / 1000;
-		tv.tv_usec = ( b_ev->timeout % 1000 ) * 1000;
-		
-		evtimer_add( &b_ev->evinfo, &tv );
-	}
-}
-
-gint b_input_add( gint fd, b_input_condition condition, b_event_handler function, gpointer data )
-{
-	struct b_event_data *b_ev;
-	
-	event_debug( "b_input_add( %d, %d, 0x%x, 0x%x ) ", fd, condition, function, data );
-	
-	if( ( condition & GAIM_INPUT_READ  && ( b_ev = g_hash_table_lookup( read_hash,  &fd ) ) ) ||
-	    ( condition & GAIM_INPUT_WRITE && ( b_ev = g_hash_table_lookup( write_hash, &fd ) ) ) )
-	{
-		/* We'll stick with this libevent entry, but give it a new BitlBee id. */
-		g_hash_table_remove( id_hash, &b_ev->id );
-		
-		event_debug( "(replacing old handler (id = %d)) = %d\n", b_ev->id, id_next );
-		
-		b_ev->id = id_next++;
-		b_ev->function = function;
-		b_ev->data = data;
-	}
-	else
-	{
-		GIOCondition out_cond;
-		
-		event_debug( "(new) = %d\n", id_next );
-		
-		b_ev = g_new0( struct b_event_data, 1 );
-		b_ev->id = id_next++;
-		b_ev->function = function;
-		b_ev->data = data;
-		
-		out_cond = EV_PERSIST;
-		if( condition & GAIM_INPUT_READ )
-			out_cond |= EV_READ;
-		if( condition & GAIM_INPUT_WRITE )
-			out_cond |= EV_WRITE;
-		
-		event_set( &b_ev->evinfo, fd, out_cond, b_event_passthrough, b_ev );
-		event_add( &b_ev->evinfo, NULL );
-		
-		if( out_cond & EV_READ )
-			g_hash_table_insert( read_hash, &b_ev->evinfo.ev_fd, b_ev );
-		if( out_cond & EV_WRITE )
-			g_hash_table_insert( write_hash, &b_ev->evinfo.ev_fd, b_ev );
-	}
-	
-	g_hash_table_insert( id_hash, &b_ev->id, b_ev );
-	return b_ev->id;
-}
-
-/* TODO: Persistence for timers! */
-gint b_timeout_add( gint timeout, b_event_handler function, gpointer data )
-{
-	struct b_event_data *b_ev = g_new0( struct b_event_data, 1 );
-	struct timeval tv;
-	
-	b_ev->id = id_next++;
-	b_ev->timeout = timeout;
-	b_ev->function = function;
-	b_ev->data = data;
-	
-	tv.tv_sec = timeout / 1000;
-	tv.tv_usec = ( timeout % 1000 ) * 1000;
-	
-	evtimer_set( &b_ev->evinfo, b_event_passthrough, b_ev );
-	evtimer_add( &b_ev->evinfo, &tv );
-	
-	event_debug( "b_timeout_add( %d, 0x%x, 0x%x ) = %d\n", timeout, function, data, b_ev->id );
-	
-	g_hash_table_insert( id_hash, &b_ev->id, b_ev );
-	
-	return b_ev->id;
-}
-
-void b_event_remove( gint id )
-{
-	struct b_event_data *b_ev = g_hash_table_lookup( id_hash, &id );
-	
-	event_debug( "b_event_remove( %d )\n", id );
-	if( b_ev )
-	{
-		g_hash_table_remove( id_hash, &b_ev->id );
-		if( b_ev->evinfo.ev_fd >= 0 )
-		{
-			if( b_ev->evinfo.ev_events & EV_READ )
-				g_hash_table_remove( read_hash, &b_ev->evinfo.ev_fd );
-			if( b_ev->evinfo.ev_events & EV_WRITE )
-				g_hash_table_remove( write_hash, &b_ev->evinfo.ev_fd );
-		}
-		
-		event_del( &b_ev->evinfo );
-		g_free( b_ev );
-	}
-	else
-	{
-		event_debug( "Already removed?\n" );
-	}
-}
-
-void closesocket( int fd )
-{
-	struct b_event_data *b_ev;
-	
-	/* Since epoll() (the main reason we use libevent) automatically removes sockets from
-	   the epoll() list when a socket gets closed and some modules have a habit of
-	   closing sockets before removing event handlers, our and libevent's administration
-	   get a little bit messed up. So this little function will remove the handlers
-	   properly before closing a socket. */
-	
-	if( ( b_ev = g_hash_table_lookup( read_hash, &fd ) ) )
-	{
-		event_debug( "Warning: fd %d still had a read event handler when shutting down.\n", fd );
-		b_event_remove( b_ev->id );
-	}
-	if( ( b_ev = g_hash_table_lookup( write_hash, &fd ) ) )
-	{
-		event_debug( "Warning: fd %d still had a write event handler when shutting down.\n", fd );
-		b_event_remove( b_ev->id );
-	}
-	
-	close( fd );
-}
Index: b/http_client.c
===================================================================
--- lib/http_client.c	(revision fef6116e89bb0651c72454effbb51e04e9e1b8dc)
+++ 	(revision )
@@ -1,453 +1,0 @@
-  /********************************************************************\
-  * BitlBee -- An IRC to other IM-networks gateway                     *
-  *                                                                    *
-  * Copyright 2002-2005 Wilmer van der Gaast and others                *
-  \********************************************************************/
-
-/* HTTP(S) module                                                       */
-
-/*
-  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
-  the Free Software Foundation; either version 2 of the License, or
-  (at your option) any later version.
-
-  This program is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-  GNU General Public License for more details.
-
-  You should have received a copy of the GNU General Public License with
-  the Debian GNU/Linux distribution in /usr/share/common-licenses/GPL;
-  if not, write to the Free Software Foundation, Inc., 59 Temple Place,
-  Suite 330, Boston, MA  02111-1307  USA
-*/
-
-#include <string.h>
-#include <stdio.h>
-
-#include "http_client.h"
-#include "url.h"
-#include "sock.h"
-
-
-static gboolean http_connected( gpointer data, int source, b_input_condition cond );
-static gboolean http_ssl_connected( gpointer data, void *source, b_input_condition cond );
-static gboolean http_incoming_data( gpointer data, int source, b_input_condition cond );
-
-
-void *http_dorequest( char *host, int port, int ssl, char *request, http_input_function func, gpointer data )
-{
-	struct http_request *req;
-	int error = 0;
-	
-	req = g_new0( struct http_request, 1 );
-	
-	if( ssl )
-	{
-		req->ssl = ssl_connect( host, port, http_ssl_connected, req );
-		if( req->ssl == NULL )
-			error = 1;
-	}
-	else
-	{
-		req->fd = proxy_connect( host, port, http_connected, req );
-		if( req->fd < 0 )
-			error = 1;
-	}
-	
-	if( error )
-	{
-		g_free( req );
-		return( NULL );
-	}
-	
-	req->func = func;
-	req->data = data;
-	req->request = g_strdup( request );
-	req->request_length = strlen( request );
-	
-	return( req );
-}
-
-void *http_dorequest_url( char *url_string, http_input_function func, gpointer data )
-{
-	url_t *url = g_new0( url_t, 1 );
-	char *request;
-	void *ret;
-	
-	if( !url_set( url, url_string ) )
-	{
-		g_free( url );
-		return NULL;
-	}
-	
-	if( url->proto != PROTO_HTTP && url->proto != PROTO_HTTPS )
-	{
-		g_free( url );
-		return NULL;
-	}
-	
-	request = g_strdup_printf( "GET %s HTTP/1.0\r\n"
-	                           "Host: %s\r\n"
-	                           "User-Agent: BitlBee " BITLBEE_VERSION " " ARCH "/" CPU "\r\n"
-	                           "\r\n", url->file, url->host );
-	
-	ret = http_dorequest( url->host, url->port,
-	                      url->proto == PROTO_HTTPS, request, func, data );
-	
-	g_free( url );
-	g_free( request );
-	return ret;
-}
-
-/* This one is actually pretty simple... Might get more calls if we can't write 
-   the whole request at once. */
-static gboolean http_connected( gpointer data, int source, b_input_condition cond )
-{
-	struct http_request *req = data;
-	int st;
-	
-	if( source < 0 )
-		goto error;
-	
-	if( req->inpa > 0 )
-		b_event_remove( req->inpa );
-	
-	sock_make_nonblocking( req->fd );
-	
-	if( req->ssl )
-	{
-		st = ssl_write( req->ssl, req->request + req->bytes_written,
-		                req->request_length - req->bytes_written );
-		if( st < 0 )
-		{
-			if( ssl_errno != SSL_AGAIN )
-			{
-				ssl_disconnect( req->ssl );
-				goto error;
-			}
-		}
-	}
-	else
-	{
-		st = write( source, req->request + req->bytes_written,
-		                    req->request_length - req->bytes_written );
-		if( st < 0 )
-		{
-			if( !sockerr_again() )
-			{
-				closesocket( req->fd );
-				goto error;
-			}
-		}
-	}
-	
-	if( st > 0 )
-		req->bytes_written += st;
-	
-	if( req->bytes_written < req->request_length )
-		req->inpa = b_input_add( source,
-		                         req->ssl ? ssl_getdirection( req->ssl ) : GAIM_INPUT_WRITE,
-	        	                 http_connected, req );
-	else
-		req->inpa = b_input_add( source, GAIM_INPUT_READ, http_incoming_data, req );
-	
-	return FALSE;
-	
-error:
-	req->status_string = g_strdup( "Error while writing HTTP request" );
-	
-	req->func( req );
-	
-	g_free( req->request );
-	g_free( req );
-	
-	return FALSE;
-}
-
-static gboolean http_ssl_connected( gpointer data, void *source, b_input_condition cond )
-{
-	struct http_request *req = data;
-	
-	if( source == NULL )
-		return http_connected( data, -1, cond );
-	
-	req->fd = ssl_getfd( source );
-	
-	return http_connected( data, req->fd, cond );
-}
-
-static gboolean http_incoming_data( gpointer data, int source, b_input_condition cond )
-{
-	struct http_request *req = data;
-	int evil_server = 0;
-	char buffer[2048];
-	char *end1, *end2;
-	int st;
-	
-	if( req->inpa > 0 )
-		b_event_remove( req->inpa );
-	
-	if( req->ssl )
-	{
-		st = ssl_read( req->ssl, buffer, sizeof( buffer ) );
-		if( st < 0 )
-		{
-			if( ssl_errno != SSL_AGAIN )
-			{
-				/* goto cleanup; */
-				
-				/* YAY! We have to deal with crappy Microsoft
-				   servers that LOVE to send invalid TLS
-				   packets that abort connections! \o/ */
-				
-				goto got_reply;
-			}
-		}
-		else if( st == 0 )
-		{
-			goto got_reply;
-		}
-	}
-	else
-	{
-		st = read( req->fd, buffer, sizeof( buffer ) );
-		if( st < 0 )
-		{
-			if( !sockerr_again() )
-			{
-				req->status_string = g_strdup( strerror( errno ) );
-				goto cleanup;
-			}
-		}
-		else if( st == 0 )
-		{
-			goto got_reply;
-		}
-	}
-	
-	if( st > 0 )
-	{
-		req->reply_headers = g_realloc( req->reply_headers, req->bytes_read + st + 1 );
-		memcpy( req->reply_headers + req->bytes_read, buffer, st );
-		req->bytes_read += st;
-	}
-	
-	/* There will be more! */
-	req->inpa = b_input_add( req->fd,
-	                         req->ssl ? ssl_getdirection( req->ssl ) : GAIM_INPUT_READ,
-	                         http_incoming_data, req );
-	
-	return FALSE;
-
-got_reply:
-	/* Maybe if the webserver is overloaded, or when there's bad SSL
-	   support... */
-	if( req->bytes_read == 0 )
-	{
-		req->status_string = g_strdup( "Empty HTTP reply" );
-		goto cleanup;
-	}
-	
-	/* Zero termination is very convenient. */
-	req->reply_headers[req->bytes_read] = 0;
-	
-	/* Find the separation between headers and body, and keep stupid
-	   webservers in mind. */
-	end1 = strstr( req->reply_headers, "\r\n\r\n" );
-	end2 = strstr( req->reply_headers, "\n\n" );
-	
-	if( end2 && end2 < end1 )
-	{
-		end1 = end2 + 1;
-		evil_server = 1;
-	}
-	else if( end1 )
-	{
-		end1 += 2;
-	}
-	else
-	{
-		req->status_string = g_strdup( "Malformed HTTP reply" );
-		goto cleanup;
-	}
-	
-	*end1 = 0;
-	
-	if( evil_server )
-		req->reply_body = end1 + 1;
-	else
-		req->reply_body = end1 + 2;
-	
-	req->body_size = req->reply_headers + req->bytes_read - req->reply_body;
-	
-	if( ( end1 = strchr( req->reply_headers, ' ' ) ) != NULL )
-	{
-		if( sscanf( end1 + 1, "%d", &req->status_code ) != 1 )
-		{
-			req->status_string = g_strdup( "Can't parse status code" );
-			req->status_code = -1;
-		}
-		else
-		{
-			char *eol;
-			
-			if( evil_server )
-				eol = strchr( end1, '\n' );
-			else
-				eol = strchr( end1, '\r' );
-			
-			req->status_string = g_strndup( end1 + 1, eol - end1 - 1 );
-			
-			/* Just to be sure... */
-			if( ( eol = strchr( req->status_string, '\r' ) ) )
-				*eol = 0;
-			if( ( eol = strchr( req->status_string, '\n' ) ) )
-				*eol = 0;
-		}
-	}
-	else
-	{
-		req->status_string = g_strdup( "Can't locate status code" );
-		req->status_code = -1;
-	}
-	
-	if( req->status_code == 301 || req->status_code == 302 )
-	{
-		char *loc, *new_request, *new_host;
-		int error = 0, new_port, new_proto;
-		
-		/* We might fill it again, so let's not leak any memory. */
-		g_free( req->status_string );
-		req->status_string = NULL;
-		
-		loc = strstr( req->reply_headers, "\nLocation: " );
-		if( loc == NULL ) /* We can't handle this redirect... */
-		{
-			req->status_string = g_strdup( "Can't locate Location: header" );
-			goto cleanup;
-		}
-		
-		loc += 11;
-		while( *loc == ' ' )
-			loc ++;
-		
-		/* TODO/FIXME: Possibly have to handle relative redirections,
-		   and rewrite Host: headers. Not necessary for now, it's
-		   enough for passport authentication like this. */
-		
-		if( *loc == '/' )
-		{
-			/* Just a different pathname... */
-			
-			/* Since we don't cache the servername, and since we
-			   don't need this yet anyway, I won't implement it. */
-			
-			req->status_string = g_strdup( "Can't handle recursive redirects" );
-			
-			goto cleanup;
-		}
-		else
-		{
-			/* A whole URL */
-			url_t *url;
-			char *s;
-			
-			s = strstr( loc, "\r\n" );
-			if( s == NULL )
-				goto cleanup;
-			
-			url = g_new0( url_t, 1 );
-			*s = 0;
-			
-			if( !url_set( url, loc ) )
-			{
-				req->status_string = g_strdup( "Malformed redirect URL" );
-				g_free( url );
-				goto cleanup;
-			}
-			
-			/* Okay, this isn't fun! We have to rebuild the request... :-( */
-			new_request = g_malloc( req->request_length + strlen( url->file ) );
-			
-			/* So, now I just allocated enough memory, so I'm
-			   going to use strcat(), whether you like it or not. :-) */
-			
-			sprintf( new_request, "GET %s HTTP/1.0", url->file );
-			
-			s = strstr( req->request, "\r\n" );
-			if( s == NULL )
-			{
-				req->status_string = g_strdup( "Error while rebuilding request string" );
-				g_free( new_request );
-				g_free( url );
-				goto cleanup;
-			}
-			
-			strcat( new_request, s );
-			new_host = g_strdup( url->host );
-			new_port = url->port;
-			new_proto = url->proto;
-			
-			g_free( url );
-		}
-		
-		if( req->ssl )
-			ssl_disconnect( req->ssl );
-		else
-			closesocket( req->fd );
-		
-		req->fd = -1;
-		req->ssl = NULL;
-		
-		if( new_proto == PROTO_HTTPS )
-		{
-			req->ssl = ssl_connect( new_host, new_port, http_ssl_connected, req );
-			if( req->ssl == NULL )
-				error = 1;
-		}
-		else
-		{
-			req->fd = proxy_connect( new_host, new_port, http_connected, req );
-			if( req->fd < 0 )
-				error = 1;
-		}
-		g_free( new_host );
-		
-		if( error )
-		{
-			req->status_string = g_strdup( "Connection problem during redirect" );
-			g_free( new_request );
-			goto cleanup;
-		}
-		
-		g_free( req->request );
-		g_free( req->reply_headers );
-		req->request = new_request;
-		req->request_length = strlen( new_request );
-		req->bytes_read = req->bytes_written = req->inpa = 0;
-		req->reply_headers = req->reply_body = NULL;
-		
-		return FALSE;
-	}
-	
-	/* Assume that a closed connection means we're finished, this indeed
-	   breaks with keep-alive connections and faulty connections. */
-	req->finished = 1;
-
-cleanup:
-	if( req->ssl )
-		ssl_disconnect( req->ssl );
-	else
-		closesocket( req->fd );
-	
-	req->func( req );
-	
-	g_free( req->request );
-	g_free( req->reply_headers );
-	g_free( req->status_string );
-	g_free( req );
-	
-	return FALSE;
-}
Index: b/http_client.h
===================================================================
--- lib/http_client.h	(revision fef6116e89bb0651c72454effbb51e04e9e1b8dc)
+++ 	(revision )
@@ -1,57 +1,0 @@
-  /********************************************************************\
-  * BitlBee -- An IRC to other IM-networks gateway                     *
-  *                                                                    *
-  * Copyright 2002-2005 Wilmer van der Gaast and others                *
-  \********************************************************************/
-
-/* HTTP(S) module                                                       */
-
-/*
-  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
-  the Free Software Foundation; either version 2 of the License, or
-  (at your option) any later version.
-
-  This program is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-  GNU General Public License for more details.
-
-  You should have received a copy of the GNU General Public License with
-  the Debian GNU/Linux distribution in /usr/share/common-licenses/GPL;
-  if not, write to the Free Software Foundation, Inc., 59 Temple Place,
-  Suite 330, Boston, MA  02111-1307  USA
-*/
-
-#include <glib.h>
-
-#include "ssl_client.h"
-
-struct http_request;
-
-typedef void (*http_input_function)( struct http_request * );
-
-struct http_request
-{
-	char *request;
-	int request_length;
-	int status_code;
-	char *status_string;
-	char *reply_headers;
-	char *reply_body;
-	int body_size;
-	int finished;
-	
-	void *ssl;
-	int fd;
-	
-	int inpa;
-	int bytes_written;
-	int bytes_read;
-	
-	http_input_function func;
-	gpointer data;
-};
-
-void *http_dorequest( char *host, int port, int ssl, char *request, http_input_function func, gpointer data );
-void *http_dorequest_url( char *url_string, http_input_function func, gpointer data );
Index: b/ini.c
===================================================================
--- lib/ini.c	(revision fef6116e89bb0651c72454effbb51e04e9e1b8dc)
+++ 	(revision )
@@ -1,90 +1,0 @@
-  /********************************************************************\
-  * BitlBee -- An IRC to other IM-networks gateway                     *
-  *                                                                    *
-  * Copyright 2002-2005 Wilmer van der Gaast and others                *
-  \********************************************************************/
-
-/* INI file reading code						*/
-
-/*
-  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
-  the Free Software Foundation; either version 2 of the License, or
-  (at your option) any later version.
-
-  This program is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-  GNU General Public License for more details.
-
-  You should have received a copy of the GNU General Public License with
-  the Debian GNU/Linux distribution in /usr/share/common-licenses/GPL;
-  if not, write to the Free Software Foundation, Inc., 59 Temple Place,
-  Suite 330, Boston, MA  02111-1307  USA
-*/
-#define BITLBEE_CORE
-#include "bitlbee.h"
-
-ini_t *ini_open( char *file )
-{
-	ini_t *ini = g_new0( ini_t, 1 );
-	
-	if( ( ini->fp = fopen( file, "r" ) ) == NULL )
-	{
-		g_free( ini );
-		return( NULL );
-	}
-	
-	return( ini );
-}
-
-int ini_read( ini_t *file )
-{
-	char key[MAX_STRING], s[MAX_STRING], *t;
-	int i;
-	
-	while( !feof( file->fp ) )
-	{
-		*s = 0;
-		fscanf( file->fp, "%127[^\n#]s", s );
-		fscanf( file->fp, "%*[^\n]s" );
-		fgetc( file->fp );		/* Skip newline		*/
-		file->line ++;
-		if( strchr( s, '=' ) )
-		{
-			sscanf( s, "%[^ =]s", key );
-			if( ( t = strchr( key, '.' ) ) )
-			{
-				*t = 0;
-				strcpy( file->section, key );
-				t ++;
-			}
-			else
-			{
-				strcpy( file->section, file->c_section );
-				t = key;
-			}
-			sscanf( t, "%s", file->key );
-			t = strchr( s, '=' ) + 1;
-			for( i = 0; t[i] == ' '; i ++ );
-			strcpy( file->value, &t[i] );
-			for( i = strlen( file->value ) - 1; file->value[i] == 32; i -- )
-				file->value[i] = 0;
-			
-			return( 1 );
-		}
-		else if( ( t = strchr( s, '[' ) ) )
-		{
-			strcpy( file->c_section, t + 1 );
-			t = strchr( file->c_section, ']' );
-			*t = 0;
-		}
-	}
-	return( 0 );
-}
-
-void ini_close( ini_t *file )
-{
-	fclose( file->fp );
-	g_free( file );
-}
Index: b/ini.h
===================================================================
--- lib/ini.h	(revision fef6116e89bb0651c72454effbb51e04e9e1b8dc)
+++ 	(revision )
@@ -1,43 +1,0 @@
-  /********************************************************************\
-  * BitlBee -- An IRC to other IM-networks gateway                     *
-  *                                                                    *
-  * Copyright 2002-2004 Wilmer van der Gaast and others                *
-  \********************************************************************/
-
-/* INI file reading code						*/
-
-/*
-  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
-  the Free Software Foundation; either version 2 of the License, or
-  (at your option) any later version.
-
-  This program is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-  GNU General Public License for more details.
-
-  You should have received a copy of the GNU General Public License with
-  the Debian GNU/Linux distribution in /usr/share/common-licenses/GPL;
-  if not, write to the Free Software Foundation, Inc., 59 Temple Place,
-  Suite 330, Boston, MA  02111-1307  USA
-*/
-
-#ifndef _INI_H
-#define _INI_H
-
-typedef struct
-{
-	FILE *fp;
-	int line;
-	char c_section[MAX_STRING];
-	char section[MAX_STRING];
-	char key[MAX_STRING];
-	char value[MAX_STRING];
-} ini_t;
-
-ini_t *ini_open( char *file );
-int ini_read( ini_t *file );
-void ini_close( ini_t *file );
-
-#endif
Index: b/md5.c
===================================================================
--- lib/md5.c	(revision fef6116e89bb0651c72454effbb51e04e9e1b8dc)
+++ 	(revision )
@@ -1,392 +1,0 @@
-/*
-  Copyright (C) 1999 Aladdin Enterprises.  All rights reserved.
-
-  This software is provided 'as-is', without any express or implied
-  warranty.  In no event will the authors be held liable for any damages
-  arising from the use of this software.
-
-  Permission is granted to anyone to use this software for any purpose,
-  including commercial applications, and to alter it and redistribute it
-  freely, subject to the following restrictions:
-
-  1. The origin of this software must not be misrepresented; you must not
-     claim that you wrote the original software. If you use this software
-     in a product, an acknowledgment in the product documentation would be
-     appreciated but is not required.
-  2. Altered source versions must be plainly marked as such, and must not be
-     misrepresented as being the original software.
-  3. This notice may not be removed or altered from any source distribution.
-
-  L. Peter Deutsch
-  ghost@aladdin.com
-
- */
-/*
-  Independent implementation of MD5 (RFC 1321).
-
-  This code implements the MD5 Algorithm defined in RFC 1321.
-  It is derived directly from the text of the RFC and not from the
-  reference implementation.
-
-  The original and principal author of md5.c is L. Peter Deutsch
-  <ghost@aladdin.com>.  Other authors are noted in the change history
-  that follows (in reverse chronological order):
-
-  1999-11-04 lpd Edited comments slightly for automatic TOC extraction.
-  1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5).
-  1999-05-03 lpd Original version.
- */
-
-#include "md5.h"
-#include <string.h>
-
-#ifdef TEST
-/*
- * Compile with -DTEST to create a self-contained executable test program.
- * The test program should print out the same values as given in section
- * A.5 of RFC 1321, reproduced below.
- */
-#include <string.h>
-main()
-{
-    static const char *const test[7] = {
-	"", /*d41d8cd98f00b204e9800998ecf8427e*/
-	"945399884.61923487334tuvga", /*0cc175b9c0f1b6a831c399e269772661*/
-	"abc", /*900150983cd24fb0d6963f7d28e17f72*/
-	"message digest", /*f96b697d7cb7938d525a2f31aaf161d0*/
-	"abcdefghijklmnopqrstuvwxyz", /*c3fcd3d76192e4007dfb496cca67e13b*/
-	"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
-				/*d174ab98d277d9f5a5611c2c9f419d9f*/
-	"12345678901234567890123456789012345678901234567890123456789012345678901234567890" /*57edf4a22be3c955ac49da2e2107b67a*/
-    };
-    int i;
-
-    for (i = 0; i < 7; ++i) {
-	md5_state_t state;
-	md5_byte_t digest[16];
-	int di;
-
-	md5_init(&state);
-	md5_append(&state, (const md5_byte_t *)test[i], strlen(test[i]));
-	md5_finish(&state, digest);
-	printf("MD5 (\"%s\") = ", test[i]);
-	for (di = 0; di < 16; ++di)
-	    printf("%02x", digest[di]);
-	printf("\n");
-    }
-    return 0;
-}
-#endif /* TEST */
-
-
-/*
- * For reference, here is the program that computed the T values.
- */
-#if 0
-#include <math.h>
-main()
-{
-    int i;
-    for (i = 1; i <= 64; ++i) {
-	unsigned long v = (unsigned long)(4294967296.0 * fabs(sin((double)i)));
-	printf("#define T%d 0x%08lx\n", i, v);
-    }
-    return 0;
-}
-#endif
-/*
- * End of T computation program.
- */
-#define T1 0xd76aa478
-#define T2 0xe8c7b756
-#define T3 0x242070db
-#define T4 0xc1bdceee
-#define T5 0xf57c0faf
-#define T6 0x4787c62a
-#define T7 0xa8304613
-#define T8 0xfd469501
-#define T9 0x698098d8
-#define T10 0x8b44f7af
-#define T11 0xffff5bb1
-#define T12 0x895cd7be
-#define T13 0x6b901122
-#define T14 0xfd987193
-#define T15 0xa679438e
-#define T16 0x49b40821
-#define T17 0xf61e2562
-#define T18 0xc040b340
-#define T19 0x265e5a51
-#define T20 0xe9b6c7aa
-#define T21 0xd62f105d
-#define T22 0x02441453
-#define T23 0xd8a1e681
-#define T24 0xe7d3fbc8
-#define T25 0x21e1cde6
-#define T26 0xc33707d6
-#define T27 0xf4d50d87
-#define T28 0x455a14ed
-#define T29 0xa9e3e905
-#define T30 0xfcefa3f8
-#define T31 0x676f02d9
-#define T32 0x8d2a4c8a
-#define T33 0xfffa3942
-#define T34 0x8771f681
-#define T35 0x6d9d6122
-#define T36 0xfde5380c
-#define T37 0xa4beea44
-#define T38 0x4bdecfa9
-#define T39 0xf6bb4b60
-#define T40 0xbebfbc70
-#define T41 0x289b7ec6
-#define T42 0xeaa127fa
-#define T43 0xd4ef3085
-#define T44 0x04881d05
-#define T45 0xd9d4d039
-#define T46 0xe6db99e5
-#define T47 0x1fa27cf8
-#define T48 0xc4ac5665
-#define T49 0xf4292244
-#define T50 0x432aff97
-#define T51 0xab9423a7
-#define T52 0xfc93a039
-#define T53 0x655b59c3
-#define T54 0x8f0ccc92
-#define T55 0xffeff47d
-#define T56 0x85845dd1
-#define T57 0x6fa87e4f
-#define T58 0xfe2ce6e0
-#define T59 0xa3014314
-#define T60 0x4e0811a1
-#define T61 0xf7537e82
-#define T62 0xbd3af235
-#define T63 0x2ad7d2bb
-#define T64 0xeb86d391
-
-static void
-md5_process(md5_state_t *pms, const md5_byte_t *data /*[64]*/)
-{
-    md5_word_t
-	a = pms->abcd[0], b = pms->abcd[1],
-	c = pms->abcd[2], d = pms->abcd[3];
-    md5_word_t t;
-
-#ifndef ARCH_IS_BIG_ENDIAN
-# define ARCH_IS_BIG_ENDIAN 1	/* slower, default implementation */
-#endif
-#if ARCH_IS_BIG_ENDIAN
-
-    /*
-     * On big-endian machines, we must arrange the bytes in the right
-     * order.  (This also works on machines of unknown byte order.)
-     */
-    md5_word_t X[16];
-    const md5_byte_t *xp = data;
-    int i;
-
-    for (i = 0; i < 16; ++i, xp += 4)
-	X[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24);
-
-#else  /* !ARCH_IS_BIG_ENDIAN */
-
-    /*
-     * On little-endian machines, we can process properly aligned data
-     * without copying it.
-     */
-    md5_word_t xbuf[16];
-    const md5_word_t *X;
-
-    if (!((data - (const md5_byte_t *)0) & 3)) {
-	/* data are properly aligned */
-	X = (const md5_word_t *)data;
-    } else {
-	/* not aligned */
-	memcpy(xbuf, data, 64);
-	X = xbuf;
-    }
-#endif
-
-#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
-
-    /* Round 1. */
-    /* Let [abcd k s i] denote the operation
-       a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */
-#define F(x, y, z) (((x) & (y)) | (~(x) & (z)))
-#define SET(a, b, c, d, k, s, Ti)\
-  t = a + F(b,c,d) + X[k] + Ti;\
-  a = ROTATE_LEFT(t, s) + b
-    /* Do the following 16 operations. */
-    SET(a, b, c, d,  0,  7,  T1);
-    SET(d, a, b, c,  1, 12,  T2);
-    SET(c, d, a, b,  2, 17,  T3);
-    SET(b, c, d, a,  3, 22,  T4);
-    SET(a, b, c, d,  4,  7,  T5);
-    SET(d, a, b, c,  5, 12,  T6);
-    SET(c, d, a, b,  6, 17,  T7);
-    SET(b, c, d, a,  7, 22,  T8);
-    SET(a, b, c, d,  8,  7,  T9);
-    SET(d, a, b, c,  9, 12, T10);
-    SET(c, d, a, b, 10, 17, T11);
-    SET(b, c, d, a, 11, 22, T12);
-    SET(a, b, c, d, 12,  7, T13);
-    SET(d, a, b, c, 13, 12, T14);
-    SET(c, d, a, b, 14, 17, T15);
-    SET(b, c, d, a, 15, 22, T16);
-#undef SET
-
-     /* Round 2. */
-     /* Let [abcd k s i] denote the operation
-          a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */
-#define G(x, y, z) (((x) & (z)) | ((y) & ~(z)))
-#define SET(a, b, c, d, k, s, Ti)\
-  t = a + G(b,c,d) + X[k] + Ti;\
-  a = ROTATE_LEFT(t, s) + b
-     /* Do the following 16 operations. */
-    SET(a, b, c, d,  1,  5, T17);
-    SET(d, a, b, c,  6,  9, T18);
-    SET(c, d, a, b, 11, 14, T19);
-    SET(b, c, d, a,  0, 20, T20);
-    SET(a, b, c, d,  5,  5, T21);
-    SET(d, a, b, c, 10,  9, T22);
-    SET(c, d, a, b, 15, 14, T23);
-    SET(b, c, d, a,  4, 20, T24);
-    SET(a, b, c, d,  9,  5, T25);
-    SET(d, a, b, c, 14,  9, T26);
-    SET(c, d, a, b,  3, 14, T27);
-    SET(b, c, d, a,  8, 20, T28);
-    SET(a, b, c, d, 13,  5, T29);
-    SET(d, a, b, c,  2,  9, T30);
-    SET(c, d, a, b,  7, 14, T31);
-    SET(b, c, d, a, 12, 20, T32);
-#undef SET
-
-     /* Round 3. */
-     /* Let [abcd k s t] denote the operation
-          a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */
-#define H(x, y, z) ((x) ^ (y) ^ (z))
-#define SET(a, b, c, d, k, s, Ti)\
-  t = a + H(b,c,d) + X[k] + Ti;\
-  a = ROTATE_LEFT(t, s) + b
-     /* Do the following 16 operations. */
-    SET(a, b, c, d,  5,  4, T33);
-    SET(d, a, b, c,  8, 11, T34);
-    SET(c, d, a, b, 11, 16, T35);
-    SET(b, c, d, a, 14, 23, T36);
-    SET(a, b, c, d,  1,  4, T37);
-    SET(d, a, b, c,  4, 11, T38);
-    SET(c, d, a, b,  7, 16, T39);
-    SET(b, c, d, a, 10, 23, T40);
-    SET(a, b, c, d, 13,  4, T41);
-    SET(d, a, b, c,  0, 11, T42);
-    SET(c, d, a, b,  3, 16, T43);
-    SET(b, c, d, a,  6, 23, T44);
-    SET(a, b, c, d,  9,  4, T45);
-    SET(d, a, b, c, 12, 11, T46);
-    SET(c, d, a, b, 15, 16, T47);
-    SET(b, c, d, a,  2, 23, T48);
-#undef SET
-
-     /* Round 4. */
-     /* Let [abcd k s t] denote the operation
-          a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */
-#define I(x, y, z) ((y) ^ ((x) | ~(z)))
-#define SET(a, b, c, d, k, s, Ti)\
-  t = a + I(b,c,d) + X[k] + Ti;\
-  a = ROTATE_LEFT(t, s) + b
-     /* Do the following 16 operations. */
-    SET(a, b, c, d,  0,  6, T49);
-    SET(d, a, b, c,  7, 10, T50);
-    SET(c, d, a, b, 14, 15, T51);
-    SET(b, c, d, a,  5, 21, T52);
-    SET(a, b, c, d, 12,  6, T53);
-    SET(d, a, b, c,  3, 10, T54);
-    SET(c, d, a, b, 10, 15, T55);
-    SET(b, c, d, a,  1, 21, T56);
-    SET(a, b, c, d,  8,  6, T57);
-    SET(d, a, b, c, 15, 10, T58);
-    SET(c, d, a, b,  6, 15, T59);
-    SET(b, c, d, a, 13, 21, T60);
-    SET(a, b, c, d,  4,  6, T61);
-    SET(d, a, b, c, 11, 10, T62);
-    SET(c, d, a, b,  2, 15, T63);
-    SET(b, c, d, a,  9, 21, T64);
-#undef SET
-
-     /* Then perform the following additions. (That is increment each
-        of the four registers by the value it had before this block
-        was started.) */
-    pms->abcd[0] += a;
-    pms->abcd[1] += b;
-    pms->abcd[2] += c;
-    pms->abcd[3] += d;
-}
-
-void
-md5_init(md5_state_t *pms)
-{
-    pms->count[0] = pms->count[1] = 0;
-    pms->abcd[0] = 0x67452301;
-    pms->abcd[1] = 0xefcdab89;
-    pms->abcd[2] = 0x98badcfe;
-    pms->abcd[3] = 0x10325476;
-}
-
-void
-md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes)
-{
-    const md5_byte_t *p = data;
-    int left = nbytes;
-    int offset = (pms->count[0] >> 3) & 63;
-    md5_word_t nbits = (md5_word_t)(nbytes << 3);
-
-    if (nbytes <= 0)
-	return;
-
-    /* Update the message length. */
-    pms->count[1] += nbytes >> 29;
-    pms->count[0] += nbits;
-    if (pms->count[0] < nbits)
-	pms->count[1]++;
-
-    /* Process an initial partial block. */
-    if (offset) {
-	int copy = (offset + nbytes > 64 ? 64 - offset : nbytes);
-
-	memcpy(pms->buf + offset, p, copy);
-	if (offset + copy < 64)
-	    return;
-	p += copy;
-	left -= copy;
-	md5_process(pms, pms->buf);
-    }
-
-    /* Process full blocks. */
-    for (; left >= 64; p += 64, left -= 64)
-	md5_process(pms, p);
-
-    /* Process a final partial block. */
-    if (left)
-	memcpy(pms->buf, p, left);
-}
-
-void
-md5_finish(md5_state_t *pms, md5_byte_t digest[16])
-{
-    static const md5_byte_t pad[64] = {
-	0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    };
-    md5_byte_t data[8];
-    int i;
-
-    /* Save the length before padding. */
-    for (i = 0; i < 8; ++i)
-	data[i] = (md5_byte_t)(pms->count[i >> 2] >> ((i & 3) << 3));
-    /* Pad to 56 bytes mod 64. */
-    md5_append(pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1);
-    /* Append the length. */
-    md5_append(pms, data, 8);
-    for (i = 0; i < 16; ++i)
-	digest[i] = (md5_byte_t)(pms->abcd[i >> 2] >> ((i & 3) << 3));
-}
Index: b/md5.h
===================================================================
--- lib/md5.h	(revision fef6116e89bb0651c72454effbb51e04e9e1b8dc)
+++ 	(revision )
@@ -1,85 +1,0 @@
-/*
-  Copyright (C) 1999 Aladdin Enterprises.  All rights reserved.
-  
-  This software is provided 'as-is', without any express or implied
-  warranty.  In no event will the authors be held liable for any damages
-  arising from the use of this software.
-
-  Permission is granted to anyone to use this software for any purpose,
-  including commercial applications, and to alter it and redistribute it
-  freely, subject to the following restrictions:
-
-  1. The origin of this software must not be misrepresented; you must not
-     claim that you wrote the original software. If you use this software
-     in a product, an acknowledgment in the product documentation would be
-     appreciated but is not required.
-  2. Altered source versions must be plainly marked as such, and must not be
-     misrepresented as being the original software.
-  3. This notice may not be removed or altered from any source distribution.
-
-  L. Peter Deutsch
-  ghost@aladdin.com
-
- */
-/*
-  Independent implementation of MD5 (RFC 1321).
-
-  This code implements the MD5 Algorithm defined in RFC 1321.
-  It is derived directly from the text of the RFC and not from the
-  reference implementation.
-
-  The original and principal author of md5.h is L. Peter Deutsch
-  <ghost@aladdin.com>.  Other authors are noted in the change history
-  that follows (in reverse chronological order):
-
-  2004-03-09 Jelmer Vernooij add G_MODULE_EXPORT for Bitlbee
-  1999-11-04 lpd Edited comments slightly for automatic TOC extraction.
-  1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5);
-	added conditionalization for C++ compilation from Martin
-	Purschke <purschke@bnl.gov>.
-  1999-05-03 lpd Original version.
- */
-
-#ifndef md5_INCLUDED
-#  define md5_INCLUDED
-
-#include <glib.h>
-#include <gmodule.h>
-
-/*
- * This code has some adaptations for the Ghostscript environment, but it
- * will compile and run correctly in any environment with 8-bit chars and
- * 32-bit ints.  Specifically, it assumes that if the following are
- * defined, they have the same meaning as in Ghostscript: P1, P2, P3,
- * ARCH_IS_BIG_ENDIAN.
- */
-
-typedef unsigned char md5_byte_t; /* 8-bit byte */
-typedef unsigned int md5_word_t; /* 32-bit word */
-
-/* Define the state of the MD5 Algorithm. */
-typedef struct md5_state_s {
-    md5_word_t count[2];	/* message length in bits, lsw first */
-    md5_word_t abcd[4];		/* digest buffer */
-    md5_byte_t buf[64];		/* accumulate block */
-} md5_state_t;
-
-#ifdef __cplusplus
-extern "C" 
-{
-#endif
-
-/* Initialize the algorithm. */
-G_MODULE_EXPORT void md5_init(md5_state_t *pms);
-
-/* Append a string to the message. */
-G_MODULE_EXPORT void md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes);
-
-/* Finish the message and return the digest. */
-G_MODULE_EXPORT void md5_finish(md5_state_t *pms, md5_byte_t digest[16]);
-
-#ifdef __cplusplus
-}  /* end extern "C" */
-#endif
-
-#endif /* md5_INCLUDED */
Index: b/misc.c
===================================================================
--- lib/misc.c	(revision fef6116e89bb0651c72454effbb51e04e9e1b8dc)
+++ 	(revision )
@@ -1,521 +1,0 @@
-  /********************************************************************\
-  * BitlBee -- An IRC to other IM-networks gateway                     *
-  *                                                                    *
-  * Copyright 2002-2006 Wilmer van der Gaast and others                *
-  \********************************************************************/
-
-/*
- * Various utility functions. Some are copied from Gaim to support the
- * IM-modules, most are from BitlBee.
- *
- * Copyright (C) 1998-1999, Mark Spencer <markster@marko.net>
- *                          (and possibly other members of the Gaim team)
- * Copyright 2002-2006 Wilmer van der Gaast <wilmer@gaast.net>
- */
-
-/*
-  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
-  the Free Software Foundation; either version 2 of the License, or
-  (at your option) any later version.
-
-  This program is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-  GNU General Public License for more details.
-
-  You should have received a copy of the GNU General Public License with
-  the Debian GNU/Linux distribution in /usr/share/common-licenses/GPL;
-  if not, write to the Free Software Foundation, Inc., 59 Temple Place,
-  Suite 330, Boston, MA  02111-1307  USA
-*/
-
-#define BITLBEE_CORE
-#include "nogaim.h"
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <glib.h>
-#include <time.h>
-
-void strip_linefeed(gchar *text)
-{
-	int i, j;
-	gchar *text2 = g_malloc(strlen(text) + 1);
-
-	for (i = 0, j = 0; text[i]; i++)
-		if (text[i] != '\r')
-			text2[j++] = text[i];
-	text2[j] = '\0';
-
-	strcpy(text, text2);
-	g_free(text2);
-}
-
-char *add_cr(char *text)
-{
-	char *ret = NULL;
-	int count = 0, j;
-	unsigned int i;
-
-	if (text[0] == '\n')
-		count++;
-	for (i = 1; i < strlen(text); i++)
-		if (text[i] == '\n' && text[i - 1] != '\r')
-			count++;
-
-	if (count == 0)
-		return g_strdup(text);
-
-	ret = g_malloc0(strlen(text) + count + 1);
-
-	i = 0; j = 0;
-	if (text[i] == '\n')
-		ret[j++] = '\r';
-	ret[j++] = text[i++];
-	for (; i < strlen(text); i++) {
-		if (text[i] == '\n' && text[i - 1] != '\r')
-			ret[j++] = '\r';
-		ret[j++] = text[i];
-	}
-
-	return ret;
-}
-
-char *normalize(const char *s)
-{
-	static char buf[BUF_LEN];
-	char *t, *u;
-	int x = 0;
-
-	g_return_val_if_fail((s != NULL), NULL);
-
-	u = t = g_strdup(s);
-
-	strcpy(t, s);
-	g_strdown(t);
-
-	while (*t && (x < BUF_LEN - 1)) {
-		if (*t != ' ') {
-			buf[x] = *t;
-			x++;
-		}
-		t++;
-	}
-	buf[x] = '\0';
-	g_free(u);
-	return buf;
-}
-
-time_t get_time(int year, int month, int day, int hour, int min, int sec)
-{
-	struct tm tm;
-
-	tm.tm_year = year - 1900;
-	tm.tm_mon = month - 1;
-	tm.tm_mday = day;
-	tm.tm_hour = hour;
-	tm.tm_min = min;
-	tm.tm_sec = sec >= 0 ? sec : time(NULL) % 60;
-	return mktime(&tm);
-}
-
-typedef struct htmlentity
-{
-	char code[8];
-	char is[4];
-} htmlentity_t;
-
-/* FIXME: This is ISO8859-1(5) centric, so might cause problems with other charsets. */
-
-static const htmlentity_t ent[] =
-{
-	{ "lt",     "<" },
-	{ "gt",     ">" },
-	{ "amp",    "&" },
-	{ "quot",   "\"" },
-	{ "aacute", "á" },
-	{ "eacute", "é" },
-	{ "iacute", "é" },
-	{ "oacute", "ó" },
-	{ "uacute", "ú" },
-	{ "agrave", "à" },
-	{ "egrave", "è" },
-	{ "igrave", "ì" },
-	{ "ograve", "ò" },
-	{ "ugrave", "ù" },
-	{ "acirc",  "â" },
-	{ "ecirc",  "ê" },
-	{ "icirc",  "î" },
-	{ "ocirc",  "ô" },
-	{ "ucirc",  "û" },
-	{ "auml",   "ä" },
-	{ "euml",   "ë" },
-	{ "iuml",   "ï" },
-	{ "ouml",   "ö" },
-	{ "uuml",   "ü" },
-	{ "nbsp",   " " },
-	{ "",        ""  }
-};
-
-void strip_html( char *in )
-{
-	char *start = in;
-	char *out = g_malloc( strlen( in ) + 1 );
-	char *s = out, *cs;
-	int i, matched;
-	
-	memset( out, 0, strlen( in ) + 1 );
-	
-	while( *in )
-	{
-		if( *in == '<' && ( isalpha( *(in+1) ) || *(in+1) == '/' ) )
-		{
-			/* If in points at a < and in+1 points at a letter or a slash, this is probably
-			   a HTML-tag. Try to find a closing > and continue there. If the > can't be
-			   found, assume that it wasn't a HTML-tag after all. */
-			
-			cs = in;
-			
-			while( *in && *in != '>' )
-				in ++;
-			
-			if( *in )
-			{
-				if( g_strncasecmp( cs+1, "br", 2) == 0 )
-					*(s++) = '\n';
-				in ++;
-			}
-			else
-			{
-				in = cs;
-				*(s++) = *(in++);
-			}
-		}
-		else if( *in == '&' )
-		{
-			cs = ++in;
-			while( *in && isalpha( *in ) )
-				in ++;
-			
-			if( *in == ';' ) in ++;
-			matched = 0;
-			
-			for( i = 0; *ent[i].code; i ++ )
-				if( g_strncasecmp( ent[i].code, cs, strlen( ent[i].code ) ) == 0 )
-				{
-					int j;
-					
-					for( j = 0; ent[i].is[j]; j ++ )
-						*(s++) = ent[i].is[j];
-					
-					matched = 1;
-					break;
-				}
-
-			/* None of the entities were matched, so return the string */
-			if( !matched )
-			{
-				in = cs - 1;
-				*(s++) = *(in++);
-			}
-		}
-		else
-		{
-			*(s++) = *(in++);
-		}
-	}
-	
-	strcpy( start, out );
-	g_free( out );
-}
-
-char *escape_html( const char *html )
-{
-	const char *c = html;
-	GString *ret;
-	char *str;
-	
-	if( html == NULL )
-		return( NULL );
-	
-	ret = g_string_new( "" );
-	
-	while( *c )
-	{
-		switch( *c )
-		{
-			case '&':
-				ret = g_string_append( ret, "&amp;" );
-				break;
-			case '<':
-				ret = g_string_append( ret, "&lt;" );
-				break;
-			case '>':
-				ret = g_string_append( ret, "&gt;" );
-				break;
-			case '"':
-				ret = g_string_append( ret, "&quot;" );
-				break;
-			default:
-				ret = g_string_append_c( ret, *c );
-		}
-		c ++;
-	}
-	
-	str = ret->str;
-	g_string_free( ret, FALSE );
-	return( str );
-}
-
-void info_string_append(GString *str, char *newline, char *name, char *value)
-{
-	if( value && value[0] )
-		g_string_sprintfa( str, "%s%s: %s", newline, name, value );
-}
-
-/* Decode%20a%20file%20name						*/
-void http_decode( char *s )
-{
-	char *t;
-	int i, j, k;
-	
-	t = g_new( char, strlen( s ) + 1 );
-	
-	for( i = j = 0; s[i]; i ++, j ++ )
-	{
-		if( s[i] == '%' )
-		{
-			if( sscanf( s + i + 1, "%2x", &k ) )
-			{
-				t[j] = k;
-				i += 2;
-			}
-			else
-			{
-				*t = 0;
-				break;
-			}
-		}
-		else
-		{
-			t[j] = s[i];
-		}
-	}
-	t[j] = 0;
-	
-	strcpy( s, t );
-	g_free( t );
-}
-
-/* Warning: This one explodes the string. Worst-cases can make the string 3x its original size! */
-/* This fuction is safe, but make sure you call it safely as well! */
-void http_encode( char *s )
-{
-	char *t;
-	int i, j;
-	
-	t = g_strdup( s );
-	
-	for( i = j = 0; t[i]; i ++, j ++ )
-	{
-		/* if( t[i] <= ' ' || ((unsigned char *)t)[i] >= 128 || t[i] == '%' ) */
-		if( !isalnum( t[i] ) )
-		{
-			sprintf( s + j, "%%%02X", ((unsigned char*)t)[i] );
-			j += 2;
-		}
-		else
-		{
-			s[j] = t[i];
-		}
-	}
-	s[j] = 0;
-	
-	g_free( t );
-}
-
-/* Strip newlines from a string. Modifies the string passed to it. */ 
-char *strip_newlines( char *source )
-{
-	int i;	
-
-	for( i = 0; source[i] != '\0'; i ++ )
-		if( source[i] == '\n' || source[i] == '\r' )
-			source[i] = ' ';
-	
-	return source;
-}
-
-#ifdef IPV6
-/* Wrap an IPv4 address into IPv6 space. Not thread-safe... */
-char *ipv6_wrap( char *src )
-{
-	static char dst[64];
-	int i;
-	
-	for( i = 0; src[i]; i ++ )
-		if( ( src[i] < '0' || src[i] > '9' ) && src[i] != '.' )
-			break;
-	
-	/* Hmm, it's not even an IP... */
-	if( src[i] )
-		return src;
-	
-	g_snprintf( dst, sizeof( dst ), "::ffff:%s", src );
-	
-	return dst;
-}
-
-/* Unwrap an IPv4 address into IPv6 space. Thread-safe, because it's very simple. :-) */
-char *ipv6_unwrap( char *src )
-{
-	int i;
-	
-	if( g_strncasecmp( src, "::ffff:", 7 ) != 0 )
-		return src;
-	
-	for( i = 7; src[i]; i ++ )
-		if( ( src[i] < '0' || src[i] > '9' ) && src[i] != '.' )
-			break;
-	
-	/* Hmm, it's not even an IP... */
-	if( src[i] )
-		return src;
-	
-	return ( src + 7 );
-}
-#endif
-
-/* Convert from one charset to another.
-   
-   from_cs, to_cs: Source and destination charsets
-   src, dst: Source and destination strings
-   size: Size if src. 0 == use strlen(). strlen() is not reliable for UNICODE/UTF16 strings though.
-   maxbuf: Maximum number of bytes to write to dst
-   
-   Returns the number of bytes written to maxbuf or -1 on an error.
-*/
-signed int do_iconv( char *from_cs, char *to_cs, char *src, char *dst, size_t size, size_t maxbuf )
-{
-	GIConv cd;
-	size_t res;
-	size_t inbytesleft, outbytesleft;
-	char *inbuf = src;
-	char *outbuf = dst;
-	
-	cd = g_iconv_open( to_cs, from_cs );
-	if( cd == (GIConv) -1 )
-		return( -1 );
-	
-	inbytesleft = size ? size : strlen( src );
-	outbytesleft = maxbuf - 1;
-	res = g_iconv( cd, &inbuf, &inbytesleft, &outbuf, &outbytesleft );
-	*outbuf = '\0';
-	g_iconv_close( cd );
-	
-	if( res == (size_t) -1 )
-		return( -1 );
-	else
-		return( outbuf - dst );
-}
-
-/* A pretty reliable random number generator. Tries to use the /dev/random
-   devices first, and falls back to the random number generator from libc
-   when it fails. Opens randomizer devices with O_NONBLOCK to make sure a
-   lack of entropy won't halt BitlBee. */
-void random_bytes( unsigned char *buf, int count )
-{
-	static int use_dev = -1;
-	
-	/* Actually this probing code isn't really necessary, is it? */
-	if( use_dev == -1 )
-	{
-		if( access( "/dev/random", R_OK ) == 0 || access( "/dev/urandom", R_OK ) == 0 )
-			use_dev = 1;
-		else
-		{
-			use_dev = 0;
-			srand( ( getpid() << 16 ) ^ time( NULL ) );
-		}
-	}
-	
-	if( use_dev )
-	{
-		int fd;
-		
-		/* At least on Linux, /dev/random can block if there's not
-		   enough entropy. We really don't want that, so if it can't
-		   give anything, use /dev/urandom instead. */
-		if( ( fd = open( "/dev/random", O_RDONLY | O_NONBLOCK ) ) >= 0 )
-			if( read( fd, buf, count ) == count )
-			{
-				close( fd );
-				return;
-			}
-		close( fd );
-		
-		/* urandom isn't supposed to block at all, but just to be
-		   sure. If it blocks, we'll disable use_dev and use the libc
-		   randomizer instead. */
-		if( ( fd = open( "/dev/urandom", O_RDONLY | O_NONBLOCK ) ) >= 0 )
-			if( read( fd, buf, count ) == count )
-			{
-				close( fd );
-				return;
-			}
-		close( fd );
-		
-		/* If /dev/random blocks once, we'll still try to use it
-		   again next time. If /dev/urandom also fails for some
-		   reason, stick with libc during this session. */
-		
-		use_dev = 0;
-		srand( ( getpid() << 16 ) ^ time( NULL ) );
-	}
-	
-	if( !use_dev )
-	{
-		int i;
-		
-		/* Possibly the LSB of rand() isn't very random on some
-		   platforms. Seems okay on at least Linux and OSX though. */
-		for( i = 0; i < count; i ++ )
-			buf[i] = rand() & 0xff;
-	}
-}
-
-int is_bool( char *value )
-{
-	if( *value == 0 )
-		return 0;
-	
-	if( ( g_strcasecmp( value, "true" ) == 0 ) || ( g_strcasecmp( value, "yes" ) == 0 ) || ( g_strcasecmp( value, "on" ) == 0 ) )
-		return 1;
-	if( ( g_strcasecmp( value, "false" ) == 0 ) || ( g_strcasecmp( value, "no" ) == 0 ) || ( g_strcasecmp( value, "off" ) == 0 ) )
-		return 1;
-	
-	while( *value )
-		if( !isdigit( *value ) )
-			return 0;
-		else
-			value ++;
-	
-	return 1;
-}
-
-int bool2int( char *value )
-{
-	int i;
-	
-	if( ( g_strcasecmp( value, "true" ) == 0 ) || ( g_strcasecmp( value, "yes" ) == 0 ) || ( g_strcasecmp( value, "on" ) == 0 ) )
-		return 1;
-	if( ( g_strcasecmp( value, "false" ) == 0 ) || ( g_strcasecmp( value, "no" ) == 0 ) || ( g_strcasecmp( value, "off" ) == 0 ) )
-		return 0;
-	
-	if( sscanf( value, "%d", &i ) == 1 )
-		return i;
-	
-	return 0;
-}
Index: b/misc.h
===================================================================
--- lib/misc.h	(revision fef6116e89bb0651c72454effbb51e04e9e1b8dc)
+++ 	(revision )
@@ -1,56 +1,0 @@
-  /********************************************************************\
-  * BitlBee -- An IRC to other IM-networks gateway                     *
-  *                                                                    *
-  * Copyright 2002-2004 Wilmer van der Gaast and others                *
-  \********************************************************************/
-
-/* Misc. functions                                                      */
-
-/*
-  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
-  the Free Software Foundation; either version 2 of the License, or
-  (at your option) any later version.
-
-  This program is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-  GNU General Public License for more details.
-
-  You should have received a copy of the GNU General Public License with
-  the Debian GNU/Linux distribution in /usr/share/common-licenses/GPL;
-  if not, write to the Free Software Foundation, Inc., 59 Temple Place,
-  Suite 330, Boston, MA  02111-1307  USA
-*/
-
-#ifndef _MISC_H
-#define _MISC_H
-
-#include <gmodule.h>
-#include <time.h>
-
-G_MODULE_EXPORT void strip_linefeed( gchar *text );
-G_MODULE_EXPORT char *add_cr( char *text );
-G_MODULE_EXPORT char *strip_newlines(char *source);
-G_MODULE_EXPORT char *normalize( const char *s );
-G_MODULE_EXPORT void info_string_append( GString *str, char *newline, char *name, char *value );
-
-G_MODULE_EXPORT time_t get_time( int year, int month, int day, int hour, int min, int sec );
-double gettime( void );
-
-G_MODULE_EXPORT void strip_html( char *msg );
-G_MODULE_EXPORT char *escape_html( const char *html );
-G_MODULE_EXPORT void http_decode( char *s );
-G_MODULE_EXPORT void http_encode( char *s );
-
-G_MODULE_EXPORT char *ipv6_wrap( char *src );
-G_MODULE_EXPORT char *ipv6_unwrap( char *src );
-
-G_MODULE_EXPORT signed int do_iconv( char *from_cs, char *to_cs, char *src, char *dst, size_t size, size_t maxbuf );
-
-G_MODULE_EXPORT void random_bytes( unsigned char *buf, int count );
-
-G_MODULE_EXPORT int is_bool( char *value );
-G_MODULE_EXPORT int bool2int( char *value );
-
-#endif
Index: b/proxy.c
===================================================================
--- lib/proxy.c	(revision fef6116e89bb0651c72454effbb51e04e9e1b8dc)
+++ 	(revision )
@@ -1,553 +1,0 @@
-/*
- * gaim
- *
- * Copyright (C) 1998-1999, Mark Spencer <markster@marko.net>
- * Copyright (C) 2002-2004, Wilmer van der Gaast, Jelmer Vernooij
- *
- * 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
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- */
-
-#define BITLBEE_CORE
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-#ifndef _WIN32
-#include <sys/socket.h>
-#include <netdb.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <unistd.h>
-#else
-#include "sock.h"
-#define ETIMEDOUT WSAETIMEDOUT
-#define EINPROGRESS WSAEINPROGRESS
-#endif
-#include <fcntl.h>
-#include <errno.h>
-#include "nogaim.h"
-#include "proxy.h"
-#include "base64.h"
-
-char proxyhost[128] = "";
-int proxyport = 0;
-int proxytype = PROXY_NONE;
-char proxyuser[128] = "";
-char proxypass[128] = "";
-
-struct PHB {
-	b_event_handler func, proxy_func;
-	gpointer data, proxy_data;
-	char *host;
-	int port;
-	int fd;
-	gint inpa;
-};
-
-
-
-static struct sockaddr_in *gaim_gethostbyname(const char *host, int port)
-{
-	static struct sockaddr_in sin;
-
-	if (!inet_aton(host, &sin.sin_addr)) {
-		struct hostent *hp;
-		if (!(hp = gethostbyname(host))) {
-			return NULL;
-		}
-		memset(&sin, 0, sizeof(struct sockaddr_in));
-		memcpy(&sin.sin_addr.s_addr, hp->h_addr, hp->h_length);
-		sin.sin_family = hp->h_addrtype;
-	} else
-		sin.sin_family = AF_INET;
-	sin.sin_port = htons(port);
-
-	return &sin;
-}
-
-static gboolean gaim_io_connected(gpointer data, gint source, b_input_condition cond)
-{
-	struct PHB *phb = data;
-	unsigned int len;
-	int error = ETIMEDOUT;
-	len = sizeof(error);
-	
-#ifndef _WIN32
-	if (getsockopt(source, SOL_SOCKET, SO_ERROR, &error, &len) < 0) {
-		closesocket(source);
-		b_event_remove(phb->inpa);
-		if( phb->proxy_func )
-			phb->proxy_func(phb->proxy_data, -1, GAIM_INPUT_READ);
-		else {
-			phb->func(phb->data, -1, GAIM_INPUT_READ);
-			g_free(phb);
-		}
-		return FALSE;
-	}
-#endif
-	sock_make_blocking(source);
-	b_event_remove(phb->inpa);
-	if( phb->proxy_func )
-		phb->proxy_func(phb->proxy_data, source, GAIM_INPUT_READ);
-	else {
-		phb->func(phb->data, source, GAIM_INPUT_READ);
-		g_free(phb);
-	}
-	
-	return FALSE;
-}
-
-static int proxy_connect_none(const char *host, unsigned short port, struct PHB *phb)
-{
-	struct sockaddr_in *sin;
-	int fd = -1;
-
-	if (!(sin = gaim_gethostbyname(host, port))) {
-		g_free(phb);
-		return -1;
-	}
-
-	if ((fd = socket(sin->sin_family, SOCK_STREAM, 0)) < 0) {
-		g_free(phb);
-		return -1;
-	}
-
-	sock_make_nonblocking(fd);
-	
-	event_debug("proxy_connect_none( \"%s\", %d ) = %d\n", host, port, fd);
-	
-	if (connect(fd, (struct sockaddr *)sin, sizeof(*sin)) < 0) {
-		if (sockerr_again()) {
-			phb->inpa = b_input_add(fd, GAIM_INPUT_WRITE, gaim_io_connected, phb);
-			phb->fd = fd;
-		} else {
-			closesocket(fd);
-			g_free(phb);
-			return -1;
-		}
-	}
-
-	return fd;
-}
-
-
-/* Connecting to HTTP proxies */
-
-#define HTTP_GOODSTRING "HTTP/1.0 200 Connection established"
-#define HTTP_GOODSTRING2 "HTTP/1.1 200 Connection established"
-
-static gboolean http_canread(gpointer data, gint source, b_input_condition cond)
-{
-	int nlc = 0;
-	int pos = 0;
-	struct PHB *phb = data;
-	char inputline[8192];
-
-	b_event_remove(phb->inpa);
-
-	while ((pos < sizeof(inputline)-1) && (nlc != 2) && (read(source, &inputline[pos++], 1) == 1)) {
-		if (inputline[pos - 1] == '\n')
-			nlc++;
-		else if (inputline[pos - 1] != '\r')
-			nlc = 0;
-	}
-	inputline[pos] = '\0';
-
-	if ((memcmp(HTTP_GOODSTRING, inputline, strlen(HTTP_GOODSTRING)) == 0) ||
-	    (memcmp(HTTP_GOODSTRING2, inputline, strlen(HTTP_GOODSTRING2)) == 0)) {
-		phb->func(phb->data, source, GAIM_INPUT_READ);
-		g_free(phb->host);
-		g_free(phb);
-		return FALSE;
-	}
-
-	close(source);
-	phb->func(phb->data, -1, GAIM_INPUT_READ);
-	g_free(phb->host);
-	g_free(phb);
-	
-	return FALSE;
-}
-
-static gboolean http_canwrite(gpointer data, gint source, b_input_condition cond)
-{
-	char cmd[384];
-	struct PHB *phb = data;
-	unsigned int len;
-	int error = ETIMEDOUT;
-	if (phb->inpa > 0)
-		b_event_remove(phb->inpa);
-	len = sizeof(error);
-	if (getsockopt(source, SOL_SOCKET, SO_ERROR, &error, &len) < 0) {
-		close(source);
-		phb->func(phb->data, -1, GAIM_INPUT_READ);
-		g_free(phb->host);
-		g_free(phb);
-		return FALSE;
-	}
-	sock_make_blocking(source);
-
-	g_snprintf(cmd, sizeof(cmd), "CONNECT %s:%d HTTP/1.1\r\nHost: %s:%d\r\n", phb->host, phb->port,
-		   phb->host, phb->port);
-	if (send(source, cmd, strlen(cmd), 0) < 0) {
-		close(source);
-		phb->func(phb->data, -1, GAIM_INPUT_READ);
-		g_free(phb->host);
-		g_free(phb);
-		return FALSE;
-	}
-
-	if (proxyuser && *proxyuser) {
-		char *t1, *t2;
-		t1 = g_strdup_printf("%s:%s", proxyuser, proxypass);
-		t2 = tobase64(t1);
-		g_free(t1);
-		g_snprintf(cmd, sizeof(cmd), "Proxy-Authorization: Basic %s\r\n", t2);
-		g_free(t2);
-		if (send(source, cmd, strlen(cmd), 0) < 0) {
-			close(source);
-			phb->func(phb->data, -1, GAIM_INPUT_READ);
-			g_free(phb->host);
-			g_free(phb);
-			return FALSE;
-		}
-	}
-
-	g_snprintf(cmd, sizeof(cmd), "\r\n");
-	if (send(source, cmd, strlen(cmd), 0) < 0) {
-		close(source);
-		phb->func(phb->data, -1, GAIM_INPUT_READ);
-		g_free(phb->host);
-		g_free(phb);
-		return FALSE;
-	}
-
-	phb->inpa = b_input_add(source, GAIM_INPUT_READ, http_canread, phb);
-	
-	return FALSE;
-}
-
-static int proxy_connect_http(const char *host, unsigned short port, struct PHB *phb)
-{
-	phb->host = g_strdup(host);
-	phb->port = port;
-	phb->proxy_func = http_canwrite;
-	phb->proxy_data = phb;
-	
-	return( proxy_connect_none( proxyhost, proxyport, phb ) );
-}
-
-
-/* Connecting to SOCKS4 proxies */
-
-static gboolean s4_canread(gpointer data, gint source, b_input_condition cond)
-{
-	unsigned char packet[12];
-	struct PHB *phb = data;
-
-	b_event_remove(phb->inpa);
-
-	memset(packet, 0, sizeof(packet));
-	if (read(source, packet, 9) >= 4 && packet[1] == 90) {
-		phb->func(phb->data, source, GAIM_INPUT_READ);
-		g_free(phb->host);
-		g_free(phb);
-		return FALSE;
-	}
-
-	close(source);
-	phb->func(phb->data, -1, GAIM_INPUT_READ);
-	g_free(phb->host);
-	g_free(phb);
-	
-	return FALSE;
-}
-
-static gboolean s4_canwrite(gpointer data, gint source, b_input_condition cond)
-{
-	unsigned char packet[12];
-	struct hostent *hp;
-	struct PHB *phb = data;
-	unsigned int len;
-	int error = ETIMEDOUT;
-	if (phb->inpa > 0)
-		b_event_remove(phb->inpa);
-	len = sizeof(error);
-	if (getsockopt(source, SOL_SOCKET, SO_ERROR, &error, &len) < 0) {
-		close(source);
-		phb->func(phb->data, -1, GAIM_INPUT_READ);
-		g_free(phb->host);
-		g_free(phb);
-		return FALSE;
-	}
-	sock_make_blocking(source);
-
-	/* XXX does socks4 not support host name lookups by the proxy? */
-	if (!(hp = gethostbyname(phb->host))) {
-		close(source);
-		phb->func(phb->data, -1, GAIM_INPUT_READ);
-		g_free(phb->host);
-		g_free(phb);
-		return FALSE;
-	}
-
-	packet[0] = 4;
-	packet[1] = 1;
-	packet[2] = phb->port >> 8;
-	packet[3] = phb->port & 0xff;
-	packet[4] = (unsigned char)(hp->h_addr_list[0])[0];
-	packet[5] = (unsigned char)(hp->h_addr_list[0])[1];
-	packet[6] = (unsigned char)(hp->h_addr_list[0])[2];
-	packet[7] = (unsigned char)(hp->h_addr_list[0])[3];
-	packet[8] = 0;
-	if (write(source, packet, 9) != 9) {
-		close(source);
-		phb->func(phb->data, -1, GAIM_INPUT_READ);
-		g_free(phb->host);
-		g_free(phb);
-		return FALSE;
-	}
-
-	phb->inpa = b_input_add(source, GAIM_INPUT_READ, s4_canread, phb);
-	
-	return FALSE;
-}
-
-static int proxy_connect_socks4(const char *host, unsigned short port, struct PHB *phb)
-{
-	phb->host = g_strdup(host);
-	phb->port = port;
-	phb->proxy_func = s4_canwrite;
-	phb->proxy_data = phb;
-	
-	return( proxy_connect_none( proxyhost, proxyport, phb ) );
-}
-
-
-/* Connecting to SOCKS5 proxies */
-
-static gboolean s5_canread_again(gpointer data, gint source, b_input_condition cond)
-{
-	unsigned char buf[512];
-	struct PHB *phb = data;
-
-	b_event_remove(phb->inpa);
-
-	if (read(source, buf, 10) < 10) {
-		close(source);
-		phb->func(phb->data, -1, GAIM_INPUT_READ);
-		g_free(phb->host);
-		g_free(phb);
-		return FALSE;
-	}
-	if ((buf[0] != 0x05) || (buf[1] != 0x00)) {
-		close(source);
-		phb->func(phb->data, -1, GAIM_INPUT_READ);
-		g_free(phb->host);
-		g_free(phb);
-		return FALSE;
-	}
-
-	phb->func(phb->data, source, GAIM_INPUT_READ);
-	g_free(phb->host);
-	g_free(phb);
-	
-	return FALSE;
-}
-
-static void s5_sendconnect(gpointer data, gint source)
-{
-	unsigned char buf[512];
-	struct PHB *phb = data;
-	int hlen = strlen(phb->host);
-	
-	buf[0] = 0x05;
-	buf[1] = 0x01;		/* CONNECT */
-	buf[2] = 0x00;		/* reserved */
-	buf[3] = 0x03;		/* address type -- host name */
-	buf[4] = hlen;
-	memcpy(buf + 5, phb->host, hlen);
-	buf[5 + strlen(phb->host)] = phb->port >> 8;
-	buf[5 + strlen(phb->host) + 1] = phb->port & 0xff;
-
-	if (write(source, buf, (5 + strlen(phb->host) + 2)) < (5 + strlen(phb->host) + 2)) {
-		close(source);
-		phb->func(phb->data, -1, GAIM_INPUT_READ);
-		g_free(phb->host);
-		g_free(phb);
-		return;
-	}
-
-	phb->inpa = b_input_add(source, GAIM_INPUT_READ, s5_canread_again, phb);
-}
-
-static gboolean s5_readauth(gpointer data, gint source, b_input_condition cond)
-{
-	unsigned char buf[512];
-	struct PHB *phb = data;
-
-	b_event_remove(phb->inpa);
-
-	if (read(source, buf, 2) < 2) {
-		close(source);
-		phb->func(phb->data, -1, GAIM_INPUT_READ);
-		g_free(phb->host);
-		g_free(phb);
-		return FALSE;
-	}
-
-	if ((buf[0] != 0x01) || (buf[1] != 0x00)) {
-		close(source);
-		phb->func(phb->data, -1, GAIM_INPUT_READ);
-		g_free(phb->host);
-		g_free(phb);
-		return FALSE;
-	}
-
-	s5_sendconnect(phb, source);
-	
-	return FALSE;
-}
-
-static gboolean s5_canread(gpointer data, gint source, b_input_condition cond)
-{
-	unsigned char buf[512];
-	struct PHB *phb = data;
-
-	b_event_remove(phb->inpa);
-
-	if (read(source, buf, 2) < 2) {
-		close(source);
-		phb->func(phb->data, -1, GAIM_INPUT_READ);
-		g_free(phb->host);
-		g_free(phb);
-		return FALSE;
-	}
-
-	if ((buf[0] != 0x05) || (buf[1] == 0xff)) {
-		close(source);
-		phb->func(phb->data, -1, GAIM_INPUT_READ);
-		g_free(phb->host);
-		g_free(phb);
-		return FALSE;
-	}
-
-	if (buf[1] == 0x02) {
-		unsigned int i = strlen(proxyuser), j = strlen(proxypass);
-		buf[0] = 0x01;	/* version 1 */
-		buf[1] = i;
-		memcpy(buf + 2, proxyuser, i);
-		buf[2 + i] = j;
-		memcpy(buf + 2 + i + 1, proxypass, j);
-		if (write(source, buf, 3 + i + j) < 3 + i + j) {
-			close(source);
-			phb->func(phb->data, -1, GAIM_INPUT_READ);
-			g_free(phb->host);
-			g_free(phb);
-			return FALSE;
-		}
-
-		phb->inpa = b_input_add(source, GAIM_INPUT_READ, s5_readauth, phb);
-	} else {
-		s5_sendconnect(phb, source);
-	}
-	
-	return FALSE;
-}
-
-static gboolean s5_canwrite(gpointer data, gint source, b_input_condition cond)
-{
-	unsigned char buf[512];
-	int i;
-	struct PHB *phb = data;
-	unsigned int len;
-	int error = ETIMEDOUT;
-	if (phb->inpa > 0)
-		b_event_remove(phb->inpa);
-	len = sizeof(error);
-	if (getsockopt(source, SOL_SOCKET, SO_ERROR, &error, &len) < 0) {
-		close(source);
-		phb->func(phb->data, -1, GAIM_INPUT_READ);
-		g_free(phb->host);
-		g_free(phb);
-		return FALSE;
-	}
-	sock_make_blocking(source);
-
-	i = 0;
-	buf[0] = 0x05;		/* SOCKS version 5 */
-	if (proxyuser[0]) {
-		buf[1] = 0x02;	/* two methods */
-		buf[2] = 0x00;	/* no authentication */
-		buf[3] = 0x02;	/* username/password authentication */
-		i = 4;
-	} else {
-		buf[1] = 0x01;
-		buf[2] = 0x00;
-		i = 3;
-	}
-
-	if (write(source, buf, i) < i) {
-		close(source);
-		phb->func(phb->data, -1, GAIM_INPUT_READ);
-		g_free(phb->host);
-		g_free(phb);
-		return FALSE;
-	}
-
-	phb->inpa = b_input_add(source, GAIM_INPUT_READ, s5_canread, phb);
-	
-	return FALSE;
-}
-
-static int proxy_connect_socks5(const char *host, unsigned short port, struct PHB *phb)
-{
-	phb->host = g_strdup(host);
-	phb->port = port;
-	phb->proxy_func = s5_canwrite;
-	phb->proxy_data = phb;
-	
-	return( proxy_connect_none( proxyhost, proxyport, phb ) );
-}
-
-
-/* Export functions */
-
-int proxy_connect(const char *host, int port, b_event_handler func, gpointer data)
-{
-	struct PHB *phb;
-	
-	if (!host || !port || (port == -1) || !func || strlen(host) > 128) {
-		return -1;
-	}
-	
-	phb = g_new0(struct PHB, 1);
-	phb->func = func;
-	phb->data = data;
-	
-	if ((proxytype == PROXY_NONE) || !proxyhost || !proxyhost[0] || !proxyport || (proxyport == -1))
-		return proxy_connect_none(host, port, phb);
-	else if (proxytype == PROXY_HTTP)
-		return proxy_connect_http(host, port, phb);
-	else if (proxytype == PROXY_SOCKS4)
-		return proxy_connect_socks4(host, port, phb);
-	else if (proxytype == PROXY_SOCKS5)
-		return proxy_connect_socks5(host, port, phb);
-	
-	if (phb->host) g_free(phb);
-	g_free(phb);
-	return -1;
-}
Index: b/proxy.h
===================================================================
--- lib/proxy.h	(revision fef6116e89bb0651c72454effbb51e04e9e1b8dc)
+++ 	(revision )
@@ -1,53 +1,0 @@
-/*
- * nogaim
- *
- * Copyright (C) 1998-1999, Mark Spencer <markster@marko.net>
- *
- * 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
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * 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_
-
-#include <sys/types.h>
-#ifndef _WIN32
-#include <sys/socket.h>
-#include <netdb.h>
-#include <netinet/in.h>
-#endif
-#include <glib.h>
-#include <gmodule.h>
-
-#include "events.h"
-
-#define PROXY_NONE 0
-#define PROXY_HTTP 1
-#define PROXY_SOCKS4 2
-#define PROXY_SOCKS5 3
-
-extern char proxyhost[128];
-extern int  proxyport;
-extern int  proxytype;
-extern char proxyuser[128];
-extern char proxypass[128];
-
-G_MODULE_EXPORT int proxy_connect(const char *host, int port, b_event_handler func, gpointer data);
-
-#endif /* _PROXY_H_ */
Index: b/rc4.c
===================================================================
--- lib/rc4.c	(revision fef6116e89bb0651c72454effbb51e04e9e1b8dc)
+++ 	(revision )
@@ -1,189 +1,0 @@
-/***************************************************************************\
-*                                                                           *
-*  BitlBee - An IRC to IM gateway                                           *
-*  Simple (but secure) RC4 implementation for safer password storage.       *
-*                                                                           *
-*  Copyright 2006 Wilmer van der Gaast <wilmer@gaast.net>                   *
-*                                                                           *
-*  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     *
-*  the Free Software Foundation; either version 2 of the License, or        *
-*  (at your option) any later version.                                      *
-*                                                                           *
-*  This program is distributed in the hope that it will be useful,          *
-*  but WITHOUT ANY WARRANTY; without even the implied warranty of           *
-*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            *
-*  GNU General Public License for more details.                             *
-*                                                                           *
-*  You should have received a copy of the GNU General Public License along  *
-*  with this program; if not, write to the Free Software Foundation, Inc.,  *
-*  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.              *
-*                                                                           *
-\***************************************************************************/
-
-/* 
-   This file implements RC4-encryption, which will mainly be used to save IM
-   passwords safely in the new XML-format. Possibly other uses will come up
-   later. It's supposed to be quite reliable (thanks to the use of a 6-byte
-   IV/seed), certainly compared to the old format. The only realistic way to
-   crack BitlBee passwords now is to use a sniffer to get your hands on the
-   user's password.
-   
-   If you see that something's wrong in this implementation (I asked a
-   couple of people to look at it already, but who knows), please tell me.
-   
-   The reason I chose for RC4 is because it's pretty simple but effective,
-   so it will work without adding several KBs or an extra library dependency.
-*/
-
-
-#include <glib.h>
-#include <gmodule.h>
-#include <stdlib.h>
-#include <string.h>
-#include "misc.h"
-#include "rc4.h"
-
-/* Add some seed to the password, to make sure we *never* use the same key.
-   This defines how many byes we use as a seed. */
-#define RC4_IV_LEN 6
-
-/* To defend against a "Fluhrer, Mantin and Shamir attack", it is recommended
-   to shuffle S[] just a bit more before you start to use it. This defines how
-   many bytes we'll request before we'll really use them for encryption. */
-#define RC4_CYCLES 1024
-
-struct rc4_state *rc4_keymaker( unsigned char *key, int kl, int cycles )
-{
-	struct rc4_state *st;
-	int i, j, tmp;
-	
-	st = g_malloc( sizeof( struct rc4_state ) );
-	st->i = st->j = 0;
-	for( i = 0; i < 256; i ++ )
-		st->S[i] = i;
-	
-	if( kl <= 0 )
-		kl = strlen( (char*) key );
-	
-	for( i = j = 0; i < 256; i ++ )
-	{
-		j = ( j + st->S[i] + key[i%kl] ) & 0xff;
-		tmp = st->S[i];
-		st->S[i] = st->S[j];
-		st->S[j] = tmp;
-	}
-	
-	for( i = 0; i < cycles; i ++ )
-		rc4_getbyte( st );
-	
-	return st;
-}
-
-/*
-   For those who don't know, RC4 is basically an algorithm that generates a
-   stream of bytes after you give it a key. Just get a byte from it and xor
-   it with your cleartext. To decrypt, just give it the same key again and
-   start xorring.
-   
-   The function above initializes the RC4 byte generator, the next function
-   can be used to get bytes from the generator (and shuffle things a bit).
-*/
-
-unsigned char rc4_getbyte( struct rc4_state *st )
-{
-	unsigned char tmp;
-	
-	/* Unfortunately the st-> stuff doesn't really improve readability here... */
-	st->i ++;
-	st->j += st->S[st->i];
-	tmp = st->S[st->i];
-	st->S[st->i] = st->S[st->j];
-	st->S[st->j] = tmp;
-	
-	return st->S[(st->S[st->i] + st->S[st->j]) & 0xff];
-}
-
-/*
-   The following two functions can be used for reliable encryption and
-   decryption. Known plaintext attacks are prevented by adding some (6,
-   by default) random bytes to the password before setting up the RC4
-   structures. These 6 bytes are also saved in the results, because of
-   course we'll need them in rc4_decode().
-   
-   Because the length of the resulting string is unknown to the caller,
-   it should pass a char**. Since the encode/decode functions allocate
-   memory for the string, make sure the char** points at a NULL-pointer
-   (or at least to something you already free()d), or you'll leak
-   memory. And of course, don't forget to free() the result when you
-   don't need it anymore.
-   
-   Both functions return the number of bytes in the result string.
-*/
-
-int rc4_encode( unsigned char *clear, int clear_len, unsigned char **crypt, char *password )
-{
-	struct rc4_state *st;
-	unsigned char *key;
-	int key_len, i;
-	
-	key_len = strlen( password ) + RC4_IV_LEN;
-	if( clear_len <= 0 )
-		clear_len = strlen( (char*) clear );
-	
-	/* Prepare buffers and the key + IV */
-	*crypt = g_malloc( clear_len + RC4_IV_LEN );
-	key = g_malloc( key_len );
-	strcpy( (char*) key, password );
-	
-	/* Add the salt. Save it for later (when decrypting) and, of course,
-	   add it to the encryption key. */
-	random_bytes( crypt[0], RC4_IV_LEN );
-	memcpy( key + key_len - RC4_IV_LEN, crypt[0], RC4_IV_LEN );
-	
-	/* Generate the initial S[] from the IVed key. */
-	st = rc4_keymaker( key, key_len, RC4_CYCLES );
-	g_free( key );
-	
-	for( i = 0; i < clear_len; i ++ )
-		crypt[0][i+RC4_IV_LEN] = clear[i] ^ rc4_getbyte( st );
-	
-	g_free( st );
-	
-	return clear_len + RC4_IV_LEN;
-}
-
-int rc4_decode( unsigned char *crypt, int crypt_len, unsigned char **clear, char *password )
-{
-	struct rc4_state *st;
-	unsigned char *key;
-	int key_len, clear_len, i;
-	
-	key_len = strlen( password ) + RC4_IV_LEN;
-	clear_len = crypt_len - RC4_IV_LEN;
-	
-	if( clear_len < 0 )
-	{
-		*clear = (unsigned char*) g_strdup( "" );
-		return 0;
-	}
-	
-	/* Prepare buffers and the key + IV */
-	*clear = g_malloc( clear_len + 1 );
-	key = g_malloc( key_len );
-	strcpy( (char*) key, password );
-	for( i = 0; i < RC4_IV_LEN; i ++ )
-		key[key_len-RC4_IV_LEN+i] = crypt[i];
-	
-	/* Generate the initial S[] from the IVed key. */
-	st = rc4_keymaker( key, key_len, RC4_CYCLES );
-	g_free( key );
-	
-	for( i = 0; i < clear_len; i ++ )
-		clear[0][i] = crypt[i+RC4_IV_LEN] ^ rc4_getbyte( st );
-	clear[0][i] = 0; /* Nice to have for plaintexts. */
-	
-	g_free( st );
-	
-	return clear_len;
-}
Index: b/rc4.h
===================================================================
--- lib/rc4.h	(revision fef6116e89bb0651c72454effbb51e04e9e1b8dc)
+++ 	(revision )
@@ -1,34 +1,0 @@
-/***************************************************************************\
-*                                                                           *
-*  BitlBee - An IRC to IM gateway                                           *
-*  Simple (but secure) RC4 implementation for safer password storage.       *
-*                                                                           *
-*  Copyright 2006 Wilmer van der Gaast <wilmer@gaast.net>                   *
-*                                                                           *
-*  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     *
-*  the Free Software Foundation; either version 2 of the License, or        *
-*  (at your option) any later version.                                      *
-*                                                                           *
-*  This program is distributed in the hope that it will be useful,          *
-*  but WITHOUT ANY WARRANTY; without even the implied warranty of           *
-*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            *
-*  GNU General Public License for more details.                             *
-*                                                                           *
-*  You should have received a copy of the GNU General Public License along  *
-*  with this program; if not, write to the Free Software Foundation, Inc.,  *
-*  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.              *
-*                                                                           *
-\***************************************************************************/
-
-
-struct rc4_state
-{
-	unsigned char S[256];
-	unsigned char i, j;
-};
-
-struct rc4_state *rc4_keymaker( unsigned char *key, int kl, int cycles );
-unsigned char rc4_getbyte( struct rc4_state *st );
-int rc4_encode( unsigned char *clear, int clear_len, unsigned char **crypt, char *password );
-int rc4_decode( unsigned char *crypt, int crypt_len, unsigned char **clear, char *password );
Index: b/sha.c
===================================================================
--- lib/sha.c	(revision fef6116e89bb0651c72454effbb51e04e9e1b8dc)
+++ 	(revision )
@@ -1,173 +1,0 @@
-/* 
- * The contents of this file are subject to the Mozilla Public
- * License Version 1.1 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of
- * the License at http://www.mozilla.org/MPL/
- * 
- * Software distributed under the License is distributed on an "AS
- * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
- * implied. See the License for the specific language governing
- * rights and limitations under the License.
- * 
- * The Original Code is SHA 180-1 Reference Implementation (Compact version)
- * 
- * The Initial Developer of the Original Code is Paul Kocher of
- * Cryptography Research.  Portions created by Paul Kocher are 
- * Copyright (C) 1995-9 by Cryptography Research, Inc.  All
- * Rights Reserved.
- * 
- * Contributor(s):
- *
- */
-
-#define BITLBEE_CORE
-#include "nogaim.h"
-
-static void shaHashBlock(SHA_CTX *ctx);
-
-void shaInit(SHA_CTX *ctx) {
-  int i;
-
-  ctx->lenW = 0;
-  ctx->sizeHi = ctx->sizeLo = 0;
-
-  /* Initialize H with the magic constants (see FIPS180 for constants)
-   */
-  ctx->H[0] = 0x67452301L;
-  ctx->H[1] = 0xefcdab89L;
-  ctx->H[2] = 0x98badcfeL;
-  ctx->H[3] = 0x10325476L;
-  ctx->H[4] = 0xc3d2e1f0L;
-
-  for (i = 0; i < 80; i++)
-    ctx->W[i] = 0;
-}
-
-
-void shaUpdate(SHA_CTX *ctx, unsigned char *dataIn, int len) {
-  int i;
-
-  /* Read the data into W and process blocks as they get full
-   */
-  for (i = 0; i < len; i++) {
-    ctx->W[ctx->lenW / 4] <<= 8;
-    ctx->W[ctx->lenW / 4] |= (guint32)dataIn[i];
-    if ((++ctx->lenW) % 64 == 0) {
-      shaHashBlock(ctx);
-      ctx->lenW = 0;
-    }
-    ctx->sizeLo += 8;
-    ctx->sizeHi += (ctx->sizeLo < 8);
-  }
-}
-
-
-void shaFinal(SHA_CTX *ctx, unsigned char hashout[20]) {
-  unsigned char pad0x80 = 0x80;
-  unsigned char pad0x00 = 0x00;
-  unsigned char padlen[8];
-  int i;
-
-  /* Pad with a binary 1 (e.g. 0x80), then zeroes, then length
-   */
-  padlen[0] = (unsigned char)((ctx->sizeHi >> 24) & 255);
-  padlen[1] = (unsigned char)((ctx->sizeHi >> 16) & 255);
-  padlen[2] = (unsigned char)((ctx->sizeHi >> 8) & 255);
-  padlen[3] = (unsigned char)((ctx->sizeHi >> 0) & 255);
-  padlen[4] = (unsigned char)((ctx->sizeLo >> 24) & 255);
-  padlen[5] = (unsigned char)((ctx->sizeLo >> 16) & 255);
-  padlen[6] = (unsigned char)((ctx->sizeLo >> 8) & 255);
-  padlen[7] = (unsigned char)((ctx->sizeLo >> 0) & 255);
-  shaUpdate(ctx, &pad0x80, 1);
-  while (ctx->lenW != 56)
-    shaUpdate(ctx, &pad0x00, 1);
-  shaUpdate(ctx, padlen, 8);
-
-  /* Output hash
-   */
-  for (i = 0; i < 20; i++) {
-    hashout[i] = (unsigned char)(ctx->H[i / 4] >> 24);
-    ctx->H[i / 4] <<= 8;
-  }
-
-  /*
-   *  Re-initialize the context (also zeroizes contents)
-   */
-  shaInit(ctx); 
-}
-
-
-void shaBlock(unsigned char *dataIn, int len, unsigned char hashout[20]) {
-  SHA_CTX ctx;
-
-  shaInit(&ctx);
-  shaUpdate(&ctx, dataIn, len);
-  shaFinal(&ctx, hashout);
-}
-
-
-#define SHA_ROTL(X,n) ((((X) << (n)) | ((X) >> (32-(n)))) & 0xffffffffL)
-
-static void shaHashBlock(SHA_CTX *ctx) {
-  int t;
-  guint32 A,B,C,D,E,TEMP;
-
-  for (t = 16; t <= 79; t++)
-    ctx->W[t] =
-      SHA_ROTL(ctx->W[t-3] ^ ctx->W[t-8] ^ ctx->W[t-14] ^ ctx->W[t-16], 1);
-
-  A = ctx->H[0];
-  B = ctx->H[1];
-  C = ctx->H[2];
-  D = ctx->H[3];
-  E = ctx->H[4];
-
-  for (t = 0; t <= 19; t++) {
-    TEMP = (SHA_ROTL(A,5) + (((C^D)&B)^D)     + E + ctx->W[t] + 0x5a827999L) & 0xffffffffL;
-    E = D; D = C; C = SHA_ROTL(B, 30); B = A; A = TEMP;
-  }
-  for (t = 20; t <= 39; t++) {
-    TEMP = (SHA_ROTL(A,5) + (B^C^D)           + E + ctx->W[t] + 0x6ed9eba1L) & 0xffffffffL;
-    E = D; D = C; C = SHA_ROTL(B, 30); B = A; A = TEMP;
-  }
-  for (t = 40; t <= 59; t++) {
-    TEMP = (SHA_ROTL(A,5) + ((B&C)|(D&(B|C))) + E + ctx->W[t] + 0x8f1bbcdcL) & 0xffffffffL;
-    E = D; D = C; C = SHA_ROTL(B, 30); B = A; A = TEMP;
-  }
-  for (t = 60; t <= 79; t++) {
-    TEMP = (SHA_ROTL(A,5) + (B^C^D)           + E + ctx->W[t] + 0xca62c1d6L) & 0xffffffffL;
-    E = D; D = C; C = SHA_ROTL(B, 30); B = A; A = TEMP;
-  }
-
-  ctx->H[0] += A;
-  ctx->H[1] += B;
-  ctx->H[2] += C;
-  ctx->H[3] += D;
-  ctx->H[4] += E;
-}
-
-/*----------------------------------------------------------------------------
- *
- * This code added by Thomas "temas" Muldowney for Jabber compatability
- *
- *---------------------------------------------------------------------------*/
-char *shahash(char *str)
-{
-    static char final[41];
-    char *pos;
-    unsigned char hashval[20];
-    int x;
-
-    if(!str || strlen(str) == 0)
-        return NULL;
-
-    shaBlock((unsigned char *)str, strlen(str), hashval);
-
-    pos = final;
-    for(x=0;x<20;x++)
-    {
-        g_snprintf(pos, 3, "%02x", hashval[x]);
-        pos += 2;
-    }
-    return (char *)final;
-}
Index: b/sha.h
===================================================================
--- lib/sha.h	(revision fef6116e89bb0651c72454effbb51e04e9e1b8dc)
+++ 	(revision )
@@ -1,21 +1,0 @@
-#ifndef __SHA_H__
-#define __SHA_H__
-
-#include <gmodule.h>
-
-G_MODULE_EXPORT int strprintsha(char *dest, int *hashval);
- 
-typedef struct {
-  guint32 H[5];
-  guint32 W[80];
-  int lenW;
-  guint32 sizeHi,sizeLo;
-} SHA_CTX;
- 
-G_MODULE_EXPORT void shaInit(SHA_CTX *ctx);
-G_MODULE_EXPORT void shaUpdate(SHA_CTX *ctx, unsigned char *dataIn, int len);
-G_MODULE_EXPORT void shaFinal(SHA_CTX *ctx, unsigned char hashout[20]);
-G_MODULE_EXPORT void shaBlock(unsigned char *dataIn, int len, unsigned char hashout[20]);
-G_MODULE_EXPORT char *shahash(char *str);
-
-#endif
Index: b/ssl_bogus.c
===================================================================
--- lib/ssl_bogus.c	(revision fef6116e89bb0651c72454effbb51e04e9e1b8dc)
+++ 	(revision )
@@ -1,57 +1,0 @@
-  /********************************************************************\
-  * BitlBee -- An IRC to other IM-networks gateway                     *
-  *                                                                    *
-  * Copyright 2002-2004 Wilmer van der Gaast and others                *
-  \********************************************************************/
-
-/* SSL module - dummy version                                           */
-
-/*
-  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
-  the Free Software Foundation; either version 2 of the License, or
-  (at your option) any later version.
-
-  This program is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-  GNU General Public License for more details.
-
-  You should have received a copy of the GNU General Public License with
-  the Debian GNU/Linux distribution in /usr/share/common-licenses/GPL;
-  if not, write to the Free Software Foundation, Inc., 59 Temple Place,
-  Suite 330, Boston, MA  02111-1307  USA
-*/
-
-#include "ssl_client.h"
-
-int ssl_errno;
-
-void *ssl_connect( char *host, int port, ssl_input_function func, gpointer data )
-{
-	return( NULL );
-}
-
-int ssl_read( void *conn, char *buf, int len )
-{
-	return( -1 );
-}
-
-int ssl_write( void *conn, const char *buf, int len )
-{
-	return( -1 );
-}
-
-void ssl_disconnect( void *conn_ )
-{
-}
-
-int ssl_getfd( void *conn )
-{
-	return( -1 );
-}
-
-b_input_condition ssl_getdirection( void *conn )
-{
-	return GAIM_INPUT_READ;
-}
Index: b/ssl_client.h
===================================================================
--- lib/ssl_client.h	(revision fef6116e89bb0651c72454effbb51e04e9e1b8dc)
+++ 	(revision )
@@ -1,42 +1,0 @@
-  /********************************************************************\
-  * BitlBee -- An IRC to other IM-networks gateway                     *
-  *                                                                    *
-  * Copyright 2002-2004 Wilmer van der Gaast and others                *
-  \********************************************************************/
-
-/* SSL module                                                           */
-
-/*
-  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
-  the Free Software Foundation; either version 2 of the License, or
-  (at your option) any later version.
-
-  This program is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-  GNU General Public License for more details.
-
-  You should have received a copy of the GNU General Public License with
-  the Debian GNU/Linux distribution in /usr/share/common-licenses/GPL;
-  if not, write to the Free Software Foundation, Inc., 59 Temple Place,
-  Suite 330, Boston, MA  02111-1307  USA
-*/
-
-#include <glib.h>
-#include "proxy.h"
-
-#define SSL_OK            0
-#define SSL_NOHANDSHAKE   1
-#define SSL_AGAIN         2
-
-extern int ssl_errno;
-
-typedef gboolean (*ssl_input_function)(gpointer, void*, b_input_condition);
-
-G_MODULE_EXPORT void *ssl_connect( char *host, int port, ssl_input_function func, gpointer data );
-G_MODULE_EXPORT int ssl_read( void *conn, char *buf, int len );
-G_MODULE_EXPORT int ssl_write( void *conn, const char *buf, int len );
-G_MODULE_EXPORT void ssl_disconnect( void *conn_ );
-G_MODULE_EXPORT int ssl_getfd( void *conn );
-G_MODULE_EXPORT b_input_condition ssl_getdirection( void *conn );
Index: b/ssl_gnutls.c
===================================================================
--- lib/ssl_gnutls.c	(revision fef6116e89bb0651c72454effbb51e04e9e1b8dc)
+++ 	(revision )
@@ -1,206 +1,0 @@
-  /********************************************************************\
-  * BitlBee -- An IRC to other IM-networks gateway                     *
-  *                                                                    *
-  * Copyright 2002-2004 Wilmer van der Gaast and others                *
-  \********************************************************************/
-
-/* SSL module - GnuTLS version                                          */
-
-/*
-  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
-  the Free Software Foundation; either version 2 of the License, or
-  (at your option) any later version.
-
-  This program is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-  GNU General Public License for more details.
-
-  You should have received a copy of the GNU General Public License with
-  the Debian GNU/Linux distribution in /usr/share/common-licenses/GPL;
-  if not, write to the Free Software Foundation, Inc., 59 Temple Place,
-  Suite 330, Boston, MA  02111-1307  USA
-*/
-
-#include <gnutls/gnutls.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include "proxy.h"
-#include "ssl_client.h"
-#include "sock.h"
-#include "stdlib.h"
-
-int ssl_errno = 0;
-
-static gboolean initialized = FALSE;
-
-struct scd
-{
-	ssl_input_function func;
-	gpointer data;
-	int fd;
-	gboolean established;
-	int inpa;
-	
-	gnutls_session session;
-	gnutls_certificate_credentials xcred;
-};
-
-static gboolean ssl_connected( gpointer data, gint source, b_input_condition cond );
-
-
-void *ssl_connect( char *host, int port, ssl_input_function func, gpointer data )
-{
-	struct scd *conn = g_new0( struct scd, 1 );
-	
-	conn->fd = proxy_connect( host, port, ssl_connected, conn );
-	conn->func = func;
-	conn->data = data;
-	conn->inpa = -1;
-	
-	if( conn->fd < 0 )
-	{
-		g_free( conn );
-		return( NULL );
-	}
-	
-	if( !initialized )
-	{
-		gnutls_global_init();
-		initialized = TRUE;
-		atexit( gnutls_global_deinit );
-	}
-	
-	gnutls_certificate_allocate_credentials( &conn->xcred );
-	gnutls_init( &conn->session, GNUTLS_CLIENT );
-	gnutls_set_default_priority( conn->session );
-	gnutls_credentials_set( conn->session, GNUTLS_CRD_CERTIFICATE, conn->xcred );
-	
-	return( conn );
-}
-
-static gboolean ssl_handshake( gpointer data, gint source, b_input_condition cond );
-
-static gboolean ssl_connected( gpointer data, gint source, b_input_condition cond )
-{
-	struct scd *conn = data;
-	
-	if( source == -1 )
-	{
-		conn->func( conn->data, NULL, cond );
-		
-		gnutls_deinit( conn->session );
-		gnutls_certificate_free_credentials( conn->xcred );
-		
-		g_free( conn );
-		
-		return FALSE;
-	}
-	
-	sock_make_nonblocking( conn->fd );
-	gnutls_transport_set_ptr( conn->session, (gnutls_transport_ptr) conn->fd );
-	
-	return ssl_handshake( data, source, cond );
-}
-
-static gboolean ssl_handshake( gpointer data, gint source, b_input_condition cond )
-{
-	struct scd *conn = data;
-	int st;
-	
-	if( ( st = gnutls_handshake( conn->session ) ) < 0 )
-	{
-		if( st == GNUTLS_E_AGAIN || st == GNUTLS_E_INTERRUPTED )
-		{
-			conn->inpa = b_input_add( conn->fd, ssl_getdirection( conn ),
-			                          ssl_handshake, data );
-		}
-		else
-		{
-			conn->func( conn->data, NULL, cond );
-			
-			gnutls_deinit( conn->session );
-			gnutls_certificate_free_credentials( conn->xcred );
-			closesocket( conn->fd );
-			
-			g_free( conn );
-		}
-	}
-	else
-	{
-		/* For now we can't handle non-blocking perfectly everywhere... */
-		sock_make_blocking( conn->fd );
-		
-		conn->established = TRUE;
-		conn->func( conn->data, conn, cond );
-	}
-	
-	return FALSE;
-}
-
-int ssl_read( void *conn, char *buf, int len )
-{
-	int st;
-	
-	if( !((struct scd*)conn)->established )
-	{
-		ssl_errno = SSL_NOHANDSHAKE;
-		return( -1 );
-	}
-	
-	st = gnutls_record_recv( ((struct scd*)conn)->session, buf, len );
-	
-	ssl_errno = SSL_OK;
-	if( st == GNUTLS_E_AGAIN || st == GNUTLS_E_INTERRUPTED )
-		ssl_errno = SSL_AGAIN;
-	
-	return st;
-}
-
-int ssl_write( void *conn, const char *buf, int len )
-{
-	int st;
-	
-	if( !((struct scd*)conn)->established )
-	{
-		ssl_errno = SSL_NOHANDSHAKE;
-		return( -1 );
-	}
-	
-	st = gnutls_record_send( ((struct scd*)conn)->session, buf, len );
-	
-	ssl_errno = SSL_OK;
-	if( st == GNUTLS_E_AGAIN || st == GNUTLS_E_INTERRUPTED )
-		ssl_errno = SSL_AGAIN;
-	
-	return st;
-}
-
-void ssl_disconnect( void *conn_ )
-{
-	struct scd *conn = conn_;
-	
-	if( conn->inpa != -1 )
-		b_event_remove( conn->inpa );
-	
-	if( conn->established )
-		gnutls_bye( conn->session, GNUTLS_SHUT_WR );
-	
-	closesocket( conn->fd );
-	
-	gnutls_deinit( conn->session );
-	gnutls_certificate_free_credentials( conn->xcred );
-	g_free( conn );
-}
-
-int ssl_getfd( void *conn )
-{
-	return( ((struct scd*)conn)->fd );
-}
-
-b_input_condition ssl_getdirection( void *conn )
-{
-	return( gnutls_record_get_direction( ((struct scd*)conn)->session ) ?
-	        GAIM_INPUT_WRITE : GAIM_INPUT_READ );
-}
Index: b/ssl_nss.c
===================================================================
--- lib/ssl_nss.c	(revision fef6116e89bb0651c72454effbb51e04e9e1b8dc)
+++ 	(revision )
@@ -1,190 +1,0 @@
-  /********************************************************************\
-  * BitlBee -- An IRC to other IM-networks gateway                     *
-  *                                                                    *
-  * Copyright 2002-2005 Wilmer van der Gaast and others                *
-  \********************************************************************/
-
-/* SSL module - NSS version                                             */
-
-/* Copyright 2005 Jelmer Vernooij                                       */
-
-/*
-  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
-  the Free Software Foundation; either version 2 of the License, or
-  (at your option) any later version.
-
-  This program is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-  GNU General Public License for more details.
-
-  You should have received a copy of the GNU General Public License with
-  the Debian GNU/Linux distribution in /usr/share/common-licenses/GPL;
-  if not, write to the Free Software Foundation, Inc., 59 Temple Place,
-  Suite 330, Boston, MA  02111-1307  USA
-*/
-
-#include "bitlbee.h"
-#include "proxy.h"
-#include "ssl_client.h"
-#include "sock.h"
-#include <nspr.h>
-#include <prio.h>
-#include <sslproto.h>
-#include <nss.h>
-#include <private/pprio.h>
-#include <ssl.h>
-#include <secerr.h>
-#include <sslerr.h>
-
-int ssl_errno = 0;
-
-static gboolean initialized = FALSE;
-
-struct scd
-{
-	ssl_input_function func;
-	gpointer data;
-	int fd;
-	PRFileDesc *prfd;
-	gboolean established;
-};
-
-static gboolean ssl_connected( gpointer data, gint source, b_input_condition cond );
-
-
-static SECStatus nss_auth_cert (void *arg, PRFileDesc *socket, PRBool checksig, PRBool isserver)
-{
-	return SECSuccess;
-}
-
-static SECStatus nss_bad_cert (void *arg, PRFileDesc *socket) 
-{
-	PRErrorCode err;
-
-	if(!arg) return SECFailure;
-
-	*(PRErrorCode *)arg = err = PORT_GetError();
-
-	switch(err) {
-	case SEC_ERROR_INVALID_AVA:
-	case SEC_ERROR_INVALID_TIME:
-	case SEC_ERROR_BAD_SIGNATURE:
-	case SEC_ERROR_EXPIRED_CERTIFICATE:
-	case SEC_ERROR_UNKNOWN_ISSUER:
-	case SEC_ERROR_UNTRUSTED_CERT:
-	case SEC_ERROR_CERT_VALID:
-	case SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE:
-	case SEC_ERROR_CRL_EXPIRED:
-	case SEC_ERROR_CRL_BAD_SIGNATURE:
-	case SEC_ERROR_EXTENSION_VALUE_INVALID:
-	case SEC_ERROR_CA_CERT_INVALID:
-	case SEC_ERROR_CERT_USAGES_INVALID:
-	case SEC_ERROR_UNKNOWN_CRITICAL_EXTENSION:
-		return SECSuccess;
-
-	default:
-		return SECFailure;
-	}
-}
-
-
-void *ssl_connect( char *host, int port, ssl_input_function func, gpointer data )
-{
-	struct scd *conn = g_new0( struct scd, 1 );
-	
-	conn->fd = proxy_connect( host, port, ssl_connected, conn );
-	conn->func = func;
-	conn->data = data;
-	
-	if( conn->fd < 0 )
-	{
-		g_free( conn );
-		return( NULL );
-	}
-	
-	if( !initialized )
-	{
-		PR_Init( PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1);
-		NSS_NoDB_Init(NULL);
-		NSS_SetDomesticPolicy();
-	}
-
-	
-	return( conn );
-}
-
-static gboolean ssl_connected( gpointer data, gint source, b_input_condition cond )
-{
-	struct scd *conn = data;
-	
-	if( source == -1 )
-		goto ssl_connected_failure;
-	
-	/* Until we find out how to handle non-blocking I/O with NSS... */
-	sock_make_blocking( conn->fd );
-	
-	conn->prfd = SSL_ImportFD(NULL, PR_ImportTCPSocket(source));
-	SSL_OptionSet(conn->prfd, SSL_SECURITY, PR_TRUE);
-	SSL_OptionSet(conn->prfd, SSL_HANDSHAKE_AS_CLIENT, PR_TRUE);
-	SSL_BadCertHook(conn->prfd, (SSLBadCertHandler)nss_bad_cert, NULL);
-	SSL_AuthCertificateHook(conn->prfd, (SSLAuthCertificate)nss_auth_cert, (void *)CERT_GetDefaultCertDB());
-	SSL_ResetHandshake(conn->prfd, PR_FALSE);
-
-	if (SSL_ForceHandshake(conn->prfd)) {
-		goto ssl_connected_failure;
-	}
-	
-	
-	conn->established = TRUE;
-	conn->func( conn->data, conn, cond );
-	return FALSE;
-	
-	ssl_connected_failure:
-	
-	conn->func( conn->data, NULL, cond );
-	
-	PR_Close( conn -> prfd );
-	if( source >= 0 ) closesocket( source );
-	g_free( conn );
-	
-	return FALSE;
-}
-
-int ssl_read( void *conn, char *buf, int len )
-{
-	if( !((struct scd*)conn)->established )
-		return( 0 );
-	
-	return( PR_Read( ((struct scd*)conn)->prfd, buf, len ) );
-}
-
-int ssl_write( void *conn, const char *buf, int len )
-{
-	if( !((struct scd*)conn)->established )
-		return( 0 );
-	
-	return( PR_Write ( ((struct scd*)conn)->prfd, buf, len ) );
-}
-
-void ssl_disconnect( void *conn_ )
-{
-	struct scd *conn = conn_;
-	
-	PR_Close( conn->prfd );
-	closesocket( conn->fd );
-	
-	g_free( conn );
-}
-
-int ssl_getfd( void *conn )
-{
-	return( ((struct scd*)conn)->fd );
-}
-
-b_input_condition ssl_getdirection( void *conn )
-{
-	/* Just in case someone calls us, let's return the most likely case: */
-	return GAIM_INPUT_READ;
-}
Index: b/ssl_openssl.c
===================================================================
--- lib/ssl_openssl.c	(revision fef6116e89bb0651c72454effbb51e04e9e1b8dc)
+++ 	(revision )
@@ -1,221 +1,0 @@
-  /********************************************************************\
-  * BitlBee -- An IRC to other IM-networks gateway                     *
-  *                                                                    *
-  * Copyright 2002-2004 Wilmer van der Gaast and others                *
-  \********************************************************************/
-
-/* SSL module - OpenSSL version                                         */
-
-/*
-  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
-  the Free Software Foundation; either version 2 of the License, or
-  (at your option) any later version.
-
-  This program is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-  GNU General Public License for more details.
-
-  You should have received a copy of the GNU General Public License with
-  the Debian GNU/Linux distribution in /usr/share/common-licenses/GPL;
-  if not, write to the Free Software Foundation, Inc., 59 Temple Place,
-  Suite 330, Boston, MA  02111-1307  USA
-*/
-
-#include <openssl/crypto.h>
-#include <openssl/rand.h>
-#include <openssl/x509.h>
-#include <openssl/pem.h>
-#include <openssl/ssl.h>
-#include <openssl/err.h>
-
-#include "proxy.h"
-#include "ssl_client.h"
-#include "sock.h"
-
-int ssl_errno = 0;
-
-static gboolean initialized = FALSE;
-
-struct scd
-{
-	ssl_input_function func;
-	gpointer data;
-	int fd;
-	gboolean established;
-	
-	int inpa;
-	int lasterr;		/* Necessary for SSL_get_error */
-	SSL *ssl;
-	SSL_CTX *ssl_ctx;
-};
-
-static gboolean ssl_connected( gpointer data, gint source, b_input_condition cond );
-
-
-void *ssl_connect( char *host, int port, ssl_input_function func, gpointer data )
-{
-	struct scd *conn = g_new0( struct scd, 1 );
-	SSL_METHOD *meth;
-	
-	conn->fd = proxy_connect( host, port, ssl_connected, conn );
-	conn->func = func;
-	conn->data = data;
-	
-	if( conn->fd < 0 )
-	{
-		g_free( conn );
-		return( NULL );
-	}
-	
-	if( !initialized )
-	{
-		initialized = TRUE;
-		SSLeay_add_ssl_algorithms();
-	}
-	
-	meth = TLSv1_client_method();
-	conn->ssl_ctx = SSL_CTX_new( meth );
-	if( conn->ssl_ctx == NULL )
-	{
-		conn->fd = -1;
-		return( NULL );
-	}
-	
-	conn->ssl = SSL_new( conn->ssl_ctx );
-	if( conn->ssl == NULL )
-	{
-		conn->fd = -1;
-		return( NULL );
-	}
-	
-	return( conn );
-}
-
-static gboolean ssl_handshake( gpointer data, gint source, b_input_condition cond );
-
-static gboolean ssl_connected( gpointer data, gint source, b_input_condition cond )
-{
-	struct scd *conn = data;
-	
-	if( source == -1 )
-		return ssl_handshake( data, -1, cond );
-	
-	/* We can do at least the handshake with non-blocking I/O */
-	sock_make_nonblocking( conn->fd );
-	SSL_set_fd( conn->ssl, conn->fd );
-	
-	return ssl_handshake( data, source, cond );
-}	
-
-static gboolean ssl_handshake( gpointer data, gint source, b_input_condition cond )
-{
-	struct scd *conn = data;
-	int st;
-	
-	if( ( st = SSL_connect( conn->ssl ) ) < 0 )
-	{
-		conn->lasterr = SSL_get_error( conn->ssl, st );
-		if( conn->lasterr != SSL_ERROR_WANT_READ && conn->lasterr != SSL_ERROR_WANT_WRITE )
-			goto ssl_connected_failure;
-		
-		conn->inpa = b_input_add( conn->fd, ssl_getdirection( conn ), ssl_handshake, data );
-		return FALSE;
-	}
-	
-	conn->established = TRUE;
-	sock_make_blocking( conn->fd );		/* For now... */
-	conn->func( conn->data, conn, cond );
-	return FALSE;
-	
-ssl_connected_failure:
-	conn->func( conn->data, NULL, cond );
-	
-	if( conn->ssl )
-	{
-		SSL_shutdown( conn->ssl );
-		SSL_free( conn->ssl );
-	}
-	if( conn->ssl_ctx )
-	{
-		SSL_CTX_free( conn->ssl_ctx );
-	}
-	if( source >= 0 ) closesocket( source );
-	g_free( conn );
-	
-	return FALSE;
-}
-
-int ssl_read( void *conn, char *buf, int len )
-{
-	int st;
-	
-	if( !((struct scd*)conn)->established )
-	{
-		ssl_errno = SSL_NOHANDSHAKE;
-		return -1;
-	}
-	
-	st = SSL_read( ((struct scd*)conn)->ssl, buf, len );
-	
-	ssl_errno = SSL_OK;
-	if( st <= 0 )
-	{
-		((struct scd*)conn)->lasterr = SSL_get_error( ((struct scd*)conn)->ssl, st );
-		if( ((struct scd*)conn)->lasterr == SSL_ERROR_WANT_READ || ((struct scd*)conn)->lasterr == SSL_ERROR_WANT_WRITE )
-			ssl_errno = SSL_AGAIN;
-	}
-	
-	return st;
-}
-
-int ssl_write( void *conn, const char *buf, int len )
-{
-	int st;
-	
-	if( !((struct scd*)conn)->established )
-	{
-		ssl_errno = SSL_NOHANDSHAKE;
-		return -1;
-	}
-	
-	st = SSL_write( ((struct scd*)conn)->ssl, buf, len );
-	
-	ssl_errno = SSL_OK;
-	if( st <= 0 )
-	{
-		((struct scd*)conn)->lasterr = SSL_get_error( ((struct scd*)conn)->ssl, st );
-		if( ((struct scd*)conn)->lasterr == SSL_ERROR_WANT_READ || ((struct scd*)conn)->lasterr == SSL_ERROR_WANT_WRITE )
-			ssl_errno = SSL_AGAIN;
-	}
-	
-	return st;
-}
-
-void ssl_disconnect( void *conn_ )
-{
-	struct scd *conn = conn_;
-	
-	if( conn->inpa != -1 )
-		b_event_remove( conn->inpa );
-	
-	if( conn->established )
-		SSL_shutdown( conn->ssl );
-	
-	closesocket( conn->fd );
-	
-	SSL_free( conn->ssl );
-	SSL_CTX_free( conn->ssl_ctx );
-	g_free( conn );
-}
-
-int ssl_getfd( void *conn )
-{
-	return( ((struct scd*)conn)->fd );
-}
-
-b_input_condition ssl_getdirection( void *conn )
-{
-	return( ((struct scd*)conn)->lasterr == SSL_ERROR_WANT_WRITE ? GAIM_INPUT_WRITE : GAIM_INPUT_READ );
-}
Index: b/url.c
===================================================================
--- lib/url.c	(revision fef6116e89bb0651c72454effbb51e04e9e1b8dc)
+++ 	(revision )
@@ -1,107 +1,0 @@
-  /********************************************************************\
-  * BitlBee -- An IRC to other IM-networks gateway                     *
-  *                                                                    *
-  * Copyright 2001-2005 Wilmer van der Gaast and others                *
-  \********************************************************************/
-
-/* URL/mirror stuff - Stolen from Axel                                  */
-
-/*
-  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
-  the Free Software Foundation; either version 2 of the License, or
-  (at your option) any later version.
-
-  This program is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-  GNU General Public License for more details.
-
-  You should have received a copy of the GNU General Public License with
-  the Debian GNU/Linux distribution in /usr/share/common-licenses/GPL;
-  if not, write to the Free Software Foundation, Inc., 59 Temple Place,
-  Suite 330, Boston, MA  02111-1307  USA
-*/
-
-#include "url.h"
-
-/* Convert an URL to a url_t structure					*/
-int url_set( url_t *url, char *set_url )
-{
-	char s[MAX_STRING];
-	char *i;
-	
-	/* protocol://							*/
-	if( ( i = strstr( set_url, "://" ) ) == NULL )
-	{
-		url->proto = PROTO_DEFAULT;
-		strncpy( s, set_url, MAX_STRING );
-	}
-	else
-	{
-		if( g_strncasecmp( set_url, "http", i - set_url ) == 0 )
-			url->proto = PROTO_HTTP;
-		else if( g_strncasecmp( set_url, "https", i - set_url ) == 0 )
-			url->proto = PROTO_HTTPS;
-		else if( g_strncasecmp( set_url, "socks4", i - set_url ) == 0 )
-			url->proto = PROTO_SOCKS4;
-		else if( g_strncasecmp( set_url, "socks5", i - set_url ) == 0 )
-			url->proto = PROTO_SOCKS5;
-		else
-		{
-			return( 0 );
-		}
-		strncpy( s, i + 3, MAX_STRING );
-	}
-	
-	/* Split							*/
-	if( ( i = strchr( s, '/' ) ) == NULL )
-	{
-		strcpy( url->file, "/" );
-	}
-	else
-	{
-		strncpy( url->file, i, MAX_STRING );
-		*i = 0;
-	}
-	strncpy( url->host, s, MAX_STRING );
-	
-	/* Check for username in host field				*/
-	if( strrchr( url->host, '@' ) != NULL )
-	{
-		strncpy( url->user, url->host, MAX_STRING );
-		i = strrchr( url->user, '@' );
-		*i = 0;
-		strcpy( url->host, i + 1 );
-		*url->pass = 0;
-	}
-	/* If not: Fill in defaults					*/
-	else
-	{
-		*url->user = *url->pass = 0;
-	}
-	
-	/* Password?							*/
-	if( ( i = strchr( url->user, ':' ) ) != NULL )
-	{
-		*i = 0;
-		strcpy( url->pass, i + 1 );
-	}
-	/* Port number?							*/
-	if( ( i = strchr( url->host, ':' ) ) != NULL )
-	{
-		*i = 0;
-		sscanf( i + 1, "%d", &url->port );
-	}
-	else
-	{
-		if( url->proto == PROTO_HTTP )
-			url->port = 80;
-		else if( url->proto == PROTO_HTTPS )
-			url->port = 443;
-		else if( url->proto == PROTO_SOCKS4 || url->proto == PROTO_SOCKS4 )
-			url->port = 1080;
-	}
-	
-	return( url->port > 0 );
-}
Index: b/url.h
===================================================================
--- lib/url.h	(revision fef6116e89bb0651c72454effbb51e04e9e1b8dc)
+++ 	(revision )
@@ -1,44 +1,0 @@
-  /********************************************************************\
-  * BitlBee -- An IRC to other IM-networks gateway                     *
-  *                                                                    *
-  * Copyright 2001-2004 Wilmer van der Gaast and others                *
-  \********************************************************************/
-
-/* URL/mirror stuff - Stolen from Axel                                  */
-
-/*
-  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
-  the Free Software Foundation; either version 2 of the License, or
-  (at your option) any later version.
-
-  This program is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-  GNU General Public License for more details.
-
-  You should have received a copy of the GNU General Public License with
-  the Debian GNU/Linux distribution in /usr/share/common-licenses/GPL;
-  if not, write to the Free Software Foundation, Inc., 59 Temple Place,
-  Suite 330, Boston, MA  02111-1307  USA
-*/
-
-#include "bitlbee.h"
-
-#define PROTO_HTTP		2
-#define PROTO_HTTPS		5
-#define PROTO_SOCKS4	3
-#define PROTO_SOCKS5	4
-#define PROTO_DEFAULT	PROTO_HTTP
-
-typedef struct url
-{
-	int proto;
-	int port;
-	char host[MAX_STRING];
-	char file[MAX_STRING];
-	char user[MAX_STRING];
-	char pass[MAX_STRING];
-} url_t;
-
-int url_set( url_t *url, char *set_url );
Index: nick.c
===================================================================
--- nick.c	(revision fef6116e89bb0651c72454effbb51e04e9e1b8dc)
+++ nick.c	(revision 3f9440db856c1b1cde54eb919543cfc23ea09983)
@@ -86,5 +86,5 @@
 		
 		nick_strip( nick );
-		if( set_getint( &irc->set, "lcnicks" ) )
+		if (set_getint(irc, "lcnicks")) 
 			nick_lc( nick );
 	}
Index: protocols/Makefile
===================================================================
--- protocols/Makefile	(revision fef6116e89bb0651c72454effbb51e04e9e1b8dc)
+++ protocols/Makefile	(revision 3f9440db856c1b1cde54eb919543cfc23ea09983)
@@ -10,5 +10,5 @@
 
 # [SH] Program variables
-objects = nogaim.o
+objects = $(EVENT_HANDLER) http_client.o md5.o nogaim.o proxy.o sha.o $(SSL_CLIENT)
 
 # [SH] The next two lines should contain the directory name (in $(subdirs))
Index: protocols/events.h
===================================================================
--- protocols/events.h	(revision 3f9440db856c1b1cde54eb919543cfc23ea09983)
+++ protocols/events.h	(revision 3f9440db856c1b1cde54eb919543cfc23ea09983)
@@ -0,0 +1,66 @@
+/*
+ * nogaim
+ *
+ * Copyright (C) 2006 Wilmer van der Gaast and others
+ *
+ * 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
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+/*
+ * Split off the event handling things from proxy.[ch] (and adding timer
+ * stuff. This to allow BitlBee to use other libs than GLib for event
+ * handling.
+ */
+
+
+#ifndef _EVENTS_H_
+#define _EVENTS_H_
+
+#include <sys/types.h>
+#ifndef _WIN32
+#include <sys/socket.h>
+#include <netdb.h>
+#include <netinet/in.h>
+#endif
+#include <glib.h>
+#include <gmodule.h>
+
+typedef enum {
+	GAIM_INPUT_READ = 1 << 1,
+	GAIM_INPUT_WRITE = 1 << 2
+} b_input_condition;
+typedef gboolean (*b_event_handler)(gpointer data, gint fd, b_input_condition cond);
+
+#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)
+#define GAIM_ERR_COND   (G_IO_HUP | G_IO_ERR | G_IO_NVAL)
+
+// #define event_debug( x... ) printf( x )
+#define event_debug( x... )
+
+G_MODULE_EXPORT void b_main_init();
+G_MODULE_EXPORT void b_main_run();
+G_MODULE_EXPORT void b_main_quit();
+
+G_MODULE_EXPORT gint b_input_add(int fd, b_input_condition cond, b_event_handler func, gpointer data);
+G_MODULE_EXPORT gint b_timeout_add(gint timeout, b_event_handler func, gpointer data);
+G_MODULE_EXPORT void b_event_remove(gint id);
+
+#ifdef EVENTS_LIBEVENT
+G_MODULE_EXPORT void closesocket(int fd);
+#endif
+
+#endif /* _EVENTS_H_ */
Index: protocols/events_glib.c
===================================================================
--- protocols/events_glib.c	(revision 3f9440db856c1b1cde54eb919543cfc23ea09983)
+++ protocols/events_glib.c	(revision 3f9440db856c1b1cde54eb919543cfc23ea09983)
@@ -0,0 +1,137 @@
+  /********************************************************************\
+  * BitlBee -- An IRC to other IM-networks gateway                     *
+  *                                                                    *
+  * Copyright 2002-2006 Wilmer van der Gaast and others                *
+  \********************************************************************/
+
+/*
+ * Event handling (using GLib)
+ */
+
+/*
+  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
+  the Free Software Foundation; either version 2 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License with
+  the Debian GNU/Linux distribution in /usr/share/common-licenses/GPL;
+  if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+  Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#define BITLBEE_CORE
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#ifndef _WIN32
+#include <sys/socket.h>
+#include <netdb.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <unistd.h>
+#else
+#include "sock.h"
+#define ETIMEDOUT WSAETIMEDOUT
+#define EINPROGRESS WSAEINPROGRESS
+#endif
+#include <fcntl.h>
+#include <errno.h>
+#include "proxy.h"
+
+typedef struct _GaimIOClosure {
+	b_event_handler function;
+	guint result;
+	gpointer data;
+} GaimIOClosure;
+
+static GMainLoop *loop;
+
+void b_main_init()
+{
+	loop = g_main_new( FALSE );
+}
+
+void b_main_run()
+{
+	g_main_run( loop );
+}
+
+void b_main_quit()
+{
+	g_main_quit( loop );
+}
+
+static gboolean gaim_io_invoke(GIOChannel *source, GIOCondition condition, gpointer data)
+{
+	GaimIOClosure *closure = data;
+	b_input_condition gaim_cond = 0;
+	gboolean st;
+
+	if (condition & GAIM_READ_COND)
+		gaim_cond |= GAIM_INPUT_READ;
+	if (condition & GAIM_WRITE_COND)
+		gaim_cond |= GAIM_INPUT_WRITE;
+	
+	event_debug( "gaim_io_invoke( %d, %d, 0x%x )\n", g_io_channel_unix_get_fd(source), condition, data );
+
+	st = closure->function(closure->data, g_io_channel_unix_get_fd(source), gaim_cond);
+	
+	if( !st )
+		event_debug( "Returned FALSE, cancelling.\n" );
+	
+	return st;
+}
+
+static void gaim_io_destroy(gpointer data)
+{
+	event_debug( "gaim_io_destroy( 0x%x )\n", data );
+	g_free(data);
+}
+
+gint b_input_add(gint source, b_input_condition condition, b_event_handler function, gpointer data)
+{
+	GaimIOClosure *closure = g_new0(GaimIOClosure, 1);
+	GIOChannel *channel;
+	GIOCondition cond = 0;
+	
+	closure->function = function;
+	closure->data = data;
+	
+	if (condition & GAIM_INPUT_READ)
+		cond |= GAIM_READ_COND;
+	if (condition & GAIM_INPUT_WRITE)
+		cond |= GAIM_WRITE_COND;
+	
+	channel = g_io_channel_unix_new(source);
+	closure->result = g_io_add_watch_full(channel, G_PRIORITY_DEFAULT, cond,
+					      gaim_io_invoke, closure, gaim_io_destroy);
+	
+	event_debug( "b_input_add( %d, %d, 0x%x, 0x%x ) = %d (0x%x)\n", source, condition, function, data, closure->result, closure );
+	
+	g_io_channel_unref(channel);
+	return closure->result;
+}
+
+gint b_timeout_add(gint timeout, b_event_handler func, gpointer data)
+{
+	gint st = g_timeout_add(timeout, func, data);
+	
+	event_debug( "b_timeout_add( %d, %d, %d ) = %d\n", timeout, func, data, st );
+	
+	return st;
+}
+
+void b_event_remove(gint tag)
+{
+	event_debug( "b_event_remove( %d )\n", tag );
+	
+	if (tag > 0)
+		g_source_remove(tag);
+}
Index: protocols/events_libevent.c
===================================================================
--- protocols/events_libevent.c	(revision 3f9440db856c1b1cde54eb919543cfc23ea09983)
+++ protocols/events_libevent.c	(revision 3f9440db856c1b1cde54eb919543cfc23ea09983)
@@ -0,0 +1,247 @@
+  /********************************************************************\
+  * BitlBee -- An IRC to other IM-networks gateway                     *
+  *                                                                    *
+  * Copyright 2002-2006 Wilmer van der Gaast and others                *
+  \********************************************************************/
+
+/*
+ * Event handling (using libevent)
+ */
+
+/*
+  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
+  the Free Software Foundation; either version 2 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License with
+  the Debian GNU/Linux distribution in /usr/share/common-licenses/GPL;
+  if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+  Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#define BITLBEE_CORE
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include "proxy.h"
+
+#include <sys/time.h>
+#include <event.h>
+
+static guint id_next;
+static GHashTable *id_hash;
+static int quitting = 0;
+
+/* Since libevent doesn't handle two event handlers for one fd-condition
+   very well (which happens sometimes when BitlBee changes event handlers
+   for a combination), let's buid some indexes so we can delete them here
+   already, just in time. */
+static GHashTable *read_hash;
+static GHashTable *write_hash;
+
+struct b_event_data
+{
+	guint id;
+	struct event evinfo;
+	gint timeout;
+	b_event_handler function;
+	void *data;
+};
+
+void b_main_init()
+{
+	event_init();
+	
+	id_next = 1;
+	id_hash = g_hash_table_new( g_int_hash, g_int_equal );
+	read_hash = g_hash_table_new( g_int_hash, g_int_equal );
+	write_hash = g_hash_table_new( g_int_hash, g_int_equal );
+}
+
+void b_main_run()
+{
+	event_dispatch();
+}
+
+void b_main_quit()
+{
+	struct timeval tv;
+	
+	/* libevent sometimes generates events before really quitting,
+	   we want to stop them. */
+	quitting = 1;
+	
+	memset( &tv, 0, sizeof( struct timeval ) );
+	event_loopexit( &tv );
+}
+
+static void b_event_passthrough( int fd, short event, void *data )
+{
+	struct b_event_data *b_ev = data;
+	b_input_condition cond = 0;
+	int id;
+	
+	if( fd >= 0 )
+	{
+		if( event & EV_READ )
+			cond |= GAIM_INPUT_READ;
+		if( event & EV_WRITE )
+			cond |= GAIM_INPUT_WRITE;
+	}
+	
+	event_debug( "b_event_passthrough( %d, %d, 0x%x ) (%d)\n", fd, event, (int) data, b_ev->id );
+	
+	/* Since the called function might cancel this handler already
+	   (which free()s b_ev, we have to remember the ID here. */
+	id = b_ev->id;
+	
+	if( quitting )
+	{
+		b_event_remove( id );
+		return;
+	}
+	
+	if( !b_ev->function( b_ev->data, fd, cond ) )
+	{
+		event_debug( "Handler returned FALSE: " );
+		b_event_remove( id );
+	}
+	else if( fd == -1 )
+	{
+		struct timeval tv;
+		
+		tv.tv_sec = b_ev->timeout / 1000;
+		tv.tv_usec = ( b_ev->timeout % 1000 ) * 1000;
+		
+		evtimer_add( &b_ev->evinfo, &tv );
+	}
+}
+
+gint b_input_add( gint fd, b_input_condition condition, b_event_handler function, gpointer data )
+{
+	struct b_event_data *b_ev;
+	
+	event_debug( "b_input_add( %d, %d, 0x%x, 0x%x ) ", fd, condition, function, data );
+	
+	if( ( condition & GAIM_INPUT_READ  && ( b_ev = g_hash_table_lookup( read_hash,  &fd ) ) ) ||
+	    ( condition & GAIM_INPUT_WRITE && ( b_ev = g_hash_table_lookup( write_hash, &fd ) ) ) )
+	{
+		/* We'll stick with this libevent entry, but give it a new BitlBee id. */
+		g_hash_table_remove( id_hash, &b_ev->id );
+		
+		event_debug( "(replacing old handler (id = %d)) = %d\n", b_ev->id, id_next );
+		
+		b_ev->id = id_next++;
+		b_ev->function = function;
+		b_ev->data = data;
+	}
+	else
+	{
+		GIOCondition out_cond;
+		
+		event_debug( "(new) = %d\n", id_next );
+		
+		b_ev = g_new0( struct b_event_data, 1 );
+		b_ev->id = id_next++;
+		b_ev->function = function;
+		b_ev->data = data;
+		
+		out_cond = EV_PERSIST;
+		if( condition & GAIM_INPUT_READ )
+			out_cond |= EV_READ;
+		if( condition & GAIM_INPUT_WRITE )
+			out_cond |= EV_WRITE;
+		
+		event_set( &b_ev->evinfo, fd, out_cond, b_event_passthrough, b_ev );
+		event_add( &b_ev->evinfo, NULL );
+		
+		if( out_cond & EV_READ )
+			g_hash_table_insert( read_hash, &b_ev->evinfo.ev_fd, b_ev );
+		if( out_cond & EV_WRITE )
+			g_hash_table_insert( write_hash, &b_ev->evinfo.ev_fd, b_ev );
+	}
+	
+	g_hash_table_insert( id_hash, &b_ev->id, b_ev );
+	return b_ev->id;
+}
+
+/* TODO: Persistence for timers! */
+gint b_timeout_add( gint timeout, b_event_handler function, gpointer data )
+{
+	struct b_event_data *b_ev = g_new0( struct b_event_data, 1 );
+	struct timeval tv;
+	
+	b_ev->id = id_next++;
+	b_ev->timeout = timeout;
+	b_ev->function = function;
+	b_ev->data = data;
+	
+	tv.tv_sec = timeout / 1000;
+	tv.tv_usec = ( timeout % 1000 ) * 1000;
+	
+	evtimer_set( &b_ev->evinfo, b_event_passthrough, b_ev );
+	evtimer_add( &b_ev->evinfo, &tv );
+	
+	event_debug( "b_timeout_add( %d, 0x%x, 0x%x ) = %d\n", timeout, function, data, b_ev->id );
+	
+	g_hash_table_insert( id_hash, &b_ev->id, b_ev );
+	
+	return b_ev->id;
+}
+
+void b_event_remove( gint id )
+{
+	struct b_event_data *b_ev = g_hash_table_lookup( id_hash, &id );
+	
+	event_debug( "b_event_remove( %d )\n", id );
+	if( b_ev )
+	{
+		g_hash_table_remove( id_hash, &b_ev->id );
+		if( b_ev->evinfo.ev_fd >= 0 )
+		{
+			if( b_ev->evinfo.ev_events & EV_READ )
+				g_hash_table_remove( read_hash, &b_ev->evinfo.ev_fd );
+			if( b_ev->evinfo.ev_events & EV_WRITE )
+				g_hash_table_remove( write_hash, &b_ev->evinfo.ev_fd );
+		}
+		
+		event_del( &b_ev->evinfo );
+		g_free( b_ev );
+	}
+	else
+	{
+		event_debug( "Already removed?\n" );
+	}
+}
+
+void closesocket( int fd )
+{
+	struct b_event_data *b_ev;
+	
+	/* Since epoll() (the main reason we use libevent) automatically removes sockets from
+	   the epoll() list when a socket gets closed and some modules have a habit of
+	   closing sockets before removing event handlers, our and libevent's administration
+	   get a little bit messed up. So this little function will remove the handlers
+	   properly before closing a socket. */
+	
+	if( ( b_ev = g_hash_table_lookup( read_hash, &fd ) ) )
+	{
+		event_debug( "Warning: fd %d still had a read event handler when shutting down.\n", fd );
+		b_event_remove( b_ev->id );
+	}
+	if( ( b_ev = g_hash_table_lookup( write_hash, &fd ) ) )
+	{
+		event_debug( "Warning: fd %d still had a write event handler when shutting down.\n", fd );
+		b_event_remove( b_ev->id );
+	}
+	
+	close( fd );
+}
Index: protocols/http_client.c
===================================================================
--- protocols/http_client.c	(revision 3f9440db856c1b1cde54eb919543cfc23ea09983)
+++ protocols/http_client.c	(revision 3f9440db856c1b1cde54eb919543cfc23ea09983)
@@ -0,0 +1,453 @@
+  /********************************************************************\
+  * BitlBee -- An IRC to other IM-networks gateway                     *
+  *                                                                    *
+  * Copyright 2002-2005 Wilmer van der Gaast and others                *
+  \********************************************************************/
+
+/* HTTP(S) module                                                       */
+
+/*
+  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
+  the Free Software Foundation; either version 2 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License with
+  the Debian GNU/Linux distribution in /usr/share/common-licenses/GPL;
+  if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+  Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include <string.h>
+#include <stdio.h>
+
+#include "http_client.h"
+#include "url.h"
+#include "sock.h"
+
+
+static gboolean http_connected( gpointer data, int source, b_input_condition cond );
+static gboolean http_ssl_connected( gpointer data, void *source, b_input_condition cond );
+static gboolean http_incoming_data( gpointer data, int source, b_input_condition cond );
+
+
+void *http_dorequest( char *host, int port, int ssl, char *request, http_input_function func, gpointer data )
+{
+	struct http_request *req;
+	int error = 0;
+	
+	req = g_new0( struct http_request, 1 );
+	
+	if( ssl )
+	{
+		req->ssl = ssl_connect( host, port, http_ssl_connected, req );
+		if( req->ssl == NULL )
+			error = 1;
+	}
+	else
+	{
+		req->fd = proxy_connect( host, port, http_connected, req );
+		if( req->fd < 0 )
+			error = 1;
+	}
+	
+	if( error )
+	{
+		g_free( req );
+		return( NULL );
+	}
+	
+	req->func = func;
+	req->data = data;
+	req->request = g_strdup( request );
+	req->request_length = strlen( request );
+	
+	return( req );
+}
+
+void *http_dorequest_url( char *url_string, http_input_function func, gpointer data )
+{
+	url_t *url = g_new0( url_t, 1 );
+	char *request;
+	void *ret;
+	
+	if( !url_set( url, url_string ) )
+	{
+		g_free( url );
+		return NULL;
+	}
+	
+	if( url->proto != PROTO_HTTP && url->proto != PROTO_HTTPS )
+	{
+		g_free( url );
+		return NULL;
+	}
+	
+	request = g_strdup_printf( "GET %s HTTP/1.0\r\n"
+	                           "Host: %s\r\n"
+	                           "User-Agent: BitlBee " BITLBEE_VERSION " " ARCH "/" CPU "\r\n"
+	                           "\r\n", url->file, url->host );
+	
+	ret = http_dorequest( url->host, url->port,
+	                      url->proto == PROTO_HTTPS, request, func, data );
+	
+	g_free( url );
+	g_free( request );
+	return ret;
+}
+
+/* This one is actually pretty simple... Might get more calls if we can't write 
+   the whole request at once. */
+static gboolean http_connected( gpointer data, int source, b_input_condition cond )
+{
+	struct http_request *req = data;
+	int st;
+	
+	if( source < 0 )
+		goto error;
+	
+	if( req->inpa > 0 )
+		b_event_remove( req->inpa );
+	
+	sock_make_nonblocking( req->fd );
+	
+	if( req->ssl )
+	{
+		st = ssl_write( req->ssl, req->request + req->bytes_written,
+		                req->request_length - req->bytes_written );
+		if( st < 0 )
+		{
+			if( ssl_errno != SSL_AGAIN )
+			{
+				ssl_disconnect( req->ssl );
+				goto error;
+			}
+		}
+	}
+	else
+	{
+		st = write( source, req->request + req->bytes_written,
+		                    req->request_length - req->bytes_written );
+		if( st < 0 )
+		{
+			if( !sockerr_again() )
+			{
+				closesocket( req->fd );
+				goto error;
+			}
+		}
+	}
+	
+	if( st > 0 )
+		req->bytes_written += st;
+	
+	if( req->bytes_written < req->request_length )
+		req->inpa = b_input_add( source,
+		                         req->ssl ? ssl_getdirection( req->ssl ) : GAIM_INPUT_WRITE,
+	        	                 http_connected, req );
+	else
+		req->inpa = b_input_add( source, GAIM_INPUT_READ, http_incoming_data, req );
+	
+	return FALSE;
+	
+error:
+	req->status_string = g_strdup( "Error while writing HTTP request" );
+	
+	req->func( req );
+	
+	g_free( req->request );
+	g_free( req );
+	
+	return FALSE;
+}
+
+static gboolean http_ssl_connected( gpointer data, void *source, b_input_condition cond )
+{
+	struct http_request *req = data;
+	
+	if( source == NULL )
+		return http_connected( data, -1, cond );
+	
+	req->fd = ssl_getfd( source );
+	
+	return http_connected( data, req->fd, cond );
+}
+
+static gboolean http_incoming_data( gpointer data, int source, b_input_condition cond )
+{
+	struct http_request *req = data;
+	int evil_server = 0;
+	char buffer[2048];
+	char *end1, *end2;
+	int st;
+	
+	if( req->inpa > 0 )
+		b_event_remove( req->inpa );
+	
+	if( req->ssl )
+	{
+		st = ssl_read( req->ssl, buffer, sizeof( buffer ) );
+		if( st < 0 )
+		{
+			if( ssl_errno != SSL_AGAIN )
+			{
+				/* goto cleanup; */
+				
+				/* YAY! We have to deal with crappy Microsoft
+				   servers that LOVE to send invalid TLS
+				   packets that abort connections! \o/ */
+				
+				goto got_reply;
+			}
+		}
+		else if( st == 0 )
+		{
+			goto got_reply;
+		}
+	}
+	else
+	{
+		st = read( req->fd, buffer, sizeof( buffer ) );
+		if( st < 0 )
+		{
+			if( !sockerr_again() )
+			{
+				req->status_string = g_strdup( strerror( errno ) );
+				goto cleanup;
+			}
+		}
+		else if( st == 0 )
+		{
+			goto got_reply;
+		}
+	}
+	
+	if( st > 0 )
+	{
+		req->reply_headers = g_realloc( req->reply_headers, req->bytes_read + st + 1 );
+		memcpy( req->reply_headers + req->bytes_read, buffer, st );
+		req->bytes_read += st;
+	}
+	
+	/* There will be more! */
+	req->inpa = b_input_add( req->fd,
+	                         req->ssl ? ssl_getdirection( req->ssl ) : GAIM_INPUT_READ,
+	                         http_incoming_data, req );
+	
+	return FALSE;
+
+got_reply:
+	/* Maybe if the webserver is overloaded, or when there's bad SSL
+	   support... */
+	if( req->bytes_read == 0 )
+	{
+		req->status_string = g_strdup( "Empty HTTP reply" );
+		goto cleanup;
+	}
+	
+	/* Zero termination is very convenient. */
+	req->reply_headers[req->bytes_read] = 0;
+	
+	/* Find the separation between headers and body, and keep stupid
+	   webservers in mind. */
+	end1 = strstr( req->reply_headers, "\r\n\r\n" );
+	end2 = strstr( req->reply_headers, "\n\n" );
+	
+	if( end2 && end2 < end1 )
+	{
+		end1 = end2 + 1;
+		evil_server = 1;
+	}
+	else if( end1 )
+	{
+		end1 += 2;
+	}
+	else
+	{
+		req->status_string = g_strdup( "Malformed HTTP reply" );
+		goto cleanup;
+	}
+	
+	*end1 = 0;
+	
+	if( evil_server )
+		req->reply_body = end1 + 1;
+	else
+		req->reply_body = end1 + 2;
+	
+	req->body_size = req->reply_headers + req->bytes_read - req->reply_body;
+	
+	if( ( end1 = strchr( req->reply_headers, ' ' ) ) != NULL )
+	{
+		if( sscanf( end1 + 1, "%d", &req->status_code ) != 1 )
+		{
+			req->status_string = g_strdup( "Can't parse status code" );
+			req->status_code = -1;
+		}
+		else
+		{
+			char *eol;
+			
+			if( evil_server )
+				eol = strchr( end1, '\n' );
+			else
+				eol = strchr( end1, '\r' );
+			
+			req->status_string = g_strndup( end1 + 1, eol - end1 - 1 );
+			
+			/* Just to be sure... */
+			if( ( eol = strchr( req->status_string, '\r' ) ) )
+				*eol = 0;
+			if( ( eol = strchr( req->status_string, '\n' ) ) )
+				*eol = 0;
+		}
+	}
+	else
+	{
+		req->status_string = g_strdup( "Can't locate status code" );
+		req->status_code = -1;
+	}
+	
+	if( req->status_code == 301 || req->status_code == 302 )
+	{
+		char *loc, *new_request, *new_host;
+		int error = 0, new_port, new_proto;
+		
+		/* We might fill it again, so let's not leak any memory. */
+		g_free( req->status_string );
+		req->status_string = NULL;
+		
+		loc = strstr( req->reply_headers, "\nLocation: " );
+		if( loc == NULL ) /* We can't handle this redirect... */
+		{
+			req->status_string = g_strdup( "Can't locate Location: header" );
+			goto cleanup;
+		}
+		
+		loc += 11;
+		while( *loc == ' ' )
+			loc ++;
+		
+		/* TODO/FIXME: Possibly have to handle relative redirections,
+		   and rewrite Host: headers. Not necessary for now, it's
+		   enough for passport authentication like this. */
+		
+		if( *loc == '/' )
+		{
+			/* Just a different pathname... */
+			
+			/* Since we don't cache the servername, and since we
+			   don't need this yet anyway, I won't implement it. */
+			
+			req->status_string = g_strdup( "Can't handle recursive redirects" );
+			
+			goto cleanup;
+		}
+		else
+		{
+			/* A whole URL */
+			url_t *url;
+			char *s;
+			
+			s = strstr( loc, "\r\n" );
+			if( s == NULL )
+				goto cleanup;
+			
+			url = g_new0( url_t, 1 );
+			*s = 0;
+			
+			if( !url_set( url, loc ) )
+			{
+				req->status_string = g_strdup( "Malformed redirect URL" );
+				g_free( url );
+				goto cleanup;
+			}
+			
+			/* Okay, this isn't fun! We have to rebuild the request... :-( */
+			new_request = g_malloc( req->request_length + strlen( url->file ) );
+			
+			/* So, now I just allocated enough memory, so I'm
+			   going to use strcat(), whether you like it or not. :-) */
+			
+			sprintf( new_request, "GET %s HTTP/1.0", url->file );
+			
+			s = strstr( req->request, "\r\n" );
+			if( s == NULL )
+			{
+				req->status_string = g_strdup( "Error while rebuilding request string" );
+				g_free( new_request );
+				g_free( url );
+				goto cleanup;
+			}
+			
+			strcat( new_request, s );
+			new_host = g_strdup( url->host );
+			new_port = url->port;
+			new_proto = url->proto;
+			
+			g_free( url );
+		}
+		
+		if( req->ssl )
+			ssl_disconnect( req->ssl );
+		else
+			closesocket( req->fd );
+		
+		req->fd = -1;
+		req->ssl = NULL;
+		
+		if( new_proto == PROTO_HTTPS )
+		{
+			req->ssl = ssl_connect( new_host, new_port, http_ssl_connected, req );
+			if( req->ssl == NULL )
+				error = 1;
+		}
+		else
+		{
+			req->fd = proxy_connect( new_host, new_port, http_connected, req );
+			if( req->fd < 0 )
+				error = 1;
+		}
+		g_free( new_host );
+		
+		if( error )
+		{
+			req->status_string = g_strdup( "Connection problem during redirect" );
+			g_free( new_request );
+			goto cleanup;
+		}
+		
+		g_free( req->request );
+		g_free( req->reply_headers );
+		req->request = new_request;
+		req->request_length = strlen( new_request );
+		req->bytes_read = req->bytes_written = req->inpa = 0;
+		req->reply_headers = req->reply_body = NULL;
+		
+		return FALSE;
+	}
+	
+	/* Assume that a closed connection means we're finished, this indeed
+	   breaks with keep-alive connections and faulty connections. */
+	req->finished = 1;
+
+cleanup:
+	if( req->ssl )
+		ssl_disconnect( req->ssl );
+	else
+		closesocket( req->fd );
+	
+	req->func( req );
+	
+	g_free( req->request );
+	g_free( req->reply_headers );
+	g_free( req->status_string );
+	g_free( req );
+	
+	return FALSE;
+}
Index: protocols/http_client.h
===================================================================
--- protocols/http_client.h	(revision 3f9440db856c1b1cde54eb919543cfc23ea09983)
+++ protocols/http_client.h	(revision 3f9440db856c1b1cde54eb919543cfc23ea09983)
@@ -0,0 +1,57 @@
+  /********************************************************************\
+  * BitlBee -- An IRC to other IM-networks gateway                     *
+  *                                                                    *
+  * Copyright 2002-2005 Wilmer van der Gaast and others                *
+  \********************************************************************/
+
+/* HTTP(S) module                                                       */
+
+/*
+  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
+  the Free Software Foundation; either version 2 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License with
+  the Debian GNU/Linux distribution in /usr/share/common-licenses/GPL;
+  if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+  Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include <glib.h>
+
+#include "ssl_client.h"
+
+struct http_request;
+
+typedef void (*http_input_function)( struct http_request * );
+
+struct http_request
+{
+	char *request;
+	int request_length;
+	int status_code;
+	char *status_string;
+	char *reply_headers;
+	char *reply_body;
+	int body_size;
+	int finished;
+	
+	void *ssl;
+	int fd;
+	
+	int inpa;
+	int bytes_written;
+	int bytes_read;
+	
+	http_input_function func;
+	gpointer data;
+};
+
+void *http_dorequest( char *host, int port, int ssl, char *request, http_input_function func, gpointer data );
+void *http_dorequest_url( char *url_string, http_input_function func, gpointer data );
Index: protocols/jabber/jabber.c
===================================================================
--- protocols/jabber/jabber.c	(revision fef6116e89bb0651c72454effbb51e04e9e1b8dc)
+++ protocols/jabber/jabber.c	(revision 3f9440db856c1b1cde54eb919543cfc23ea09983)
@@ -561,5 +561,5 @@
 static void gjab_start(gjconn gjc)
 {
-	account_t *acc;
+	struct aim_user *user;
 	int port = -1, ssl = 0;
 	char *server = NULL, *s;
@@ -568,9 +568,9 @@
 		return;
 
-	acc = GJ_GC(gjc)->acc;
-	if (acc->server) {
+	user = GJ_GC(gjc)->user;
+	if (*user->proto_opt[0]) {
 		/* If there's a dot, assume there's a hostname in the beginning */
-		if (strchr(acc->server, '.')) {
-			server = g_strdup(acc->server);
+		if (strchr(user->proto_opt[0], '.')) {
+			server = g_strdup(user->proto_opt[0]);
 			if ((s = strchr(server, ':')))
 				*s = 0;
@@ -578,10 +578,10 @@
 		
 		/* After the hostname, there can be a port number */
-		s = strchr(acc->server, ':');
+		s = strchr(user->proto_opt[0], ':');
 		if (s && isdigit(s[1]))
 			sscanf(s + 1, "%d", &port);
 		
 		/* And if there's the string ssl, the user wants an SSL-connection */
-		if (strstr(acc->server, ":ssl") || g_strcasecmp(acc->server, "ssl") == 0)
+		if (strstr(user->proto_opt[0], ":ssl") || g_strcasecmp(user->proto_opt[0], "ssl") == 0)
 			ssl = 1;
 	}
@@ -616,5 +616,5 @@
 	g_free(server);
 	
-	if (!acc->gc || (gjc->fd < 0)) {
+	if (!user->gc || (gjc->fd < 0)) {
 		STATE_EVT(JCONN_STATE_OFF)
 		return;
@@ -1516,9 +1516,9 @@
 }
 
-static void jabber_login(account_t *acc)
-{
-	struct gaim_connection *gc = new_gaim_conn(acc);
+static void jabber_login(struct aim_user *user)
+{
+	struct gaim_connection *gc = new_gaim_conn(user);
 	struct jabber_data *jd = gc->proto_data = g_new0(struct jabber_data, 1);
-	char *loginname = create_valid_jid(acc->user, DEFAULT_SERVER, "BitlBee");
+	char *loginname = create_valid_jid(user->username, DEFAULT_SERVER, "BitlBee");
 
 	jd->hash = g_hash_table_new(g_str_hash, g_str_equal);
@@ -1527,5 +1527,5 @@
 	set_login_progress(gc, 1, _("Connecting"));
 
-	if (!(jd->gjc = gjab_new(loginname, acc->pass, gc))) {
+	if (!(jd->gjc = gjab_new(loginname, user->password, gc))) {
 		g_free(loginname);
 		hide_login_progress(gc, _("Unable to connect"));
Index: protocols/md5.c
===================================================================
--- protocols/md5.c	(revision 3f9440db856c1b1cde54eb919543cfc23ea09983)
+++ protocols/md5.c	(revision 3f9440db856c1b1cde54eb919543cfc23ea09983)
@@ -0,0 +1,392 @@
+/*
+  Copyright (C) 1999 Aladdin Enterprises.  All rights reserved.
+
+  This software is provided 'as-is', without any express or implied
+  warranty.  In no event will the authors be held liable for any damages
+  arising from the use of this software.
+
+  Permission is granted to anyone to use this software for any purpose,
+  including commercial applications, and to alter it and redistribute it
+  freely, subject to the following restrictions:
+
+  1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+  2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+  3. This notice may not be removed or altered from any source distribution.
+
+  L. Peter Deutsch
+  ghost@aladdin.com
+
+ */
+/*
+  Independent implementation of MD5 (RFC 1321).
+
+  This code implements the MD5 Algorithm defined in RFC 1321.
+  It is derived directly from the text of the RFC and not from the
+  reference implementation.
+
+  The original and principal author of md5.c is L. Peter Deutsch
+  <ghost@aladdin.com>.  Other authors are noted in the change history
+  that follows (in reverse chronological order):
+
+  1999-11-04 lpd Edited comments slightly for automatic TOC extraction.
+  1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5).
+  1999-05-03 lpd Original version.
+ */
+
+#include "md5.h"
+#include <string.h>
+
+#ifdef TEST
+/*
+ * Compile with -DTEST to create a self-contained executable test program.
+ * The test program should print out the same values as given in section
+ * A.5 of RFC 1321, reproduced below.
+ */
+#include <string.h>
+main()
+{
+    static const char *const test[7] = {
+	"", /*d41d8cd98f00b204e9800998ecf8427e*/
+	"945399884.61923487334tuvga", /*0cc175b9c0f1b6a831c399e269772661*/
+	"abc", /*900150983cd24fb0d6963f7d28e17f72*/
+	"message digest", /*f96b697d7cb7938d525a2f31aaf161d0*/
+	"abcdefghijklmnopqrstuvwxyz", /*c3fcd3d76192e4007dfb496cca67e13b*/
+	"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
+				/*d174ab98d277d9f5a5611c2c9f419d9f*/
+	"12345678901234567890123456789012345678901234567890123456789012345678901234567890" /*57edf4a22be3c955ac49da2e2107b67a*/
+    };
+    int i;
+
+    for (i = 0; i < 7; ++i) {
+	md5_state_t state;
+	md5_byte_t digest[16];
+	int di;
+
+	md5_init(&state);
+	md5_append(&state, (const md5_byte_t *)test[i], strlen(test[i]));
+	md5_finish(&state, digest);
+	printf("MD5 (\"%s\") = ", test[i]);
+	for (di = 0; di < 16; ++di)
+	    printf("%02x", digest[di]);
+	printf("\n");
+    }
+    return 0;
+}
+#endif /* TEST */
+
+
+/*
+ * For reference, here is the program that computed the T values.
+ */
+#if 0
+#include <math.h>
+main()
+{
+    int i;
+    for (i = 1; i <= 64; ++i) {
+	unsigned long v = (unsigned long)(4294967296.0 * fabs(sin((double)i)));
+	printf("#define T%d 0x%08lx\n", i, v);
+    }
+    return 0;
+}
+#endif
+/*
+ * End of T computation program.
+ */
+#define T1 0xd76aa478
+#define T2 0xe8c7b756
+#define T3 0x242070db
+#define T4 0xc1bdceee
+#define T5 0xf57c0faf
+#define T6 0x4787c62a
+#define T7 0xa8304613
+#define T8 0xfd469501
+#define T9 0x698098d8
+#define T10 0x8b44f7af
+#define T11 0xffff5bb1
+#define T12 0x895cd7be
+#define T13 0x6b901122
+#define T14 0xfd987193
+#define T15 0xa679438e
+#define T16 0x49b40821
+#define T17 0xf61e2562
+#define T18 0xc040b340
+#define T19 0x265e5a51
+#define T20 0xe9b6c7aa
+#define T21 0xd62f105d
+#define T22 0x02441453
+#define T23 0xd8a1e681
+#define T24 0xe7d3fbc8
+#define T25 0x21e1cde6
+#define T26 0xc33707d6
+#define T27 0xf4d50d87
+#define T28 0x455a14ed
+#define T29 0xa9e3e905
+#define T30 0xfcefa3f8
+#define T31 0x676f02d9
+#define T32 0x8d2a4c8a
+#define T33 0xfffa3942
+#define T34 0x8771f681
+#define T35 0x6d9d6122
+#define T36 0xfde5380c
+#define T37 0xa4beea44
+#define T38 0x4bdecfa9
+#define T39 0xf6bb4b60
+#define T40 0xbebfbc70
+#define T41 0x289b7ec6
+#define T42 0xeaa127fa
+#define T43 0xd4ef3085
+#define T44 0x04881d05
+#define T45 0xd9d4d039
+#define T46 0xe6db99e5
+#define T47 0x1fa27cf8
+#define T48 0xc4ac5665
+#define T49 0xf4292244
+#define T50 0x432aff97
+#define T51 0xab9423a7
+#define T52 0xfc93a039
+#define T53 0x655b59c3
+#define T54 0x8f0ccc92
+#define T55 0xffeff47d
+#define T56 0x85845dd1
+#define T57 0x6fa87e4f
+#define T58 0xfe2ce6e0
+#define T59 0xa3014314
+#define T60 0x4e0811a1
+#define T61 0xf7537e82
+#define T62 0xbd3af235
+#define T63 0x2ad7d2bb
+#define T64 0xeb86d391
+
+static void
+md5_process(md5_state_t *pms, const md5_byte_t *data /*[64]*/)
+{
+    md5_word_t
+	a = pms->abcd[0], b = pms->abcd[1],
+	c = pms->abcd[2], d = pms->abcd[3];
+    md5_word_t t;
+
+#ifndef ARCH_IS_BIG_ENDIAN
+# define ARCH_IS_BIG_ENDIAN 1	/* slower, default implementation */
+#endif
+#if ARCH_IS_BIG_ENDIAN
+
+    /*
+     * On big-endian machines, we must arrange the bytes in the right
+     * order.  (This also works on machines of unknown byte order.)
+     */
+    md5_word_t X[16];
+    const md5_byte_t *xp = data;
+    int i;
+
+    for (i = 0; i < 16; ++i, xp += 4)
+	X[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24);
+
+#else  /* !ARCH_IS_BIG_ENDIAN */
+
+    /*
+     * On little-endian machines, we can process properly aligned data
+     * without copying it.
+     */
+    md5_word_t xbuf[16];
+    const md5_word_t *X;
+
+    if (!((data - (const md5_byte_t *)0) & 3)) {
+	/* data are properly aligned */
+	X = (const md5_word_t *)data;
+    } else {
+	/* not aligned */
+	memcpy(xbuf, data, 64);
+	X = xbuf;
+    }
+#endif
+
+#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
+
+    /* Round 1. */
+    /* Let [abcd k s i] denote the operation
+       a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */
+#define F(x, y, z) (((x) & (y)) | (~(x) & (z)))
+#define SET(a, b, c, d, k, s, Ti)\
+  t = a + F(b,c,d) + X[k] + Ti;\
+  a = ROTATE_LEFT(t, s) + b
+    /* Do the following 16 operations. */
+    SET(a, b, c, d,  0,  7,  T1);
+    SET(d, a, b, c,  1, 12,  T2);
+    SET(c, d, a, b,  2, 17,  T3);
+    SET(b, c, d, a,  3, 22,  T4);
+    SET(a, b, c, d,  4,  7,  T5);
+    SET(d, a, b, c,  5, 12,  T6);
+    SET(c, d, a, b,  6, 17,  T7);
+    SET(b, c, d, a,  7, 22,  T8);
+    SET(a, b, c, d,  8,  7,  T9);
+    SET(d, a, b, c,  9, 12, T10);
+    SET(c, d, a, b, 10, 17, T11);
+    SET(b, c, d, a, 11, 22, T12);
+    SET(a, b, c, d, 12,  7, T13);
+    SET(d, a, b, c, 13, 12, T14);
+    SET(c, d, a, b, 14, 17, T15);
+    SET(b, c, d, a, 15, 22, T16);
+#undef SET
+
+     /* Round 2. */
+     /* Let [abcd k s i] denote the operation
+          a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */
+#define G(x, y, z) (((x) & (z)) | ((y) & ~(z)))
+#define SET(a, b, c, d, k, s, Ti)\
+  t = a + G(b,c,d) + X[k] + Ti;\
+  a = ROTATE_LEFT(t, s) + b
+     /* Do the following 16 operations. */
+    SET(a, b, c, d,  1,  5, T17);
+    SET(d, a, b, c,  6,  9, T18);
+    SET(c, d, a, b, 11, 14, T19);
+    SET(b, c, d, a,  0, 20, T20);
+    SET(a, b, c, d,  5,  5, T21);
+    SET(d, a, b, c, 10,  9, T22);
+    SET(c, d, a, b, 15, 14, T23);
+    SET(b, c, d, a,  4, 20, T24);
+    SET(a, b, c, d,  9,  5, T25);
+    SET(d, a, b, c, 14,  9, T26);
+    SET(c, d, a, b,  3, 14, T27);
+    SET(b, c, d, a,  8, 20, T28);
+    SET(a, b, c, d, 13,  5, T29);
+    SET(d, a, b, c,  2,  9, T30);
+    SET(c, d, a, b,  7, 14, T31);
+    SET(b, c, d, a, 12, 20, T32);
+#undef SET
+
+     /* Round 3. */
+     /* Let [abcd k s t] denote the operation
+          a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */
+#define H(x, y, z) ((x) ^ (y) ^ (z))
+#define SET(a, b, c, d, k, s, Ti)\
+  t = a + H(b,c,d) + X[k] + Ti;\
+  a = ROTATE_LEFT(t, s) + b
+     /* Do the following 16 operations. */
+    SET(a, b, c, d,  5,  4, T33);
+    SET(d, a, b, c,  8, 11, T34);
+    SET(c, d, a, b, 11, 16, T35);
+    SET(b, c, d, a, 14, 23, T36);
+    SET(a, b, c, d,  1,  4, T37);
+    SET(d, a, b, c,  4, 11, T38);
+    SET(c, d, a, b,  7, 16, T39);
+    SET(b, c, d, a, 10, 23, T40);
+    SET(a, b, c, d, 13,  4, T41);
+    SET(d, a, b, c,  0, 11, T42);
+    SET(c, d, a, b,  3, 16, T43);
+    SET(b, c, d, a,  6, 23, T44);
+    SET(a, b, c, d,  9,  4, T45);
+    SET(d, a, b, c, 12, 11, T46);
+    SET(c, d, a, b, 15, 16, T47);
+    SET(b, c, d, a,  2, 23, T48);
+#undef SET
+
+     /* Round 4. */
+     /* Let [abcd k s t] denote the operation
+          a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */
+#define I(x, y, z) ((y) ^ ((x) | ~(z)))
+#define SET(a, b, c, d, k, s, Ti)\
+  t = a + I(b,c,d) + X[k] + Ti;\
+  a = ROTATE_LEFT(t, s) + b
+     /* Do the following 16 operations. */
+    SET(a, b, c, d,  0,  6, T49);
+    SET(d, a, b, c,  7, 10, T50);
+    SET(c, d, a, b, 14, 15, T51);
+    SET(b, c, d, a,  5, 21, T52);
+    SET(a, b, c, d, 12,  6, T53);
+    SET(d, a, b, c,  3, 10, T54);
+    SET(c, d, a, b, 10, 15, T55);
+    SET(b, c, d, a,  1, 21, T56);
+    SET(a, b, c, d,  8,  6, T57);
+    SET(d, a, b, c, 15, 10, T58);
+    SET(c, d, a, b,  6, 15, T59);
+    SET(b, c, d, a, 13, 21, T60);
+    SET(a, b, c, d,  4,  6, T61);
+    SET(d, a, b, c, 11, 10, T62);
+    SET(c, d, a, b,  2, 15, T63);
+    SET(b, c, d, a,  9, 21, T64);
+#undef SET
+
+     /* Then perform the following additions. (That is increment each
+        of the four registers by the value it had before this block
+        was started.) */
+    pms->abcd[0] += a;
+    pms->abcd[1] += b;
+    pms->abcd[2] += c;
+    pms->abcd[3] += d;
+}
+
+void
+md5_init(md5_state_t *pms)
+{
+    pms->count[0] = pms->count[1] = 0;
+    pms->abcd[0] = 0x67452301;
+    pms->abcd[1] = 0xefcdab89;
+    pms->abcd[2] = 0x98badcfe;
+    pms->abcd[3] = 0x10325476;
+}
+
+void
+md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes)
+{
+    const md5_byte_t *p = data;
+    int left = nbytes;
+    int offset = (pms->count[0] >> 3) & 63;
+    md5_word_t nbits = (md5_word_t)(nbytes << 3);
+
+    if (nbytes <= 0)
+	return;
+
+    /* Update the message length. */
+    pms->count[1] += nbytes >> 29;
+    pms->count[0] += nbits;
+    if (pms->count[0] < nbits)
+	pms->count[1]++;
+
+    /* Process an initial partial block. */
+    if (offset) {
+	int copy = (offset + nbytes > 64 ? 64 - offset : nbytes);
+
+	memcpy(pms->buf + offset, p, copy);
+	if (offset + copy < 64)
+	    return;
+	p += copy;
+	left -= copy;
+	md5_process(pms, pms->buf);
+    }
+
+    /* Process full blocks. */
+    for (; left >= 64; p += 64, left -= 64)
+	md5_process(pms, p);
+
+    /* Process a final partial block. */
+    if (left)
+	memcpy(pms->buf, p, left);
+}
+
+void
+md5_finish(md5_state_t *pms, md5_byte_t digest[16])
+{
+    static const md5_byte_t pad[64] = {
+	0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+    };
+    md5_byte_t data[8];
+    int i;
+
+    /* Save the length before padding. */
+    for (i = 0; i < 8; ++i)
+	data[i] = (md5_byte_t)(pms->count[i >> 2] >> ((i & 3) << 3));
+    /* Pad to 56 bytes mod 64. */
+    md5_append(pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1);
+    /* Append the length. */
+    md5_append(pms, data, 8);
+    for (i = 0; i < 16; ++i)
+	digest[i] = (md5_byte_t)(pms->abcd[i >> 2] >> ((i & 3) << 3));
+}
Index: protocols/md5.h
===================================================================
--- protocols/md5.h	(revision 3f9440db856c1b1cde54eb919543cfc23ea09983)
+++ protocols/md5.h	(revision 3f9440db856c1b1cde54eb919543cfc23ea09983)
@@ -0,0 +1,85 @@
+/*
+  Copyright (C) 1999 Aladdin Enterprises.  All rights reserved.
+  
+  This software is provided 'as-is', without any express or implied
+  warranty.  In no event will the authors be held liable for any damages
+  arising from the use of this software.
+
+  Permission is granted to anyone to use this software for any purpose,
+  including commercial applications, and to alter it and redistribute it
+  freely, subject to the following restrictions:
+
+  1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+  2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+  3. This notice may not be removed or altered from any source distribution.
+
+  L. Peter Deutsch
+  ghost@aladdin.com
+
+ */
+/*
+  Independent implementation of MD5 (RFC 1321).
+
+  This code implements the MD5 Algorithm defined in RFC 1321.
+  It is derived directly from the text of the RFC and not from the
+  reference implementation.
+
+  The original and principal author of md5.h is L. Peter Deutsch
+  <ghost@aladdin.com>.  Other authors are noted in the change history
+  that follows (in reverse chronological order):
+
+  2004-03-09 Jelmer Vernooij add G_MODULE_EXPORT for Bitlbee
+  1999-11-04 lpd Edited comments slightly for automatic TOC extraction.
+  1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5);
+	added conditionalization for C++ compilation from Martin
+	Purschke <purschke@bnl.gov>.
+  1999-05-03 lpd Original version.
+ */
+
+#ifndef md5_INCLUDED
+#  define md5_INCLUDED
+
+#include <glib.h>
+#include <gmodule.h>
+
+/*
+ * This code has some adaptations for the Ghostscript environment, but it
+ * will compile and run correctly in any environment with 8-bit chars and
+ * 32-bit ints.  Specifically, it assumes that if the following are
+ * defined, they have the same meaning as in Ghostscript: P1, P2, P3,
+ * ARCH_IS_BIG_ENDIAN.
+ */
+
+typedef unsigned char md5_byte_t; /* 8-bit byte */
+typedef unsigned int md5_word_t; /* 32-bit word */
+
+/* Define the state of the MD5 Algorithm. */
+typedef struct md5_state_s {
+    md5_word_t count[2];	/* message length in bits, lsw first */
+    md5_word_t abcd[4];		/* digest buffer */
+    md5_byte_t buf[64];		/* accumulate block */
+} md5_state_t;
+
+#ifdef __cplusplus
+extern "C" 
+{
+#endif
+
+/* Initialize the algorithm. */
+G_MODULE_EXPORT void md5_init(md5_state_t *pms);
+
+/* Append a string to the message. */
+G_MODULE_EXPORT void md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes);
+
+/* Finish the message and return the digest. */
+G_MODULE_EXPORT void md5_finish(md5_state_t *pms, md5_byte_t digest[16]);
+
+#ifdef __cplusplus
+}  /* end extern "C" */
+#endif
+
+#endif /* md5_INCLUDED */
Index: protocols/msn/msn.c
===================================================================
--- protocols/msn/msn.c	(revision fef6116e89bb0651c72454effbb51e04e9e1b8dc)
+++ protocols/msn/msn.c	(revision 3f9440db856c1b1cde54eb919543cfc23ea09983)
@@ -27,7 +27,7 @@
 #include "msn.h"
 
-static void msn_login( account_t *acc )
-{
-	struct gaim_connection *gc = new_gaim_conn( acc );
+static void msn_login( struct aim_user *acct )
+{
+	struct gaim_connection *gc = new_gaim_conn( acct );
 	struct msn_data *md = g_new0( struct msn_data, 1 );
 	
@@ -37,5 +37,5 @@
 	md->fd = -1;
 	
-	if( strchr( acc->user, '@' ) == NULL )
+	if( strchr( acct->username, '@' ) == NULL )
 	{
 		hide_login_progress( gc, "Invalid account name" );
Index: protocols/nogaim.c
===================================================================
--- protocols/nogaim.c	(revision fef6116e89bb0651c72454effbb51e04e9e1b8dc)
+++ protocols/nogaim.c	(revision 3f9440db856c1b1cde54eb919543cfc23ea09983)
@@ -145,19 +145,31 @@
 /* multi.c */
 
-struct gaim_connection *new_gaim_conn( account_t *acc )
+struct gaim_connection *new_gaim_conn( struct aim_user *user )
 {
 	struct gaim_connection *gc;
+	account_t *a;
 	
 	gc = g_new0( struct gaim_connection, 1 );
 	
-	/* Maybe we should get rid of this memory waste later. ;-) */
-	g_snprintf( gc->username, sizeof( gc->username ), "%s", acc->user );
-	g_snprintf( gc->password, sizeof( gc->password ), "%s", acc->pass );
-	
-	gc->irc = acc->irc;
-	gc->acc = acc;
-	acc->gc = gc;
+	gc->prpl = user->prpl;
+	g_snprintf( gc->username, sizeof( gc->username ), "%s", user->username );
+	g_snprintf( gc->password, sizeof( gc->password ), "%s", user->password );
+	/* [MD]	BUGFIX: don't set gc->irc to the global IRC, but use the one from the struct aim_user.
+	 * This fixes daemon mode breakage where IRC doesn't point to the currently active connection.
+	 */
+	gc->irc = user->irc;
 	
 	connections = g_slist_append( connections, gc );
+	
+	user->gc = gc;
+	gc->user = user;
+	
+	// Find the account_t so we can set its gc pointer
+	for( a = gc->irc->accounts; a; a = a->next )
+		if( ( struct aim_user * ) a->gc == user )
+		{
+			a->gc = gc;
+			break;
+		}
 	
 	return( gc );
@@ -177,4 +189,5 @@
 	
 	connections = g_slist_remove( connections, gc );
+	g_free( gc->user );
 	g_free( gc );
 }
@@ -207,18 +220,18 @@
 	va_end( params );
 
-	if( ( g_strcasecmp( set_getstr( &gc->irc->set, "strip_html" ), "always" ) == 0 ) ||
-	    ( ( gc->flags & OPT_CONN_HTML ) && set_getint( &gc->irc->set, "strip_html" ) ) )
+	if( ( g_strcasecmp( set_getstr( gc->irc, "strip_html" ), "always" ) == 0 ) ||
+	    ( ( gc->flags & OPT_CONN_HTML ) && set_getint( gc->irc, "strip_html" ) ) )
 		strip_html( text );
 	
 	/* Try to find a different connection on the same protocol. */
 	for( a = gc->irc->accounts; a; a = a->next )
-		if( a->prpl == gc->acc->prpl && a->gc != gc )
+		if( a->prpl == gc->prpl && a->gc != gc )
 			break;
 	
 	/* If we found one, include the screenname in the message. */
 	if( a )
-		irc_usermsg( gc->irc, "%s(%s) - %s", gc->acc->prpl->name, gc->username, text );
+		irc_usermsg( gc->irc, "%s(%s) - %s", gc->prpl->name, gc->username, text );
 	else
-		irc_usermsg( gc->irc, "%s - %s", gc->acc->prpl->name, text );
+		irc_usermsg( gc->irc, "%s - %s", gc->prpl->name, text );
 	
 	g_free( text );
@@ -229,6 +242,6 @@
 	struct gaim_connection *gc = d;
 	
-	if( gc->acc->prpl->keepalive )
-		gc->acc->prpl->keepalive( gc );
+	if( gc->prpl && gc->prpl->keepalive )
+		gc->prpl->keepalive( gc );
 	
 	return TRUE;
@@ -284,7 +297,6 @@
 	b_event_remove( gc->keepalive );
 	gc->flags |= OPT_LOGGING_OUT;
-	
 	gc->keepalive = 0;
-	gc->acc->prpl->close( gc );
+	gc->prpl->close( gc );
 	b_event_remove( gc->inpa );
 	
@@ -311,7 +323,7 @@
 		/* Uhm... This is very sick. */
 	}
-	else if( !gc->wants_to_die && set_getint( &irc->set, "auto_reconnect" ) )
-	{
-		int delay = set_getint( &irc->set, "auto_reconnect_delay" );
+	else if( !gc->wants_to_die && set_getint( irc, "auto_reconnect" ) )
+	{
+		int delay = set_getint( irc, "auto_reconnect_delay" );
 		
 		serv_got_crap( gc, "Reconnecting in %d seconds..", delay );
@@ -352,10 +364,10 @@
 	irc_t *irc = gc->irc;
 	
-	if( set_getint( &irc->set, "debug" ) && 0 ) /* This message is too useless */
+	if( set_getint( irc, "debug" ) && 0 ) /* This message is too useless */
 		serv_got_crap( gc, "Receiving user add from handle: %s", handle );
 	
 	if( user_findhandle( gc, handle ) )
 	{
-		if( set_getint( &irc->set, "debug" ) )
+		if( set_getint( irc, "debug" ) )
 			serv_got_crap( gc, "User already exists, ignoring add request: %s", handle );
 		
@@ -366,5 +378,5 @@
 	
 	memset( nick, 0, MAX_NICK_LENGTH + 1 );
-	strcpy( nick, nick_get( gc->irc, handle, gc->acc->prpl, realname ) );
+	strcpy( nick, nick_get( gc->irc, handle, gc->prpl, realname ) );
 	
 	u = user_add( gc->irc, nick );
@@ -378,13 +390,13 @@
 		u->user = g_strndup( handle, s - handle );
 	}
-	else if( *gc->acc->server )
+	else if( gc->user->proto_opt[0] && *gc->user->proto_opt[0] )
 	{
 		char *colon;
 		
-		if( ( colon = strchr( gc->acc->server, ':' ) ) )
-			u->host = g_strndup( gc->acc->server,
-			                     colon - gc->acc->server );
+		if( ( colon = strchr( gc->user->proto_opt[0], ':' ) ) )
+			u->host = g_strndup( gc->user->proto_opt[0],
+			                     colon - gc->user->proto_opt[0] );
 		else
-			u->host = g_strdup( gc->acc->server );
+			u->host = g_strdup( gc->user->proto_opt[0] );
 		
 		u->user = g_strdup( handle );
@@ -397,5 +409,5 @@
 	else
 	{
-		u->host = g_strdup( gc->acc->prpl->name );
+		u->host = g_strdup( gc->user->prpl->name );
 		u->user = g_strdup( handle );
 	}
@@ -445,5 +457,5 @@
 		u->realname = g_strdup( realname );
 		
-		if( ( gc->flags & OPT_LOGGED_IN ) && set_getint( &gc->irc->set, "display_namechanges" ) )
+		if( ( gc->flags & OPT_LOGGED_IN ) && set_getint( gc->irc, "display_namechanges" ) )
 			serv_got_crap( gc, "User `%s' changed name to `%s'", u->nick, u->realname );
 	}
@@ -467,5 +479,5 @@
 void show_got_added_yes( gpointer w, struct show_got_added_data *data )
 {
-	data->gc->acc->prpl->add_buddy( data->gc, data->handle );
+	data->gc->prpl->add_buddy( data->gc, data->handle );
 	add_buddy( data->gc, NULL, data->handle, data->handle );
 	
@@ -501,5 +513,5 @@
 	if( !u )
 	{
-		if( g_strcasecmp( set_getstr( &gc->irc->set, "handle_unknown" ), "add" ) == 0 )
+		if( g_strcasecmp( set_getstr( gc->irc, "handle_unknown" ), "add" ) == 0 )
 		{
 			add_buddy( gc, NULL, handle, NULL );
@@ -508,5 +520,5 @@
 		else
 		{
-			if( set_getint( &gc->irc->set, "debug" ) || g_strcasecmp( set_getstr( &gc->irc->set, "handle_unknown" ), "ignore" ) != 0 )
+			if( set_getint( gc->irc, "debug" ) || g_strcasecmp( set_getstr( gc->irc, "handle_unknown" ), "ignore" ) != 0 )
 			{
 				serv_got_crap( gc, "serv_got_update() for handle %s:", handle );
@@ -546,9 +558,9 @@
 	}
 	
-	if( ( type & UC_UNAVAILABLE ) && ( strcmp( gc->acc->prpl->name, "oscar" ) == 0 || strcmp( gc->acc->prpl->name, "icq" ) == 0 ) )
+	if( ( type & UC_UNAVAILABLE ) && ( !strcmp(gc->prpl->name, "oscar") || !strcmp(gc->prpl->name, "icq")) )
 	{
 		u->away = g_strdup( "Away" );
 	}
-	else if( ( type & UC_UNAVAILABLE ) && ( strcmp( gc->acc->prpl->name, "jabber" ) == 0 ) )
+	else if( ( type & UC_UNAVAILABLE ) && ( !strcmp(gc->prpl->name, "jabber") ) )
 	{
 		if( type & UC_DND )
@@ -559,7 +571,7 @@
 			u->away = g_strdup( "Away" );
 	}
-	else if( ( type & UC_UNAVAILABLE ) && gc->acc->prpl->get_status_string )
-	{
-		u->away = g_strdup( gc->acc->prpl->get_status_string( gc, type ) );
+	else if( ( type & UC_UNAVAILABLE ) && gc->prpl->get_status_string )
+	{
+		u->away = g_strdup( gc->prpl->get_status_string( gc, type ) );
 	}
 	else
@@ -567,5 +579,5 @@
 	
 	/* LISPy... */
-	if( ( set_getint( &gc->irc->set, "away_devoice" ) ) &&		/* Don't do a thing when user doesn't want it */
+	if( ( set_getint( gc->irc, "away_devoice" ) ) &&		/* Don't do a thing when user doesn't want it */
 	    ( u->online ) &&						/* Don't touch offline people */
 	    ( ( ( u->online != oo ) && !u->away ) ||			/* Voice joining people */
@@ -586,9 +598,9 @@
 	if( !u )
 	{
-		char *h = set_getstr( &irc->set, "handle_unknown" );
+		char *h = set_getstr( irc, "handle_unknown" );
 		
 		if( g_strcasecmp( h, "ignore" ) == 0 )
 		{
-			if( set_getint( &irc->set, "debug" ) )
+			if( set_getint( irc, "debug" ) )
 				serv_got_crap( gc, "Ignoring message from unknown handle %s", handle );
 			
@@ -597,5 +609,5 @@
 		else if( g_strncasecmp( h, "add", 3 ) == 0 )
 		{
-			int private = set_getint( &irc->set, "private" );
+			int private = set_getint( irc, "private" );
 			
 			if( h[3] )
@@ -618,6 +630,6 @@
 	}
 	
-	if( ( g_strcasecmp( set_getstr( &gc->irc->set, "strip_html" ), "always" ) == 0 ) ||
-	    ( ( gc->flags & OPT_CONN_HTML ) && set_getint( &gc->irc->set, "strip_html" ) ) )
+	if( ( g_strcasecmp( set_getstr( gc->irc, "strip_html" ), "always" ) == 0 ) ||
+	    ( ( gc->flags & OPT_CONN_HTML ) && set_getint( gc->irc, "strip_html" ) ) )
 		strip_html( msg );
 
@@ -659,5 +671,5 @@
 	user_t *u;
 	
-	if( !set_getint( &gc->irc->set, "typing_notice" ) )
+	if( !set_getint( gc->irc, "typing_notice" ) )
 		return;
 	
@@ -681,5 +693,5 @@
 	GList *ir;
 	
-	if( set_getint( &gc->irc->set, "debug" ) )
+	if( set_getint( gc->irc, "debug" ) )
 		serv_got_crap( gc, "You were removed from conversation %d", (int) id );
 	
@@ -720,5 +732,5 @@
 	
 	/* Gaim sends own messages through this too. IRC doesn't want this, so kill them */
-	if( g_strcasecmp( who, gc->username ) == 0 )
+	if( g_strcasecmp( who, gc->user->username ) == 0 )
 		return;
 	
@@ -726,6 +738,6 @@
 	for( c = gc->conversations; c && c->id != id; c = c->next );
 	
-	if( ( g_strcasecmp( set_getstr( &gc->irc->set, "strip_html" ), "always" ) == 0 ) ||
-	    ( ( gc->flags & OPT_CONN_HTML ) && set_getint( &gc->irc->set, "strip_html" ) ) )
+	if( ( g_strcasecmp( set_getstr( gc->irc, "strip_html" ), "always" ) == 0 ) ||
+	    ( ( gc->flags & OPT_CONN_HTML ) && set_getint( gc->irc, "strip_html" ) ) )
 		strip_html( msg );
 	
@@ -760,5 +772,5 @@
 	g_free( s );
 	
-	if( set_getint( &gc->irc->set, "debug" ) )
+	if( set_getint( gc->irc, "debug" ) )
 		serv_got_crap( gc, "Creating new conversation: (id=%d,handle=%s)", id, handle );
 	
@@ -774,9 +786,9 @@
 	int me = 0;
 	
-	if( set_getint( &b->gc->irc->set, "debug" ) )
+	if( set_getint( b->gc->irc, "debug" ) )
 		serv_got_crap( b->gc, "User %s added to conversation %d", handle, b->id );
 	
 	/* It might be yourself! */
-	if( b->gc->acc->prpl->cmp_buddynames( handle, b->gc->username ) == 0 )
+	if( b->gc->prpl->cmp_buddynames( handle, b->gc->user->username ) == 0 )
 	{
 		u = user_find( b->gc->irc, b->gc->irc->nick );
@@ -808,9 +820,9 @@
 	int me = 0;
 	
-	if( set_getint( &b->gc->irc->set, "debug" ) )
+	if( set_getint( b->gc->irc, "debug" ) )
 		serv_got_crap( b->gc, "User %s removed from conversation %d (%s)", handle, b->id, reason ? reason : "" );
 	
 	/* It might be yourself! */
-	if( g_strcasecmp( handle, b->gc->username ) == 0 )
+	if( g_strcasecmp( handle, b->gc->user->username ) == 0 )
 	{
 		u = user_find( b->gc->irc, b->gc->irc->nick );
@@ -870,7 +882,6 @@
 }
 
-char *set_eval_away_devoice( set_t *set, char *value )
-{
-	irc_t *irc = set->data;
+char *set_eval_away_devoice( irc_t *irc, set_t *set, char *value )
+{
 	int st;
 	
@@ -886,5 +897,5 @@
 	/* Horror.... */
 	
-	if( st != set_getint( &irc->set, "away_devoice" ) )
+	if( st != set_getint( irc, "away_devoice" ) )
 	{
 		char list[80] = "";
@@ -926,5 +937,5 @@
 	}
 	
-	return( set_eval_bool( set, value ) );
+	return( set_eval_bool( irc, set, value ) );
 }
 
@@ -946,5 +957,5 @@
 	}
 	
-	st = gc->acc->prpl->send_im( gc, handle, msg, strlen( msg ), flags );
+	st = gc->prpl->send_im( gc, handle, msg, strlen( msg ), flags );
 	g_free( buf );
 	
@@ -963,5 +974,5 @@
 	}
 	
-	st = gc->acc->prpl->chat_send( gc, id, msg );
+	st = gc->prpl->chat_send( gc, id, msg );
 	g_free( buf );
 	
@@ -977,5 +988,5 @@
 	
 	if( !away ) away = "";
-	ms = m = gc->acc->prpl->away_states( gc );
+	ms = m = gc->prpl->away_states( gc );
 	
 	while( m )
@@ -998,5 +1009,5 @@
 	if( m )
 	{
-		gc->acc->prpl->set_away( gc, m->data, *away ? away : NULL );
+		gc->prpl->set_away( gc, m->data, *away ? away : NULL );
 	}
 	else
@@ -1005,10 +1016,10 @@
 		if( s )
 		{
-			gc->acc->prpl->set_away( gc, s, away );
-			if( set_getint( &gc->irc->set, "debug" ) )
+			gc->prpl->set_away( gc, s, away );
+			if( set_getint( gc->irc, "debug" ) )
 				serv_got_crap( gc, "Setting away state to %s", s );
 		}
 		else
-			gc->acc->prpl->set_away( gc, GAIM_AWAY_CUSTOM, away );
+			gc->prpl->set_away( gc, GAIM_AWAY_CUSTOM, away );
 	}
 	
@@ -1062,10 +1073,10 @@
 void bim_add_allow( struct gaim_connection *gc, char *handle )
 {
-	if( g_slist_find_custom( gc->permit, handle, (GCompareFunc) gc->acc->prpl->cmp_buddynames ) == NULL )
+	if( g_slist_find_custom( gc->permit, handle, (GCompareFunc) gc->prpl->cmp_buddynames ) == NULL )
 	{
 		gc->permit = g_slist_prepend( gc->permit, g_strdup( handle ) );
 	}
 	
-	gc->acc->prpl->add_permit( gc, handle );
+	gc->prpl->add_permit( gc, handle );
 }
 
@@ -1074,5 +1085,5 @@
 	GSList *l;
 	
-	if( ( l = g_slist_find_custom( gc->permit, handle, (GCompareFunc) gc->acc->prpl->cmp_buddynames ) ) )
+	if( ( l = g_slist_find_custom( gc->permit, handle, (GCompareFunc) gc->prpl->cmp_buddynames ) ) )
 	{
 		g_free( l->data );
@@ -1080,15 +1091,15 @@
 	}
 	
-	gc->acc->prpl->rem_permit( gc, handle );
+	gc->prpl->rem_permit( gc, handle );
 }
 
 void bim_add_block( struct gaim_connection *gc, char *handle )
 {
-	if( g_slist_find_custom( gc->deny, handle, (GCompareFunc) gc->acc->prpl->cmp_buddynames ) == NULL )
+	if( g_slist_find_custom( gc->deny, handle, (GCompareFunc) gc->prpl->cmp_buddynames ) == NULL )
 	{
 		gc->deny = g_slist_prepend( gc->deny, g_strdup( handle ) );
 	}
 	
-	gc->acc->prpl->add_deny( gc, handle );
+	gc->prpl->add_deny( gc, handle );
 }
 
@@ -1097,5 +1108,5 @@
 	GSList *l;
 	
-	if( ( l = g_slist_find_custom( gc->deny, handle, (GCompareFunc) gc->acc->prpl->cmp_buddynames ) ) )
+	if( ( l = g_slist_find_custom( gc->deny, handle, (GCompareFunc) gc->prpl->cmp_buddynames ) ) )
 	{
 		g_free( l->data );
@@ -1103,4 +1114,4 @@
 	}
 	
-	gc->acc->prpl->rem_deny( gc, handle );
-}
+	gc->prpl->rem_deny( gc, handle );
+}
Index: protocols/nogaim.h
===================================================================
--- protocols/nogaim.h	(revision fef6116e89bb0651c72454effbb51e04e9e1b8dc)
+++ protocols/nogaim.h	(revision 3f9440db856c1b1cde54eb919543cfc23ea09983)
@@ -39,5 +39,4 @@
 
 #include "bitlbee.h"
-#include "account.h"
 #include "proxy.h"
 #include "md5.h"
@@ -64,5 +63,5 @@
 struct gaim_connection
 {
-	account_t *acc;
+	struct prpl *prpl;
 	guint32 flags;
 	
@@ -79,4 +78,6 @@
 	GSList *deny;
 	int permdeny;
+	
+	struct aim_user *user;
 	
 	char username[64];
@@ -125,9 +126,24 @@
 };
 
+struct aim_user {
+	char username[64];
+	char alias[SELF_ALIAS_LEN]; 
+	char password[32];
+	char user_info[2048];
+	int options;
+	struct prpl *prpl;
+	/* prpls can use this to save information about the user,
+	 * like which server to connect to, etc */
+	char proto_opt[7][256];
+
+	struct gaim_connection *gc;
+	irc_t *irc;
+};
+
 struct prpl {
 	int options;
 	const char *name;
 
-	void (* login)		(account_t *);
+	void (* login)		(struct aim_user *);
 	void (* keepalive)	(struct gaim_connection *);
 	void (* close)		(struct gaim_connection *);
@@ -190,5 +206,5 @@
 
 void nogaim_init();
-char *set_eval_away_devoice( set_t *set, char *value );
+char *set_eval_away_devoice( irc_t *irc, set_t *set, char *value );
 
 gboolean auto_reconnect( gpointer data, gint fd, b_input_condition cond );
@@ -196,5 +212,5 @@
 
 /* multi.c */
-G_MODULE_EXPORT struct gaim_connection *new_gaim_conn( account_t *acc );
+G_MODULE_EXPORT struct gaim_connection *new_gaim_conn( struct aim_user *user );
 G_MODULE_EXPORT void destroy_gaim_conn( struct gaim_connection *gc );
 G_MODULE_EXPORT void set_login_progress( struct gaim_connection *gc, int step, char *msg );
Index: protocols/oscar/oscar.c
===================================================================
--- protocols/oscar/oscar.c	(revision fef6116e89bb0651c72454effbb51e04e9e1b8dc)
+++ protocols/oscar/oscar.c	(revision 3f9440db856c1b1cde54eb919543cfc23ea09983)
@@ -356,16 +356,16 @@
 }
 
-static void oscar_login(account_t *acc) {
+static void oscar_login(struct aim_user *user) {
 	aim_session_t *sess;
 	aim_conn_t *conn;
 	char buf[256];
-	struct gaim_connection *gc = new_gaim_conn(acc);
+	struct gaim_connection *gc = new_gaim_conn(user);
 	struct oscar_data *odata = gc->proto_data = g_new0(struct oscar_data, 1);
 
-	if (isdigit(acc->user[0])) {
+	if (isdigit(*user->username)) {
 		odata->icq = TRUE;
 		/* This is odd but it's necessary for a proper do_import and do_export.
 		   We don't do those anymore, but let's stick with it, just in case
-		   it accidentally fixes something else too... </bitlbee> */
+		   it accidentally fixes something else too... */
 		gc->password[8] = 0;
 	} else {
@@ -390,7 +390,7 @@
 	}
 	
-	if (g_strcasecmp(acc->server, "login.icq.com") != 0 &&
-	    g_strcasecmp(acc->server, "login.oscar.aol.com") != 0) {
-		serv_got_crap(gc, "Warning: Unknown OSCAR server: `%s'. Please review your configuration if the connection fails.",acc->server);
+	if (g_strcasecmp(user->proto_opt[USEROPT_AUTH], "login.icq.com") != 0 &&
+	    g_strcasecmp(user->proto_opt[USEROPT_AUTH], "login.oscar.aol.com") != 0) {
+		serv_got_crap(gc, "Warning: Unknown OSCAR server: `%s'. Please review your configuration if the connection fails.",user->proto_opt[USEROPT_AUTH]);
 	}
 	
@@ -402,5 +402,9 @@
 
 	conn->status |= AIM_CONN_STATUS_INPROGRESS;
-	conn->fd = proxy_connect(acc->server, AIM_LOGIN_PORT, oscar_login_connect, gc);
+	conn->fd = proxy_connect(user->proto_opt[USEROPT_AUTH][0] ?
+					user->proto_opt[USEROPT_AUTH] : AIM_DEFAULT_LOGIN_SERVER,
+				 user->proto_opt[USEROPT_AUTHPORT][0] ?
+					atoi(user->proto_opt[USEROPT_AUTHPORT]) : AIM_LOGIN_PORT,
+				 oscar_login_connect, gc);
 	if (conn->fd < 0) {
 		hide_login_progress(gc, _("Couldn't connect to host"));
@@ -481,9 +485,12 @@
 	struct aim_authresp_info *info;
 	int i; char *host; int port;
+	struct aim_user *user;
 	aim_conn_t *bosconn;
 
 	struct gaim_connection *gc = sess->aux_data;
         struct oscar_data *od = gc->proto_data;
-	port = AIM_LOGIN_PORT;
+	user = gc->user;
+	port = user->proto_opt[USEROPT_AUTHPORT][0] ?
+		atoi(user->proto_opt[USEROPT_AUTHPORT]) : AIM_LOGIN_PORT,
 
 	va_start(ap, fr);
@@ -864,4 +871,5 @@
 	struct aim_redirect_data *redir;
 	struct gaim_connection *gc = sess->aux_data;
+	struct aim_user *user = gc->user;
 	aim_conn_t *tstconn;
 	int i;
@@ -869,9 +877,11 @@
 	int port;
 
+	port = user->proto_opt[USEROPT_AUTHPORT][0] ?
+		atoi(user->proto_opt[USEROPT_AUTHPORT]) : AIM_LOGIN_PORT,
+
 	va_start(ap, fr);
 	redir = va_arg(ap, struct aim_redirect_data *);
 	va_end(ap);
 
-	port = AIM_LOGIN_PORT;
 	for (i = 0; i < (int)strlen(redir->ip); i++) {
 		if (redir->ip[i] == ':') {
@@ -1713,9 +1723,6 @@
 	odata->rights.maxsiglen = odata->rights.maxawaymsglen = (guint)maxsiglen;
 
-	/* FIXME: It seems we're not really using this, and it broke now that
-	   struct aim_user is dead.
 	aim_bos_setprofile(sess, fr->conn, gc->user->user_info, NULL, gaim_caps);
-	*/
-	
+
 	return 1;
 }
Index: protocols/proxy.c
===================================================================
--- protocols/proxy.c	(revision 3f9440db856c1b1cde54eb919543cfc23ea09983)
+++ protocols/proxy.c	(revision 3f9440db856c1b1cde54eb919543cfc23ea09983)
@@ -0,0 +1,552 @@
+/*
+ * gaim
+ *
+ * Copyright (C) 1998-1999, Mark Spencer <markster@marko.net>
+ * Copyright (C) 2002-2004, Wilmer van der Gaast, Jelmer Vernooij
+ *
+ * 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
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#define BITLBEE_CORE
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#ifndef _WIN32
+#include <sys/socket.h>
+#include <netdb.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <unistd.h>
+#else
+#include "sock.h"
+#define ETIMEDOUT WSAETIMEDOUT
+#define EINPROGRESS WSAEINPROGRESS
+#endif
+#include <fcntl.h>
+#include <errno.h>
+#include "nogaim.h"
+#include "proxy.h"
+
+char proxyhost[128] = "";
+int proxyport = 0;
+int proxytype = PROXY_NONE;
+char proxyuser[128] = "";
+char proxypass[128] = "";
+
+struct PHB {
+	b_event_handler func, proxy_func;
+	gpointer data, proxy_data;
+	char *host;
+	int port;
+	int fd;
+	gint inpa;
+};
+
+
+
+static struct sockaddr_in *gaim_gethostbyname(const char *host, int port)
+{
+	static struct sockaddr_in sin;
+
+	if (!inet_aton(host, &sin.sin_addr)) {
+		struct hostent *hp;
+		if (!(hp = gethostbyname(host))) {
+			return NULL;
+		}
+		memset(&sin, 0, sizeof(struct sockaddr_in));
+		memcpy(&sin.sin_addr.s_addr, hp->h_addr, hp->h_length);
+		sin.sin_family = hp->h_addrtype;
+	} else
+		sin.sin_family = AF_INET;
+	sin.sin_port = htons(port);
+
+	return &sin;
+}
+
+static gboolean gaim_io_connected(gpointer data, gint source, b_input_condition cond)
+{
+	struct PHB *phb = data;
+	unsigned int len;
+	int error = ETIMEDOUT;
+	len = sizeof(error);
+	
+#ifndef _WIN32
+	if (getsockopt(source, SOL_SOCKET, SO_ERROR, &error, &len) < 0) {
+		closesocket(source);
+		b_event_remove(phb->inpa);
+		if( phb->proxy_func )
+			phb->proxy_func(phb->proxy_data, -1, GAIM_INPUT_READ);
+		else {
+			phb->func(phb->data, -1, GAIM_INPUT_READ);
+			g_free(phb);
+		}
+		return FALSE;
+	}
+#endif
+	sock_make_blocking(source);
+	b_event_remove(phb->inpa);
+	if( phb->proxy_func )
+		phb->proxy_func(phb->proxy_data, source, GAIM_INPUT_READ);
+	else {
+		phb->func(phb->data, source, GAIM_INPUT_READ);
+		g_free(phb);
+	}
+	
+	return FALSE;
+}
+
+static int proxy_connect_none(const char *host, unsigned short port, struct PHB *phb)
+{
+	struct sockaddr_in *sin;
+	int fd = -1;
+
+	if (!(sin = gaim_gethostbyname(host, port))) {
+		g_free(phb);
+		return -1;
+	}
+
+	if ((fd = socket(sin->sin_family, SOCK_STREAM, 0)) < 0) {
+		g_free(phb);
+		return -1;
+	}
+
+	sock_make_nonblocking(fd);
+	
+	event_debug("proxy_connect_none( \"%s\", %d ) = %d\n", host, port, fd);
+	
+	if (connect(fd, (struct sockaddr *)sin, sizeof(*sin)) < 0) {
+		if (sockerr_again()) {
+			phb->inpa = b_input_add(fd, GAIM_INPUT_WRITE, gaim_io_connected, phb);
+			phb->fd = fd;
+		} else {
+			closesocket(fd);
+			g_free(phb);
+			return -1;
+		}
+	}
+
+	return fd;
+}
+
+
+/* Connecting to HTTP proxies */
+
+#define HTTP_GOODSTRING "HTTP/1.0 200 Connection established"
+#define HTTP_GOODSTRING2 "HTTP/1.1 200 Connection established"
+
+static gboolean http_canread(gpointer data, gint source, b_input_condition cond)
+{
+	int nlc = 0;
+	int pos = 0;
+	struct PHB *phb = data;
+	char inputline[8192];
+
+	b_event_remove(phb->inpa);
+
+	while ((pos < sizeof(inputline)-1) && (nlc != 2) && (read(source, &inputline[pos++], 1) == 1)) {
+		if (inputline[pos - 1] == '\n')
+			nlc++;
+		else if (inputline[pos - 1] != '\r')
+			nlc = 0;
+	}
+	inputline[pos] = '\0';
+
+	if ((memcmp(HTTP_GOODSTRING, inputline, strlen(HTTP_GOODSTRING)) == 0) ||
+	    (memcmp(HTTP_GOODSTRING2, inputline, strlen(HTTP_GOODSTRING2)) == 0)) {
+		phb->func(phb->data, source, GAIM_INPUT_READ);
+		g_free(phb->host);
+		g_free(phb);
+		return FALSE;
+	}
+
+	close(source);
+	phb->func(phb->data, -1, GAIM_INPUT_READ);
+	g_free(phb->host);
+	g_free(phb);
+	
+	return FALSE;
+}
+
+static gboolean http_canwrite(gpointer data, gint source, b_input_condition cond)
+{
+	char cmd[384];
+	struct PHB *phb = data;
+	unsigned int len;
+	int error = ETIMEDOUT;
+	if (phb->inpa > 0)
+		b_event_remove(phb->inpa);
+	len = sizeof(error);
+	if (getsockopt(source, SOL_SOCKET, SO_ERROR, &error, &len) < 0) {
+		close(source);
+		phb->func(phb->data, -1, GAIM_INPUT_READ);
+		g_free(phb->host);
+		g_free(phb);
+		return FALSE;
+	}
+	sock_make_blocking(source);
+
+	g_snprintf(cmd, sizeof(cmd), "CONNECT %s:%d HTTP/1.1\r\nHost: %s:%d\r\n", phb->host, phb->port,
+		   phb->host, phb->port);
+	if (send(source, cmd, strlen(cmd), 0) < 0) {
+		close(source);
+		phb->func(phb->data, -1, GAIM_INPUT_READ);
+		g_free(phb->host);
+		g_free(phb);
+		return FALSE;
+	}
+
+	if (proxyuser && *proxyuser) {
+		char *t1, *t2;
+		t1 = g_strdup_printf("%s:%s", proxyuser, proxypass);
+		t2 = tobase64(t1);
+		g_free(t1);
+		g_snprintf(cmd, sizeof(cmd), "Proxy-Authorization: Basic %s\r\n", t2);
+		g_free(t2);
+		if (send(source, cmd, strlen(cmd), 0) < 0) {
+			close(source);
+			phb->func(phb->data, -1, GAIM_INPUT_READ);
+			g_free(phb->host);
+			g_free(phb);
+			return FALSE;
+		}
+	}
+
+	g_snprintf(cmd, sizeof(cmd), "\r\n");
+	if (send(source, cmd, strlen(cmd), 0) < 0) {
+		close(source);
+		phb->func(phb->data, -1, GAIM_INPUT_READ);
+		g_free(phb->host);
+		g_free(phb);
+		return FALSE;
+	}
+
+	phb->inpa = b_input_add(source, GAIM_INPUT_READ, http_canread, phb);
+	
+	return FALSE;
+}
+
+static int proxy_connect_http(const char *host, unsigned short port, struct PHB *phb)
+{
+	phb->host = g_strdup(host);
+	phb->port = port;
+	phb->proxy_func = http_canwrite;
+	phb->proxy_data = phb;
+	
+	return( proxy_connect_none( proxyhost, proxyport, phb ) );
+}
+
+
+/* Connecting to SOCKS4 proxies */
+
+static gboolean s4_canread(gpointer data, gint source, b_input_condition cond)
+{
+	unsigned char packet[12];
+	struct PHB *phb = data;
+
+	b_event_remove(phb->inpa);
+
+	memset(packet, 0, sizeof(packet));
+	if (read(source, packet, 9) >= 4 && packet[1] == 90) {
+		phb->func(phb->data, source, GAIM_INPUT_READ);
+		g_free(phb->host);
+		g_free(phb);
+		return FALSE;
+	}
+
+	close(source);
+	phb->func(phb->data, -1, GAIM_INPUT_READ);
+	g_free(phb->host);
+	g_free(phb);
+	
+	return FALSE;
+}
+
+static gboolean s4_canwrite(gpointer data, gint source, b_input_condition cond)
+{
+	unsigned char packet[12];
+	struct hostent *hp;
+	struct PHB *phb = data;
+	unsigned int len;
+	int error = ETIMEDOUT;
+	if (phb->inpa > 0)
+		b_event_remove(phb->inpa);
+	len = sizeof(error);
+	if (getsockopt(source, SOL_SOCKET, SO_ERROR, &error, &len) < 0) {
+		close(source);
+		phb->func(phb->data, -1, GAIM_INPUT_READ);
+		g_free(phb->host);
+		g_free(phb);
+		return FALSE;
+	}
+	sock_make_blocking(source);
+
+	/* XXX does socks4 not support host name lookups by the proxy? */
+	if (!(hp = gethostbyname(phb->host))) {
+		close(source);
+		phb->func(phb->data, -1, GAIM_INPUT_READ);
+		g_free(phb->host);
+		g_free(phb);
+		return FALSE;
+	}
+
+	packet[0] = 4;
+	packet[1] = 1;
+	packet[2] = phb->port >> 8;
+	packet[3] = phb->port & 0xff;
+	packet[4] = (unsigned char)(hp->h_addr_list[0])[0];
+	packet[5] = (unsigned char)(hp->h_addr_list[0])[1];
+	packet[6] = (unsigned char)(hp->h_addr_list[0])[2];
+	packet[7] = (unsigned char)(hp->h_addr_list[0])[3];
+	packet[8] = 0;
+	if (write(source, packet, 9) != 9) {
+		close(source);
+		phb->func(phb->data, -1, GAIM_INPUT_READ);
+		g_free(phb->host);
+		g_free(phb);
+		return FALSE;
+	}
+
+	phb->inpa = b_input_add(source, GAIM_INPUT_READ, s4_canread, phb);
+	
+	return FALSE;
+}
+
+static int proxy_connect_socks4(const char *host, unsigned short port, struct PHB *phb)
+{
+	phb->host = g_strdup(host);
+	phb->port = port;
+	phb->proxy_func = s4_canwrite;
+	phb->proxy_data = phb;
+	
+	return( proxy_connect_none( proxyhost, proxyport, phb ) );
+}
+
+
+/* Connecting to SOCKS5 proxies */
+
+static gboolean s5_canread_again(gpointer data, gint source, b_input_condition cond)
+{
+	unsigned char buf[512];
+	struct PHB *phb = data;
+
+	b_event_remove(phb->inpa);
+
+	if (read(source, buf, 10) < 10) {
+		close(source);
+		phb->func(phb->data, -1, GAIM_INPUT_READ);
+		g_free(phb->host);
+		g_free(phb);
+		return FALSE;
+	}
+	if ((buf[0] != 0x05) || (buf[1] != 0x00)) {
+		close(source);
+		phb->func(phb->data, -1, GAIM_INPUT_READ);
+		g_free(phb->host);
+		g_free(phb);
+		return FALSE;
+	}
+
+	phb->func(phb->data, source, GAIM_INPUT_READ);
+	g_free(phb->host);
+	g_free(phb);
+	
+	return FALSE;
+}
+
+static void s5_sendconnect(gpointer data, gint source)
+{
+	unsigned char buf[512];
+	struct PHB *phb = data;
+	int hlen = strlen(phb->host);
+	
+	buf[0] = 0x05;
+	buf[1] = 0x01;		/* CONNECT */
+	buf[2] = 0x00;		/* reserved */
+	buf[3] = 0x03;		/* address type -- host name */
+	buf[4] = hlen;
+	memcpy(buf + 5, phb->host, hlen);
+	buf[5 + strlen(phb->host)] = phb->port >> 8;
+	buf[5 + strlen(phb->host) + 1] = phb->port & 0xff;
+
+	if (write(source, buf, (5 + strlen(phb->host) + 2)) < (5 + strlen(phb->host) + 2)) {
+		close(source);
+		phb->func(phb->data, -1, GAIM_INPUT_READ);
+		g_free(phb->host);
+		g_free(phb);
+		return;
+	}
+
+	phb->inpa = b_input_add(source, GAIM_INPUT_READ, s5_canread_again, phb);
+}
+
+static gboolean s5_readauth(gpointer data, gint source, b_input_condition cond)
+{
+	unsigned char buf[512];
+	struct PHB *phb = data;
+
+	b_event_remove(phb->inpa);
+
+	if (read(source, buf, 2) < 2) {
+		close(source);
+		phb->func(phb->data, -1, GAIM_INPUT_READ);
+		g_free(phb->host);
+		g_free(phb);
+		return FALSE;
+	}
+
+	if ((buf[0] != 0x01) || (buf[1] != 0x00)) {
+		close(source);
+		phb->func(phb->data, -1, GAIM_INPUT_READ);
+		g_free(phb->host);
+		g_free(phb);
+		return FALSE;
+	}
+
+	s5_sendconnect(phb, source);
+	
+	return FALSE;
+}
+
+static gboolean s5_canread(gpointer data, gint source, b_input_condition cond)
+{
+	unsigned char buf[512];
+	struct PHB *phb = data;
+
+	b_event_remove(phb->inpa);
+
+	if (read(source, buf, 2) < 2) {
+		close(source);
+		phb->func(phb->data, -1, GAIM_INPUT_READ);
+		g_free(phb->host);
+		g_free(phb);
+		return FALSE;
+	}
+
+	if ((buf[0] != 0x05) || (buf[1] == 0xff)) {
+		close(source);
+		phb->func(phb->data, -1, GAIM_INPUT_READ);
+		g_free(phb->host);
+		g_free(phb);
+		return FALSE;
+	}
+
+	if (buf[1] == 0x02) {
+		unsigned int i = strlen(proxyuser), j = strlen(proxypass);
+		buf[0] = 0x01;	/* version 1 */
+		buf[1] = i;
+		memcpy(buf + 2, proxyuser, i);
+		buf[2 + i] = j;
+		memcpy(buf + 2 + i + 1, proxypass, j);
+		if (write(source, buf, 3 + i + j) < 3 + i + j) {
+			close(source);
+			phb->func(phb->data, -1, GAIM_INPUT_READ);
+			g_free(phb->host);
+			g_free(phb);
+			return FALSE;
+		}
+
+		phb->inpa = b_input_add(source, GAIM_INPUT_READ, s5_readauth, phb);
+	} else {
+		s5_sendconnect(phb, source);
+	}
+	
+	return FALSE;
+}
+
+static gboolean s5_canwrite(gpointer data, gint source, b_input_condition cond)
+{
+	unsigned char buf[512];
+	int i;
+	struct PHB *phb = data;
+	unsigned int len;
+	int error = ETIMEDOUT;
+	if (phb->inpa > 0)
+		b_event_remove(phb->inpa);
+	len = sizeof(error);
+	if (getsockopt(source, SOL_SOCKET, SO_ERROR, &error, &len) < 0) {
+		close(source);
+		phb->func(phb->data, -1, GAIM_INPUT_READ);
+		g_free(phb->host);
+		g_free(phb);
+		return FALSE;
+	}
+	sock_make_blocking(source);
+
+	i = 0;
+	buf[0] = 0x05;		/* SOCKS version 5 */
+	if (proxyuser[0]) {
+		buf[1] = 0x02;	/* two methods */
+		buf[2] = 0x00;	/* no authentication */
+		buf[3] = 0x02;	/* username/password authentication */
+		i = 4;
+	} else {
+		buf[1] = 0x01;
+		buf[2] = 0x00;
+		i = 3;
+	}
+
+	if (write(source, buf, i) < i) {
+		close(source);
+		phb->func(phb->data, -1, GAIM_INPUT_READ);
+		g_free(phb->host);
+		g_free(phb);
+		return FALSE;
+	}
+
+	phb->inpa = b_input_add(source, GAIM_INPUT_READ, s5_canread, phb);
+	
+	return FALSE;
+}
+
+static int proxy_connect_socks5(const char *host, unsigned short port, struct PHB *phb)
+{
+	phb->host = g_strdup(host);
+	phb->port = port;
+	phb->proxy_func = s5_canwrite;
+	phb->proxy_data = phb;
+	
+	return( proxy_connect_none( proxyhost, proxyport, phb ) );
+}
+
+
+/* Export functions */
+
+int proxy_connect(const char *host, int port, b_event_handler func, gpointer data)
+{
+	struct PHB *phb;
+	
+	if (!host || !port || (port == -1) || !func || strlen(host) > 128) {
+		return -1;
+	}
+	
+	phb = g_new0(struct PHB, 1);
+	phb->func = func;
+	phb->data = data;
+	
+	if ((proxytype == PROXY_NONE) || !proxyhost || !proxyhost[0] || !proxyport || (proxyport == -1))
+		return proxy_connect_none(host, port, phb);
+	else if (proxytype == PROXY_HTTP)
+		return proxy_connect_http(host, port, phb);
+	else if (proxytype == PROXY_SOCKS4)
+		return proxy_connect_socks4(host, port, phb);
+	else if (proxytype == PROXY_SOCKS5)
+		return proxy_connect_socks5(host, port, phb);
+	
+	if (phb->host) g_free(phb);
+	g_free(phb);
+	return -1;
+}
Index: protocols/proxy.h
===================================================================
--- protocols/proxy.h	(revision 3f9440db856c1b1cde54eb919543cfc23ea09983)
+++ protocols/proxy.h	(revision 3f9440db856c1b1cde54eb919543cfc23ea09983)
@@ -0,0 +1,53 @@
+/*
+ * nogaim
+ *
+ * Copyright (C) 1998-1999, Mark Spencer <markster@marko.net>
+ *
+ * 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
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * 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_
+
+#include <sys/types.h>
+#ifndef _WIN32
+#include <sys/socket.h>
+#include <netdb.h>
+#include <netinet/in.h>
+#endif
+#include <glib.h>
+#include <gmodule.h>
+
+#include "events.h"
+
+#define PROXY_NONE 0
+#define PROXY_HTTP 1
+#define PROXY_SOCKS4 2
+#define PROXY_SOCKS5 3
+
+extern char proxyhost[128];
+extern int  proxyport;
+extern int  proxytype;
+extern char proxyuser[128];
+extern char proxypass[128];
+
+G_MODULE_EXPORT int proxy_connect(const char *host, int port, b_event_handler func, gpointer data);
+
+#endif /* _PROXY_H_ */
Index: protocols/sha.c
===================================================================
--- protocols/sha.c	(revision 3f9440db856c1b1cde54eb919543cfc23ea09983)
+++ protocols/sha.c	(revision 3f9440db856c1b1cde54eb919543cfc23ea09983)
@@ -0,0 +1,173 @@
+/* 
+ * The contents of this file are subject to the Mozilla Public
+ * License Version 1.1 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.mozilla.org/MPL/
+ * 
+ * Software distributed under the License is distributed on an "AS
+ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * rights and limitations under the License.
+ * 
+ * The Original Code is SHA 180-1 Reference Implementation (Compact version)
+ * 
+ * The Initial Developer of the Original Code is Paul Kocher of
+ * Cryptography Research.  Portions created by Paul Kocher are 
+ * Copyright (C) 1995-9 by Cryptography Research, Inc.  All
+ * Rights Reserved.
+ * 
+ * Contributor(s):
+ *
+ */
+
+#define BITLBEE_CORE
+#include "nogaim.h"
+
+static void shaHashBlock(SHA_CTX *ctx);
+
+void shaInit(SHA_CTX *ctx) {
+  int i;
+
+  ctx->lenW = 0;
+  ctx->sizeHi = ctx->sizeLo = 0;
+
+  /* Initialize H with the magic constants (see FIPS180 for constants)
+   */
+  ctx->H[0] = 0x67452301L;
+  ctx->H[1] = 0xefcdab89L;
+  ctx->H[2] = 0x98badcfeL;
+  ctx->H[3] = 0x10325476L;
+  ctx->H[4] = 0xc3d2e1f0L;
+
+  for (i = 0; i < 80; i++)
+    ctx->W[i] = 0;
+}
+
+
+void shaUpdate(SHA_CTX *ctx, unsigned char *dataIn, int len) {
+  int i;
+
+  /* Read the data into W and process blocks as they get full
+   */
+  for (i = 0; i < len; i++) {
+    ctx->W[ctx->lenW / 4] <<= 8;
+    ctx->W[ctx->lenW / 4] |= (guint32)dataIn[i];
+    if ((++ctx->lenW) % 64 == 0) {
+      shaHashBlock(ctx);
+      ctx->lenW = 0;
+    }
+    ctx->sizeLo += 8;
+    ctx->sizeHi += (ctx->sizeLo < 8);
+  }
+}
+
+
+void shaFinal(SHA_CTX *ctx, unsigned char hashout[20]) {
+  unsigned char pad0x80 = 0x80;
+  unsigned char pad0x00 = 0x00;
+  unsigned char padlen[8];
+  int i;
+
+  /* Pad with a binary 1 (e.g. 0x80), then zeroes, then length
+   */
+  padlen[0] = (unsigned char)((ctx->sizeHi >> 24) & 255);
+  padlen[1] = (unsigned char)((ctx->sizeHi >> 16) & 255);
+  padlen[2] = (unsigned char)((ctx->sizeHi >> 8) & 255);
+  padlen[3] = (unsigned char)((ctx->sizeHi >> 0) & 255);
+  padlen[4] = (unsigned char)((ctx->sizeLo >> 24) & 255);
+  padlen[5] = (unsigned char)((ctx->sizeLo >> 16) & 255);
+  padlen[6] = (unsigned char)((ctx->sizeLo >> 8) & 255);
+  padlen[7] = (unsigned char)((ctx->sizeLo >> 0) & 255);
+  shaUpdate(ctx, &pad0x80, 1);
+  while (ctx->lenW != 56)
+    shaUpdate(ctx, &pad0x00, 1);
+  shaUpdate(ctx, padlen, 8);
+
+  /* Output hash
+   */
+  for (i = 0; i < 20; i++) {
+    hashout[i] = (unsigned char)(ctx->H[i / 4] >> 24);
+    ctx->H[i / 4] <<= 8;
+  }
+
+  /*
+   *  Re-initialize the context (also zeroizes contents)
+   */
+  shaInit(ctx); 
+}
+
+
+void shaBlock(unsigned char *dataIn, int len, unsigned char hashout[20]) {
+  SHA_CTX ctx;
+
+  shaInit(&ctx);
+  shaUpdate(&ctx, dataIn, len);
+  shaFinal(&ctx, hashout);
+}
+
+
+#define SHA_ROTL(X,n) ((((X) << (n)) | ((X) >> (32-(n)))) & 0xffffffffL)
+
+static void shaHashBlock(SHA_CTX *ctx) {
+  int t;
+  guint32 A,B,C,D,E,TEMP;
+
+  for (t = 16; t <= 79; t++)
+    ctx->W[t] =
+      SHA_ROTL(ctx->W[t-3] ^ ctx->W[t-8] ^ ctx->W[t-14] ^ ctx->W[t-16], 1);
+
+  A = ctx->H[0];
+  B = ctx->H[1];
+  C = ctx->H[2];
+  D = ctx->H[3];
+  E = ctx->H[4];
+
+  for (t = 0; t <= 19; t++) {
+    TEMP = (SHA_ROTL(A,5) + (((C^D)&B)^D)     + E + ctx->W[t] + 0x5a827999L) & 0xffffffffL;
+    E = D; D = C; C = SHA_ROTL(B, 30); B = A; A = TEMP;
+  }
+  for (t = 20; t <= 39; t++) {
+    TEMP = (SHA_ROTL(A,5) + (B^C^D)           + E + ctx->W[t] + 0x6ed9eba1L) & 0xffffffffL;
+    E = D; D = C; C = SHA_ROTL(B, 30); B = A; A = TEMP;
+  }
+  for (t = 40; t <= 59; t++) {
+    TEMP = (SHA_ROTL(A,5) + ((B&C)|(D&(B|C))) + E + ctx->W[t] + 0x8f1bbcdcL) & 0xffffffffL;
+    E = D; D = C; C = SHA_ROTL(B, 30); B = A; A = TEMP;
+  }
+  for (t = 60; t <= 79; t++) {
+    TEMP = (SHA_ROTL(A,5) + (B^C^D)           + E + ctx->W[t] + 0xca62c1d6L) & 0xffffffffL;
+    E = D; D = C; C = SHA_ROTL(B, 30); B = A; A = TEMP;
+  }
+
+  ctx->H[0] += A;
+  ctx->H[1] += B;
+  ctx->H[2] += C;
+  ctx->H[3] += D;
+  ctx->H[4] += E;
+}
+
+/*----------------------------------------------------------------------------
+ *
+ * This code added by Thomas "temas" Muldowney for Jabber compatability
+ *
+ *---------------------------------------------------------------------------*/
+char *shahash(char *str)
+{
+    static char final[41];
+    char *pos;
+    unsigned char hashval[20];
+    int x;
+
+    if(!str || strlen(str) == 0)
+        return NULL;
+
+    shaBlock((unsigned char *)str, strlen(str), hashval);
+
+    pos = final;
+    for(x=0;x<20;x++)
+    {
+        g_snprintf(pos, 3, "%02x", hashval[x]);
+        pos += 2;
+    }
+    return (char *)final;
+}
Index: protocols/sha.h
===================================================================
--- protocols/sha.h	(revision 3f9440db856c1b1cde54eb919543cfc23ea09983)
+++ protocols/sha.h	(revision 3f9440db856c1b1cde54eb919543cfc23ea09983)
@@ -0,0 +1,21 @@
+#ifndef __SHA_H__
+#define __SHA_H__
+
+#include <gmodule.h>
+
+G_MODULE_EXPORT int strprintsha(char *dest, int *hashval);
+ 
+typedef struct {
+  guint32 H[5];
+  guint32 W[80];
+  int lenW;
+  guint32 sizeHi,sizeLo;
+} SHA_CTX;
+ 
+G_MODULE_EXPORT void shaInit(SHA_CTX *ctx);
+G_MODULE_EXPORT void shaUpdate(SHA_CTX *ctx, unsigned char *dataIn, int len);
+G_MODULE_EXPORT void shaFinal(SHA_CTX *ctx, unsigned char hashout[20]);
+G_MODULE_EXPORT void shaBlock(unsigned char *dataIn, int len, unsigned char hashout[20]);
+G_MODULE_EXPORT char *shahash(char *str);
+
+#endif
Index: protocols/ssl_bogus.c
===================================================================
--- protocols/ssl_bogus.c	(revision 3f9440db856c1b1cde54eb919543cfc23ea09983)
+++ protocols/ssl_bogus.c	(revision 3f9440db856c1b1cde54eb919543cfc23ea09983)
@@ -0,0 +1,57 @@
+  /********************************************************************\
+  * BitlBee -- An IRC to other IM-networks gateway                     *
+  *                                                                    *
+  * Copyright 2002-2004 Wilmer van der Gaast and others                *
+  \********************************************************************/
+
+/* SSL module - dummy version                                           */
+
+/*
+  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
+  the Free Software Foundation; either version 2 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License with
+  the Debian GNU/Linux distribution in /usr/share/common-licenses/GPL;
+  if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+  Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include "ssl_client.h"
+
+int ssl_errno;
+
+void *ssl_connect( char *host, int port, ssl_input_function func, gpointer data )
+{
+	return( NULL );
+}
+
+int ssl_read( void *conn, char *buf, int len )
+{
+	return( -1 );
+}
+
+int ssl_write( void *conn, const char *buf, int len )
+{
+	return( -1 );
+}
+
+void ssl_disconnect( void *conn_ )
+{
+}
+
+int ssl_getfd( void *conn )
+{
+	return( -1 );
+}
+
+b_input_condition ssl_getdirection( void *conn )
+{
+	return GAIM_INPUT_READ;
+}
Index: protocols/ssl_client.h
===================================================================
--- protocols/ssl_client.h	(revision 3f9440db856c1b1cde54eb919543cfc23ea09983)
+++ protocols/ssl_client.h	(revision 3f9440db856c1b1cde54eb919543cfc23ea09983)
@@ -0,0 +1,42 @@
+  /********************************************************************\
+  * BitlBee -- An IRC to other IM-networks gateway                     *
+  *                                                                    *
+  * Copyright 2002-2004 Wilmer van der Gaast and others                *
+  \********************************************************************/
+
+/* SSL module                                                           */
+
+/*
+  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
+  the Free Software Foundation; either version 2 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License with
+  the Debian GNU/Linux distribution in /usr/share/common-licenses/GPL;
+  if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+  Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include <glib.h>
+#include "proxy.h"
+
+#define SSL_OK            0
+#define SSL_NOHANDSHAKE   1
+#define SSL_AGAIN         2
+
+extern int ssl_errno;
+
+typedef gboolean (*ssl_input_function)(gpointer, void*, b_input_condition);
+
+G_MODULE_EXPORT void *ssl_connect( char *host, int port, ssl_input_function func, gpointer data );
+G_MODULE_EXPORT int ssl_read( void *conn, char *buf, int len );
+G_MODULE_EXPORT int ssl_write( void *conn, const char *buf, int len );
+G_MODULE_EXPORT void ssl_disconnect( void *conn_ );
+G_MODULE_EXPORT int ssl_getfd( void *conn );
+G_MODULE_EXPORT b_input_condition ssl_getdirection( void *conn );
Index: protocols/ssl_gnutls.c
===================================================================
--- protocols/ssl_gnutls.c	(revision 3f9440db856c1b1cde54eb919543cfc23ea09983)
+++ protocols/ssl_gnutls.c	(revision 3f9440db856c1b1cde54eb919543cfc23ea09983)
@@ -0,0 +1,206 @@
+  /********************************************************************\
+  * BitlBee -- An IRC to other IM-networks gateway                     *
+  *                                                                    *
+  * Copyright 2002-2004 Wilmer van der Gaast and others                *
+  \********************************************************************/
+
+/* SSL module - GnuTLS version                                          */
+
+/*
+  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
+  the Free Software Foundation; either version 2 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License with
+  the Debian GNU/Linux distribution in /usr/share/common-licenses/GPL;
+  if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+  Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include <gnutls/gnutls.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include "proxy.h"
+#include "ssl_client.h"
+#include "sock.h"
+#include "stdlib.h"
+
+int ssl_errno = 0;
+
+static gboolean initialized = FALSE;
+
+struct scd
+{
+	ssl_input_function func;
+	gpointer data;
+	int fd;
+	gboolean established;
+	int inpa;
+	
+	gnutls_session session;
+	gnutls_certificate_credentials xcred;
+};
+
+static gboolean ssl_connected( gpointer data, gint source, b_input_condition cond );
+
+
+void *ssl_connect( char *host, int port, ssl_input_function func, gpointer data )
+{
+	struct scd *conn = g_new0( struct scd, 1 );
+	
+	conn->fd = proxy_connect( host, port, ssl_connected, conn );
+	conn->func = func;
+	conn->data = data;
+	conn->inpa = -1;
+	
+	if( conn->fd < 0 )
+	{
+		g_free( conn );
+		return( NULL );
+	}
+	
+	if( !initialized )
+	{
+		gnutls_global_init();
+		initialized = TRUE;
+		atexit( gnutls_global_deinit );
+	}
+	
+	gnutls_certificate_allocate_credentials( &conn->xcred );
+	gnutls_init( &conn->session, GNUTLS_CLIENT );
+	gnutls_set_default_priority( conn->session );
+	gnutls_credentials_set( conn->session, GNUTLS_CRD_CERTIFICATE, conn->xcred );
+	
+	return( conn );
+}
+
+static gboolean ssl_handshake( gpointer data, gint source, b_input_condition cond );
+
+static gboolean ssl_connected( gpointer data, gint source, b_input_condition cond )
+{
+	struct scd *conn = data;
+	
+	if( source == -1 )
+	{
+		conn->func( conn->data, NULL, cond );
+		
+		gnutls_deinit( conn->session );
+		gnutls_certificate_free_credentials( conn->xcred );
+		
+		g_free( conn );
+		
+		return FALSE;
+	}
+	
+	sock_make_nonblocking( conn->fd );
+	gnutls_transport_set_ptr( conn->session, (gnutls_transport_ptr) conn->fd );
+	
+	return ssl_handshake( data, source, cond );
+}
+
+static gboolean ssl_handshake( gpointer data, gint source, b_input_condition cond )
+{
+	struct scd *conn = data;
+	int st;
+	
+	if( ( st = gnutls_handshake( conn->session ) ) < 0 )
+	{
+		if( st == GNUTLS_E_AGAIN || st == GNUTLS_E_INTERRUPTED )
+		{
+			conn->inpa = b_input_add( conn->fd, ssl_getdirection( conn ),
+			                          ssl_handshake, data );
+		}
+		else
+		{
+			conn->func( conn->data, NULL, cond );
+			
+			gnutls_deinit( conn->session );
+			gnutls_certificate_free_credentials( conn->xcred );
+			closesocket( conn->fd );
+			
+			g_free( conn );
+		}
+	}
+	else
+	{
+		/* For now we can't handle non-blocking perfectly everywhere... */
+		sock_make_blocking( conn->fd );
+		
+		conn->established = TRUE;
+		conn->func( conn->data, conn, cond );
+	}
+	
+	return FALSE;
+}
+
+int ssl_read( void *conn, char *buf, int len )
+{
+	int st;
+	
+	if( !((struct scd*)conn)->established )
+	{
+		ssl_errno = SSL_NOHANDSHAKE;
+		return( -1 );
+	}
+	
+	st = gnutls_record_recv( ((struct scd*)conn)->session, buf, len );
+	
+	ssl_errno = SSL_OK;
+	if( st == GNUTLS_E_AGAIN || st == GNUTLS_E_INTERRUPTED )
+		ssl_errno = SSL_AGAIN;
+	
+	return st;
+}
+
+int ssl_write( void *conn, const char *buf, int len )
+{
+	int st;
+	
+	if( !((struct scd*)conn)->established )
+	{
+		ssl_errno = SSL_NOHANDSHAKE;
+		return( -1 );
+	}
+	
+	st = gnutls_record_send( ((struct scd*)conn)->session, buf, len );
+	
+	ssl_errno = SSL_OK;
+	if( st == GNUTLS_E_AGAIN || st == GNUTLS_E_INTERRUPTED )
+		ssl_errno = SSL_AGAIN;
+	
+	return st;
+}
+
+void ssl_disconnect( void *conn_ )
+{
+	struct scd *conn = conn_;
+	
+	if( conn->inpa != -1 )
+		b_event_remove( conn->inpa );
+	
+	if( conn->established )
+		gnutls_bye( conn->session, GNUTLS_SHUT_WR );
+	
+	closesocket( conn->fd );
+	
+	gnutls_deinit( conn->session );
+	gnutls_certificate_free_credentials( conn->xcred );
+	g_free( conn );
+}
+
+int ssl_getfd( void *conn )
+{
+	return( ((struct scd*)conn)->fd );
+}
+
+b_input_condition ssl_getdirection( void *conn )
+{
+	return( gnutls_record_get_direction( ((struct scd*)conn)->session ) ?
+	        GAIM_INPUT_WRITE : GAIM_INPUT_READ );
+}
Index: protocols/ssl_nss.c
===================================================================
--- protocols/ssl_nss.c	(revision 3f9440db856c1b1cde54eb919543cfc23ea09983)
+++ protocols/ssl_nss.c	(revision 3f9440db856c1b1cde54eb919543cfc23ea09983)
@@ -0,0 +1,190 @@
+  /********************************************************************\
+  * BitlBee -- An IRC to other IM-networks gateway                     *
+  *                                                                    *
+  * Copyright 2002-2005 Wilmer van der Gaast and others                *
+  \********************************************************************/
+
+/* SSL module - NSS version                                             */
+
+/* Copyright 2005 Jelmer Vernooij                                       */
+
+/*
+  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
+  the Free Software Foundation; either version 2 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License with
+  the Debian GNU/Linux distribution in /usr/share/common-licenses/GPL;
+  if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+  Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include "bitlbee.h"
+#include "proxy.h"
+#include "ssl_client.h"
+#include "sock.h"
+#include <nspr.h>
+#include <prio.h>
+#include <sslproto.h>
+#include <nss.h>
+#include <private/pprio.h>
+#include <ssl.h>
+#include <secerr.h>
+#include <sslerr.h>
+
+int ssl_errno = 0;
+
+static gboolean initialized = FALSE;
+
+struct scd
+{
+	ssl_input_function func;
+	gpointer data;
+	int fd;
+	PRFileDesc *prfd;
+	gboolean established;
+};
+
+static gboolean ssl_connected( gpointer data, gint source, b_input_condition cond );
+
+
+static SECStatus nss_auth_cert (void *arg, PRFileDesc *socket, PRBool checksig, PRBool isserver)
+{
+	return SECSuccess;
+}
+
+static SECStatus nss_bad_cert (void *arg, PRFileDesc *socket) 
+{
+	PRErrorCode err;
+
+	if(!arg) return SECFailure;
+
+	*(PRErrorCode *)arg = err = PORT_GetError();
+
+	switch(err) {
+	case SEC_ERROR_INVALID_AVA:
+	case SEC_ERROR_INVALID_TIME:
+	case SEC_ERROR_BAD_SIGNATURE:
+	case SEC_ERROR_EXPIRED_CERTIFICATE:
+	case SEC_ERROR_UNKNOWN_ISSUER:
+	case SEC_ERROR_UNTRUSTED_CERT:
+	case SEC_ERROR_CERT_VALID:
+	case SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE:
+	case SEC_ERROR_CRL_EXPIRED:
+	case SEC_ERROR_CRL_BAD_SIGNATURE:
+	case SEC_ERROR_EXTENSION_VALUE_INVALID:
+	case SEC_ERROR_CA_CERT_INVALID:
+	case SEC_ERROR_CERT_USAGES_INVALID:
+	case SEC_ERROR_UNKNOWN_CRITICAL_EXTENSION:
+		return SECSuccess;
+
+	default:
+		return SECFailure;
+	}
+}
+
+
+void *ssl_connect( char *host, int port, ssl_input_function func, gpointer data )
+{
+	struct scd *conn = g_new0( struct scd, 1 );
+	
+	conn->fd = proxy_connect( host, port, ssl_connected, conn );
+	conn->func = func;
+	conn->data = data;
+	
+	if( conn->fd < 0 )
+	{
+		g_free( conn );
+		return( NULL );
+	}
+	
+	if( !initialized )
+	{
+		PR_Init( PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1);
+		NSS_NoDB_Init(NULL);
+		NSS_SetDomesticPolicy();
+	}
+
+	
+	return( conn );
+}
+
+static gboolean ssl_connected( gpointer data, gint source, b_input_condition cond )
+{
+	struct scd *conn = data;
+	
+	if( source == -1 )
+		goto ssl_connected_failure;
+	
+	/* Until we find out how to handle non-blocking I/O with NSS... */
+	sock_make_blocking( conn->fd );
+	
+	conn->prfd = SSL_ImportFD(NULL, PR_ImportTCPSocket(source));
+	SSL_OptionSet(conn->prfd, SSL_SECURITY, PR_TRUE);
+	SSL_OptionSet(conn->prfd, SSL_HANDSHAKE_AS_CLIENT, PR_TRUE);
+	SSL_BadCertHook(conn->prfd, (SSLBadCertHandler)nss_bad_cert, NULL);
+	SSL_AuthCertificateHook(conn->prfd, (SSLAuthCertificate)nss_auth_cert, (void *)CERT_GetDefaultCertDB());
+	SSL_ResetHandshake(conn->prfd, PR_FALSE);
+
+	if (SSL_ForceHandshake(conn->prfd)) {
+		goto ssl_connected_failure;
+	}
+	
+	
+	conn->established = TRUE;
+	conn->func( conn->data, conn, cond );
+	return FALSE;
+	
+	ssl_connected_failure:
+	
+	conn->func( conn->data, NULL, cond );
+	
+	PR_Close( conn -> prfd );
+	if( source >= 0 ) closesocket( source );
+	g_free( conn );
+	
+	return FALSE;
+}
+
+int ssl_read( void *conn, char *buf, int len )
+{
+	if( !((struct scd*)conn)->established )
+		return( 0 );
+	
+	return( PR_Read( ((struct scd*)conn)->prfd, buf, len ) );
+}
+
+int ssl_write( void *conn, const char *buf, int len )
+{
+	if( !((struct scd*)conn)->established )
+		return( 0 );
+	
+	return( PR_Write ( ((struct scd*)conn)->prfd, buf, len ) );
+}
+
+void ssl_disconnect( void *conn_ )
+{
+	struct scd *conn = conn_;
+	
+	PR_Close( conn->prfd );
+	closesocket( conn->fd );
+	
+	g_free( conn );
+}
+
+int ssl_getfd( void *conn )
+{
+	return( ((struct scd*)conn)->fd );
+}
+
+b_input_condition ssl_getdirection( void *conn )
+{
+	/* Just in case someone calls us, let's return the most likely case: */
+	return GAIM_INPUT_READ;
+}
Index: protocols/ssl_openssl.c
===================================================================
--- protocols/ssl_openssl.c	(revision 3f9440db856c1b1cde54eb919543cfc23ea09983)
+++ protocols/ssl_openssl.c	(revision 3f9440db856c1b1cde54eb919543cfc23ea09983)
@@ -0,0 +1,221 @@
+  /********************************************************************\
+  * BitlBee -- An IRC to other IM-networks gateway                     *
+  *                                                                    *
+  * Copyright 2002-2004 Wilmer van der Gaast and others                *
+  \********************************************************************/
+
+/* SSL module - OpenSSL version                                         */
+
+/*
+  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
+  the Free Software Foundation; either version 2 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License with
+  the Debian GNU/Linux distribution in /usr/share/common-licenses/GPL;
+  if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+  Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include <openssl/crypto.h>
+#include <openssl/rand.h>
+#include <openssl/x509.h>
+#include <openssl/pem.h>
+#include <openssl/ssl.h>
+#include <openssl/err.h>
+
+#include "proxy.h"
+#include "ssl_client.h"
+#include "sock.h"
+
+int ssl_errno = 0;
+
+static gboolean initialized = FALSE;
+
+struct scd
+{
+	ssl_input_function func;
+	gpointer data;
+	int fd;
+	gboolean established;
+	
+	int inpa;
+	int lasterr;		/* Necessary for SSL_get_error */
+	SSL *ssl;
+	SSL_CTX *ssl_ctx;
+};
+
+static gboolean ssl_connected( gpointer data, gint source, b_input_condition cond );
+
+
+void *ssl_connect( char *host, int port, ssl_input_function func, gpointer data )
+{
+	struct scd *conn = g_new0( struct scd, 1 );
+	SSL_METHOD *meth;
+	
+	conn->fd = proxy_connect( host, port, ssl_connected, conn );
+	conn->func = func;
+	conn->data = data;
+	
+	if( conn->fd < 0 )
+	{
+		g_free( conn );
+		return( NULL );
+	}
+	
+	if( !initialized )
+	{
+		initialized = TRUE;
+		SSLeay_add_ssl_algorithms();
+	}
+	
+	meth = TLSv1_client_method();
+	conn->ssl_ctx = SSL_CTX_new( meth );
+	if( conn->ssl_ctx == NULL )
+	{
+		conn->fd = -1;
+		return( NULL );
+	}
+	
+	conn->ssl = SSL_new( conn->ssl_ctx );
+	if( conn->ssl == NULL )
+	{
+		conn->fd = -1;
+		return( NULL );
+	}
+	
+	return( conn );
+}
+
+static gboolean ssl_handshake( gpointer data, gint source, b_input_condition cond );
+
+static gboolean ssl_connected( gpointer data, gint source, b_input_condition cond )
+{
+	struct scd *conn = data;
+	
+	if( source == -1 )
+		return ssl_handshake( data, -1, cond );
+	
+	/* We can do at least the handshake with non-blocking I/O */
+	sock_make_nonblocking( conn->fd );
+	SSL_set_fd( conn->ssl, conn->fd );
+	
+	return ssl_handshake( data, source, cond );
+}	
+
+static gboolean ssl_handshake( gpointer data, gint source, b_input_condition cond )
+{
+	struct scd *conn = data;
+	int st;
+	
+	if( ( st = SSL_connect( conn->ssl ) ) < 0 )
+	{
+		conn->lasterr = SSL_get_error( conn->ssl, st );
+		if( conn->lasterr != SSL_ERROR_WANT_READ && conn->lasterr != SSL_ERROR_WANT_WRITE )
+			goto ssl_connected_failure;
+		
+		conn->inpa = b_input_add( conn->fd, ssl_getdirection( conn ), ssl_handshake, data );
+		return FALSE;
+	}
+	
+	conn->established = TRUE;
+	sock_make_blocking( conn->fd );		/* For now... */
+	conn->func( conn->data, conn, cond );
+	return FALSE;
+	
+ssl_connected_failure:
+	conn->func( conn->data, NULL, cond );
+	
+	if( conn->ssl )
+	{
+		SSL_shutdown( conn->ssl );
+		SSL_free( conn->ssl );
+	}
+	if( conn->ssl_ctx )
+	{
+		SSL_CTX_free( conn->ssl_ctx );
+	}
+	if( source >= 0 ) closesocket( source );
+	g_free( conn );
+	
+	return FALSE;
+}
+
+int ssl_read( void *conn, char *buf, int len )
+{
+	int st;
+	
+	if( !((struct scd*)conn)->established )
+	{
+		ssl_errno = SSL_NOHANDSHAKE;
+		return -1;
+	}
+	
+	st = SSL_read( ((struct scd*)conn)->ssl, buf, len );
+	
+	ssl_errno = SSL_OK;
+	if( st <= 0 )
+	{
+		((struct scd*)conn)->lasterr = SSL_get_error( ((struct scd*)conn)->ssl, st );
+		if( ((struct scd*)conn)->lasterr == SSL_ERROR_WANT_READ || ((struct scd*)conn)->lasterr == SSL_ERROR_WANT_WRITE )
+			ssl_errno = SSL_AGAIN;
+	}
+	
+	return st;
+}
+
+int ssl_write( void *conn, const char *buf, int len )
+{
+	int st;
+	
+	if( !((struct scd*)conn)->established )
+	{
+		ssl_errno = SSL_NOHANDSHAKE;
+		return -1;
+	}
+	
+	st = SSL_write( ((struct scd*)conn)->ssl, buf, len );
+	
+	ssl_errno = SSL_OK;
+	if( st <= 0 )
+	{
+		((struct scd*)conn)->lasterr = SSL_get_error( ((struct scd*)conn)->ssl, st );
+		if( ((struct scd*)conn)->lasterr == SSL_ERROR_WANT_READ || ((struct scd*)conn)->lasterr == SSL_ERROR_WANT_WRITE )
+			ssl_errno = SSL_AGAIN;
+	}
+	
+	return st;
+}
+
+void ssl_disconnect( void *conn_ )
+{
+	struct scd *conn = conn_;
+	
+	if( conn->inpa != -1 )
+		b_event_remove( conn->inpa );
+	
+	if( conn->established )
+		SSL_shutdown( conn->ssl );
+	
+	closesocket( conn->fd );
+	
+	SSL_free( conn->ssl );
+	SSL_CTX_free( conn->ssl_ctx );
+	g_free( conn );
+}
+
+int ssl_getfd( void *conn )
+{
+	return( ((struct scd*)conn)->fd );
+}
+
+b_input_condition ssl_getdirection( void *conn )
+{
+	return( ((struct scd*)conn)->lasterr == SSL_ERROR_WANT_WRITE ? GAIM_INPUT_WRITE : GAIM_INPUT_READ );
+}
Index: protocols/yahoo/libyahoo2.c
===================================================================
--- protocols/yahoo/libyahoo2.c	(revision fef6116e89bb0651c72454effbb51e04e9e1b8dc)
+++ protocols/yahoo/libyahoo2.c	(revision 3f9440db856c1b1cde54eb919543cfc23ea09983)
@@ -89,6 +89,4 @@
 #define vsnprintf _vsnprintf
 #endif
-
-#include "base64.h"
 
 #ifdef USE_STRUCT_CALLBACKS
@@ -697,8 +695,32 @@
 }
 
+static char base64digits[] = 	"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+				"abcdefghijklmnopqrstuvwxyz"
+				"0123456789._";
+static void to_y64(unsigned char *out, const unsigned char *in, int inlen)
 /* raw bytes in quasi-big-endian order to base 64 string (NUL-terminated) */
-static void to_y64(unsigned char *out, const unsigned char *in, int inlen)
-{
-	base64_encode_real(in, inlen, out, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789._-");
+{
+	for (; inlen >= 3; inlen -= 3)
+		{
+			*out++ = base64digits[in[0] >> 2];
+			*out++ = base64digits[((in[0]<<4) & 0x30) | (in[1]>>4)];
+			*out++ = base64digits[((in[1]<<2) & 0x3c) | (in[2]>>6)];
+			*out++ = base64digits[in[2] & 0x3f];
+			in += 3;
+		}
+	if (inlen > 0)
+		{
+			unsigned char fragment;
+
+			*out++ = base64digits[in[0] >> 2];
+			fragment = (in[0] << 4) & 0x30;
+			if (inlen > 1)
+				fragment |= in[1] >> 4;
+			*out++ = base64digits[fragment];
+			*out++ = (inlen < 2) ? '-' 
+					: base64digits[(in[1] << 2) & 0x3c];
+			*out++ = '-';
+		}
+	*out = '\0';
 }
 
Index: protocols/yahoo/yahoo.c
===================================================================
--- protocols/yahoo/yahoo.c	(revision fef6116e89bb0651c72454effbb51e04e9e1b8dc)
+++ protocols/yahoo/yahoo.c	(revision 3f9440db856c1b1cde54eb919543cfc23ea09983)
@@ -121,7 +121,7 @@
 }
 
-static void byahoo_login( account_t *acc )
-{
-	struct gaim_connection *gc = new_gaim_conn( acc );
+static void byahoo_login( struct aim_user *user )
+{
+	struct gaim_connection *gc = new_gaim_conn( user );
 	struct byahoo_data *yd = gc->proto_data = g_new0( struct byahoo_data, 1 );
 	
@@ -130,5 +130,5 @@
 	
 	set_login_progress( gc, 1, "Connecting" );
-	yd->y2_id = yahoo_init( acc->user, acc->pass );
+	yd->y2_id = yahoo_init( user->username, user->password );
 	yahoo_login( yd->y2_id, yd->current_status );
 }
@@ -425,5 +425,5 @@
 		yd = gc->proto_data;
 		
-		if( strcmp( gc->acc->prpl->name, "yahoo" ) == 0 && yd->y2_id == id )
+		if( !strcmp(gc->prpl->name, "yahoo") && yd->y2_id == id )
 			return( gc );
 	}
Index: query.c
===================================================================
--- query.c	(revision fef6116e89bb0651c72454effbb51e04e9e1b8dc)
+++ query.c	(revision 3f9440db856c1b1cde54eb919543cfc23ea09983)
@@ -63,5 +63,5 @@
 	}
 	
-	if( g_strcasecmp( set_getstr( &irc->set, "query_order" ), "lifo" ) == 0 || irc->queries == q )
+	if( g_strcasecmp( set_getstr( irc, "query_order" ), "lifo" ) == 0 || irc->queries == q )
 		query_display( irc, q );
 	
@@ -172,5 +172,5 @@
 	query_t *q;
 	
-	if( g_strcasecmp( set_getstr( &irc->set, "query_order" ), "fifo" ) == 0 )
+	if( g_strcasecmp( set_getstr( irc, "query_order" ), "fifo" ) == 0 )
 		q = irc->queries;
 	else
Index: root_commands.c
===================================================================
--- root_commands.c	(revision fef6116e89bb0651c72454effbb51e04e9e1b8dc)
+++ root_commands.c	(revision 3f9440db856c1b1cde54eb919543cfc23ea09983)
@@ -127,10 +127,7 @@
 }
 
-static void cmd_account( irc_t *irc, char **cmd );
-
 static void cmd_identify( irc_t *irc, char **cmd )
 {
 	storage_status_t status = storage_load( irc->nick, cmd[1], irc );
-	char *account_on[] = { "account", "on", NULL };
 	
 	switch (status) {
@@ -142,12 +139,9 @@
 		break;
 	case STORAGE_OK:
-		irc_usermsg( irc, "Password accepted, settings and accounts loaded" );
+		irc_usermsg( irc, "Password accepted" );
 		irc_umode_set( irc, "+R", 1 );
-		if( set_getint( &irc->set, "auto_connect" ) )
-			cmd_account( irc, account_on );
 		break;
-	case STORAGE_OTHER_ERROR:
 	default:
-		irc_usermsg( irc, "Unknown error while loading configuration" );
+		irc_usermsg( irc, "Something very weird happened" );
 		break;
 	}
@@ -232,6 +226,7 @@
 
 		a = account_add( irc, prpl, cmd[3], cmd[4] );
+		
 		if( cmd[5] )
-			set_setstr( &a->set, "server", cmd[5] );
+			a->server = g_strdup( cmd[5] );
 		
 		irc_usermsg( irc, "Account successfully added" );
@@ -311,5 +306,5 @@
 			
 				for( a = irc->accounts; a; a = a->next )
-					if( !a->gc && a->auto_connect )
+					if( !a->gc )
 						account_on( irc, a );
 			} 
@@ -357,66 +352,4 @@
 		}
 	}
-	else if( g_strcasecmp( cmd[1], "set" ) == 0 )
-	{
-		char *acc_handle, *set_name = NULL, *tmp;
-		
-		if( !cmd[2] )
-		{
-			irc_usermsg( irc, "Not enough parameters given (need %d)", 2 );
-			return;
-		}
-		
-		acc_handle = g_strdup( cmd[2] );
-		if( ( tmp = strchr( acc_handle, '/' ) ) )
-		{
-			*tmp = 0;
-			set_name = tmp + 1;
-		}
-		a = account_get( irc, acc_handle );
-		
-		if( a == NULL )
-		{
-			irc_usermsg( irc, "Invalid account" );
-			return;
-		}
-		
-		if( cmd[3] )
-		{
-			set_t *s = set_find( &a->set, set_name );
-			
-			if( a->gc && s && s->flags & ACC_SET_OFFLINE_ONLY )
-			{
-				irc_usermsg( irc, "This setting can only be changed when the account is off-line" );
-				return;
-			}
-			
-			set_setstr( &a->set, set_name, cmd[3] );
-			
-			if( ( strcmp( cmd[3], "=" ) ) == 0 && cmd[4] )
-				irc_usermsg( irc, "Warning: Correct syntax: \002account set <variable> <value>\002 (without =)" );
-		}
-		if( set_name ) /* else 'forgotten' on purpose.. Must show new value after changing */
-		{
-			char *s = set_getstr( &a->set, set_name );
-			if( s )
-				irc_usermsg( irc, "%s = `%s'", set_name, s );
-			else
-				irc_usermsg( irc, "%s is empty", set_name );
-		}
-		else
-		{
-			set_t *s = a->set;
-			while( s )
-			{
-				if( s->value || s->def )
-					irc_usermsg( irc, "%s = `%s'", s->key, s->value?s->value:s->def );
-				else
-					irc_usermsg( irc, "%s is empty", s->key );
-				s = s->next;
-			}
-		}
-		
-		g_free( acc_handle );
-	}
 	else
 	{
@@ -461,5 +394,5 @@
 		else
 		{
-			nick_set( irc, cmd[2], a->gc->acc->prpl, cmd[3] );
+			nick_set( irc, cmd[2], a->gc->prpl, cmd[3] );
 		}
 	}
@@ -468,5 +401,5 @@
 	   add them to your *real* (server-side) contact list. */
 	if( add_for_real )
-		a->gc->acc->prpl->add_buddy( a->gc, cmd[2] );
+		a->gc->prpl->add_buddy( a->gc, cmd[2] );
 		
 	add_buddy( a->gc, NULL, cmd[2], cmd[2] );
@@ -502,5 +435,5 @@
 	}
 	
-	if( !gc->acc->prpl->get_info )
+	if( !gc->prpl->get_info )
 	{
 		irc_usermsg( irc, "Command `%s' not supported by this protocol", cmd[0] );
@@ -508,5 +441,5 @@
 	else
 	{
-		gc->acc->prpl->get_info( gc, cmd[2] );
+		gc->prpl->get_info( gc, cmd[2] );
 	}
 }
@@ -543,5 +476,5 @@
 		else if( u->send_handler == buddy_send_handler )
 		{
-			nick_set( irc, u->handle, u->gc->acc->prpl, cmd[2] );
+			nick_set( irc, u->handle, u->gc->prpl, cmd[2] );
 		}
 		
@@ -562,5 +495,5 @@
 	s = g_strdup( u->handle );
 	
-	u->gc->acc->prpl->remove_buddy( u->gc, u->handle, NULL );
+	u->gc->prpl->remove_buddy( u->gc, u->handle, NULL );
 	user_del( irc, cmd[1] );
 	nick_del( irc, cmd[1] );
@@ -619,5 +552,5 @@
 	}
 	
-	if( !gc->acc->prpl->add_deny || !gc->acc->prpl->rem_permit )
+	if( !gc->prpl->add_deny || !gc->prpl->rem_permit )
 	{
 		irc_usermsg( irc, "Command `%s' not supported by this protocol", cmd[0] );
@@ -678,5 +611,5 @@
 	}
 	
-	if( !gc->acc->prpl->rem_deny || !gc->acc->prpl->add_permit )
+	if( !gc->prpl->rem_deny || !gc->prpl->add_permit )
 	{
 		irc_usermsg( irc, "Command `%s' not supported by this protocol", cmd[0] );
@@ -733,5 +666,5 @@
 	if( cmd[1] && cmd[2] )
 	{
-		set_setstr( &irc->set, cmd[1], cmd[2] );
+		set_setstr( irc, cmd[1], cmd[2] );
 		
 		if( ( strcmp( cmd[2], "=" ) ) == 0 && cmd[3] )
@@ -740,9 +673,7 @@
 	if( cmd[1] ) /* else 'forgotten' on purpose.. Must show new value after changing */
 	{
-		char *s = set_getstr( &irc->set, cmd[1] );
+		char *s = set_getstr( irc, cmd[1] );
 		if( s )
 			irc_usermsg( irc, "%s = `%s'", cmd[1], s );
-		else
-			irc_usermsg( irc, "%s is empty", cmd[1] );
 	}
 	else
@@ -753,6 +684,4 @@
 			if( s->value || s->def )
 				irc_usermsg( irc, "%s = `%s'", s->key, s->value?s->value:s->def );
-			else
-				irc_usermsg( irc, "%s is empty", s->key );
 			s = s->next;
 		}
@@ -798,5 +727,5 @@
 		if( online == 1 )
 		{
-			g_snprintf( s, sizeof( s ) - 1, "%s@%s (%s)", u->user, u->host, u->gc->acc->prpl->name );
+			g_snprintf( s, sizeof( s ) - 1, "%s@%s (%s)", u->user, u->host, u->gc->user->prpl->name );
 			irc_usermsg( irc, format, u->nick, s, "Online" );
 		}
@@ -809,5 +738,5 @@
 		if( away == 1 )
 		{
-			g_snprintf( s, sizeof( s ) - 1, "%s@%s (%s)", u->user, u->host, u->gc->acc->prpl->name );
+			g_snprintf( s, sizeof( s ) - 1, "%s@%s (%s)", u->user, u->host, u->gc->user->prpl->name );
 			irc_usermsg( irc, format, u->nick, s, u->away );
 		}
@@ -819,5 +748,5 @@
 		if( offline == 1 )
 		{
-			g_snprintf( s, sizeof( s ) - 1, "%s@%s (%s)", u->user, u->host, u->gc->acc->prpl->name );
+			g_snprintf( s, sizeof( s ) - 1, "%s@%s (%s)", u->user, u->host, u->gc->user->prpl->name );
 			irc_usermsg( irc, format, u->nick, s, "Offline" );
 		}
@@ -844,5 +773,5 @@
 		irc_usermsg( irc, "Your name is `%s'" , a->gc->displayname ? a->gc->displayname : "NULL" );
 	}
-	else if ( !a->prpl->set_info ) 
+	else if ( !a->gc->prpl->set_info ) 
 	{
 		irc_usermsg( irc, "Command `%s' not supported by this protocol", cmd[0] );
@@ -852,5 +781,5 @@
 		irc_usermsg( irc, "Setting your name to `%s'", cmd[2] );
 		
-		a->prpl->set_info( a->gc, cmd[2] );
+		a->gc->prpl->set_info( a->gc, cmd[2] );
 	}
 }
@@ -871,5 +800,5 @@
 	for( num = 0; q; q = q->next, num ++ )
 		if( q->gc ) /* Not necessary yet, but it might come later */
-			irc_usermsg( irc, "%d, %s(%s): %s", num, q->gc->acc->prpl->name, q->gc->username, q->question );
+			irc_usermsg( irc, "%d, %s(%s): %s", num, q->gc->prpl->name, q->gc->username, q->question );
 		else
 			irc_usermsg( irc, "%d, BitlBee: %s", num, q->question );
@@ -899,9 +828,8 @@
 			user_t *u;
 			
-			/* FIXME: Hmmm, this is actually pretty dangerous code... REMOVEME? :-) */
 			for( u = irc->users; u; u = u->next )
 				if( u->gc == gc )
 				{
-					u->gc->acc->prpl->remove_buddy( u->gc, u->handle, NULL );
+					u->gc->prpl->remove_buddy( u->gc, u->handle, NULL );
 					user_del( irc, u->nick );
 				}
@@ -918,7 +846,7 @@
 	for( n = gc->irc->nicks; n; n = n->next )
 	{
-		if( n->proto == gc->acc->prpl && !user_findhandle( gc, n->handle ) )
-		{
-	                gc->acc->prpl->add_buddy( gc, n->handle );
+		if( n->proto == gc->prpl && !user_findhandle( gc, n->handle ) )
+		{
+	                gc->prpl->add_buddy( gc, n->handle );
 	                add_buddy( gc, NULL, n->handle, NULL );
 		}
Index: set.c
===================================================================
--- set.c	(revision fef6116e89bb0651c72454effbb51e04e9e1b8dc)
+++ set.c	(revision 3f9440db856c1b1cde54eb919543cfc23ea09983)
@@ -26,22 +26,21 @@
 #include "bitlbee.h"
 
-set_t *set_add( set_t **head, char *key, char *def, void *eval, void *data )
-{
-	set_t *s = set_find( head, key );
-	
-	/* Possibly the setting already exists. If it doesn't exist yet,
-	   we create it. If it does, we'll just change the default. */
+set_t *set_add( irc_t *irc, char *key, char *def, void *eval )
+{
+	set_t *s = set_find( irc, key );
+	
 	if( !s )
 	{
-		if( ( s = *head ) )
+		if( ( s = irc->set ) )
 		{
 			while( s->next ) s = s->next;
-			s->next = g_new0( set_t, 1 );
+			s->next = g_new ( set_t, 1 );
 			s = s->next;
 		}
 		else
 		{
-			s = *head = g_new0( set_t, 1 );
+			s = irc->set = g_new( set_t, 1 );
 		}
+		memset( s, 0, sizeof( set_t ) );
 		s->key = g_strdup( key );
 	}
@@ -54,13 +53,17 @@
 	if( def ) s->def = g_strdup( def );
 	
-	s->eval = eval;
-	s->data = data;
-	
-	return s;
-}
-
-set_t *set_find( set_t **head, char *key )
-{
-	set_t *s = *head;
+	if( s->eval )
+	{
+		g_free( s->eval );
+		s->eval = NULL;
+	}
+	if( eval ) s->eval = eval;
+	
+	return( s );
+}
+
+set_t *set_find( irc_t *irc, char *key )
+{
+	set_t *s = irc->set;
 	
 	while( s )
@@ -71,54 +74,44 @@
 	}
 	
-	return s;
-}
-
-char *set_getstr( set_t **head, char *key )
-{
-	set_t *s = set_find( head, key );
+	return( s );
+}
+
+char *set_getstr( irc_t *irc, char *key )
+{
+	set_t *s = set_find( irc, key );
 	
 	if( !s || ( !s->value && !s->def ) )
-		return NULL;
-	
-	return s->value ? s->value : s->def;
-}
-
-int set_getint( set_t **head, char *key )
-{
-	char *s = set_getstr( head, key );
+		return( NULL );
+	
+	return( s->value?s->value:s->def );
+}
+
+int set_getint( irc_t *irc, char *key )
+{
+	char *s = set_getstr( irc, key );
 	int i = 0;
 	
 	if( !s )
-		return 0;
+		return( 0 );
 	
 	if( ( g_strcasecmp( s, "true" ) == 0 ) || ( g_strcasecmp( s, "yes" ) == 0 ) || ( g_strcasecmp( s, "on" ) == 0 ) )
-		return 1;
+		return( 1 );
 	
 	if( sscanf( s, "%d", &i ) != 1 )
-		return 0;
-	
-	return i;
-}
-
-int set_getbool( set_t **head, char *key )
-{
-	char *s = set_getstr( head, key );
+		return( 0 );
+	
+	return( i );
+}
+
+int set_setstr( irc_t *irc, char *key, char *value )
+{
+	set_t *s = set_find( irc, key );
+	char *nv = value;
 	
 	if( !s )
-		return 0;
-	
-	return bool2int( s );
-}
-
-int set_setstr( set_t **head, char *key, char *value )
-{
-	set_t *s = set_find( head, key );
-	char *nv = value;
-	
-	if( !s )
-		s = set_add( head, key, NULL, NULL, NULL );
-	
-	if( s->eval && !( nv = s->eval( s, value ) ) )
-		return 0;
+		s = set_add( irc, key, NULL, NULL );
+	
+	if( s->eval && !( nv = s->eval( irc, s, value ) ) )
+		return( 0 );
 	
 	if( s->value )
@@ -128,6 +121,4 @@
 	}
 	
-	/* If there's a default setting and it's equal to what we're trying to
-	   set, stick with s->value = NULL. Otherwise, remember the setting. */
 	if( !s->def || ( strcmp( nv, s->def ) != 0 ) )
 		s->value = g_strdup( nv );
@@ -136,18 +127,18 @@
 		g_free( nv );
 	
-	return 1;
-}
-
-int set_setint( set_t **head, char *key, int value )
+	return( 1 );
+}
+
+int set_setint( irc_t *irc, char *key, int value )
 {
 	char s[24];	/* Not quite 128-bit clean eh? ;-) */
 	
-	g_snprintf( s, sizeof( s ), "%d", value );
-	return set_setstr( head, key, s );
-}
-
-void set_del( set_t **head, char *key )
-{
-	set_t *s = *head, *t = NULL;
+	sprintf( s, "%d", value );
+	return( set_setstr( irc, key, s ) );
+}
+
+void set_del( irc_t *irc, char *key )
+{
+	set_t *s = irc->set, *t = NULL;
 	
 	while( s )
@@ -162,5 +153,5 @@
 			t->next = s->next;
 		else
-			*head = s->next;
+			irc->set = s->next;
 		
 		g_free( s->key );
@@ -171,21 +162,25 @@
 }
 
-char *set_eval_int( set_t *set, char *value )
-{
-	char *s;
-	
-	for( s = value; *s; s ++ )
-		if( !isdigit( *s ) )
-			return NULL;
-	
-	return value;
-}
-
-char *set_eval_bool( set_t *set, char *value )
-{
-	return is_bool( value ) ? value : NULL;
-}
-
-char *set_eval_to_char( set_t *set, char *value )
+char *set_eval_int( irc_t *irc, set_t *set, char *value )
+{
+	char *s = value;
+	
+	for( ; *s; s ++ )
+		if( *s < '0' || *s > '9' )
+			return( NULL );
+	
+	return( value );
+}
+
+char *set_eval_bool( irc_t *irc, set_t *set, char *value )
+{
+	if( ( g_strcasecmp( value, "true" ) == 0 ) || ( g_strcasecmp( value, "yes" ) == 0 ) || ( g_strcasecmp( value, "on" ) == 0 ) )
+		return( value );
+	if( ( g_strcasecmp( value, "false" ) == 0 ) || ( g_strcasecmp( value, "no" ) == 0 ) || ( g_strcasecmp( value, "off" ) == 0 ) )
+		return( value );
+	return( set_eval_int( irc, set, value ) );
+}
+
+char *set_eval_to_char( irc_t *irc, set_t *set, char *value )
 {
 	char *s = g_new( char, 3 );
@@ -196,41 +191,35 @@
 		sprintf( s, "%c ", *value );
 	
-	return s;
-}
-
-char *set_eval_ops( set_t *set, char *value )
-{
-	irc_t *irc = set->data;
-	
+	return( s );
+}
+
+char *set_eval_ops( irc_t *irc, set_t *set, char *value )
+{
 	if( g_strcasecmp( value, "user" ) == 0 )
+	{
 		irc_write( irc, ":%s!%s@%s MODE %s %s %s %s", irc->mynick, irc->mynick, irc->myhost,
 		                                              irc->channel, "+o-o", irc->nick, irc->mynick );
+		return( value );
+	}
 	else if( g_strcasecmp( value, "root" ) == 0 )
+	{
 		irc_write( irc, ":%s!%s@%s MODE %s %s %s %s", irc->mynick, irc->mynick, irc->myhost,
 		                                              irc->channel, "-o+o", irc->nick, irc->mynick );
+		return( value );
+	}
 	else if( g_strcasecmp( value, "both" ) == 0 )
+	{
 		irc_write( irc, ":%s!%s@%s MODE %s %s %s %s", irc->mynick, irc->mynick, irc->myhost,
 		                                              irc->channel, "+oo", irc->nick, irc->mynick );
+		return( value );
+	}
 	else if( g_strcasecmp( value, "none" ) == 0 )
+	{
 		irc_write( irc, ":%s!%s@%s MODE %s %s %s %s", irc->mynick, irc->mynick, irc->myhost,
 		                                              irc->channel, "-oo", irc->nick, irc->mynick );
-	else
-		return NULL;
-	
-	return value;
-}
-
-char *set_eval_charset( set_t *set, char *value )
-{
-	GIConv cd;
-
-	if ( g_strncasecmp( value, "none", 4 ) == 0 )
-		return value;
-
-	cd = g_iconv_open( "UTF-8", value );
-	if( cd == (GIConv) -1 )
-		return NULL;
-
-	g_iconv_close( cd );
-	return value;
-}
+		return( value );
+	}
+	
+	return( NULL );
+}
+
Index: set.h
===================================================================
--- set.h	(revision fef6116e89bb0651c72454effbb51e04e9e1b8dc)
+++ set.h	(revision 3f9440db856c1b1cde54eb919543cfc23ea09983)
@@ -2,5 +2,5 @@
   * BitlBee -- An IRC to other IM-networks gateway                     *
   *                                                                    *
-  * Copyright 2002-2006 Wilmer van der Gaast and others                *
+  * Copyright 2002-2004 Wilmer van der Gaast and others                *
   \********************************************************************/
 
@@ -26,32 +26,27 @@
 typedef struct set
 {
-	void *data;
-	
 	char *key;
 	char *value;
 	char *def;	/* Default */
 	
-	int flags;
-	
-	/* Eval: Returns NULL if the value is incorrect or exactly the
-	   passed value variable. When returning a corrected value,
-	   set_setstr() should be able to free() the returned string! */
-	char *(*eval) ( struct set *set, char *value );
+	/* Eval: Returns NULL if the value is incorrect. Can return a
+	   corrected value. set_setstr() should be able to free() the
+	   returned string! */
+	char *(*eval) ( irc_t *irc, struct set *set, char *value );
 	struct set *next;
 } set_t;
 
-set_t *set_add( set_t **head, char *key, char *def, void *eval, void *data );
-set_t *set_find( set_t **head, char *key );
-G_MODULE_EXPORT char *set_getstr( set_t **head, char *key );
-G_MODULE_EXPORT int set_getint( set_t **head, char *key );
-G_MODULE_EXPORT int set_getbool( set_t **head, char *key );
-int set_setstr( set_t **head, char *key, char *value );
-int set_setint( set_t **head, char *key, int value );
-void set_del( set_t **head, char *key );
+set_t *set_add( irc_t *irc, char *key, char *def, void *eval );
+G_MODULE_EXPORT set_t *set_find( irc_t *irc, char *key );
+G_MODULE_EXPORT char *set_getstr( irc_t *irc, char *key );
+G_MODULE_EXPORT int set_getint( irc_t *irc, char *key );
+int set_setstr( irc_t *irc, char *key, char *value );
+int set_setint( irc_t *irc, char *key, int value );
+void set_del( irc_t *irc, char *key );
 
-char *set_eval_int( set_t *set, char *value );
-char *set_eval_bool( set_t *set, char *value );
+char *set_eval_int( irc_t *irc, set_t *set, char *value );
+char *set_eval_bool( irc_t *irc, set_t *set, char *value );
+char *set_eval_to_char( irc_t *irc, set_t *set, char *value );
+char *set_eval_ops( irc_t *irc, set_t *set, char *value );
 
-char *set_eval_to_char( set_t *set, char *value );
-char *set_eval_ops( set_t *set, char *value );
-char *set_eval_charset( set_t *set, char *value );
+
Index: storage.c
===================================================================
--- storage.c	(revision fef6116e89bb0651c72454effbb51e04e9e1b8dc)
+++ storage.c	(revision 3f9440db856c1b1cde54eb919543cfc23ea09983)
@@ -6,6 +6,4 @@
 
 /* Support for multiple storage backends */
-
-/* Copyright (C) 2005 Jelmer Vernooij <jelmer@samba.org> */
 
 /*
@@ -31,7 +29,7 @@
 
 extern storage_t storage_text;
-extern storage_t storage_xml;
 
-static GList *storage_backends = NULL;
+static GList text_entry = { &storage_text, NULL, NULL };
+static GList *storage_backends = &text_entry;
 
 void register_storage_backend(storage_t *backend)
@@ -43,5 +41,5 @@
 {
 	GList *gl;
-	storage_t *st = NULL;
+	storage_t *st;
 
 	for (gl = storage_backends; gl; gl = gl->next) {
@@ -65,8 +63,5 @@
 	int i;
 	storage_t *storage;
-	
-	register_storage_backend(&storage_text);
-	register_storage_backend(&storage_xml);
-	
+
 	storage = storage_init_single(primary);
 	if (storage == NULL)
Index: storage.h
===================================================================
--- storage.h	(revision fef6116e89bb0651c72454effbb51e04e9e1b8dc)
+++ storage.h	(revision 3f9440db856c1b1cde54eb919543cfc23ea09983)
@@ -33,6 +33,6 @@
 	STORAGE_ALREADY_EXISTS,
 	STORAGE_OTHER_ERROR /* Error that isn't caused by user input, such as 
-	                       a database that is unreachable. log() will be 
-	                       used for the exact error message */
+						   a database that is unreachable. log() will be 
+						   used for the exact error message */
 } storage_status_t;
 
Index: orage_ldap.c
===================================================================
--- storage_ldap.c	(revision fef6116e89bb0651c72454effbb51e04e9e1b8dc)
+++ 	(revision )
@@ -1,177 +1,0 @@
-  /********************************************************************\
-  * BitlBee -- An IRC to other IM-networks gateway                     *
-  *                                                                    *
-  * Copyright 2002-2004 Wilmer van der Gaast and others                *
-  \********************************************************************/
-
-/* Storage backend that uses a LDAP database */
-
-/* Copyright (C) 2006 Jelmer Vernooij <jelmer@samba.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
-  the Free Software Foundation; either version 2 of the License, or
-  (at your option) any later version.
-
-  This program is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-  GNU General Public License for more details.
-
-  You should have received a copy of the GNU General Public License with
-  the Debian GNU/Linux distribution in /usr/share/common-licenses/GPL;
-  if not, write to the Free Software Foundation, Inc., 59 Temple Place,
-  Suite 330, Boston, MA  02111-1307  USA
-*/
-
-#define BITLBEE_CORE
-#include "bitlbee.h"
-#include <ldap.h>
-
-#define BB_LDAP_HOST "localhost"
-#define BB_LDAP_BASE ""
-
-static char *nick_dn(const char *nick)
-{
-	return g_strdup_printf("bitlBeeNick=%s%s%s", nick, BB_LDAP_BASE?",":"", BB_LDAP_BASE?BB_LDAP_BASE:"");
-}
-
-static storage_status_t nick_connect(const char *nick, const char *password, LDAP **ld)
-{
-	char *mydn;
-	int ret;
-	storage_status_t status;
-	*ld = ldap_init(BB_LDAP_HOST, LDAP_PORT);
-
-	if (!ld) {
-		log_message( LOGLVL_WARNING, "Unable to connect to LDAP server at %s", BB_LDAP_HOST );
-		return STORAGE_OTHER_ERROR;
-	}
-
-	mydn = nick_dn(nick);
-
-	ret = ldap_simple_bind_s(*ld, mydn, password);
-
-	switch (ret) {
-	 case LDAP_SUCCESS: status = STORAGE_OK; break;
-	 case LDAP_INVALID_CREDENTIALS: status = STORAGE_INVALID_PASSWORD; break;
-	 default: 
-		log_message( LOGLVL_WARNING, "Unable to authenticate %s: %s", mydn, ldap_err2string(ret) );
-		status = STORAGE_OTHER_ERROR;
-		break;
-	}
-
-	g_free(mydn);
-
-	return status;
-}
-
-static storage_status_t sldap_load ( const char *my_nick, const char* password, irc_t *irc )
-{
-	LDAPMessage *res, *msg;
-	LDAP *ld;
-	int ret, i;
-	storage_status_t status;
-	char *mydn; 
-
-	status = nick_connect(my_nick, password, &ld);
-	if (status != STORAGE_OK)
-		return status;
-
-	mydn = nick_dn(my_nick);
-
-	ret = ldap_search_s(ld, mydn, LDAP_SCOPE_BASE, "(objectClass=*)", NULL, 0, &res);
-
-	if (ret != LDAP_SUCCESS) {
-		log_message( LOGLVL_WARNING, "Unable to search for %s: %s", mydn, ldap_err2string(ret) );
-		ldap_unbind_s(ld);
-		return STORAGE_OTHER_ERROR;
-	}
-
-	g_free(mydn);
-
-	for (msg = ldap_first_entry(ld, res); msg; msg = ldap_next_entry(ld, msg)) {
-	}
-
-	/* FIXME: Store in irc_t */
-
-	ldap_unbind_s(ld);
-	
-	return STORAGE_OK;
-}
-
-static storage_status_t sldap_check_pass( const char *nick, const char *password )
-{
-	LDAP *ld;
-	storage_status_t status;
-
-	status = nick_connect(nick, password, &ld);
-
-	ldap_unbind_s(ld);
-
-	return status;
-}
-
-static storage_status_t sldap_remove( const char *nick, const char *password )
-{
-	storage_status_t status;
-	LDAP *ld;
-	char *mydn;
-	int ret;
-	
-	status = nick_connect(nick, password, &ld);
-
-	if (status != STORAGE_OK)
-		return status;
-
-	mydn = nick_dn(nick);
-	
-	ret = ldap_delete(ld, mydn);
-
-	if (ret != LDAP_SUCCESS) {
-		log_message( LOGLVL_WARNING, "Error removing %s: %s", mydn, ldap_err2string(ret) );
-		ldap_unbind_s(ld);
-		return STORAGE_OTHER_ERROR;
-	}
-
-	ldap_unbind_s(ld);
-
-	g_free(mydn);
-	return STORAGE_OK;
-}
-
-static storage_status_t sldap_save( irc_t *irc, int overwrite )
-{
-	LDAP *ld;
-	char *mydn;
-	storage_status_t status;
-	LDAPMessage *msg;
-
-	status = nick_connect(irc->nick, irc->password, &ld);
-	if (status != STORAGE_OK)
-		return status;
-
-	mydn = nick_dn(irc->nick);
-
-	/* FIXME: Make this a bit more atomic? What if we crash after 
-	 * removing the old account but before adding the new one ? */
-	if (overwrite) 
-		sldap_remove(irc->nick, irc->password);
-
-	g_free(mydn);
-
-	ldap_unbind_s(ld);
-	
-	return STORAGE_OK;
-}
-
-
-
-storage_t storage_ldap = {
-	.name = "ldap",
-	.check_pass = sldap_check_pass,
-	.remove = sldap_remove,
-	.load = sldap_load,
-	.save = sldap_save
-};
Index: storage_text.c
===================================================================
--- storage_text.c	(revision fef6116e89bb0651c72454effbb51e04e9e1b8dc)
+++ storage_text.c	(revision 3f9440db856c1b1cde54eb919543cfc23ea09983)
@@ -116,4 +116,10 @@
 	}
 	fclose( fp );
+	
+	if( set_getint( irc, "auto_connect" ) )
+	{
+		strcpy( s, "account on" );	/* Can't do this directly because r_c_s alters the string */
+		root_command_string( irc, ru, s, 0 );
+	}
 	
 	return STORAGE_OK;
Index: orage_xml.c
===================================================================
--- storage_xml.c	(revision fef6116e89bb0651c72454effbb51e04e9e1b8dc)
+++ 	(revision )
@@ -1,503 +1,0 @@
-  /********************************************************************\
-  * BitlBee -- An IRC to other IM-networks gateway                     *
-  *                                                                    *
-  * Copyright 2002-2006 Wilmer van der Gaast and others                *
-  \********************************************************************/
-
-/* Storage backend that uses an XMLish format for all data. */
-
-/*
-  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
-  the Free Software Foundation; either version 2 of the License, or
-  (at your option) any later version.
-
-  This program is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-  GNU General Public License for more details.
-
-  You should have received a copy of the GNU General Public License with
-  the Debian GNU/Linux distribution in /usr/share/common-licenses/GPL;
-  if not, write to the Free Software Foundation, Inc., 59 Temple Place,
-  Suite 330, Boston, MA  02111-1307  USA
-*/
-
-#define BITLBEE_CORE
-#include "bitlbee.h"
-#include "base64.h"
-#include "rc4.h"
-#include "md5.h"
-
-typedef enum
-{
-	XML_PASS_CHECK_ONLY = -1,
-	XML_PASS_UNKNOWN = 0,
-	XML_PASS_WRONG,
-	XML_PASS_OK
-} xml_pass_st;
-
-/* To make it easier later when extending the format: */
-#define XML_FORMAT_VERSION 1
-
-struct xml_parsedata
-{
-	irc_t *irc;
-	char *current_setting;
-	account_t *current_account;
-	char *given_nick;
-	char *given_pass;
-	xml_pass_st pass_st;
-};
-
-static char *xml_attr( const gchar **attr_names, const gchar **attr_values, const gchar *key )
-{
-	int i;
-	
-	for( i = 0; attr_names[i]; i ++ )
-		if( g_strcasecmp( attr_names[i], key ) == 0 )
-			return (char*) attr_values[i];
-	
-	return NULL;
-}
-
-static void xml_destroy_xd( gpointer data )
-{
-	struct xml_parsedata *xd = data;
-	
-	g_free( xd->given_nick );
-	g_free( xd->given_pass );
-	g_free( xd );
-}
-
-static void xml_start_element( GMarkupParseContext *ctx, const gchar *element_name, const gchar **attr_names, const gchar **attr_values, gpointer data, GError **error )
-{
-	struct xml_parsedata *xd = data;
-	irc_t *irc = xd->irc;
-	
-	if( g_strcasecmp( element_name, "user" ) == 0 )
-	{
-		char *nick = xml_attr( attr_names, attr_values, "nick" );
-		char *pass = xml_attr( attr_names, attr_values, "password" );
-		md5_byte_t *pass_dec = NULL;
-		
-		if( !nick || !pass )
-		{
-			g_set_error( error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
-			             "Missing attributes for %s element", element_name );
-		}
-		else if( base64_decode( pass, &pass_dec ) != 21 )
-		{
-			g_set_error( error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
-			             "Error while decoding password attribute" );
-		}
-		else
-		{
-			md5_byte_t pass_md5[16];
-			md5_state_t md5_state;
-			int i;
-			
-			md5_init( &md5_state );
-			md5_append( &md5_state, (md5_byte_t*) xd->given_pass, strlen( xd->given_pass ) );
-			md5_append( &md5_state, (md5_byte_t*) pass_dec + 16, 5 ); /* Hmmm, salt! */
-			md5_finish( &md5_state, pass_md5 );
-			
-			for( i = 0; i < 16; i ++ )
-			{
-				if( pass_dec[i] != pass_md5[i] )
-				{
-					xd->pass_st = XML_PASS_WRONG;
-					g_set_error( error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
-					             "Password mismatch" );
-					break;
-				}
-			}
-			
-			/* If we reached the end of the loop, it was a match! */
-			if( i == 16 )
-			{
-				if( xd->pass_st != XML_PASS_CHECK_ONLY )
-					xd->pass_st = XML_PASS_OK;
-			}
-		}
-		
-		g_free( pass_dec );
-	}
-	else if( xd->pass_st < XML_PASS_OK )
-	{
-		/* Let's not parse anything else if we only have to check
-		   the password. */
-	}
-	else if( g_strcasecmp( element_name, "account" ) == 0 )
-	{
-		char *protocol, *handle, *server, *password = NULL, *autoconnect;
-		char *pass_b64 = NULL, *pass_rc4 = NULL;
-		int pass_len;
-		struct prpl *prpl = NULL;
-		
-		handle = xml_attr( attr_names, attr_values, "handle" );
-		pass_b64 = xml_attr( attr_names, attr_values, "password" );
-		server = xml_attr( attr_names, attr_values, "server" );
-		autoconnect = xml_attr( attr_names, attr_values, "autoconnect" );
-		
-		protocol = xml_attr( attr_names, attr_values, "protocol" );
-		if( protocol )
-			prpl = find_protocol( protocol );
-		
-		if( !handle || !pass_b64 || !protocol )
-			g_set_error( error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
-			             "Missing attributes for %s element", element_name );
-		else if( !prpl )
-			g_set_error( error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
-			             "Unknown protocol: %s", protocol );
-		else if( ( pass_len = base64_decode( pass_b64, (unsigned char**) &pass_rc4 ) ) &&
-		                rc4_decode( (unsigned char*) pass_rc4, pass_len,
-		                            (unsigned char**) &password, xd->given_pass ) )
-		{
-			xd->current_account = account_add( irc, prpl, handle, password );
-			if( server )
-				set_setstr( &xd->current_account->set, "server", server );
-			if( autoconnect )
-				set_setstr( &xd->current_account->set, "auto_connect", autoconnect );
-		}
-		else
-		{
-			/* Actually the _decode functions don't even return error codes,
-			   but maybe they will later... */
-			g_set_error( error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
-			             "Error while decrypting account password" );
-		}
-		
-		g_free( pass_rc4 );
-		g_free( password );
-	}
-	else if( g_strcasecmp( element_name, "setting" ) == 0 )
-	{
-		char *setting;
-		
-		if( xd->current_setting )
-		{
-			g_free( xd->current_setting );
-			xd->current_setting = NULL;
-		}
-		
-		if( ( setting = xml_attr( attr_names, attr_values, "name" ) ) )
-			xd->current_setting = g_strdup( setting );
-		else
-			g_set_error( error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
-			             "Missing attributes for %s element", element_name );
-	}
-	else if( g_strcasecmp( element_name, "buddy" ) == 0 )
-	{
-		char *handle, *nick;
-		
-		handle = xml_attr( attr_names, attr_values, "handle" );
-		nick = xml_attr( attr_names, attr_values, "nick" );
-		
-		if( xd->current_account && handle && nick )
-		{
-			nick_set( irc, handle, xd->current_account->prpl, nick );
-		}
-		else
-		{
-			g_set_error( error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
-			             "Missing attributes for %s element", element_name );
-		}
-	}
-	else
-	{
-		g_set_error( error, G_MARKUP_ERROR, G_MARKUP_ERROR_UNKNOWN_ELEMENT,
-		             "Unkown element: %s", element_name );
-	}
-}
-
-static void xml_end_element( GMarkupParseContext *ctx, const gchar *element_name, gpointer data, GError **error )
-{
-	struct xml_parsedata *xd = data;
-	
-	if( g_strcasecmp( element_name, "setting" ) == 0 && xd->current_setting )
-	{
-		g_free( xd->current_setting );
-		xd->current_setting = NULL;
-	}
-	else if( g_strcasecmp( element_name, "account" ) == 0 )
-	{
-		xd->current_account = NULL;
-	}
-}
-
-static void xml_text( GMarkupParseContext *ctx, const gchar *text, gsize text_len, gpointer data, GError **error )
-{
-	struct xml_parsedata *xd = data;
-	irc_t *irc = xd->irc;
-	
-	if( xd->pass_st < XML_PASS_OK )
-	{
-		/* Let's not parse anything else if we only have to check
-		   the password, or if we didn't get the chance to check it
-		   yet. */
-	}
-	else if( g_strcasecmp( g_markup_parse_context_get_element( ctx ), "setting" ) == 0 && xd->current_setting )
-	{
-		set_setstr( xd->current_account ? &xd->current_account->set : &irc->set,
-		            xd->current_setting, (char*) text );
-		g_free( xd->current_setting );
-		xd->current_setting = NULL;
-	}
-}
-
-GMarkupParser xml_parser =
-{
-	xml_start_element,
-	xml_end_element,
-	xml_text,
-	NULL,
-	NULL
-};
-
-static void xml_init( void )
-{
-	if( access( global.conf->configdir, F_OK ) != 0 )
-		log_message( LOGLVL_WARNING, "The configuration directory %s does not exist. Configuration won't be saved.", CONFIG );
-	else if( access( global.conf->configdir, R_OK ) != 0 || access( global.conf->configdir, W_OK ) != 0 )
-		log_message( LOGLVL_WARNING, "Permission problem: Can't read/write from/to %s.", global.conf->configdir );
-}
-
-static storage_status_t xml_load_real( const char *my_nick, const char *password, irc_t *irc, xml_pass_st action )
-{
-	GMarkupParseContext *ctx;
-	struct xml_parsedata *xd;
-	char *fn, buf[512];
-	GError *gerr = NULL;
-	int fd, st;
-	
-	if( irc && irc->status & USTATUS_IDENTIFIED )
-		return( 1 );
-	
-	xd = g_new0( struct xml_parsedata, 1 );
-	xd->irc = irc;
-	xd->given_nick = g_strdup( my_nick );
-	xd->given_pass = g_strdup( password );
-	xd->pass_st = action;
-	nick_lc( xd->given_nick );
-	
-	fn = g_strdup_printf( "%s%s%s", global.conf->configdir, xd->given_nick, ".xml" );
-	if( ( fd = open( fn, O_RDONLY ) ) < 0 )
-	{
-		xml_destroy_xd( xd );
-		g_free( fn );
-		return STORAGE_NO_SUCH_USER;
-	}
-	g_free( fn );
-	
-	ctx = g_markup_parse_context_new( &xml_parser, 0, xd, xml_destroy_xd );
-	
-	while( ( st = read( fd, buf, sizeof( buf ) ) ) > 0 )
-	{
-		if( !g_markup_parse_context_parse( ctx, buf, st, &gerr ) || gerr )
-		{
-			xml_pass_st pass_st = xd->pass_st;
-			
-			g_markup_parse_context_free( ctx );
-			close( fd );
-			
-			if( pass_st == XML_PASS_WRONG )
-			{
-				g_clear_error( &gerr );
-				return STORAGE_INVALID_PASSWORD;
-			}
-			else
-			{
-				if( gerr && irc )
-					irc_usermsg( irc, "Error from XML-parser: %s", gerr->message );
-				
-				g_clear_error( &gerr );
-				return STORAGE_OTHER_ERROR;
-			}
-		}
-	}
-	/* Just to be sure... */
-	g_clear_error( &gerr );
-	
-	g_markup_parse_context_free( ctx );
-	close( fd );
-	
-	if( action == XML_PASS_CHECK_ONLY )
-		return STORAGE_OK;
-	
-	irc->status |= USTATUS_IDENTIFIED;
-	
-	return STORAGE_OK;
-}
-
-static storage_status_t xml_load( const char *my_nick, const char *password, irc_t *irc )
-{
-	return xml_load_real( my_nick, password, irc, XML_PASS_UNKNOWN );
-}
-
-static storage_status_t xml_check_pass( const char *my_nick, const char *password )
-{
-	/* This is a little bit risky because we have to pass NULL for the
-	   irc_t argument. This *should* be fine, if I didn't miss anything... */
-	return xml_load_real( my_nick, password, NULL, XML_PASS_CHECK_ONLY );
-}
-
-static int xml_printf( int fd, int indent, char *fmt, ... )
-{
-	va_list params;
-	char *out;
-	char tabs[9] = "\t\t\t\t\t\t\t\t";
-	int len;
-	
-	/* Maybe not very clean, but who needs more than 8 levels of indentation anyway? */
-	if( write( fd, tabs, indent <= 8 ? indent : 8 ) != indent )
-		return 0;
-	
-	va_start( params, fmt );
-	out = g_markup_vprintf_escaped( fmt, params );
-	va_end( params );
-	
-	len = strlen( out );
-	len -= write( fd, out, len );
-	g_free( out );
-	
-	return len == 0;
-}
-
-static storage_status_t xml_save( irc_t *irc, int overwrite )
-{
-	char path[512], *path2, *pass_buf = NULL;
-	set_t *set;
-	nick_t *nick;
-	account_t *acc;
-	int fd;
-	md5_byte_t pass_md5[21];
-	md5_state_t md5_state;
-	
-	if( irc->password == NULL )
-	{
-		irc_usermsg( irc, "Please register yourself if you want to save your settings." );
-		return STORAGE_OTHER_ERROR;
-	}
-	
-	g_snprintf( path, sizeof( path ) - 2, "%s%s%s", global.conf->configdir, irc->nick, ".xml" );
-	
-	if( !overwrite && access( path, F_OK ) != -1 )
-		return STORAGE_ALREADY_EXISTS;
-	
-	strcat( path, "~" );
-	if( ( fd = open( path, O_WRONLY | O_CREAT, 0600 ) ) < 0 )
-	{
-		irc_usermsg( irc, "Error while opening configuration file." );
-		return STORAGE_OTHER_ERROR;
-	}
-	
-	/* Generate a salted md5sum of the password. Use 5 bytes for the salt
-	   (to prevent dictionary lookups of passwords) to end up with a 21-
-	   byte password hash, more convenient for base64 encoding. */
-	random_bytes( pass_md5 + 16, 5 );
-	md5_init( &md5_state );
-	md5_append( &md5_state, (md5_byte_t*) irc->password, strlen( irc->password ) );
-	md5_append( &md5_state, pass_md5 + 16, 5 ); /* Add the salt. */
-	md5_finish( &md5_state, pass_md5 );
-	/* Save the hash in base64-encoded form. */
-	pass_buf = base64_encode( (char*) pass_md5, 21 );
-	
-	if( !xml_printf( fd, 0, "<user nick=\"%s\" password=\"%s\" version=\"%d\">\n", irc->nick, pass_buf, XML_FORMAT_VERSION ) )
-		goto write_error;
-	
-	g_free( pass_buf );
-	
-	for( set = irc->set; set; set = set->next )
-		if( set->value && set->def )
-			if( !xml_printf( fd, 1, "<setting name=\"%s\">%s</setting>\n", set->key, set->value ) )
-				goto write_error;
-	
-	for( acc = irc->accounts; acc; acc = acc->next )
-	{
-		char *pass_rc4, *pass_b64;
-		int pass_len;
-		
-		pass_len = rc4_encode( (unsigned char*) acc->pass, strlen( acc->pass ), (unsigned char**) &pass_rc4, irc->password );
-		pass_b64 = base64_encode( pass_rc4, pass_len );
-		g_free( pass_rc4 );
-		
-		if( !xml_printf( fd, 1, "<account protocol=\"%s\" handle=\"%s\" password=\"%s\" autoconnect=\"%d\"", acc->prpl->name, acc->user, pass_b64, acc->auto_connect ) )
-		{
-			g_free( pass_b64 );
-			goto write_error;
-		}
-		g_free( pass_b64 );
-		
-		if( acc->server && acc->server[0] && !xml_printf( fd, 0, " server=\"%s\"", acc->server ) )
-			goto write_error;
-		if( !xml_printf( fd, 0, ">\n" ) )
-			goto write_error;
-		
-		for( set = acc->set; set; set = set->next )
-			if( set->value && set->def && !( set->flags & ACC_SET_NOSAVE ) )
-				if( !xml_printf( fd, 2, "<setting name=\"%s\">%s</setting>\n", set->key, set->value ) )
-					goto write_error;
-		
-		for( nick = irc->nicks; nick; nick = nick->next )
-			if( nick->proto == acc->prpl )
-				if( !xml_printf( fd, 2, "<buddy handle=\"%s\" nick=\"%s\" />\n", nick->handle, nick->nick ) )
-					goto write_error;
-		
-		if( !xml_printf( fd, 1, "</account>\n" ) )
-			goto write_error;
-	}
-	
-	if( !xml_printf( fd, 0, "</user>\n" ) )
-		goto write_error;
-	
-	close( fd );
-	
-	path2 = g_strndup( path, strlen( path ) - 1 );
-	if( rename( path, path2 ) != 0 )
-	{
-		irc_usermsg( irc, "Error while renaming temporary configuration file." );
-		
-		g_free( path2 );
-		unlink( path );
-		
-		return STORAGE_OTHER_ERROR;
-	}
-	
-	g_free( path2 );
-	
-	return STORAGE_OK;
-
-write_error:
-	g_free( pass_buf );
-	
-	irc_usermsg( irc, "Write error. Disk full?" );
-	close( fd );
-	
-	return STORAGE_OTHER_ERROR;
-}
-
-static storage_status_t xml_remove( const char *nick, const char *password )
-{
-	char s[512];
-	storage_status_t status;
-
-	status = xml_check_pass( nick, password );
-	if( status != STORAGE_OK )
-		return status;
-
-	g_snprintf( s, 511, "%s%s%s", global.conf->configdir, nick, ".xml" );
-	if( unlink( s ) == -1 )
-		return STORAGE_OTHER_ERROR;
-	
-	return STORAGE_OK;
-}
-
-storage_t storage_xml = {
-	.name = "xml",
-	.init = xml_init,
-	.check_pass = xml_check_pass,
-	.remove = xml_remove,
-	.load = xml_load,
-	.save = xml_save
-};
Index: unix.c
===================================================================
--- unix.c	(revision fef6116e89bb0651c72454effbb51e04e9e1b8dc)
+++ unix.c	(revision 3f9440db856c1b1cde54eb919543cfc23ea09983)
@@ -48,16 +48,18 @@
 	
 	b_main_init();
+	
 	log_init();
+
 	nogaim_init();
-	
-	srand( time( NULL ) ^ getpid() );
-	
+
 	CONF_FILE = g_strdup( CONF_FILE_DEF );
+	
 	global.helpfile = g_strdup( HELP_FILE );
-	
+
 	global.conf = conf_load( argc, argv );
 	if( global.conf == NULL )
 		return( 1 );
-	
+
+
 	if( global.conf->runmode == RUNMODE_INETD )
 	{
@@ -87,5 +89,5 @@
 	if( i != 0 )
 		return( i );
-	
+
 	global.storage = storage_init( global.conf->primary_storage, global.conf->migrate_storage );
 	if ( global.storage == NULL) {
Index: url.c
===================================================================
--- url.c	(revision 3f9440db856c1b1cde54eb919543cfc23ea09983)
+++ url.c	(revision 3f9440db856c1b1cde54eb919543cfc23ea09983)
@@ -0,0 +1,107 @@
+  /********************************************************************\
+  * BitlBee -- An IRC to other IM-networks gateway                     *
+  *                                                                    *
+  * Copyright 2001-2005 Wilmer van der Gaast and others                *
+  \********************************************************************/
+
+/* URL/mirror stuff - Stolen from Axel                                  */
+
+/*
+  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
+  the Free Software Foundation; either version 2 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License with
+  the Debian GNU/Linux distribution in /usr/share/common-licenses/GPL;
+  if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+  Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include "url.h"
+
+/* Convert an URL to a url_t structure					*/
+int url_set( url_t *url, char *set_url )
+{
+	char s[MAX_STRING];
+	char *i;
+	
+	/* protocol://							*/
+	if( ( i = strstr( set_url, "://" ) ) == NULL )
+	{
+		url->proto = PROTO_DEFAULT;
+		strncpy( s, set_url, MAX_STRING );
+	}
+	else
+	{
+		if( g_strncasecmp( set_url, "http", i - set_url ) == 0 )
+			url->proto = PROTO_HTTP;
+		else if( g_strncasecmp( set_url, "https", i - set_url ) == 0 )
+			url->proto = PROTO_HTTPS;
+		else if( g_strncasecmp( set_url, "socks4", i - set_url ) == 0 )
+			url->proto = PROTO_SOCKS4;
+		else if( g_strncasecmp( set_url, "socks5", i - set_url ) == 0 )
+			url->proto = PROTO_SOCKS5;
+		else
+		{
+			return( 0 );
+		}
+		strncpy( s, i + 3, MAX_STRING );
+	}
+	
+	/* Split							*/
+	if( ( i = strchr( s, '/' ) ) == NULL )
+	{
+		strcpy( url->file, "/" );
+	}
+	else
+	{
+		strncpy( url->file, i, MAX_STRING );
+		*i = 0;
+	}
+	strncpy( url->host, s, MAX_STRING );
+	
+	/* Check for username in host field				*/
+	if( strrchr( url->host, '@' ) != NULL )
+	{
+		strncpy( url->user, url->host, MAX_STRING );
+		i = strrchr( url->user, '@' );
+		*i = 0;
+		strcpy( url->host, i + 1 );
+		*url->pass = 0;
+	}
+	/* If not: Fill in defaults					*/
+	else
+	{
+		*url->user = *url->pass = 0;
+	}
+	
+	/* Password?							*/
+	if( ( i = strchr( url->user, ':' ) ) != NULL )
+	{
+		*i = 0;
+		strcpy( url->pass, i + 1 );
+	}
+	/* Port number?							*/
+	if( ( i = strchr( url->host, ':' ) ) != NULL )
+	{
+		*i = 0;
+		sscanf( i + 1, "%d", &url->port );
+	}
+	else
+	{
+		if( url->proto == PROTO_HTTP )
+			url->port = 80;
+		else if( url->proto == PROTO_HTTPS )
+			url->port = 443;
+		else if( url->proto == PROTO_SOCKS4 || url->proto == PROTO_SOCKS4 )
+			url->port = 1080;
+	}
+	
+	return( url->port > 0 );
+}
Index: url.h
===================================================================
--- url.h	(revision 3f9440db856c1b1cde54eb919543cfc23ea09983)
+++ url.h	(revision 3f9440db856c1b1cde54eb919543cfc23ea09983)
@@ -0,0 +1,44 @@
+  /********************************************************************\
+  * BitlBee -- An IRC to other IM-networks gateway                     *
+  *                                                                    *
+  * Copyright 2001-2004 Wilmer van der Gaast and others                *
+  \********************************************************************/
+
+/* URL/mirror stuff - Stolen from Axel                                  */
+
+/*
+  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
+  the Free Software Foundation; either version 2 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License with
+  the Debian GNU/Linux distribution in /usr/share/common-licenses/GPL;
+  if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+  Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include "bitlbee.h"
+
+#define PROTO_HTTP		2
+#define PROTO_HTTPS		5
+#define PROTO_SOCKS4	3
+#define PROTO_SOCKS5	4
+#define PROTO_DEFAULT	PROTO_HTTP
+
+typedef struct url
+{
+	int proto;
+	int port;
+	char host[MAX_STRING];
+	char file[MAX_STRING];
+	char user[MAX_STRING];
+	char pass[MAX_STRING];
+} url_t;
+
+int url_set( url_t *url, char *set_url );
Index: user.c
===================================================================
--- user.c	(revision fef6116e89bb0651c72454effbb51e04e9e1b8dc)
+++ user.c	(revision 3f9440db856c1b1cde54eb919543cfc23ea09983)
@@ -67,5 +67,5 @@
 	
 	u->user = u->realname = u->host = u->nick = g_strdup( nick );
-	u->is_private = set_getint( &irc->set, "private" );
+	u->is_private = set_getint( irc, "private" );
 	
 	key = g_strdup( nick );
@@ -147,5 +147,5 @@
 	while( u )
 	{
-		if( u->gc == gc && u->handle && gc->acc->prpl->cmp_buddynames ( u->handle, handle ) == 0 )
+		if( u->gc == gc && u->handle && gc->prpl->cmp_buddynames ( u->handle, handle ) == 0 )
 			break;
 		u = u->next;
Index: util.c
===================================================================
--- util.c	(revision 3f9440db856c1b1cde54eb919543cfc23ea09983)
+++ util.c	(revision 3f9440db856c1b1cde54eb919543cfc23ea09983)
@@ -0,0 +1,494 @@
+  /********************************************************************\
+  * BitlBee -- An IRC to other IM-networks gateway                     *
+  *                                                                    *
+  * Copyright 2002-2004 Wilmer van der Gaast and others                *
+  \********************************************************************/
+
+/*
+ * Various utility functions. Some are copied from Gaim to support the
+ * IM-modules, most are from BitlBee.
+ *
+ * Copyright (C) 1998-1999, Mark Spencer <markster@marko.net>
+ *                          (and possibly other members of the Gaim team)
+ * Copyright 2002-2005 Wilmer van der Gaast <wilmer@gaast.net>
+ */
+
+/*
+  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
+  the Free Software Foundation; either version 2 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License with
+  the Debian GNU/Linux distribution in /usr/share/common-licenses/GPL;
+  if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+  Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#define BITLBEE_CORE
+#include "nogaim.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <glib.h>
+#include <time.h>
+
+void strip_linefeed(gchar *text)
+{
+	int i, j;
+	gchar *text2 = g_malloc(strlen(text) + 1);
+
+	for (i = 0, j = 0; text[i]; i++)
+		if (text[i] != '\r')
+			text2[j++] = text[i];
+	text2[j] = '\0';
+
+	strcpy(text, text2);
+	g_free(text2);
+}
+
+char *add_cr(char *text)
+{
+	char *ret = NULL;
+	int count = 0, j;
+	unsigned int i;
+
+	if (text[0] == '\n')
+		count++;
+	for (i = 1; i < strlen(text); i++)
+		if (text[i] == '\n' && text[i - 1] != '\r')
+			count++;
+
+	if (count == 0)
+		return g_strdup(text);
+
+	ret = g_malloc0(strlen(text) + count + 1);
+
+	i = 0; j = 0;
+	if (text[i] == '\n')
+		ret[j++] = '\r';
+	ret[j++] = text[i++];
+	for (; i < strlen(text); i++) {
+		if (text[i] == '\n' && text[i - 1] != '\r')
+			ret[j++] = '\r';
+		ret[j++] = text[i];
+	}
+
+	return ret;
+}
+
+static char alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" "0123456789+/";
+
+/* XXX Find bug */
+char *tobase64(const char *text)
+{
+	char *out = NULL;
+	const char *c;
+	unsigned int tmp = 0;
+	int len = 0, n = 0;
+
+	c = text;
+
+	while (*c) {
+		tmp = tmp << 8;
+		tmp += *c;
+		n++;
+
+		if (n == 3) {
+			out = g_realloc(out, len + 4);
+			out[len] = alphabet[(tmp >> 18) & 0x3f];
+			out[len + 1] = alphabet[(tmp >> 12) & 0x3f];
+			out[len + 2] = alphabet[(tmp >> 6) & 0x3f];
+			out[len + 3] = alphabet[tmp & 0x3f];
+			len += 4;
+			tmp = 0;
+			n = 0;
+		}
+		c++;
+	}
+	switch (n) {
+
+	case 2:
+		tmp <<= 8;
+		out = g_realloc(out, len + 5);
+		out[len] = alphabet[(tmp >> 18) & 0x3f];
+		out[len + 1] = alphabet[(tmp >> 12) & 0x3f];
+		out[len + 2] = alphabet[(tmp >> 6) & 0x3f];
+		out[len + 3] = '=';
+		out[len + 4] = 0;
+		break;
+	case 1:
+		tmp <<= 16;
+		out = g_realloc(out, len + 5);
+		out[len] = alphabet[(tmp >> 18) & 0x3f];
+		out[len + 1] = alphabet[(tmp >> 12) & 0x3f];
+		out[len + 2] = '=';
+		out[len + 3] = '=';
+		out[len + 4] = 0;
+		break;
+	case 0:
+		out = g_realloc(out, len + 1);
+		out[len] = 0;
+		break;
+	}
+	return out;
+}
+
+char *normalize(const char *s)
+{
+	static char buf[BUF_LEN];
+	char *t, *u;
+	int x = 0;
+
+	g_return_val_if_fail((s != NULL), NULL);
+
+	u = t = g_strdup(s);
+
+	strcpy(t, s);
+	g_strdown(t);
+
+	while (*t && (x < BUF_LEN - 1)) {
+		if (*t != ' ') {
+			buf[x] = *t;
+			x++;
+		}
+		t++;
+	}
+	buf[x] = '\0';
+	g_free(u);
+	return buf;
+}
+
+time_t get_time(int year, int month, int day, int hour, int min, int sec)
+{
+	struct tm tm;
+
+	tm.tm_year = year - 1900;
+	tm.tm_mon = month - 1;
+	tm.tm_mday = day;
+	tm.tm_hour = hour;
+	tm.tm_min = min;
+	tm.tm_sec = sec >= 0 ? sec : time(NULL) % 60;
+	return mktime(&tm);
+}
+
+typedef struct htmlentity
+{
+	char code[8];
+	char is[4];
+} htmlentity_t;
+
+/* FIXME: This is ISO8859-1(5) centric, so might cause problems with other charsets. */
+
+static const htmlentity_t ent[] =
+{
+	{ "lt",     "<" },
+	{ "gt",     ">" },
+	{ "amp",    "&" },
+	{ "quot",   "\"" },
+	{ "aacute", "á" },
+	{ "eacute", "é" },
+	{ "iacute", "é" },
+	{ "oacute", "ó" },
+	{ "uacute", "ú" },
+	{ "agrave", "à" },
+	{ "egrave", "è" },
+	{ "igrave", "ì" },
+	{ "ograve", "ò" },
+	{ "ugrave", "ù" },
+	{ "acirc",  "â" },
+	{ "ecirc",  "ê" },
+	{ "icirc",  "î" },
+	{ "ocirc",  "ô" },
+	{ "ucirc",  "û" },
+	{ "auml",   "ä" },
+	{ "euml",   "ë" },
+	{ "iuml",   "ï" },
+	{ "ouml",   "ö" },
+	{ "uuml",   "ü" },
+	{ "nbsp",   " " },
+	{ "",        ""  }
+};
+
+void strip_html( char *in )
+{
+	char *start = in;
+	char *out = g_malloc( strlen( in ) + 1 );
+	char *s = out, *cs;
+	int i, matched;
+	
+	memset( out, 0, strlen( in ) + 1 );
+	
+	while( *in )
+	{
+		if( *in == '<' && ( isalpha( *(in+1) ) || *(in+1) == '/' ) )
+		{
+			/* If in points at a < and in+1 points at a letter or a slash, this is probably
+			   a HTML-tag. Try to find a closing > and continue there. If the > can't be
+			   found, assume that it wasn't a HTML-tag after all. */
+			
+			cs = in;
+			
+			while( *in && *in != '>' )
+				in ++;
+			
+			if( *in )
+			{
+				if( g_strncasecmp( cs+1, "br", 2) == 0 )
+					*(s++) = '\n';
+				in ++;
+			}
+			else
+			{
+				in = cs;
+				*(s++) = *(in++);
+			}
+		}
+		else if( *in == '&' )
+		{
+			cs = ++in;
+			while( *in && isalpha( *in ) )
+				in ++;
+			
+			if( *in == ';' ) in ++;
+			matched = 0;
+			
+			for( i = 0; *ent[i].code; i ++ )
+				if( g_strncasecmp( ent[i].code, cs, strlen( ent[i].code ) ) == 0 )
+				{
+					int j;
+					
+					for( j = 0; ent[i].is[j]; j ++ )
+						*(s++) = ent[i].is[j];
+					
+					matched = 1;
+					break;
+				}
+
+			/* None of the entities were matched, so return the string */
+			if( !matched )
+			{
+				in = cs - 1;
+				*(s++) = *(in++);
+			}
+		}
+		else
+		{
+			*(s++) = *(in++);
+		}
+	}
+	
+	strcpy( start, out );
+	g_free( out );
+}
+
+char *escape_html( const char *html )
+{
+	const char *c = html;
+	GString *ret;
+	char *str;
+	
+	if( html == NULL )
+		return( NULL );
+	
+	ret = g_string_new( "" );
+	
+	while( *c )
+	{
+		switch( *c )
+		{
+			case '&':
+				ret = g_string_append( ret, "&amp;" );
+				break;
+			case '<':
+				ret = g_string_append( ret, "&lt;" );
+				break;
+			case '>':
+				ret = g_string_append( ret, "&gt;" );
+				break;
+			case '"':
+				ret = g_string_append( ret, "&quot;" );
+				break;
+			default:
+				ret = g_string_append_c( ret, *c );
+		}
+		c ++;
+	}
+	
+	str = ret->str;
+	g_string_free( ret, FALSE );
+	return( str );
+}
+
+void info_string_append(GString *str, char *newline, char *name, char *value)
+{
+	if( value && value[0] )
+		g_string_sprintfa( str, "%s%s: %s", newline, name, value );
+}
+
+/* Decode%20a%20file%20name						*/
+void http_decode( char *s )
+{
+	char *t;
+	int i, j, k;
+	
+	t = g_new( char, strlen( s ) + 1 );
+	
+	for( i = j = 0; s[i]; i ++, j ++ )
+	{
+		if( s[i] == '%' )
+		{
+			if( sscanf( s + i + 1, "%2x", &k ) )
+			{
+				t[j] = k;
+				i += 2;
+			}
+			else
+			{
+				*t = 0;
+				break;
+			}
+		}
+		else
+		{
+			t[j] = s[i];
+		}
+	}
+	t[j] = 0;
+	
+	strcpy( s, t );
+	g_free( t );
+}
+
+/* Warning: This one explodes the string. Worst-cases can make the string 3x its original size! */
+/* This fuction is safe, but make sure you call it safely as well! */
+void http_encode( char *s )
+{
+	char *t;
+	int i, j;
+	
+	t = g_strdup( s );
+	
+	for( i = j = 0; t[i]; i ++, j ++ )
+	{
+		/* if( t[i] <= ' ' || ((unsigned char *)t)[i] >= 128 || t[i] == '%' ) */
+		if( !isalnum( t[i] ) )
+		{
+			sprintf( s + j, "%%%02X", ((unsigned char*)t)[i] );
+			j += 2;
+		}
+		else
+		{
+			s[j] = t[i];
+		}
+	}
+	s[j] = 0;
+	
+	g_free( t );
+}
+
+/* Strip newlines from a string. Modifies the string passed to it. */ 
+char *strip_newlines( char *source )
+{
+	int i;	
+
+	for( i = 0; source[i] != '\0'; i ++ )
+		if( source[i] == '\n' || source[i] == '\r' )
+			source[i] = ' ';
+	
+	return source;
+}
+
+#ifdef IPV6
+/* Wrap an IPv4 address into IPv6 space. Not thread-safe... */
+char *ipv6_wrap( char *src )
+{
+	static char dst[64];
+	int i;
+	
+	for( i = 0; src[i]; i ++ )
+		if( ( src[i] < '0' || src[i] > '9' ) && src[i] != '.' )
+			break;
+	
+	/* Hmm, it's not even an IP... */
+	if( src[i] )
+		return src;
+	
+	g_snprintf( dst, sizeof( dst ), "::ffff:%s", src );
+	
+	return dst;
+}
+
+/* Unwrap an IPv4 address into IPv6 space. Thread-safe, because it's very simple. :-) */
+char *ipv6_unwrap( char *src )
+{
+	int i;
+	
+	if( g_strncasecmp( src, "::ffff:", 7 ) != 0 )
+		return src;
+	
+	for( i = 7; src[i]; i ++ )
+		if( ( src[i] < '0' || src[i] > '9' ) && src[i] != '.' )
+			break;
+	
+	/* Hmm, it's not even an IP... */
+	if( src[i] )
+		return src;
+	
+	return ( src + 7 );
+}
+#endif
+
+/* Convert from one charset to another.
+   
+   from_cs, to_cs: Source and destination charsets
+   src, dst: Source and destination strings
+   size: Size if src. 0 == use strlen(). strlen() is not reliable for UNICODE/UTF16 strings though.
+   maxbuf: Maximum number of bytes to write to dst
+   
+   Returns the number of bytes written to maxbuf or -1 on an error.
+*/
+signed int do_iconv( char *from_cs, char *to_cs, char *src, char *dst, size_t size, size_t maxbuf )
+{
+	GIConv cd;
+	size_t res;
+	size_t inbytesleft, outbytesleft;
+	char *inbuf = src;
+	char *outbuf = dst;
+	
+	cd = g_iconv_open( to_cs, from_cs );
+	if( cd == (GIConv) -1 )
+		return( -1 );
+	
+	inbytesleft = size ? size : strlen( src );
+	outbytesleft = maxbuf - 1;
+	res = g_iconv( cd, &inbuf, &inbytesleft, &outbuf, &outbytesleft );
+	*outbuf = '\0';
+	g_iconv_close( cd );
+	
+	if( res == (size_t) -1 )
+		return( -1 );
+	else
+		return( outbuf - dst );
+}
+
+char *set_eval_charset( irc_t *irc, set_t *set, char *value )
+{
+	GIConv cd;
+
+	if ( g_strncasecmp( value, "none", 4 ) == 0 )
+		return( value );
+
+	cd = g_iconv_open( "UTF-8", value );
+	if( cd == (GIConv) -1 )
+		return( NULL );
+
+	g_iconv_close( cd );
+	return( value );
+}
Index: util.h
===================================================================
--- util.h	(revision 3f9440db856c1b1cde54eb919543cfc23ea09983)
+++ util.h	(revision 3f9440db856c1b1cde54eb919543cfc23ea09983)
@@ -0,0 +1,50 @@
+  /********************************************************************\
+  * BitlBee -- An IRC to other IM-networks gateway                     *
+  *                                                                    *
+  * Copyright 2002-2004 Wilmer van der Gaast and others                *
+  \********************************************************************/
+
+/* Misc. functions                                                      */
+
+/*
+  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
+  the Free Software Foundation; either version 2 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License with
+  the Debian GNU/Linux distribution in /usr/share/common-licenses/GPL;
+  if not, write to the Free Software Foundation, Inc., 59 Temple Place,
+  Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#ifndef _UTIL_H
+#define _UTIL_H
+
+G_MODULE_EXPORT void strip_linefeed( gchar *text );
+G_MODULE_EXPORT char *add_cr( char *text );
+G_MODULE_EXPORT char *strip_newlines(char *source);
+G_MODULE_EXPORT char *tobase64( const char *text );
+G_MODULE_EXPORT char *normalize( const char *s );
+G_MODULE_EXPORT void info_string_append( GString *str, char *newline, char *name, char *value );
+
+G_MODULE_EXPORT time_t get_time( int year, int month, int day, int hour, int min, int sec );
+double gettime( void );
+
+G_MODULE_EXPORT void strip_html( char *msg );
+G_MODULE_EXPORT char *escape_html( const char *html );
+G_MODULE_EXPORT void http_decode( char *s );
+G_MODULE_EXPORT void http_encode( char *s );
+
+G_MODULE_EXPORT char *ipv6_wrap( char *src );
+G_MODULE_EXPORT char *ipv6_unwrap( char *src );
+
+G_MODULE_EXPORT signed int do_iconv( char *from_cs, char *to_cs, char *src, char *dst, size_t size, size_t maxbuf );
+char *set_eval_charset( irc_t *irc, set_t *set, char *value );
+
+#endif
