Index: nick.c
===================================================================
--- nick.c	(revision 5c9512ffa716f2bc8bbf9e2c31ee40624a0ff842)
+++ nick.c	(revision 5b52a4895e5a59ff6509f7771f4d8665737688c3)
@@ -2,5 +2,5 @@
   * BitlBee -- An IRC to other IM-networks gateway                     *
   *                                                                    *
-  * Copyright 2002-2004 Wilmer van der Gaast and others                *
+  * Copyright 2002-2006 Wilmer van der Gaast and others                *
   \********************************************************************/
 
@@ -27,48 +27,46 @@
 #include "bitlbee.h"
 
-void nick_set( irc_t *irc, const char *handle, struct prpl *proto, const char *nick )
-{
-	nick_t *m = NULL, *n = irc->nicks;
-	
-	while( n )
-	{
-		if( ( g_strcasecmp( n->handle, handle ) == 0 ) && n->proto == proto )
-		{
-			g_free( n->nick );
-			n->nick = nick_dup( nick );
-			nick_strip( n->nick );
-			
-			return;
-		}
-		n = ( m = n )->next;	// :-P
-	}
-	
-	if( m )
-		n = m->next = g_new0( nick_t, 1 );
+/* Store handles in lower case and strip spaces, because AIM is braindead. */
+static char *clean_handle( const char *orig )
+{
+	char *new = g_malloc( strlen( orig ) + 1 );
+	int i = 0;
+	
+	do {
+		if (*orig != ' ')
+			new[i++] = tolower( *orig );
+	}
+	while (*(orig++));
+	
+	return new;
+}
+
+void nick_set( account_t *acc, const char *handle, const char *nick )
+{
+	char *store_handle, *store_nick = g_malloc( MAX_NICK_LENGTH + 1 );
+	
+	store_handle = clean_handle( handle );
+	strncpy( store_nick, nick, MAX_NICK_LENGTH );
+	nick_strip( store_nick );
+	
+	g_hash_table_replace( acc->nicks, store_handle, store_nick );
+}
+
+char *nick_get( account_t *acc, const char *handle, const char *realname )
+{
+	static char nick[MAX_NICK_LENGTH+1];
+	char *store_handle, *found_nick;
+	int inf_protection = 256;
+	
+	memset( nick, 0, MAX_NICK_LENGTH + 1 );
+	
+	store_handle = clean_handle( handle );
+	/* Find out if we stored a nick for this person already. If not, try
+	   to generate a sane nick automatically. */
+	if( ( found_nick = g_hash_table_lookup( acc->nicks, store_handle ) ) )
+	{
+		strncpy( nick, found_nick, MAX_NICK_LENGTH );
+	}
 	else
-		n = irc->nicks = g_new0( nick_t, 1 );
-	
-	n->handle = g_strdup( handle );
-	n->proto = proto;
-	n->nick = nick_dup( nick );
-	
-	nick_strip( n->nick );
-}
-
-char *nick_get( irc_t *irc, const char *handle, struct prpl *proto, const char *realname )
-{
-	static char nick[MAX_NICK_LENGTH+1];
-	nick_t *n = irc->nicks;
-	int inf_protection = 256;
-	
-	memset( nick, 0, MAX_NICK_LENGTH + 1 );
-	
-	while( n && !*nick )
-		if( ( n->proto == proto ) && ( g_strcasecmp( n->handle, handle ) == 0 ) )
-			strcpy( nick, n->nick );
-		else
-			n = n->next;
-	
-	if( !n )
 	{
 		char *s;
@@ -86,9 +84,12 @@
 		
 		nick_strip( nick );
-		if( set_getint( &irc->set, "lcnicks" ) )
+		if( set_getbool( &acc->irc->set, "lcnicks" ) )
 			nick_lc( nick );
 	}
-	
-	while( !nick_ok( nick ) || user_find( irc, nick ) )
+	g_free( store_handle );
+	
+	/* Now, find out if the nick is already in use at the moment, and make
+	   subtle changes to make it unique. */
+	while( !nick_ok( nick ) || user_find( acc->irc, nick ) )
 	{
 		if( strlen( nick ) < ( MAX_NICK_LENGTH - 1 ) )
@@ -106,17 +107,17 @@
 			int i;
 			
-			irc_usermsg( irc, "WARNING: Almost had an infinite loop in nick_get()! "
-			                  "This used to be a fatal BitlBee bug, but we tried to fix it. "
-			                  "This message should *never* appear anymore. "
-			                  "If it does, please *do* send us a bug report! "
-			                  "Please send all the following lines in your report:" );
-			
-			irc_usermsg( irc, "Trying to get a sane nick for handle %s", handle );
+			irc_usermsg( acc->irc, "WARNING: Almost had an infinite loop in nick_get()! "
+			                       "This used to be a fatal BitlBee bug, but we tried to fix it. "
+			                       "This message should *never* appear anymore. "
+			                       "If it does, please *do* send us a bug report! "
+			                       "Please send all the following lines in your report:" );
+			
+			irc_usermsg( acc->irc, "Trying to get a sane nick for handle %s", handle );
 			for( i = 0; i < MAX_NICK_LENGTH; i ++ )
-				irc_usermsg( irc, "Char %d: %c/%d", i, nick[i], nick[i] );
-			
-			irc_usermsg( irc, "FAILED. Returning an insane nick now. Things might break. "
-			                  "Good luck, and please don't forget to paste the lines up here "
-			                  "in #bitlbee on OFTC or in a mail to wilmer@gaast.net" );
+				irc_usermsg( acc->irc, "Char %d: %c/%d", i, nick[i], nick[i] );
+			
+			irc_usermsg( acc->irc, "FAILED. Returning an insane nick now. Things might break. "
+			                       "Good luck, and please don't forget to paste the lines up here "
+			                       "in #bitlbee on OFTC or in a mail to wilmer@gaast.net" );
 			
 			g_snprintf( nick, MAX_NICK_LENGTH + 1, "xx%x", rand() );
@@ -126,28 +127,10 @@
 	}
 	
-	return( nick );
-}
-
-void nick_del( irc_t *irc, const char *nick )
-{
-	nick_t *l = NULL, *n = irc->nicks;
-	
-	while( n )
-	{
-		if( g_strcasecmp( n->nick, nick ) == 0 )
-		{
-			if( l )
-				l->next = n->next;
-			else
-				irc->nicks = n->next;
-			
-			g_free( n->handle );
-			g_free( n->nick );
-			g_free( n );
-			
-			break;
-		}
-		n = (l=n)->next;
-	}
+	return nick;
+}
+
+void nick_del( account_t *acc, const char *handle )
+{
+	g_hash_table_remove( acc->nicks, handle );
 }
 
