Index: .bzrignore
===================================================================
--- .bzrignore	(revision 22bf64eab8a79352317ee190cddfeef3011aa8dc)
+++ .bzrignore	(revision e7f46c56ffa29c6f8f4917c5f367a61706758e2a)
@@ -8,4 +8,2 @@
 build-arch-stamp
 tags
-decode
-encode
Index: Makefile
===================================================================
--- Makefile	(revision 22bf64eab8a79352317ee190cddfeef3011aa8dc)
+++ Makefile	(revision e7f46c56ffa29c6f8f4917c5f367a61706758e2a)
@@ -10,5 +10,5 @@
 
 # Program variables
-objects = account.o bitlbee.o commands.o conf.o crypting.o help.o ini.o irc.o log.o nick.o query.o set.o unix.o url.o user.o storage_text.o storage.o
+objects = account.o bitlbee.o commands.o conf.o crypting.o help.o ini.o irc.o log.o nick.o query.o set.o unix.o url.o user.o
 subdirs = protocols
 
Index: bitlbee.c
===================================================================
--- bitlbee.c	(revision 22bf64eab8a79352317ee190cddfeef3011aa8dc)
+++ bitlbee.c	(revision e7f46c56ffa29c6f8f4917c5f367a61706758e2a)
@@ -27,4 +27,5 @@
 #include "bitlbee.h"
 #include "commands.h"
+#include "crypting.h"
 #include "protocols/nogaim.h"
 #include "help.h"
@@ -164,13 +165,5 @@
 		return FALSE;
 	} 
-	
-	/* Very naughty, go read the RFCs! >:) */
-	if( irc->readbuffer && ( strlen( irc->readbuffer ) > 1024 ) )
-	{
-		log_message( LOGLVL_ERROR, "Maximum line length exceeded." );
-		irc_free( irc );
-		return FALSE;
-	}
-	
+		
 	return TRUE;
 }
@@ -243,4 +236,222 @@
 }
 
+int bitlbee_load( irc_t *irc, char* password )
+{
+	char s[512];
+	char *line;
+	int proto;
+	char nick[MAX_NICK_LENGTH+1];
+	FILE *fp;
+	user_t *ru = user_find( irc, ROOT_NICK );
+	
+	if( irc->status == USTATUS_IDENTIFIED )
+		return( 1 );
+	
+	g_snprintf( s, 511, "%s%s%s", global.conf->configdir, irc->nick, ".accounts" );
+   	fp = fopen( s, "r" );
+   	if( !fp ) return( 0 );
+	
+	fscanf( fp, "%32[^\n]s", s );
+	if( setpass( irc, password, s ) < 0 )
+	{
+		fclose( fp );
+		return( -1 );
+	}
+	
+	/* Do this now. If the user runs with AuthMode = Registered, the
+	   account command will not work otherwise. */
+	irc->status = USTATUS_IDENTIFIED;
+	
+	while( fscanf( fp, "%511[^\n]s", s ) > 0 )
+	{
+		fgetc( fp );
+		line = deobfucrypt( irc, s );
+		root_command_string( irc, ru, line, 0 );
+		g_free( line );
+	}
+	fclose( fp );
+	
+	g_snprintf( s, 511, "%s%s%s", global.conf->configdir, irc->nick, ".nicks" );
+	fp = fopen( s, "r" );
+	if( !fp ) return( 0 );
+	while( fscanf( fp, "%s %d %s", s, &proto, nick ) > 0 )
+	{
+		http_decode( s );
+		nick_set( irc, s, proto, nick );
+	}
+	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( 1 );
+}
+
+int bitlbee_save( irc_t *irc )
+{
+	char s[512];
+	char path[512], new_path[512];
+	char *line;
+	nick_t *n;
+	set_t *set;
+	mode_t ou = umask( 0077 );
+	account_t *a;
+	FILE *fp;
+	char *hash;
+	
+	/*\
+	 *  [SH] Nothing should be saved if no password is set, because the
+	 *  password is not set if it was wrong, or if one is not identified
+	 *  yet. This means that a malicious user could easily overwrite
+	 *  files owned by someone else:
+	 *  a Bad Thing, methinks
+	\*/
+
+	/* [WVG] No? Really? */
+
+	/*\
+	 *  [SH] Okay, okay, it wasn't really Wilmer who said that, it was
+	 *  me. I just thought it was funny.
+	\*/
+	
+	hash = hashpass( irc );
+	if( hash == NULL )
+	{
+		irc_usermsg( irc, "Please register yourself if you want to save your settings." );
+		return( 0 );
+	}
+	
+	g_snprintf( path, 511, "%s%s%s", global.conf->configdir, irc->nick, ".nicks~" );
+	fp = fopen( path, "w" );
+	if( !fp ) return( 0 );
+	for( n = irc->nicks; n; n = n->next )
+	{
+		strcpy( s, n->handle );
+		s[169] = 0; /* Prevent any overflow (169 ~ 512 / 3) */
+		http_encode( s );
+		g_snprintf( s + strlen( s ), 510 - strlen( s ), " %d %s", n->proto, n->nick );
+		if( fprintf( fp, "%s\n", s ) != strlen( s ) + 1 )
+		{
+			irc_usermsg( irc, "fprintf() wrote too little. Disk full?" );
+			fclose( fp );
+			return( 0 );
+		}
+	}
+	if( fclose( fp ) != 0 )
+	{
+		irc_usermsg( irc, "fclose() reported an error. Disk full?" );
+		return( 0 );
+	}
+  
+	g_snprintf( new_path, 512, "%s%s%s", global.conf->configdir, irc->nick, ".nicks" );
+	if( unlink( new_path ) != 0 )
+	{
+		if( errno != ENOENT )
+		{
+			irc_usermsg( irc, "Error while removing old .nicks file" );
+			return( 0 );
+		}
+	}
+	if( rename( path, new_path ) != 0 )
+	{
+		irc_usermsg( irc, "Error while renaming new .nicks file" );
+		return( 0 );
+	}
+	
+	g_snprintf( path, 511, "%s%s%s", global.conf->configdir, irc->nick, ".accounts~" );
+	fp = fopen( path, "w" );
+	if( !fp ) return( 0 );
+	if( fprintf( fp, "%s", hash ) != strlen( hash ) )
+	{
+		irc_usermsg( irc, "fprintf() wrote too little. Disk full?" );
+		fclose( fp );
+		return( 0 );
+	}
+	g_free( hash );
+
+	for( a = irc->accounts; a; a = a->next )
+	{
+		if( a->protocol == PROTO_OSCAR || a->protocol == PROTO_ICQ || a->protocol == PROTO_TOC )
+			g_snprintf( s, sizeof( s ), "account add oscar \"%s\" \"%s\" %s", a->user, a->pass, a->server );
+		else
+			g_snprintf( s, sizeof( s ), "account add %s \"%s\" \"%s\" \"%s\"",
+			            proto_name[a->protocol], a->user, a->pass, a->server ? a->server : "" );
+		
+		line = obfucrypt( irc, s );
+		if( *line )
+		{
+			if( fprintf( fp, "%s\n", line ) != strlen( line ) + 1 )
+			{
+				irc_usermsg( irc, "fprintf() wrote too little. Disk full?" );
+				fclose( fp );
+				return( 0 );
+			}
+		}
+		g_free( line );
+	}
+	
+	for( set = irc->set; set; set = set->next )
+	{
+		if( set->value && set->def )
+		{
+			g_snprintf( s, sizeof( s ), "set %s \"%s\"", set->key, set->value );
+			line = obfucrypt( irc, s );
+			if( *line )
+			{
+				if( fprintf( fp, "%s\n", line ) != strlen( line ) + 1 )
+				{
+					irc_usermsg( irc, "fprintf() wrote too little. Disk full?" );
+					fclose( fp );
+					return( 0 );
+				}
+			}
+			g_free( line );
+		}
+	}
+	
+	if( strcmp( irc->mynick, ROOT_NICK ) != 0 )
+	{
+		g_snprintf( s, sizeof( s ), "rename %s %s", ROOT_NICK, irc->mynick );
+		line = obfucrypt( irc, s );
+		if( *line )
+		{
+			if( fprintf( fp, "%s\n", line ) != strlen( line ) + 1 )
+			{
+				irc_usermsg( irc, "fprintf() wrote too little. Disk full?" );
+				fclose( fp );
+				return( 0 );
+			}
+		}
+		g_free( line );
+	}
+	if( fclose( fp ) != 0 )
+	{
+		irc_usermsg( irc, "fclose() reported an error. Disk full?" );
+		return( 0 );
+	}
+	
+ 	g_snprintf( new_path, 512, "%s%s%s", global.conf->configdir, irc->nick, ".accounts" );
+ 	if( unlink( new_path ) != 0 )
+	{
+		if( errno != ENOENT )
+		{
+			irc_usermsg( irc, "Error while removing old .accounts file" );
+			return( 0 );
+		}
+	}
+	if( rename( path, new_path ) != 0 )
+	{
+		irc_usermsg( irc, "Error while renaming new .accounts file" );
+		return( 0 );
+	}
+	
+	umask( ou );
+	
+	return( 1 );
+}
+
 void bitlbee_shutdown( gpointer data )
 {
Index: bitlbee.h
===================================================================
--- bitlbee.h	(revision 22bf64eab8a79352317ee190cddfeef3011aa8dc)
+++ bitlbee.h	(revision e7f46c56ffa29c6f8f4917c5f367a61706758e2a)
@@ -30,5 +30,5 @@
 
 #define PACKAGE "BitlBee"
-#define BITLBEE_VERSION "BZR"
+#define BITLBEE_VERSION "1.0pre"
 #define VERSION BITLBEE_VERSION
 
@@ -100,5 +100,4 @@
 
 #include "irc.h"
-#include "storage.h"
 #include "set.h"
 #include "protocols/nogaim.h"
@@ -116,5 +115,4 @@
 	help_t *help;
 	conf_t *conf;
-	GList *storage; /* The first backend in the list will be used for saving */
 	char *helpfile;
 	GMainLoop *loop;
@@ -129,4 +127,6 @@
 int root_command_string( irc_t *irc, user_t *u, char *command, int flags );
 int root_command( irc_t *irc, char *command[] );
+int bitlbee_load( irc_t *irc, char *password );
+int bitlbee_save( irc_t *irc );
 void bitlbee_shutdown( gpointer data );
 double gettime( void );
Index: commands.c
===================================================================
--- commands.c	(revision 22bf64eab8a79352317ee190cddfeef3011aa8dc)
+++ commands.c	(revision e7f46c56ffa29c6f8f4917c5f367a61706758e2a)
@@ -86,21 +86,23 @@
 int cmd_identify( irc_t *irc, char **cmd )
 {
-	storage_status_t status = storage_load( irc->nick, cmd[1], irc );
-	
-	switch (status) {
-	case STORAGE_INVALID_PASSWORD:
+	int checkie = bitlbee_load( irc, cmd[1] );
+	
+	if( checkie == -1 )
+	{
 		irc_usermsg( irc, "Incorrect password" );
-		break;
-	case STORAGE_NO_SUCH_USER:
+	}
+	else if( checkie == 0 )
+	{
 		irc_usermsg( irc, "The nick is (probably) not registered" );
-		break;
-	case STORAGE_OK:
+	}
+	else if( checkie == 1 )
+	{
 		irc_usermsg( irc, "Password accepted" );
-		break;
-	default:
+	}
+	else
+	{
 		irc_usermsg( irc, "Something very weird happened" );
-		break;
-	}
-
+	}
+	
 	return( 0 );
 }
@@ -108,4 +110,7 @@
 int cmd_register( irc_t *irc, char **cmd )
 {
+	int checkie;
+	char path[512];
+	
 	if( global.conf->authmode == AUTHMODE_REGISTERED )
 	{
@@ -113,18 +118,20 @@
 		return( 0 );
 	}
-
-	irc_setpass( irc, cmd[1] );
-	switch( storage_save( irc, FALSE )) {
-		case STORAGE_ALREADY_EXISTS:
-			irc_usermsg( irc, "Nick is already registered" );
-			break;
-			
-		case STORAGE_OK:
-			irc->status = USTATUS_IDENTIFIED;
-			break;
-
-		default:
-			irc_usermsg( irc, "Error registering" );
-			break;
+	
+	g_snprintf( path, 511, "%s%s%s", global.conf->configdir, irc->nick, ".accounts" );
+	checkie = access( path, F_OK );
+	
+	g_snprintf( path, 511, "%s%s%s", global.conf->configdir, irc->nick, ".nicks" );
+	checkie += access( path, F_OK );
+	
+	if( checkie == -2 )
+	{
+		setpassnc( irc, cmd[1] );
+		root_command_string( irc, user_find( irc, irc->mynick ), "save", 0 );
+		irc->status = USTATUS_IDENTIFIED;
+	}
+	else
+	{
+		irc_usermsg( irc, "Nick is already registered" );
 	}
 	
@@ -134,22 +141,33 @@
 int cmd_drop( irc_t *irc, char **cmd )
 {
-	storage_status_t status;
-	
-	status = storage_remove (irc->nick, cmd[1]);
-	switch (status) {
-	case STORAGE_NO_SUCH_USER:
+	char s[512];
+	FILE *fp;
+	
+	g_snprintf( s, 511, "%s%s%s", global.conf->configdir, irc->nick, ".accounts" );
+	fp = fopen( s, "r" );
+	if( !fp )
+	{
 		irc_usermsg( irc, "That account does not exist" );
 		return( 0 );
-	case STORAGE_INVALID_PASSWORD:
-		irc_usermsg( irc, "Password invalid" );
-		return( 0 );
-	case STORAGE_OK:
-		irc_setpass( irc, NULL );
-		irc_usermsg( irc, "Account `%s' removed", irc->nick );
-		return( 0 );
-	default:
-		irc_usermsg( irc, "Error: '%d'", status );
-		return( 0 );
-	}
+	}
+	
+	fscanf( fp, "%32[^\n]s", s );
+	fclose( fp );
+	if( setpass( irc, cmd[1], s ) < 0 )
+	{
+		irc_usermsg( irc, "Incorrect password" );
+		return( 0 );
+	}
+	
+	g_snprintf( s, 511, "%s%s%s", global.conf->configdir, irc->nick, ".accounts" );
+	unlink( s );
+	
+	g_snprintf( s, 511, "%s%s%s", global.conf->configdir, irc->nick, ".nicks" );
+	unlink( s );
+	
+	setpassnc( irc, NULL );
+	irc_usermsg( irc, "Files belonging to account `%s' removed", irc->nick );
+	
+	return( 0 );
 }
 
@@ -616,5 +634,5 @@
 int cmd_save( irc_t *irc, char **cmd )
 {
-	if( storage_save( irc, TRUE ) == STORAGE_OK )
+	if( bitlbee_save( irc ) )
 		irc_usermsg( irc, "Configuration saved" );
 	else
Index: conf.c
===================================================================
--- conf.c	(revision 22bf64eab8a79352317ee190cddfeef3011aa8dc)
+++ conf.c	(revision e7f46c56ffa29c6f8f4917c5f367a61706758e2a)
@@ -50,5 +50,4 @@
 	conf->nofork = 0;
 	conf->verbose = 0;
-	conf->primary_storage = "text";
 	conf->runmode = RUNMODE_INETD;
 	conf->authmode = AUTHMODE_OPEN;
@@ -199,14 +198,4 @@
 				conf->motdfile = g_strdup( ini->value );
 			}
-			else if( g_strcasecmp( ini->key, "account_storage" ) == 0 )
-			{
-				g_free( conf->primary_storage );
-				conf->primary_storage = g_strdup( ini->value );
-			}
-			else if( g_strcasecmp( ini->key, "account_storage_migrate" ) == 0 )
-			{
-				g_strfreev( conf->migrate_storage );
-				conf->migrate_storage = g_strsplit( ini->value, " \t,;", -1 );
-			}
 			else if( g_strcasecmp( ini->key, "pinginterval" ) == 0 )
 			{
Index: conf.h
===================================================================
--- conf.h	(revision 22bf64eab8a79352317ee190cddfeef3011aa8dc)
+++ conf.h	(revision e7f46c56ffa29c6f8f4917c5f367a61706758e2a)
@@ -42,6 +42,4 @@
 	char *configdir;
 	char *motdfile;
-	char *primary_storage;
-	char **migrate_storage;
 	int ping_interval;
 	int ping_timeout;
Index: configure
===================================================================
--- configure	(revision 22bf64eab8a79352317ee190cddfeef3011aa8dc)
+++ configure	(revision e7f46c56ffa29c6f8f4917c5f367a61706758e2a)
@@ -343,11 +343,15 @@
 case "$arch" in
 Linux )
+	echo 'Linux.'
 ;;
 GNU/* )
+	echo 'Debian with non-Linux kernel?'
 ;;
 *BSD )
+	echo '*BSD.'
 	echo 'EFLAGS+=-liconv' >> Makefile.settings;
 ;;
 SunOS )
+	echo 'Solaris.'
 	echo 'EFLAGS+=-lresolv -lnsl -lsocket' >> Makefile.settings
 	echo 'STRIP=\# skip strip' >> Makefile.settings
@@ -355,7 +359,9 @@
 ;;
 Darwin )
+	echo 'Darwin/Mac OS X.'
 	echo 'EFLAGS+=-liconv' >> Makefile.settings;
 ;;
 IRIX )
+	echo 'IRIX.'
 ;;
 CYGWIN* )
@@ -363,6 +369,5 @@
 ;;
 * )
-	echo 'We haven'\''t tested BitlBee on many platforms yet, yours is untested. YMMV.'
-	echo 'Please report any problems at http://bugs.bitlbee.org/.'
+	echo 'We haven'\''t tested BitlBee on many platforms yet, yours is untested. YMMV. Please report any problems to <wilmer@gaast.net>.'
 ;;
 esac
Index: crypting.c
===================================================================
--- crypting.c	(revision 22bf64eab8a79352317ee190cddfeef3011aa8dc)
+++ crypting.c	(revision e7f46c56ffa29c6f8f4917c5f367a61706758e2a)
@@ -29,4 +29,8 @@
    the programs will be built. */
 
+#ifndef CRYPTING_MAIN
+#define BITLBEE_CORE
+#include "bitlbee.h"
+#include "irc.h"
 #include "md5.h"
 #include "crypting.h"
@@ -35,4 +39,24 @@
 #include <stdlib.h>
 
+#else
+
+typedef struct irc
+{
+	char *password;
+} irc_t;
+
+#define set_add( a, b, c, d )
+#define set_find( a, b ) NULL
+
+#include "md5.h"
+#include "crypting.h"
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#define irc_usermsg
+
+#endif
+
 /*\
  * [SH] Do _not_ call this if it's not entirely sure that it will not cause
@@ -41,6 +65,26 @@
 \*/
 
-int checkpass (const char *pass, const char *md5sum)
-{
+/* USE WITH CAUTION!
+   Sets pass without checking */
+void setpassnc (irc_t *irc, char *pass) {
+	if (!set_find (irc, "password"))
+		set_add (irc, "password", NULL, passchange);
+	
+	if (irc->password) g_free (irc->password);
+	
+	if (pass) {
+		irc->password = g_strdup (pass);
+		irc_usermsg (irc, "Password successfully changed");
+	} else {
+		irc->password = NULL;
+	}
+}
+
+char *passchange (irc_t *irc, void *set, char *value) {
+	setpassnc (irc, value);
+	return (NULL);
+}
+
+int setpass (irc_t *irc, char *pass, char* md5sum) {
 	md5_state_t md5state;
 	md5_byte_t digest[16];
@@ -59,11 +103,12 @@
 		if (digits[1] != md5sum[j + 1]) return (-1);
 	}
-
-	return( 0 );
-}
-
-
-char *hashpass (const char *password)
-{
+	
+	/* If pass is correct, we end up here and we set the pass */
+	setpassnc (irc, pass);
+	
+	return (0);
+}
+
+char *hashpass (irc_t *irc) {
 	md5_state_t md5state;
 	md5_byte_t digest[16];
@@ -72,10 +117,11 @@
 	char *rv;
 	
-	if (password == NULL) return (NULL);
-	
-	rv = g_new0 (char, 33);
+	if (irc->password == NULL) return (NULL);
+	
+	rv = (char *)g_malloc (33);
+	memset (rv, 0, 33);
 	
 	md5_init (&md5state);
-	md5_append (&md5state, (const unsigned char *)password, strlen (password));
+	md5_append (&md5state, (unsigned char *)irc->password, strlen (irc->password));
 	md5_finish (&md5state, digest);
 	
@@ -89,12 +135,12 @@
 }
 
-char *obfucrypt (char *line, const char *password) 
-{
+char *obfucrypt (irc_t *irc, char *line) {
 	int i, j;
 	char *rv;
 	
-	if (password == NULL) return (NULL);
-	
-	rv = g_new0 (char, strlen (line) + 1);
+	if (irc->password == NULL) return (NULL);
+	
+	rv = (char *)g_malloc (strlen (line) + 1);
+	memset (rv, '\0', strlen (line) + 1);
 	
 	i = j = 0;
@@ -102,9 +148,10 @@
 		/* Encrypt/obfuscate the line, using the password */
 		if (*(signed char*)line < 0) *line = - (*line);
-		
-		rv[j] = *line + password[i]; /* Overflow intended */
+		if (((signed char*)irc->password)[i] < 0) irc->password[i] = - irc->password[i];
+		
+		rv[j] = *line + irc->password[i]; /* Overflow intended */
 		
 		line++;
-		if (!password[++i]) i = 0;
+		if (!irc->password[++i]) i = 0;
 		j++;
 	}
@@ -113,20 +160,20 @@
 }
 
-char *deobfucrypt (char *line, const char *password) 
-{
+char *deobfucrypt (irc_t *irc, char *line) {
 	int i, j;
 	char *rv;
 	
-	if (password == NULL) return (NULL);
-	
-	rv = g_new0 (char, strlen (line) + 1);
+	if (irc->password == NULL) return (NULL);
+	
+	rv = (char *)g_malloc (strlen (line) + 1);
+	memset (rv, '\0', strlen (line) + 1);
 	
 	i = j = 0;
 	while (*line) {
 		/* Decrypt/deobfuscate the line, using the pass */
-		rv[j] = *line - password[i]; /* Overflow intended */
+		rv[j] = *line - irc->password[i]; /* Overflow intended */
 		
 		line++;
-		if (!password[++i]) i = 0;
+		if (!irc->password[++i]) i = 0;
 		j++;
 	}
@@ -142,6 +189,7 @@
 int main( int argc, char *argv[] )
 {
+	irc_t *irc = g_malloc( sizeof( irc_t ) );
 	char *hash, *action, line[256];
-	char* (*func)( char *, const char * );
+	char* (*func)( irc_t *, char * );
 	
 	if( argc < 2 )
@@ -153,5 +201,8 @@
 	}
 	
-	hash = hashpass( argv[1] );
+	memset( irc, 0, sizeof( irc_t ) );
+	irc->password = g_strdup( argv[1] );
+	
+	hash = hashpass( irc );
 	action = argv[0] + strlen( argv[0] ) - strlen( "encode" );
 	
@@ -185,5 +236,5 @@
 		fgetc( stdin );
 		
-		out = func( line, argv[1] );
+		out = func( irc, line );
 		printf( "%s\n", out );
 		g_free( out );
Index: crypting.h
===================================================================
--- crypting.h	(revision 22bf64eab8a79352317ee190cddfeef3011aa8dc)
+++ crypting.h	(revision e7f46c56ffa29c6f8f4917c5f367a61706758e2a)
@@ -24,6 +24,8 @@
 */
 
-int checkpass (const char *password, const char *md5sum);
-char *hashpass (const char *password);
-char *obfucrypt (char *line, const char *password);
-char *deobfucrypt (char *line, const char *password);
+void setpassnc (irc_t *irc, char *pass); /* USE WITH CAUTION! */
+char *passchange (irc_t *irc, void *set, char *value);
+int setpass (irc_t *irc, char *pass, char* md5sum);
+char *hashpass (irc_t *irc);
+char *obfucrypt (irc_t *irc, char *line);
+char *deobfucrypt (irc_t *irc, char *line);
Index: doc/AUTHORS
===================================================================
--- doc/AUTHORS	(revision 22bf64eab8a79352317ee190cddfeef3011aa8dc)
+++ doc/AUTHORS	(revision e7f46c56ffa29c6f8f4917c5f367a61706758e2a)
@@ -4,5 +4,5 @@
 	Main developer
 
-Jelmer 'ctrlsoft' Vernooij <jelmer@samba.org>
+Jelmer 'ctrlsoft' Vernooij <jelmer@nl.linux.org>
 	Documentation, general hacking, Win32 port
 
Index: doc/CHANGES
===================================================================
--- doc/CHANGES	(revision 22bf64eab8a79352317ee190cddfeef3011aa8dc)
+++ doc/CHANGES	(revision e7f46c56ffa29c6f8f4917c5f367a61706758e2a)
@@ -22,13 +22,6 @@
   abusing it as a port scanner. We aren't aware of any Jabber server that
   runs on other ports than those. If you are, please warn us.
-- Send flood protection can't be enabled anymore. It was disabled by default
-  for a good reason for some time already, but some package maintainers
-  turned it back on while it's way too unreliable and trigger-happy to be
-  used.
-- Removed TODO file, the current to-do list is always in the on-line bug
-  tracking system.
-- Fixed a potential DoS bug in input handling.
-
-Finished 4 Dec 2005
+
+Finished ...
 
 Version 0.99:
Index: doc/FAQ
===================================================================
--- doc/FAQ	(revision 22bf64eab8a79352317ee190cddfeef3011aa8dc)
+++ doc/FAQ	(revision e7f46c56ffa29c6f8f4917c5f367a61706758e2a)
@@ -46,9 +46,6 @@
    non-ASCII characters!
 A: You probably have to change some settings. To get rid of HTML in messages,
-   see "help set strip_html". If you seem to have problems with your charset,
-   see "help set charset".
-   
-   Although actually most of these problems should be gone by now. So if you
-   can't get things to work well, you might have found a bug.
+   see "help set html". If you seem to have problems with your charset, see
+   "help set charset".
 
 Q: Is BitlBee forked from Gaim?
Index: doc/README
===================================================================
--- doc/README	(revision 22bf64eab8a79352317ee190cddfeef3011aa8dc)
+++ doc/README	(revision e7f46c56ffa29c6f8f4917c5f367a61706758e2a)
@@ -108,8 +108,9 @@
 See utils/bitlbeed.c for more information about the program.
 
-Just a little note: Now that we reach version 1.0, this shouldn't be that
-much of an issue anymore. However, on a public server, especially if you
-also use it for other things, it can't hurt to protect yourself against
-possible problems.
+Just a little note: We run our public server im.bitlbee.org for a couple of
+months now, and so far we haven't experienced this problem yet. The only
+BitlBee processes killed because of CPU-time overuse were running for a long
+time already, they were usually killed during the MSN login process (which
+is quite CPU-time consuming).
 
 
@@ -144,10 +145,4 @@
 You can find new releases of BitlBee at:
 http://www.bitlbee.org/
-
-The bug tracking system:
-http://bugs.bitlbee.org/
-
-Our version control system is Bazaar-NG. Our repository is at:
-http://code.bitlbee.org/
 
 
@@ -192,4 +187,4 @@
 	BitlBee - An IRC to other chat networks gateway 
 	          <http://www.bitlbee.org/>
-	Copyright (C) 2002-2005  Wilmer van der Gaast <wilmer@gaast.net>
+	Copyright (C) 2002-2004  Wilmer van der Gaast <wilmer@gaast.net>
 	                         and others
Index: doc/user-guide/user-guide.xml
===================================================================
--- doc/user-guide/user-guide.xml	(revision 22bf64eab8a79352317ee190cddfeef3011aa8dc)
+++ doc/user-guide/user-guide.xml	(revision e7f46c56ffa29c6f8f4917c5f367a61706758e2a)
@@ -24,8 +24,5 @@
 
    <releaseinfo>
-   		This is the BitlBee User Guide. For now, the on-line help is
-		the most up-to-date documentation. Although this document shares
-		some parts with the on-line help system, other parts might be
-		very outdated.
+   		This is the initial release of the BitlBee User Guide.
    </releaseinfo>
 
Index: irc.c
===================================================================
--- irc.c	(revision 22bf64eab8a79352317ee190cddfeef3011aa8dc)
+++ irc.c	(revision e7f46c56ffa29c6f8f4917c5f367a61706758e2a)
@@ -31,10 +31,4 @@
 
 GSList *irc_connection_list = NULL;
-
-static char *passchange (irc_t *irc, void *set, char *value) 
-{
-	irc_setpass (irc, value);
-	return (NULL);
-}
 
 irc_t *irc_new( int fd )
@@ -135,5 +129,4 @@
 	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 );
@@ -161,5 +154,5 @@
 	
 	if( irc->status >= USTATUS_IDENTIFIED && set_getint( irc, "save_on_quit" ) ) 
-		if( storage_save( irc, TRUE ) != STORAGE_OK )
+		if( !bitlbee_save( irc ) )
 			irc_usermsg( irc, "Error while saving settings!" );
 	
@@ -266,18 +259,4 @@
 	if( global.conf->runmode == RUNMODE_INETD )
 		g_main_quit( global.loop );
-}
-
-/* USE WITH CAUTION!
-   Sets pass without checking */
-void irc_setpass (irc_t *irc, const char *pass) 
-{
-	if (irc->password) g_free (irc->password);
-	
-	if (pass) {
-		irc->password = g_strdup (pass);
-		irc_usermsg (irc, "Password successfully changed");
-	} else {
-		irc->password = NULL;
-	}
 }
 
Index: irc.h
===================================================================
--- irc.h	(revision 22bf64eab8a79352317ee190cddfeef3011aa8dc)
+++ irc.h	(revision e7f46c56ffa29c6f8f4917c5f367a61706758e2a)
@@ -137,5 +137,4 @@
 void irc_whois( irc_t *irc, char *nick );
 int irc_away( irc_t *irc, char *away );
-void irc_setpass( irc_t *irc, const char *pass ); /* USE WITH CAUTION! */
 
 int irc_send( irc_t *irc, char *nick, char *s, int flags );
Index: nick.c
===================================================================
--- nick.c	(revision 22bf64eab8a79352317ee190cddfeef3011aa8dc)
+++ nick.c	(revision e7f46c56ffa29c6f8f4917c5f367a61706758e2a)
@@ -27,5 +27,5 @@
 #include "bitlbee.h"
 
-void nick_set( irc_t *irc, const char *handle, int proto, const char *nick )
+void nick_set( irc_t *irc, char *handle, int proto, char *nick )
 {
 	nick_t *m = NULL, *n = irc->nicks;
@@ -56,5 +56,5 @@
 }
 
-char *nick_get( irc_t *irc, const char *handle, int proto, const char *realname )
+char *nick_get( irc_t *irc, char *handle, int proto, const char *realname )
 {
 	static char nick[MAX_NICK_LENGTH+1];
@@ -129,5 +129,5 @@
 }
 
-void nick_del( irc_t *irc, const char *nick )
+void nick_del( irc_t *irc, char *nick )
 {
 	nick_t *l = NULL, *n = irc->nicks;
@@ -176,7 +176,7 @@
 }
 
-int nick_ok( const char *nick )
-{
-	const char *s;
+int nick_ok( char *nick )
+{
+	char *s;
 	
 	/* Empty/long nicks are not allowed */
@@ -237,5 +237,5 @@
 }
 
-int nick_cmp( const char *a, const char *b )
+int nick_cmp( char *a, char *b )
 {
 	char aa[1024] = "", bb[1024] = "";
@@ -253,6 +253,11 @@
 }
 
-char *nick_dup( const char *nick )
-{
-	return g_strndup( nick, MAX_NICK_LENGTH );
-}
+char *nick_dup( char *nick )
+{
+	char *cp;
+	
+	cp = g_new0 ( char, MAX_NICK_LENGTH + 1 );
+	strncpy( cp, nick, MAX_NICK_LENGTH );
+	
+	return( cp );
+}
Index: nick.h
===================================================================
--- nick.h	(revision 22bf64eab8a79352317ee190cddfeef3011aa8dc)
+++ nick.h	(revision e7f46c56ffa29c6f8f4917c5f367a61706758e2a)
@@ -32,12 +32,12 @@
 } nick_t;
 
-void nick_set( irc_t *irc, const char *handle, int proto, const char *nick );
-char *nick_get( irc_t *irc, const char *handle, int proto, const char *realname );
-void nick_del( irc_t *irc, const char *nick );
+void nick_set( irc_t *irc, char *handle, int proto, char *nick );
+char *nick_get( irc_t *irc, char *handle, int proto, const char *realname );
+void nick_del( irc_t *irc, char *nick );
 void nick_strip( char *nick );
 
-int nick_ok( const char *nick );
+int nick_ok( char *nick );
 int nick_lc( char *nick );
 int nick_uc( char *nick );
-int nick_cmp( const char *a, const char *b );
-char *nick_dup( const char *nick );
+int nick_cmp( char *a, char *b );
+char *nick_dup( char *nick );
Index: protocols/oscar/aim.h
===================================================================
--- protocols/oscar/aim.h	(revision 22bf64eab8a79352317ee190cddfeef3011aa8dc)
+++ protocols/oscar/aim.h	(revision e7f46c56ffa29c6f8f4917c5f367a61706758e2a)
@@ -466,5 +466,4 @@
 int aim_addtlvtochain_caps(aim_tlvlist_t **list, const guint16 t, const guint32 caps);
 int aim_addtlvtochain_noval(aim_tlvlist_t **list, const guint16 type);
-int aim_addtlvtochain_chatroom(aim_tlvlist_t **list, guint16 type, guint16 exchange, const char *roomname, guint16 instance);
 int aim_addtlvtochain_userinfo(aim_tlvlist_t **list, guint16 type, aim_userinfo_t *ui);
 int aim_addtlvtochain_frozentlvlist(aim_tlvlist_t **list, guint16 type, aim_tlvlist_t **tl);
@@ -573,9 +572,4 @@
 };
 
-struct aim_chat_invitation {
-	struct gaim_connection * gc;
-	char * name;
-	guint8 exchange;
-};
 
 #define AIM_VISIBILITYCHANGE_PERMITADD    0x05
Index: protocols/oscar/chat.c
===================================================================
--- protocols/oscar/chat.c	(revision 22bf64eab8a79352317ee190cddfeef3011aa8dc)
+++ protocols/oscar/chat.c	(revision e7f46c56ffa29c6f8f4917c5f367a61706758e2a)
@@ -180,4 +180,29 @@
 	
 	aim_tx_enqueue(sess, fr);
+
+	return 0;
+}
+
+static int aim_addtlvtochain_chatroom(aim_tlvlist_t **list, guint16 type, guint16 exchange, const char *roomname, guint16 instance)
+{
+	guint8 *buf;
+	int buflen;
+	aim_bstream_t bs;
+
+	buflen = 2 + 1 + strlen(roomname) + 2;
+	
+	if (!(buf = g_malloc(buflen)))
+		return 0;
+
+	aim_bstream_init(&bs, buf, buflen);
+
+	aimbs_put16(&bs, exchange);
+	aimbs_put8(&bs, strlen(roomname));
+	aimbs_putraw(&bs, (guint8 *)roomname, strlen(roomname));
+	aimbs_put16(&bs, instance);
+
+	aim_addtlvtochain_raw(list, type, aim_bstream_curpos(&bs), buf);
+
+	g_free(buf);
 
 	return 0;
Index: protocols/oscar/im.c
===================================================================
--- protocols/oscar/im.c	(revision 22bf64eab8a79352317ee190cddfeef3011aa8dc)
+++ protocols/oscar/im.c	(revision e7f46c56ffa29c6f8f4917c5f367a61706758e2a)
@@ -1369,28 +1369,4 @@
 }
 
-
-static void incomingim_ch2_chat_free(aim_session_t *sess, struct aim_incomingim_ch2_args *args)
-{
-
-	/* XXX aim_chat_roominfo_free() */
-	g_free(args->info.chat.roominfo.name);
-
-	return;
-}
-
-static void incomingim_ch2_chat(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_userinfo_t *userinfo, struct aim_incomingim_ch2_args *args, aim_bstream_t *servdata)
-{
-
-	/*
-	 * Chat room info.
-	 */
-	if (servdata)
-		aim_chat_readroominfo(servdata, &args->info.chat.roominfo);
-
-	args->destructor = (void *)incomingim_ch2_chat_free;
-
-	return;
-}
-
 static void incomingim_ch2_icqserverrelay_free(aim_session_t *sess, struct aim_incomingim_ch2_args *args)
 {
@@ -1641,6 +1617,4 @@
 	if (args.reqclass & AIM_CAPS_ICQSERVERRELAY)
 		incomingim_ch2_icqserverrelay(sess, mod, rx, snac, userinfo, &args, sdbsptr);
-	else if (args.reqclass & AIM_CAPS_CHAT)
-		incomingim_ch2_chat(sess, mod, rx, snac, userinfo, &args, sdbsptr);
 
 
Index: protocols/oscar/oscar.c
===================================================================
--- protocols/oscar/oscar.c	(revision 22bf64eab8a79352317ee190cddfeef3011aa8dc)
+++ protocols/oscar/oscar.c	(revision e7f46c56ffa29c6f8f4917c5f367a61706758e2a)
@@ -62,5 +62,5 @@
    static int gaim_caps = AIM_CAPS_UTF8; */
 
-static int gaim_caps = AIM_CAPS_INTEROP | AIM_CAPS_ICHAT | AIM_CAPS_ICQSERVERRELAY | AIM_CAPS_CHAT;
+static int gaim_caps = AIM_CAPS_INTEROP | AIM_CAPS_ICHAT | AIM_CAPS_ICQSERVERRELAY;
 static guint8 gaim_features[] = {0x01, 0x01, 0x01, 0x02};
 
@@ -156,4 +156,5 @@
 }
 
+#if 0
 static struct chat_connection *find_oscar_chat(struct gaim_connection *gc, int id) {
 	GSList *g = ((struct oscar_data *)gc->proto_data)->oscar_chats;
@@ -170,5 +171,5 @@
 	return c;
 }
-
+#endif
 
 static struct chat_connection *find_oscar_chat_by_conn(struct gaim_connection *gc,
@@ -1075,13 +1076,12 @@
 }
 
-void oscar_accept_chat(gpointer w, struct aim_chat_invitation * inv);
-void oscar_reject_chat(gpointer w, struct aim_chat_invitation * inv);
-	
 static int incomingim_chan2(aim_session_t *sess, aim_conn_t *conn, aim_userinfo_t *userinfo, struct aim_incomingim_ch2_args *args) {
+#if 0
 	struct gaim_connection *gc = sess->aux_data;
+#endif
 
 	if (args->status != AIM_RENDEZVOUS_PROPOSE)
 		return 1;
-
+#if 0
 	if (args->reqclass & AIM_CAPS_CHAT) {
 		char *name = extract_name(args->info.chat.roominfo.name);
@@ -1091,21 +1091,13 @@
 		*exch = args->info.chat.roominfo.exchange;
 		m = g_list_append(m, exch);
-
-		char txt[1024];
-
-		g_snprintf( txt, 1024, "Got an invitation to chatroom %s from %s: %s", name, userinfo->sn, args->msg );
-
-		struct aim_chat_invitation * inv = g_new0(struct aim_chat_invitation, 1);
-
-		inv->gc = gc;
-		inv->exchange = *exch;
-		inv->name = g_strdup(name);
-		
-		do_ask_dialog( gc, txt, inv, oscar_accept_chat, oscar_reject_chat);
-	
+		serv_got_chat_invite(gc,
+				     name ? name : args->info.chat.roominfo.name,
+				     userinfo->sn,
+				     (char *)args->msg,
+				     m);
 		if (name)
 			g_free(name);
 	}
-
+#endif
 	return 1;
 }
@@ -2502,136 +2494,4 @@
 }
 
-int oscar_chat_send(struct gaim_connection * gc, int id, char *message)
-{
-	struct oscar_data * od = (struct oscar_data*)gc->proto_data;
-	struct chat_connection * ccon;
-	
-	if(!(ccon = find_oscar_chat(gc, id)))
-		return -1;
-	
-	int ret;
-	guint8 len = strlen(message);
-	char *s;
-	  	
-	for (s = message; *s; s++)
-		if (*s & 128)
-			break;
-	  	
-	/* Message contains high ASCII chars, time for some translation! */
-	if (*s) {
-		s = g_malloc(BUF_LONG);
-		/* Try if we can put it in an ISO8859-1 string first.
-		   If we can't, fall back to UTF16. */
-		if ((ret = do_iconv("UTF-8", "ISO8859-1", message, s, len, BUF_LONG)) >= 0) {
-			len = ret;
-		} else if ((ret = do_iconv("UTF-8", "UNICODEBIG", message, s, len, BUF_LONG)) >= 0) {
-			len = ret;
-		} else {
-			/* OOF, translation failed... Oh well.. */
-			g_free( s );
-			s = message;
-		}
-	} else {
-		s = message;
-	}
-	  	
-	ret = aim_chat_send_im(od->sess, ccon->conn, AIM_CHATFLAGS_NOREFLECT, s, len);
-	  	
-	if (s != message) {	
-		g_free(s);
-  }
-  
-  return (ret >= 0);
-}
-
-void oscar_chat_invite(struct gaim_connection * gc, int id, char *message, char *who)
-{
-	struct oscar_data * od = (struct oscar_data *)gc->proto_data;
-	struct chat_connection *ccon = find_oscar_chat(gc, id);
-	
-	if (ccon == NULL)
-		return;
-	
-	aim_chat_invite(od->sess, od->conn, who, message ? message : "",
-					ccon->exchange, ccon->name, 0x0);
-}
-
-void oscar_chat_kill(struct gaim_connection *gc, struct chat_connection *cc)
-{
-	struct oscar_data *od = (struct oscar_data *)gc->proto_data;
-
-	/* Notify the conversation window that we've left the chat */
-	serv_got_chat_left(gc, cc->id);
-
-	/* Destroy the chat_connection */
-	od->oscar_chats = g_slist_remove(od->oscar_chats, cc);
-	if (cc->inpa > 0)
-		gaim_input_remove(cc->inpa);
-	aim_conn_kill(od->sess, &cc->conn);
-	g_free(cc->name);
-	g_free(cc->show);
-	g_free(cc);
-}
-
-void oscar_chat_leave(struct gaim_connection * gc, int id)
-{
-	struct chat_connection * ccon = find_oscar_chat(gc, id);
-
-	if(ccon == NULL)
-		return;
-
-	oscar_chat_kill(gc, ccon);
-}
-
-int oscar_chat_join(struct gaim_connection * gc, char * name)
-{
-    struct oscar_data * od = (struct oscar_data *)gc->proto_data;
-	
-	aim_conn_t * cur;
-
-	if((cur = aim_getconn_type(od->sess, AIM_CONN_TYPE_CHATNAV))) {
-	
-		return (aim_chatnav_createroom(od->sess, cur, name, 4) == 0);
-	
-	} else {
-		struct create_room * cr = g_new0(struct create_room, 1);
-		cr->exchange = 4;
-		cr->name = g_strdup(name);
-		od->create_rooms = g_slist_append(od->create_rooms, cr);
-		aim_reqservice(od->sess, od->conn, AIM_CONN_TYPE_CHATNAV);
-		return 1;
-	}
-}
-
-int oscar_chat_open(struct gaim_connection * gc, char *who)
-{
-	struct oscar_data * od = (struct oscar_data *)gc->proto_data;
-
-	static int chat_id = 0;
-	char * chatname = g_new0(char, strlen(gc->username)+4);
-	g_snprintf(chatname, strlen(gc->username) + 4, "%s%d", gc->username, chat_id++);
-  
-	int ret = oscar_chat_join(gc, chatname);
-
-	aim_chat_invite(od->sess, od->conn, who, "", 4, chatname, 0x0);
-
-	g_free(chatname);
-	
-	return ret;
-}
-
-void oscar_accept_chat(gpointer w, struct aim_chat_invitation * inv)
-{
-	oscar_chat_join(inv->gc, inv->name);
-	g_free(inv->name);
-	g_free(inv);
-}
-
-void oscar_reject_chat(gpointer w, struct aim_chat_invitation * inv)
-{
-	g_free(inv->name);
-	g_free(inv);
-}
-
 static struct prpl *my_protocol = NULL;
 
@@ -2647,8 +2507,4 @@
 	ret->add_buddy = oscar_add_buddy;
 	ret->remove_buddy = oscar_remove_buddy;
-	ret->chat_send = oscar_chat_send;
-	ret->chat_invite = oscar_chat_invite;
-	ret->chat_leave = oscar_chat_leave;
-	ret->chat_open = oscar_chat_open;
 	ret->add_permit = oscar_add_permit;
 	ret->add_deny = oscar_add_deny;
Index: protocols/oscar/tlv.c
===================================================================
--- protocols/oscar/tlv.c	(revision 22bf64eab8a79352317ee190cddfeef3011aa8dc)
+++ protocols/oscar/tlv.c	(revision e7f46c56ffa29c6f8f4917c5f367a61706758e2a)
@@ -340,29 +340,4 @@
 }
 
-int aim_addtlvtochain_chatroom(aim_tlvlist_t **list, guint16 type, guint16 exchange, const char *roomname, guint16 instance)
-{
-	guint8 *buf;
-	int buflen;
-	aim_bstream_t bs;
-
-	buflen = 2 + 1 + strlen(roomname) + 2;
-	
-	if (!(buf = g_malloc(buflen)))
-		return 0;
-
-	aim_bstream_init(&bs, buf, buflen);
-
-	aimbs_put16(&bs, exchange);
-	aimbs_put8(&bs, strlen(roomname));
-	aimbs_putraw(&bs, (guint8 *)roomname, strlen(roomname));
-	aimbs_put16(&bs, instance);
-
-	aim_addtlvtochain_raw(list, type, aim_bstream_curpos(&bs), buf);
-
-	g_free(buf);
-
-	return 0;
-}
-
 /**
  * aim_writetlvchain - Write a TLV chain into a data buffer.
Index: protocols/proxy.c
===================================================================
--- protocols/proxy.c	(revision 22bf64eab8a79352317ee190cddfeef3011aa8dc)
+++ protocols/proxy.c	(revision e7f46c56ffa29c6f8f4917c5f367a61706758e2a)
@@ -50,4 +50,14 @@
 #define GAIM_ERR_COND   (G_IO_HUP | G_IO_ERR | G_IO_NVAL)
 
+/*FIXME*		
+	#ifndef _WIN32
+		if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &len) < 0) {
+			closesocket(fd);
+			g_free(phb);
+			return -1;
+		}
+		fcntl(fd, F_SETFL, 0);
+#endif*/
+
 char proxyhost[128] = "";
 int proxyport = 0;
@@ -73,5 +83,5 @@
 
 
-static struct sockaddr_in *gaim_gethostbyname(const char *host, int port)
+static struct sockaddr_in *gaim_gethostbyname(char *host, int port)
 {
 	static struct sockaddr_in sin;
@@ -144,5 +154,5 @@
 }
 
-static int proxy_connect_none(const char *host, unsigned short port, struct PHB *phb)
+static int proxy_connect_none(char *host, unsigned short port, struct PHB *phb)
 {
 	struct sockaddr_in *sin;
@@ -271,5 +281,5 @@
 }
 
-static int proxy_connect_http(const char *host, unsigned short port, struct PHB *phb)
+static int proxy_connect_http(char *host, unsigned short port, struct PHB *phb)
 {
 	phb->host = g_strdup(host);
@@ -355,5 +365,5 @@
 }
 
-static int proxy_connect_socks4(const char *host, unsigned short port, struct PHB *phb)
+static int proxy_connect_socks4(char *host, unsigned short port, struct PHB *phb)
 {
 	phb->host = g_strdup(host);
@@ -537,5 +547,5 @@
 }
 
-static int proxy_connect_socks5(const char *host, unsigned short port, struct PHB *phb)
+static int proxy_connect_socks5(char *host, unsigned short port, struct PHB *phb)
 {
 	phb->host = g_strdup(host);
@@ -578,5 +588,5 @@
 }
 
-int proxy_connect(const char *host, int port, GaimInputFunction func, gpointer data)
+int proxy_connect(char *host, int port, GaimInputFunction func, gpointer data)
 {
 	struct PHB *phb;
Index: protocols/proxy.h
===================================================================
--- protocols/proxy.h	(revision 22bf64eab8a79352317ee190cddfeef3011aa8dc)
+++ protocols/proxy.h	(revision e7f46c56ffa29c6f8f4917c5f367a61706758e2a)
@@ -56,5 +56,5 @@
 G_MODULE_EXPORT void gaim_input_remove(gint);
 
-G_MODULE_EXPORT int proxy_connect(const char *host, int port, GaimInputFunction func, gpointer data);
+G_MODULE_EXPORT int proxy_connect(char *host, int port, GaimInputFunction func, gpointer data);
 
 #endif /* _PROXY_H_ */
Index: orage.c
===================================================================
--- storage.c	(revision 22bf64eab8a79352317ee190cddfeef3011aa8dc)
+++ 	(revision )
@@ -1,185 +1,0 @@
-  /********************************************************************\
-  * BitlBee -- An IRC to other IM-networks gateway                     *
-  *                                                                    *
-  * Copyright 2002-2004 Wilmer van der Gaast and others                *
-  \********************************************************************/
-
-/* Support for multiple storage backends */
-
-/*
-  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 "crypting.h"
-
-extern storage_t storage_text;
-
-static GList text_entry = { &storage_text, NULL, NULL };
-static GList *storage_backends = &text_entry;
-
-void register_storage_backend(storage_t *backend)
-{
-	storage_backends = g_list_append(storage_backends, backend);
-}
-
-static storage_t *storage_init_single(const char *name)
-{
-	GList *gl;
-	storage_t *st;
-
-	for (gl = storage_backends; gl; gl = gl->next) {
-		st = gl->data;
-		if (strcmp(st->name, name) == 0)
-			break;
-	}
-
-	if (gl == NULL) 
-		return NULL;
-
-	if (st->init)
-		st->init();
-
-	return st;
-}
-
-GList *storage_init(const char *primary, char **migrate)
-{
-	GList *ret = NULL;
-	int i;
-	storage_t *storage;
-
-	storage = storage_init_single(primary);
-	if (storage == NULL)
-		return NULL;
-
-	ret = g_list_append(ret, storage);
-
-	for (i = 0; migrate && migrate[i]; i++) {
-		storage = storage_init_single(migrate[i]);
-	
-		if (storage)
-			ret = g_list_append(ret, storage);
-	}
-
-	return ret;
-}
-
-storage_status_t storage_check_pass (const char *nick, const char *password)
-{
-	GList *gl;
-	
-	/* Loop until we don't get NO_SUCH_USER */
-
-	for (gl = global.storage; gl; gl = gl->next) {
-		storage_t *st = gl->data;
-		storage_status_t status;
-
-		status = st->check_pass(nick, password);
-		if (status != STORAGE_NO_SUCH_USER)
-			return status;
-	}
-	
-	return STORAGE_NO_SUCH_USER;
-}
-
-storage_status_t storage_load (const char *nick, const char *password, irc_t * irc)
-{
-	GList *gl;
-	
-	/* Loop until we don't get NO_SUCH_USER */
-	for (gl = global.storage; gl; gl = gl->next) {
-		storage_t *st = gl->data;
-		storage_status_t status;
-
-		status = st->load(nick, password, irc);
-		if (status == STORAGE_OK) {
-			irc_setpass(irc, password);
-			return status;
-		}
-		
-		if (status != STORAGE_NO_SUCH_USER) 
-			return status;
-	}
-	
-	return STORAGE_NO_SUCH_USER;
-}
-
-storage_status_t storage_save (irc_t *irc, int overwrite)
-{
-	return ((storage_t *)global.storage->data)->save(irc, overwrite);
-}
-
-storage_status_t storage_remove (const char *nick, const char *password)
-{
-	GList *gl;
-	storage_status_t ret = STORAGE_OK;
-	
-	/* Remove this account from all storage backends. If this isn't 
-	 * done, the account will still be usable, it'd just be 
-	 * loaded from a different backend. */
-	for (gl = global.storage; gl; gl = gl->next) {
-		storage_t *st = gl->data;
-		storage_status_t status;
-
-		status = st->remove(nick, password);
-		if (status != STORAGE_NO_SUCH_USER && 
-			status != STORAGE_OK)
-			ret = status;
-	}
-	
-	return ret;
-}
-
-storage_status_t storage_rename (const char *onick, const char *nnick, const char *password)
-{
-	storage_status_t status;
-	GList *gl = global.storage;
-	storage_t *primary_storage = gl->data;
-	irc_t *irc;
-
-	/* First, try to rename in the current write backend, assuming onick 
-	 * is stored there */
-	status = primary_storage->rename(onick, nnick, password);
-	if (status != STORAGE_NO_SUCH_USER)
-		return status;
-
-	/* Try to load from a migration backend and save to the current backend. 
-	 * Explicitly remove the account from the migration backend as otherwise 
-	 * it'd still be usable under the old name */
-	
-	irc = g_new0(irc_t, 1);
-	status = storage_load(onick, password, irc);
-	if (status != STORAGE_OK) {
-		irc_free(irc);
-		return status;
-	}
-
-	g_free(irc->nick);
-	irc->nick = g_strdup(nnick);
-
-	status = storage_save(irc, FALSE);
-	if (status != STORAGE_OK) {
-		irc_free(irc);
-		return status;
-	}
-	irc_free(irc);
-
-	storage_remove(onick, password);
-
-	return STORAGE_OK;
-}
Index: orage.h
===================================================================
--- storage.h	(revision 22bf64eab8a79352317ee190cddfeef3011aa8dc)
+++ 	(revision )
@@ -1,66 +1,0 @@
-  /********************************************************************\
-  * BitlBee -- An IRC to other IM-networks gateway                     *
-  *                                                                    *
-  * Copyright 2002-2004 Wilmer van der Gaast and others                *
-  \********************************************************************/
-
-/* Layer for retrieving and storing buddy information */
-
-/*
-  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 __STORAGE_H__
-#define __STORAGE_H__
-
-typedef enum {
-	STORAGE_OK = 0,
-	STORAGE_NO_SUCH_USER,
-	STORAGE_INVALID_PASSWORD,
-	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 */
-} storage_status_t;
-
-typedef struct {
-	const char *name;
-	
-	/* May be set to NULL if not required */
-	void (*init) (void);
-
-	storage_status_t (*check_pass) (const char *nick, const char *password);
-
-	storage_status_t (*load) (const char *nick, const char *password, irc_t * irc);
-	storage_status_t (*save) (irc_t *irc, int overwrite);
-	storage_status_t (*remove) (const char *nick, const char *password);
-
-	/* May be NULL if not supported by backend */
-	storage_status_t (*rename) (const char *onick, const char *nnick, const char *password);
-} storage_t;
-
-storage_status_t storage_check_pass (const char *nick, const char *password);
-
-storage_status_t storage_load (const char *nick, const char *password, irc_t * irc);
-storage_status_t storage_save (irc_t *irc, int overwrite);
-storage_status_t storage_remove (const char *nick, const char *password);
-
-storage_status_t storage_rename (const char *onick, const char *nnick, const char *password);
-
-void register_storage_backend(storage_t *);
-GList *storage_init(const char *primary, char **migrate);
-
-#endif /* __STORAGE_H__ */
Index: orage_text.c
===================================================================
--- storage_text.c	(revision 22bf64eab8a79352317ee190cddfeef3011aa8dc)
+++ 	(revision )
@@ -1,314 +1,0 @@
-  /********************************************************************\
-  * BitlBee -- An IRC to other IM-networks gateway                     *
-  *                                                                    *
-  * Copyright 2002-2004 Wilmer van der Gaast and others                *
-  \********************************************************************/
-
-/* Storage backend that uses the same file format as <=1.0 */
-
-/*
-  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 "crypting.h"
-
-static void text_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 text_load ( const char *my_nick, const char* password, irc_t *irc )
-{
-	char s[512];
-	char *line;
-	int proto;
-	char nick[MAX_NICK_LENGTH+1];
-	FILE *fp;
-	user_t *ru = user_find( irc, ROOT_NICK );
-	
-	if( irc->status == USTATUS_IDENTIFIED )
-		return( 1 );
-	
-	g_snprintf( s, 511, "%s%s%s", global.conf->configdir, my_nick, ".accounts" );
-   	fp = fopen( s, "r" );
-   	if( !fp ) return STORAGE_NO_SUCH_USER;
-	
-	fscanf( fp, "%32[^\n]s", s );
-
-	if (checkpass (password, s) != 0) 
-	{
-		fclose( fp );
-		return STORAGE_INVALID_PASSWORD;
-	}
-	
-	/* Do this now. If the user runs with AuthMode = Registered, the
-	   account command will not work otherwise. */
-	irc->status = USTATUS_IDENTIFIED;
-	
-	while( fscanf( fp, "%511[^\n]s", s ) > 0 )
-	{
-		fgetc( fp );
-		line = deobfucrypt( s, password );
-		if (line == NULL) return STORAGE_OTHER_ERROR;
-		root_command_string( irc, ru, line, 0 );
-		g_free( line );
-	}
-	fclose( fp );
-	
-	g_snprintf( s, 511, "%s%s%s", global.conf->configdir, my_nick, ".nicks" );
-	fp = fopen( s, "r" );
-	if( !fp ) return STORAGE_NO_SUCH_USER;
-	while( fscanf( fp, "%s %d %s", s, &proto, nick ) > 0 )
-	{
-		http_decode( s );
-		nick_set( irc, s, proto, nick );
-	}
-	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;
-}
-
-static storage_status_t text_save( irc_t *irc, int overwrite )
-{
-	char s[512];
-	char path[512], new_path[512];
-	char *line;
-	nick_t *n;
-	set_t *set;
-	mode_t ou = umask( 0077 );
-	account_t *a;
-	FILE *fp;
-	char *hash;
-
-	if (!overwrite) {
-		g_snprintf( path, 511, "%s%s%s", global.conf->configdir, irc->nick, ".accounts" );
-		if (access( path, F_OK ) != -1)
-			return STORAGE_ALREADY_EXISTS;
-	
-		g_snprintf( path, 511, "%s%s%s", global.conf->configdir, irc->nick, ".nicks" );
-		if (access( path, F_OK ) != -1)
-			return STORAGE_ALREADY_EXISTS;
-	}
-	
-	/*\
-	 *  [SH] Nothing should be saved if no password is set, because the
-	 *  password is not set if it was wrong, or if one is not identified
-	 *  yet. This means that a malicious user could easily overwrite
-	 *  files owned by someone else:
-	 *  a Bad Thing, methinks
-	\*/
-
-	/* [WVG] No? Really? */
-
-	/*\
-	 *  [SH] Okay, okay, it wasn't really Wilmer who said that, it was
-	 *  me. I just thought it was funny.
-	\*/
-	
-	hash = hashpass( irc->password );
-	if( hash == NULL )
-	{
-		irc_usermsg( irc, "Please register yourself if you want to save your settings." );
-		return STORAGE_OTHER_ERROR;
-	}
-	
-	g_snprintf( path, 511, "%s%s%s", global.conf->configdir, irc->nick, ".nicks~" );
-	fp = fopen( path, "w" );
-	if( !fp ) return STORAGE_OTHER_ERROR;
-	for( n = irc->nicks; n; n = n->next )
-	{
-		strcpy( s, n->handle );
-		s[169] = 0; /* Prevent any overflow (169 ~ 512 / 3) */
-		http_encode( s );
-		g_snprintf( s + strlen( s ), 510 - strlen( s ), " %d %s", n->proto, n->nick );
-		if( fprintf( fp, "%s\n", s ) != strlen( s ) + 1 )
-		{
-			irc_usermsg( irc, "fprintf() wrote too little. Disk full?" );
-			fclose( fp );
-			return STORAGE_OTHER_ERROR;
-		}
-	}
-	if( fclose( fp ) != 0 )
-	{
-		irc_usermsg( irc, "fclose() reported an error. Disk full?" );
-		return STORAGE_OTHER_ERROR;
-	}
-  
-	g_snprintf( new_path, 512, "%s%s%s", global.conf->configdir, irc->nick, ".nicks" );
-	if( unlink( new_path ) != 0 )
-	{
-		if( errno != ENOENT )
-		{
-			irc_usermsg( irc, "Error while removing old .nicks file" );
-			return STORAGE_OTHER_ERROR;
-		}
-	}
-	if( rename( path, new_path ) != 0 )
-	{
-		irc_usermsg( irc, "Error while renaming new .nicks file" );
-		return STORAGE_OTHER_ERROR;
-	}
-	
-	g_snprintf( path, 511, "%s%s%s", global.conf->configdir, irc->nick, ".accounts~" );
-	fp = fopen( path, "w" );
-	if( !fp ) return STORAGE_OTHER_ERROR;
-	if( fprintf( fp, "%s", hash ) != strlen( hash ) )
-	{
-		irc_usermsg( irc, "fprintf() wrote too little. Disk full?" );
-		fclose( fp );
-		return STORAGE_OTHER_ERROR;
-	}
-	g_free( hash );
-
-	for( a = irc->accounts; a; a = a->next )
-	{
-		if( a->protocol == PROTO_OSCAR || a->protocol == PROTO_ICQ || a->protocol == PROTO_TOC )
-			g_snprintf( s, sizeof( s ), "account add oscar \"%s\" \"%s\" %s", a->user, a->pass, a->server );
-		else
-			g_snprintf( s, sizeof( s ), "account add %s \"%s\" \"%s\" \"%s\"",
-			            proto_name[a->protocol], a->user, a->pass, a->server ? a->server : "" );
-		
-		line = obfucrypt( s, irc->password );
-		if( *line )
-		{
-			if( fprintf( fp, "%s\n", line ) != strlen( line ) + 1 )
-			{
-				irc_usermsg( irc, "fprintf() wrote too little. Disk full?" );
-				fclose( fp );
-				return STORAGE_OTHER_ERROR;
-			}
-		}
-		g_free( line );
-	}
-	
-	for( set = irc->set; set; set = set->next )
-	{
-		if( set->value && set->def )
-		{
-			g_snprintf( s, sizeof( s ), "set %s \"%s\"", set->key, set->value );
-			line = obfucrypt( s, irc->password );
-			if( *line )
-			{
-				if( fprintf( fp, "%s\n", line ) != strlen( line ) + 1 )
-				{
-					irc_usermsg( irc, "fprintf() wrote too little. Disk full?" );
-					fclose( fp );
-					return STORAGE_OTHER_ERROR;
-				}
-			}
-			g_free( line );
-		}
-	}
-	
-	if( strcmp( irc->mynick, ROOT_NICK ) != 0 )
-	{
-		g_snprintf( s, sizeof( s ), "rename %s %s", ROOT_NICK, irc->mynick );
-		line = obfucrypt( s, irc->password );
-		if( *line )
-		{
-			if( fprintf( fp, "%s\n", line ) != strlen( line ) + 1 )
-			{
-				irc_usermsg( irc, "fprintf() wrote too little. Disk full?" );
-				fclose( fp );
-				return STORAGE_OTHER_ERROR;
-			}
-		}
-		g_free( line );
-	}
-	if( fclose( fp ) != 0 )
-	{
-		irc_usermsg( irc, "fclose() reported an error. Disk full?" );
-		return STORAGE_OTHER_ERROR;
-	}
-	
- 	g_snprintf( new_path, 512, "%s%s%s", global.conf->configdir, irc->nick, ".accounts" );
- 	if( unlink( new_path ) != 0 )
-	{
-		if( errno != ENOENT )
-		{
-			irc_usermsg( irc, "Error while removing old .accounts file" );
-			return STORAGE_OTHER_ERROR;
-		}
-	}
-	if( rename( path, new_path ) != 0 )
-	{
-		irc_usermsg( irc, "Error while renaming new .accounts file" );
-		return STORAGE_OTHER_ERROR;
-	}
-	
-	umask( ou );
-	
-	return STORAGE_OK;
-}
-
-static storage_status_t text_check_pass( const char *nick, const char *password )
-{
-	char s[512];
-	FILE *fp;
-	
-	g_snprintf( s, 511, "%s%s%s", global.conf->configdir, nick, ".accounts" );
-	fp = fopen( s, "r" );
-	if (!fp)
-		return STORAGE_NO_SUCH_USER;
-
-	fscanf( fp, "%32[^\n]s", s );
-	fclose( fp );
-
-	if (checkpass( password, s) == -1)
-		return STORAGE_INVALID_PASSWORD;
-
-	return STORAGE_OK;
-}
-
-static storage_status_t text_remove( const char *nick, const char *password )
-{
-	char s[512];
-	storage_status_t status;
-
-	status = text_check_pass( nick, password );
-	if (status != STORAGE_OK)
-		return status;
-
-	g_snprintf( s, 511, "%s%s%s", global.conf->configdir, nick, ".accounts" );
-	if (unlink( s ) == -1)
-		return STORAGE_OTHER_ERROR;
-	
-	g_snprintf( s, 511, "%s%s%s", global.conf->configdir, nick, ".nicks" );
-	if (unlink( s ) == -1)
-		return STORAGE_OTHER_ERROR;
-
-	return STORAGE_OK;
-}
-
-storage_t storage_text = {
-	.name = "text",
-	.init = text_init,
-	.check_pass = text_check_pass,
-	.remove = text_remove,
-	.load = text_load,
-	.save = text_save
-};
Index: unix.c
===================================================================
--- unix.c	(revision 22bf64eab8a79352317ee190cddfeef3011aa8dc)
+++ unix.c	(revision e7f46c56ffa29c6f8f4917c5f367a61706758e2a)
@@ -52,10 +52,9 @@
 	
 	global.helpfile = g_strdup( HELP_FILE );
-
+	
 	global.conf = conf_load( argc, argv );
 	if( global.conf == NULL )
 		return( 1 );
-
-
+	
 	if( global.conf->runmode == RUNMODE_INETD )
 	{
@@ -71,12 +70,4 @@
 	if( i != 0 )
 		return( i );
-
-	global.storage = storage_init( global.conf->primary_storage, 
-								   global.conf->migrate_storage );
-	if ( global.storage == NULL) {
-		log_message( LOGLVL_ERROR, "Unable to load storage backend '%s'", global.conf->primary_storage );
-		return( 1 );
-	}
-	
  	
 	/* Catch some signals to tell the user what's happening before quitting */
@@ -96,4 +87,8 @@
 	if( !getuid() || !geteuid() )
 		log_message( LOGLVL_WARNING, "BitlBee is running with root privileges. Why?" );
+	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 );
 	if( help_init( &(global.help) ) == NULL )
 		log_message( LOGLVL_WARNING, "Error opening helpfile %s.", HELP_FILE );
