Index: .bzrignore
===================================================================
--- .bzrignore	(revision 83586911a0aa768ed196051950ebd8ffce37d467)
+++ .bzrignore	(revision f5c0d8e4dd3ce01945a6334a5d87c89a9f43b16b)
@@ -20,2 +20,3 @@
 bitlbee.info
 bitlbee.exe
+.depend
Index: Makefile
===================================================================
--- Makefile	(revision 83586911a0aa768ed196051950ebd8ffce37d467)
+++ Makefile	(revision f5c0d8e4dd3ce01945a6334a5d87c89a9f43b16b)
@@ -52,6 +52,9 @@
 
 distclean: clean $(subdirs)
+	rm -rf .depend
 	rm -f Makefile.settings config.h bitlbee.pc
 	find . -name 'DEADJOE' -o -name '*.orig' -o -name '*.rej' -o -name '*~' -exec rm -f {} \;
+	@# May still be present in dirs of disabled protocols.
+	find . -name .depend | xargs -r rmdir
 	$(MAKE) -C tests distclean
 
@@ -105,5 +108,5 @@
 	x=$$(basename $$(pwd)); \
 	cd ..; \
-	tar czf $$x.tar.gz --exclude=debian --exclude=.bzr* $$x
+	tar czf $$x.tar.gz --exclude=debian --exclude=.bzr* --exclude=.depend $$x
 
 $(subdirs):
@@ -131,2 +134,4 @@
 helloworld:
 	@echo Hello World
+
+-include .depend/*.d
Index: configure
===================================================================
--- configure	(revision 83586911a0aa768ed196051950ebd8ffce37d467)
+++ configure	(revision f5c0d8e4dd3ce01945a6334a5d87c89a9f43b16b)
@@ -595,4 +595,12 @@
 fi
 
+case "$CC" in
+*gcc* )
+	echo CFLAGS+=-MD -MF .depend/\$@.d >> Makefile.settings
+	for i in . lib protocols protocols/*/; do
+		mkdir -p $i/.depend
+	done
+esac
+
 if [ "$msn" = 0 ]; then
 	echo '#undef WITH_MSN' >> config.h
Index: doc/user-guide/commands.xml
===================================================================
--- doc/user-guide/commands.xml	(revision 83586911a0aa768ed196051950ebd8ffce37d467)
+++ doc/user-guide/commands.xml	(revision f5c0d8e4dd3ce01945a6334a5d87c89a9f43b16b)
@@ -73,5 +73,5 @@
 					
 					<para>
-						By default all your Twitter contacts will come from a contact called twitter_(yourusername). You can change this behaviour using the <emphasis>mode</emphasis> setting (see <emphasis>help set mode</emphasis>).
+						By default all your Twitter contacts will appear in a new channel called #twitter_yourusername. You can change this behaviour using the <emphasis>mode</emphasis> setting (see <emphasis>help set mode</emphasis>).
 					</para>
 					
@@ -970,17 +970,21 @@
 	<bitlbee-setting name="mode" type="string" scope="account">
 		<possible-values>one, many, chat</possible-values>
-		<default>one</default>
-
-		<description>
-			<para>
-				By default, everything from the Twitter module will come from one nick, twitter_(yourusername). If you prefer to have individual nicks for everyone, you can set this setting to "many" instead.
-			</para>
-			
-			<para>
-				If you prefer to have all your Twitter things in a separate channel, you can set this setting to "chat".
-			</para>
-			
-			<para>
-				In the last two modes, you can send direct messages by /msg'ing your contacts directly. Note, however, that incoming DMs are not fetched yet.
+		<default>chat</default>
+
+		<description>
+			<para>
+				By default, BitlBee will create a separate channel (called #twitter_yourusername) for all your Twitter contacts/messages.
+			</para>
+
+			<para>
+				If you don't want an extra channel, you can set this setting to "one" (everything will come from one nick, twitter_yourusername), or to "many" (individual nicks for everyone).
+			</para>
+			
+			<para>
+				With modes "chat" and "many", you can send direct messages by /msg'ing your contacts directly. Note, however, that incoming DMs are not fetched yet.
+			</para>
+			
+			<para>
+				With modes "many" and "one", you can post tweets by /msg'ing the twitter_yourusername contact. In mode "chat", messages posted in the Twitter channel will also be posted as tweets.
 			</para>
 		</description>
@@ -1637,15 +1641,15 @@
 	</bitlbee-command>
 	
-	<bitlbee-command name="transfers">
+	<bitlbee-command name="transfer">
 		<short-description>Monitor, cancel, or reject file transfers</short-description>
-		<syntax>transfers [&lt;cancel&gt; id | &lt;reject&gt;]</syntax>
+		<syntax>transfer [&lt;cancel&gt; id | &lt;reject&gt;]</syntax>
 		
 		<description>
 			<para>
-				Without parameters the currently pending file transfers and their status will be listed. Available actions are <emphasis>cancel</emphasis> and <emphasis>reject</emphasis>. See <emphasis>help transfers &lt;action&gt;</emphasis> for more information.
+				Without parameters the currently pending file transfers and their status will be listed. Available actions are <emphasis>cancel</emphasis> and <emphasis>reject</emphasis>. See <emphasis>help transfer &lt;action&gt;</emphasis> for more information.
 			</para>
 
 			<ircexample>
-				<ircline nick="ulim">transfers</ircline>
+				<ircline nick="ulim">transfer</ircline>
 			</ircexample>
 		</description>
@@ -1653,5 +1657,5 @@
 		<bitlbee-command name="cancel">
 			<short-description>Cancels the file transfer with the given id</short-description>
-			<syntax>transfers &lt;cancel&gt; id</syntax>
+			<syntax>transfer &lt;cancel&gt; id</syntax>
 
 			<description>
@@ -1660,5 +1664,5 @@
 
 			<ircexample>
-				<ircline nick="ulim">transfers cancel 1</ircline>
+				<ircline nick="ulim">transfer cancel 1</ircline>
 				<ircline nick="root">Canceling file transfer for test</ircline>
 			</ircexample>
@@ -1667,5 +1671,5 @@
 		<bitlbee-command name="reject">
 			<short-description>Rejects all incoming transfers</short-description>
-			<syntax>transfers &lt;reject&gt;</syntax>
+			<syntax>transfer &lt;reject&gt;</syntax>
 
 			<description>
@@ -1674,5 +1678,5 @@
 
 			<ircexample>
-				<ircline nick="ulim">transfers reject</ircline>
+				<ircline nick="ulim">transfer reject</ircline>
 			</ircexample>
 		</bitlbee-command>
Index: irc.h
===================================================================
--- irc.h	(revision 83586911a0aa768ed196051950ebd8ffce37d467)
+++ irc.h	(revision f5c0d8e4dd3ce01945a6334a5d87c89a9f43b16b)
@@ -289,4 +289,5 @@
 void irc_send_channel_user_mode_diff( irc_channel_t *ic, irc_user_t *iu,
                                       irc_channel_user_flags_t old, irc_channel_user_flags_t new );
+void irc_send_invite( irc_user_t *iu, irc_channel_t *ic );
 
 /* irc_user.c */
Index: irc_commands.c
===================================================================
--- irc_commands.c	(revision 83586911a0aa768ed196051950ebd8ffce37d467)
+++ irc_commands.c	(revision f5c0d8e4dd3ce01945a6334a5d87c89a9f43b16b)
@@ -302,4 +302,5 @@
 	char *channel = cmd[1];
 	irc_channel_t *ic;
+	irc_user_t *iu;
 	
 	if( !channel || *channel == '0' || *channel == '*' || !*channel )
@@ -307,4 +308,11 @@
 	else if( ( ic = irc_channel_by_name( irc, channel ) ) )
 		irc_send_who( irc, ic->users, channel );
+	else if( ( iu = irc_user_by_name( irc, channel ) ) )
+	{
+		/* Tiny hack! */
+		GSList *l = g_slist_append( NULL, iu );
+		irc_send_who( irc, l, channel );
+		g_slist_free( l );
+	}
 	else
 		irc_send_num( irc, 403, "%s :No such channel", channel );
Index: irc_im.c
===================================================================
--- irc_im.c	(revision 83586911a0aa768ed196051950ebd8ffce37d467)
+++ irc_im.c	(revision f5c0d8e4dd3ce01945a6334a5d87c89a9f43b16b)
@@ -252,5 +252,4 @@
 {
 	irc_user_t *iu = (irc_user_t *) bu->ui_data;
-	irc_t *irc = (irc_t *) bee->ui_data;
 	char *s;
 	
@@ -266,6 +265,9 @@
 	if( ( bu->ic->flags & OPT_LOGGED_IN ) && set_getbool( &bee->set, "display_namechanges" ) )
 	{
+		/* People don't like this /NOTICE. Meh, let's go back to the old one.
 		char *msg = g_strdup_printf( "<< \002BitlBee\002 - Changed name to `%s' >>", iu->fullname );
 		irc_send_msg( iu, "NOTICE", irc->user->nick, msg, NULL );
+		*/
+		imcb_log( bu->ic, "User `%s' changed name to `%s'", iu->nick, iu->fullname );
 	}
 	
@@ -613,4 +615,61 @@
 }
 
+static gboolean bee_irc_chat_invite( bee_t *bee, bee_user_t *bu, const char *name, const char *msg )
+{
+	char *channel, *s;
+	irc_t *irc = bee->ui_data;
+	irc_user_t *iu = bu->ui_data;
+	irc_channel_t *chan;
+	
+	if( strchr( CTYPES, name[0] ) )
+		channel = g_strdup( name );
+	else
+		channel = g_strdup_printf( "#%s", name );
+	
+	if( ( s = strchr( channel, '@' ) ) )
+		*s = '\0';
+	
+	if( strlen( channel ) > MAX_NICK_LENGTH )
+	{
+		/* If the channel name is very long (like those insane GTalk
+		   UUID names), try if we can use the inviter's nick. */
+		s = g_strdup_printf( "#%s", iu->nick );
+		if( irc_channel_by_name( irc, s ) == NULL )
+		{
+			g_free( channel );
+			channel = s;
+		}
+	}
+	
+	if( ( chan = irc_channel_new( irc, channel ) ) &&
+	    set_setstr( &chan->set, "type", "chat" ) &&
+	    set_setstr( &chan->set, "chat_type", "room" ) &&
+	    set_setstr( &chan->set, "account", bu->ic->acc->tag ) &&
+	    set_setstr( &chan->set, "room", (char*) name ) )
+	{
+		/* I'm assuming that if the user didn't "chat add" the room
+		   himself but got invited, it's temporary, so make this a
+		   temporary mapping that is removed as soon as we /PART. */
+		chan->flags |= IRC_CHANNEL_TEMP;
+	}
+	else
+	{
+		irc_channel_free( chan );
+		chan = NULL;
+	}
+	g_free( channel );
+	
+	irc_send_msg_f( iu, "PRIVMSG", irc->user->nick, "<< \002BitlBee\002 - Invitation to chatroom %s >>", name );
+	if( msg )
+		irc_send_msg( iu, "PRIVMSG", irc->user->nick, msg, NULL );
+	if( chan )
+	{
+		irc_send_msg_f( iu, "PRIVMSG", irc->user->nick, "To join the room, just /join %s", chan->name );
+		irc_send_invite( iu, chan );
+	}
+	
+	return TRUE;
+}
+
 /* IRC->IM */
 static gboolean bee_irc_channel_chat_privmsg_cb( gpointer data, gint fd, b_input_condition cond );
@@ -909,4 +968,5 @@
 	bee_irc_chat_topic,
 	bee_irc_chat_name_hint,
+	bee_irc_chat_invite,
 	
 	bee_irc_ft_in_start,
Index: irc_send.c
===================================================================
--- irc_send.c	(revision 83586911a0aa768ed196051950ebd8ffce37d467)
+++ irc_send.c	(revision f5c0d8e4dd3ce01945a6334a5d87c89a9f43b16b)
@@ -264,5 +264,5 @@
 void irc_send_who( irc_t *irc, GSList *l, const char *channel )
 {
-	gboolean is_channel = strcmp( channel, "**" ) != 0;
+	gboolean is_channel = strchr( CTYPES, channel[0] ) != NULL;
 	
 	while( l )
@@ -273,5 +273,5 @@
 		/* TODO(wilmer): Restore away/channel information here */
 		irc_send_num( irc, 352, "%s %s %s %s %s %c :0 %s",
-		              channel ? : "*", iu->user, iu->host, irc->root->host,
+		              is_channel ? channel : "*", iu->user, iu->host, irc->root->host,
 		              iu->nick, iu->flags & IRC_USER_AWAY ? 'G' : 'H',
 		              iu->fullname );
@@ -398,2 +398,10 @@
 		irc_write( ic->irc, ":%s MODE %s %s", from, ic->name, changes );
 }
+
+void irc_send_invite( irc_user_t *iu, irc_channel_t *ic )
+{
+	irc_t *irc = iu->irc;
+	
+	irc_write( iu->irc, ":%s!%s@%s INVITE %s :%s",
+	           iu->nick, iu->user, iu->host, irc->user->nick, ic->name );
+}
Index: lib/Makefile
===================================================================
--- lib/Makefile	(revision 83586911a0aa768ed196051950ebd8ffce37d467)
+++ lib/Makefile	(revision f5c0d8e4dd3ce01945a6334a5d87c89a9f43b16b)
@@ -30,4 +30,5 @@
 
 distclean: clean $(subdirs)
+	rm -rf .depend
 
 ### MAIN PROGRAM
@@ -42,2 +43,4 @@
 	@echo '*' Compiling $<
 	@$(CC) -c $(CFLAGS) $< -o $@
+
+-include .depend/*.d
Index: protocols/Makefile
===================================================================
--- protocols/Makefile	(revision 83586911a0aa768ed196051950ebd8ffce37d467)
+++ protocols/Makefile	(revision f5c0d8e4dd3ce01945a6334a5d87c89a9f43b16b)
@@ -40,4 +40,5 @@
 
 distclean: clean $(subdirs)
+	rm -rf .depend
 
 $(subdirs):
@@ -55,2 +56,4 @@
 	@echo '*' Compiling $<
 	@$(CC) -c $(CFLAGS) $< -o $@
+
+-include .depend/*.d
Index: protocols/bee.h
===================================================================
--- protocols/bee.h	(revision 83586911a0aa768ed196051950ebd8ffce37d467)
+++ protocols/bee.h	(revision f5c0d8e4dd3ce01945a6334a5d87c89a9f43b16b)
@@ -123,4 +123,5 @@
 	gboolean (*chat_topic)( bee_t *bee, struct groupchat *c, const char *new, bee_user_t *bu );
 	gboolean (*chat_name_hint)( bee_t *bee, struct groupchat *c, const char *name );
+	gboolean (*chat_invite)( bee_t *bee, bee_user_t *bu, const char *name, const char *msg );
 	
 	struct file_transfer* (*ft_in_start)( bee_t *bee, bee_user_t *bu, const char *file_name, size_t file_size );
@@ -175,4 +176,5 @@
 G_MODULE_EXPORT int bee_chat_msg( bee_t *bee, struct groupchat *c, const char *msg, int flags );
 G_MODULE_EXPORT struct groupchat *bee_chat_by_title( bee_t *bee, struct im_connection *ic, const char *title );
+G_MODULE_EXPORT void imcb_chat_invite( struct im_connection *ic, const char *name, const char *who, const char *msg );
 
 #endif /* __BEE_H__ */
Index: protocols/bee_chat.c
===================================================================
--- protocols/bee_chat.c	(revision 83586911a0aa768ed196051950ebd8ffce37d467)
+++ protocols/bee_chat.c	(revision f5c0d8e4dd3ce01945a6334a5d87c89a9f43b16b)
@@ -233,2 +233,10 @@
 	return NULL;
 }
+
+void imcb_chat_invite( struct im_connection *ic, const char *name, const char *who, const char *msg )
+{
+	bee_user_t *bu = bee_user_by_handle( ic->bee, ic, who );
+	
+	if( bu && ic->bee->ui->chat_invite )
+		ic->bee->ui->chat_invite( ic->bee, bu, name, msg );
+}
Index: protocols/jabber/Makefile
===================================================================
--- protocols/jabber/Makefile	(revision 83586911a0aa768ed196051950ebd8ffce37d467)
+++ protocols/jabber/Makefile	(revision f5c0d8e4dd3ce01945a6334a5d87c89a9f43b16b)
@@ -30,4 +30,5 @@
 
 distclean: clean
+	rm -rf .depend
 
 ### MAIN PROGRAM
@@ -42,2 +43,4 @@
 	@echo '*' Linking jabber_mod.o
 	@$(LD) $(LFLAGS) $(objects) -o jabber_mod.o
+
+-include .depend/*.d
Index: protocols/jabber/jabber.h
===================================================================
--- protocols/jabber/jabber.h	(revision 83586911a0aa768ed196051950ebd8ffce37d467)
+++ protocols/jabber/jabber.h	(revision f5c0d8e4dd3ce01945a6334a5d87c89a9f43b16b)
@@ -59,4 +59,6 @@
 	JBFLAG_IS_ANONYMOUS = 8,        /* For anonymous chatrooms, when we don't have
 	                                   have a real JID. */
+	JBFLAG_HIDE_SUBJECT = 16,       /* Hide the subject field since we probably
+	                                   showed it already. */
 } jabber_buddy_flags_t;
 
Index: protocols/jabber/message.c
===================================================================
--- protocols/jabber/message.c	(revision 83586911a0aa768ed196051950ebd8ffce37d467)
+++ protocols/jabber/message.c	(revision f5c0d8e4dd3ce01945a6334a5d87c89a9f43b16b)
@@ -31,5 +31,5 @@
 	struct xt_node *body = xt_find_node( node->children, "body" ), *c;
 	struct jabber_buddy *bud = NULL;
-	char *s;
+	char *s, *room = NULL, *reason = NULL;
 	
 	if( !from )
@@ -52,17 +52,17 @@
 		for( c = node->children; ( c = xt_find_node( c, "x" ) ); c = c->next )
 		{
-			char *ns = xt_find_attr( c, "xmlns" ), *room;
-			struct xt_node *inv, *reason;
+			char *ns = xt_find_attr( c, "xmlns" );
+			struct xt_node *inv;
 			
 			if( ns && strcmp( ns, XMLNS_MUC_USER ) == 0 &&
 			    ( inv = xt_find_node( c->children, "invite" ) ) )
 			{
+				/* This is an invitation. Set some vars which
+				   will be passed to imcb_chat_invite() below. */
 				room = from;
 				if( ( from = xt_find_attr( inv, "from" ) ) == NULL )
 					from = room;
-
-				g_string_append_printf( fullmsg, "<< \002BitlBee\002 - Invitation to chatroom %s >>\n", room );
-				if( ( reason = xt_find_node( inv->children, "reason" ) ) && reason->text_len > 0 )
-					g_string_append( fullmsg, reason->text );
+				if( ( inv = xt_find_node( inv->children, "reason" ) ) && inv->text_len > 0 )
+					reason = inv->text;
 			}
 		}
@@ -93,7 +93,18 @@
 			}
 		}
-		else if( ( c = xt_find_node( node->children, "subject" ) ) && c->text_len > 0 )
+		else if( ( c = xt_find_node( node->children, "subject" ) ) && c->text_len > 0 &&
+		         ( !bud || !( bud->flags & JBFLAG_HIDE_SUBJECT ) ) )
 		{
 			g_string_append_printf( fullmsg, "<< \002BitlBee\002 - Message with subject: %s >>\n", c->text );
+			if( bud )
+				bud->flags |= JBFLAG_HIDE_SUBJECT;
+		}
+		else if( bud && !c )
+		{
+			/* Yeah, possibly we're hiding changes to this field now. But nobody uses
+			   this for anything useful anyway, except GMail when people reply to an
+			   e-mail via chat, repeating the same subject all the time. I don't want
+			   to have to remember full subject strings for everyone. */
+			bud->flags &= ~JBFLAG_HIDE_SUBJECT;
 		}
 		
@@ -104,4 +115,6 @@
 			imcb_buddy_msg( ic, from, fullmsg->str,
 			                0, jabber_get_timestamp( node ) );
+		if( room )
+			imcb_chat_invite( ic, room, from, reason );
 		
 		g_string_free( fullmsg, TRUE );
Index: protocols/jabber/si.c
===================================================================
--- protocols/jabber/si.c	(revision 83586911a0aa768ed196051950ebd8ffce37d467)
+++ protocols/jabber/si.c	(revision f5c0d8e4dd3ce01945a6334a5d87c89a9f43b16b)
@@ -262,4 +262,8 @@
 				break;
 			}
+			else
+			{
+				c = c->next;
+			}
 
 		if ( !requestok )
Index: protocols/msn/Makefile
===================================================================
--- protocols/msn/Makefile	(revision 83586911a0aa768ed196051950ebd8ffce37d467)
+++ protocols/msn/Makefile	(revision f5c0d8e4dd3ce01945a6334a5d87c89a9f43b16b)
@@ -30,4 +30,5 @@
 
 distclean: clean
+	rm -rf .depend
 
 ### MAIN PROGRAM
@@ -42,4 +43,4 @@
 	@echo '*' Linking msn_mod.o
 	@$(LD) $(LFLAGS) $(objects) -o msn_mod.o
-	
 
+-include .depend/*.d
Index: protocols/oscar/Makefile
===================================================================
--- protocols/oscar/Makefile	(revision 83586911a0aa768ed196051950ebd8ffce37d467)
+++ protocols/oscar/Makefile	(revision f5c0d8e4dd3ce01945a6334a5d87c89a9f43b16b)
@@ -31,4 +31,5 @@
 
 distclean: clean
+	rm -rf .depend
 
 ### MAIN PROGRAM
@@ -43,2 +44,4 @@
 	@echo '*' Linking oscar_mod.o
 	@$(LD) $(LFLAGS) $(objects) -o oscar_mod.o
+
+-include .depend/*.d
Index: protocols/oscar/oscar.c
===================================================================
--- protocols/oscar/oscar.c	(revision 83586911a0aa768ed196051950ebd8ffce37d467)
+++ protocols/oscar/oscar.c	(revision f5c0d8e4dd3ce01945a6334a5d87c89a9f43b16b)
@@ -517,4 +517,12 @@
 			/* Incorrect nick/password */
 			imcb_error(ic, _("Incorrect nickname or password."));
+			{
+				int max = od->icq ? 8 : 16;
+				if (strlen(ic->acc->pass) > max)
+					imcb_log(ic, "Note that the maximum password "
+					         "length supported by this protocol is "
+					         "%d characters, try logging in using "
+					         "a shorter password.", max);
+			}
 //			plugin_event(event_error, (void *)980, 0, 0, 0);
 			break;
Index: protocols/purple/Makefile
===================================================================
--- protocols/purple/Makefile	(revision 83586911a0aa768ed196051950ebd8ffce37d467)
+++ protocols/purple/Makefile	(revision f5c0d8e4dd3ce01945a6334a5d87c89a9f43b16b)
@@ -31,4 +31,5 @@
 
 distclean: clean
+	rm -rf .depend
 
 ### MAIN PROGRAM
@@ -43,2 +44,4 @@
 	@echo '*' Linking purple_mod.o
 	$(LD) $(LFLAGS) $(objects) -o purple_mod.o
+
+-include .depend/*.d
Index: protocols/twitter/Makefile
===================================================================
--- protocols/twitter/Makefile	(revision 83586911a0aa768ed196051950ebd8ffce37d467)
+++ protocols/twitter/Makefile	(revision f5c0d8e4dd3ce01945a6334a5d87c89a9f43b16b)
@@ -30,4 +30,5 @@
 
 distclean: clean
+	rm -rf .depend
 
 ### MAIN PROGRAM
@@ -43,3 +44,3 @@
 	@$(LD) $(LFLAGS) $(objects) -o twitter_mod.o
 	
-
+-include .depend/*.d
Index: protocols/twitter/twitter.c
===================================================================
--- protocols/twitter/twitter.c	(revision 83586911a0aa768ed196051950ebd8ffce37d467)
+++ protocols/twitter/twitter.c	(revision f5c0d8e4dd3ce01945a6334a5d87c89a9f43b16b)
@@ -195,5 +195,5 @@
 	s = set_add( &acc->set, "message_length", "140", set_eval_int, acc );
 	
-	s = set_add( &acc->set, "mode", "one", set_eval_mode, acc );
+	s = set_add( &acc->set, "mode", "chat", set_eval_mode, acc );
 	s->flags |= ACC_SET_OFFLINE_ONLY;
 	
Index: protocols/yahoo/Makefile
===================================================================
--- protocols/yahoo/Makefile	(revision 83586911a0aa768ed196051950ebd8ffce37d467)
+++ protocols/yahoo/Makefile	(revision f5c0d8e4dd3ce01945a6334a5d87c89a9f43b16b)
@@ -31,4 +31,5 @@
 
 distclean: clean
+	rm -rf .depend
 
 ### MAIN PROGRAM
@@ -43,2 +44,4 @@
 	@echo '*' Linking yahoo_mod.o
 	@$(LD) $(LFLAGS) $(objects) -o yahoo_mod.o
+
+-include .depend/*.d
Index: protocols/yahoo/libyahoo2.c
===================================================================
--- protocols/yahoo/libyahoo2.c	(revision 83586911a0aa768ed196051950ebd8ffce37d467)
+++ protocols/yahoo/libyahoo2.c	(revision f5c0d8e4dd3ce01945a6334a5d87c89a9f43b16b)
@@ -2169,4 +2169,16 @@
 	yd->buddies = y_list_append(yd->buddies, bud);
 
+#if 0
+	/* BitlBee: This seems to be wrong in my experience. I think:
+	   status = 0: Success
+	   status = 2: Already on list
+	   status = 3: Doesn't exist
+	   status = 42: Invalid handle (possibly banned/reserved, I get it for
+	                handles like joe or jjjjjj)
+	   Haven't seen others yet. But whenever the add is successful, there
+	   will be a separate "went online" packet when the auth. request is
+	   accepted. Couldn't find any test account that doesn't require auth.
+	   unfortunately (if there is even such a thing?) */
+	   
 	/* A non-zero status (i've seen 2) seems to mean the buddy is already 
 	 * added and is online */
@@ -2176,4 +2188,11 @@
 		YAHOO_CALLBACK(ext_yahoo_status_changed) (yd->client_id, who,
 			YAHOO_STATUS_AVAILABLE, NULL, 0, 0, 0);
+	}
+#endif
+	/* BitlBee: Need ACK of added buddy, if it was successful. */
+	if (status == 0) {
+		YList *tmp = y_list_append(NULL, bud);
+		YAHOO_CALLBACK(ext_yahoo_got_buddies) (yd->client_id, tmp);
+		y_list_free(tmp);
 	}
 }
Index: root_commands.c
===================================================================
--- root_commands.c	(revision 83586911a0aa768ed196051950ebd8ffce37d467)
+++ root_commands.c	(revision f5c0d8e4dd3ce01945a6334a5d87c89a9f43b16b)
@@ -1284,4 +1284,9 @@
 }
 
+static void cmd_nick( irc_t *irc, char **cmd )
+{
+	irc_usermsg( irc, "This command is deprecated. Try: account %s set display_name", cmd[1] );
+}
+
 /* Maybe this should be a stand-alone command as well? */
 static void bitlbee_whatsnew( irc_t *irc )
@@ -1338,4 +1343,5 @@
 	{ "identify",       1, cmd_identify,       0 },
 	{ "info",           1, cmd_info,           0 },
+	{ "nick",           1, cmd_nick,           0 },
 	{ "no",             0, cmd_yesno,          0 },
 	{ "qlist",          0, cmd_qlist,          0 },
Index: utils/README
===================================================================
--- utils/README	(revision 83586911a0aa768ed196051950ebd8ffce37d467)
+++ utils/README	(revision f5c0d8e4dd3ce01945a6334a5d87c89a9f43b16b)
@@ -18,31 +18,8 @@
 
 
-* create_nicksfile.pl (Christian Friedl <christian.friedl@chello.at>)
+* convert_purple.py
 
-This program reads your ~/.licq/ configuration data and convert it to a
-correct .nicks file. This program can be extended to read other contact
-list file formats as well.
-
-
-* centericq2bitlbee.sh (geno <geno@xenyon.com>)
-
-Converter script for CenterICQ ICQ contact lists. See the documentation
-for more information.
-
-
-* convert_gnomeicu.txt
-
-Not a program, but this one contains a regex which should correctly
-convert GnomeICU configuration files into the BitlBee format.
-
-
-* Dynamic MOTD for BitlBee (Geert Hauwaerts <geert@hauwaerts.be>)
-
-Originally, I wanted to put this program here, but Geert put it online
-on his own server, with docs and stuff, so I guess it's better to put
-a link here. dmotd is a little script which generates a motd with some
-nice statistics, especially nice for servers with many people on it.
-
-See http://dmotd.hauwaerts.be/ for more information.
+Converts libpurple configs into something BitlBee can use, so you don't
+have to re-add all your accounts by hand.
 
 
Index: ils/centericq2bitlbee.sh
===================================================================
--- utils/centericq2bitlbee.sh	(revision 83586911a0aa768ed196051950ebd8ffce37d467)
+++ 	(revision )
@@ -1,115 +1,0 @@
-#!/bin/bash
-#
-#  Author       geno, <geno@xenyon.com>
-#  Date         2004-04-24
-#  Version      0.1c
-#
-
-show_help()
-{
-cat << _EOF_
-
-This script converts your CenterICQ contacts (AIM/ICQ) to BitlBee's contacts.
-The use of this script is on you own risk. You agree by using this script. :-)
-
-SYNTAX: `basename $0` <protoname> [<add_proto_tag>]
-
-	protoname     - Choose the protocol you want to get your contacts from
-			by using "aim" or "icq" here.
-
-	add_proto_tag - This is optional and adds a suffix to each nickname.
-			For an AIM contact it will look like this: geno|aim
-			For an ICQ contact it will be |icq , WOW! :-D
-			To enable this option use "on". 
-
-NOTE:
-	After the conversion of one protocol is done you will find a file
-	called bitlbee_[protoname] in ~/.centericq . Append the content of
-	this file to /var/lib/bitlbee/[username].nicks .
-
-	[username] is your username you use to talk to the BitlBee Server.
-	You will have to be root to edit this file!
-
-CREDITS:
-	This script was written by geno (geno@xenyon.com).
-	I hope it will help you to make the switch to BitlBee a bit easier. :-)
-
-_EOF_
-exit 0
-}
-
-case $1 in
-	"") show_help ;;
-	"icq")
-		nick_protocol="[1-9]*/"
-		protocol_const="3"
-	;;
-	
-	"aim")
-		nick_protocol="a*/"
-		protocol_const="1"
-	;;
-	
-	*) show_help ;;
-esac
-
-# can we see CenterICQ's directory ?
-if [ ! -d ~/.centericq ]; then
-	echo "The directory of CenterICQ (~/.centericq) was not found!"
-	echo "Maybe you are logged in with the wrong username."
-	exit 1
-fi
-
-# change to the center of all evil ;)
-cd ~/.centericq
-
-# get the listing of all nicks
-nick_listing=`ls -d $nick_protocol | sed 's/\ /_DuMmY_/g' | sed 's/\/_DuMmY_/\/ /g'`
-
-echo -e "\nConverting ...\n"
-
-# remove old conversion
-rm -f ~/.centericq/bitlbee_$1
-
-for nick_accountname in $nick_listing; do
-	# get rid of the slash and replace _DuMmY_ with space
-	nick_accountname=`echo "$nick_accountname" | sed 's/\/$//' | sed 's/_DuMmY_/\ /g'`
-	
-	# find centericq alias
-	nick_cicq_alias=`cat "$nick_accountname/info" | sed '46!d'`
-	
-	# if the centericq alias is the same as the account's name then
-	# it's not a real alias; search for account nickname
-	if [ "$nick_accountname" == "$nick_cicq_alias" ]; then
-		nick_accountalias=`cat "$nick_accountname/info" | sed '1!d'`
-	fi
-
-	# save the best nickname for conversion
-	if [ "x$nick_accountalias" == "x" ]; then
-		nick="$nick_cicq_alias"
-	else
-		nick="$nick_accountalias"
-	fi
-
-	# cut off the prefix 'a' of the accountname
-	if [ "$1" == "aim" ]; then
-		nick_accountname=`echo "$nick_accountname" | sed 's/^a//'`
-	fi
-
-	# replace each space with an underscore (spaces are not allowed in irc nicknames)
-	nick=`echo "$nick" | sed 's/\ /_/g'`
-
-	# if tags are wanted we will add them here
-	if [ "$2" == "on" ]; then
-		nick=`echo "$nick"\|$1`
-	fi
-
-	# print output to std
-	echo "Found '$nick_accountname' with alias '$nick'"
-	# save output to file
-	echo "$nick_accountname" $protocol_const "$nick" >> ~/.centericq/bitlbee_$1
-done
-
-echo -e "\nYou can find this list as a file in ~/.centericq/bitlbee_$1."
-echo -e "See help if you don't know what you have to do next.\n"
-
Index: ils/convert_gnomeicu.txt
===================================================================
--- utils/convert_gnomeicu.txt	(revision 83586911a0aa768ed196051950ebd8ffce37d467)
+++ 	(revision )
@@ -1,7 +1,0 @@
-15:03:38        zoo| wilmer: watch this:
-15:03:40        zoo| cat ~/.icq/contacts.xml | sed "s/<\/user>/\n/g" |
-                     sed "s/^.*<uin>//g" | sed "s/<\/nick>//" | sed "s/ /_/g" |
-                     sed "s/<\/uin><nick>/ 3 /g" | grep -v -e "^<"
-15:04:23        zoo| it does output your gnomeicu nicks to stdout
-
-Thanks to Claas Langbehn. Use this at your own risk, it's not tested by us.
Index: utils/convert_purple.py
===================================================================
--- utils/convert_purple.py	(revision f5c0d8e4dd3ce01945a6334a5d87c89a9f43b16b)
+++ utils/convert_purple.py	(revision f5c0d8e4dd3ce01945a6334a5d87c89a9f43b16b)
@@ -0,0 +1,113 @@
+#!/usr/bin/python
+#
+# Part of BitlBee. Reads a libpurple accounts.xml file and generates some
+# commands/XML that BitlBee understands. For easy migration from Pidgin/
+# Finch/whatever to BitlBee, be it a public server or your own.
+#
+# Licensed under the GPL2 like the rest of BitlBee.
+#
+# Copyright 2010 Wilmer van der Gaast <wilmer@gaast.net>
+#
+
+import getopt
+import getpass
+import os
+import subprocess
+import sys
+
+import xml.dom.minidom
+
+BITLBEE = '/usr/sbin/bitlbee'
+
+def parse_purple(f):
+	protomap = {
+		'msn-pecan': 'msn',
+		'aim': 'oscar',
+		'icq': 'oscar',
+	}
+	supported = ('msn', 'jabber', 'oscar', 'yahoo', 'twitter')
+	accs = list()
+	
+	if os.path.isdir(f):
+		f = f + '/accounts.xml'
+	xt = xml.dom.minidom.parse(f)
+	for acc in xt.getElementsByTagName('account')[1:]:
+		protocol = acc.getElementsByTagName('protocol')[0].firstChild.wholeText
+		name = acc.getElementsByTagName('name')[0].firstChild.wholeText
+		password = acc.getElementsByTagName('password')[0].firstChild.wholeText
+		if protocol.startswith('prpl-'):
+			protocol = protocol[5:]
+		if name.endswith('/'):
+			name = name[:-1]
+		if protocol in protomap:
+			protocol = protomap[protocol]
+		if protocol not in supported:
+			print 'Warning: protocol probably not supported by BitlBee: ' + protocol
+		accs.append((protocol, name, password))
+	
+	return accs
+
+def print_commands(accs):
+	print 'To copy all your Pidgin accounts to BitlBee, just copy-paste the following'
+	print 'commands into your &bitlbee channel:'
+	print
+	for acc in accs:
+		print 'account add %s %s %s' % acc
+
+def bitlbee_x(*args):
+	bb = subprocess.Popen([BITLBEE, '-x'] + list(args), stdout=subprocess.PIPE)
+	return bb.stdout.read().strip()
+
+def print_xml(accs):
+	try:
+		bitlbee_x('hash', 'blaataap')
+	except:
+		print "Can't find/use BitlBee binary. It has to be a 1.2.5 binary or higher."
+		print
+		usage()
+	
+	print 'BitlBee .xml files are encrypted using the identify password. Please type your'
+	print 'preferred identify password.'
+	user = getpass.getuser()
+	pwd = getpass.getpass()
+	
+	root = xml.dom.minidom.Element('user')
+	root.setAttribute('nick', user)
+	root.setAttribute('password', bitlbee_x('hash', pwd))
+	root.setAttribute('version', '1')
+	for acc in accs:
+		accx = xml.dom.minidom.Element('account')
+		accx.setAttribute('protocol', acc[0])
+		accx.setAttribute('handle', acc[1])
+		accx.setAttribute('password', bitlbee_x('enc', pwd, acc[2]))
+		accx.setAttribute('autoconnect', '1')
+		root.appendChild(accx)
+	
+	print
+	print 'Write the following XML data to a file called %s.xml (rename it if'
+	print 'you want to use a different nickname). It should be in the directory where'
+	print 'your BitlBee account files are stored (most likely /var/lib/bitlbee).'
+	print
+	print root.toprettyxml()
+
+def usage():
+	print 'Usage: %s [-f <purple accounts file>] [-b <bitlbee executable>] [-x]' % sys.argv[0]
+	print
+	print 'Generates "account add" commands by default. -x generates a .xml file instead.'
+	print 'The accounts file can normally be found in ~/.purple/.'
+	sys.exit(os.EX_USAGE)
+
+try:
+	flags = dict(getopt.getopt(sys.argv[1:], 'f:b:x')[0])
+except getopt.GetoptError:
+	usage()
+if '-f' not in flags:
+	usage()
+if '-b' in flags:
+	BITLBEE = flags['-b']
+
+parsed = parse_purple(flags['-f'])
+if '-x' in flags:
+	print_xml(parsed)
+else:
+	print_commands(parsed)
Index: ils/create_nicksfile.pl
===================================================================
--- utils/create_nicksfile.pl	(revision 83586911a0aa768ed196051950ebd8ffce37d467)
+++ 	(revision )
@@ -1,210 +1,0 @@
-#!/usr/bin/perl
-use strict;
-use Getopt::Long;
-
-
-my $conn                = undef;
-my %readline_funcs      = ( 'licq' => \&import_readline_licq );
-my %open_funcs          = ( 'licq' => \&import_open_licq );
-my %close_funcs         = ( 'licq' => \&import_close_licq );
-my $funcname            = undef;
-my $dirname             = undef;
-my $filename            = undef;
-my $imported            = 0;
-my $not_imported        = 0;
-my $debug               = 0;
-
-main();
-exit(0);
-
-
-sub main {
-        my ($server,$port,$nick,$pass,$func,$dir,$file,$outfile);
-        my $dirfile;
-        if (($dirfile=pop @ARGV) =~ /^\-/ || !$dirfile) {
-                tell_usage();
-                exit(0);
-        }
-        if ($dirfile =~ m|/|) {
-                $dirfile =~ m|^(.*)(/.+)$|;
-                $dir=$1;
-                $file=$2;
-        } else {
-                $dir=undef;
-                $file = $dirfile;
-        }
-        GetOptions(
-                'from=s',  => \$func,
-                'of=s',  => \$outfile,
-                'debug',  => \$debug
-        );
-        if (!import_start($func,$dir,$file,$outfile,$debug)) {
-                tell_usage();
-        }
-}
-
-sub tell_usage {
-        print "Usage: create_nicksfile.pl [--from=FROM] [--of=OUTPUTFILE] [--debug] FILENAME\n";
-        print "       FROM defines which application we import from.\n",
-        print "       Note that currently the only valid value for FROM is licq.\n";
-        print "       For further information, you might want to do perldoc create_nicksfile.pl\n";
-}
-
-sub import_start {
-        $funcname          = (shift) || 'licq';
-        $dirname        = shift;
-        $filename       = shift;
-        my $outfile        = shift || 'bitlbee.nicks';
-        $debug          = shift;
-        my ($alias,$protocol,$name,$found);
-        open(OUT,'>'.$outfile) || die "unable to open $outfile";
-        if (defined $open_funcs{$funcname}) {
-                if (&{$open_funcs{$funcname}}($dirname,$filename)) {
-                        do {
-                                ($alias,$protocol,$name,$found)=&{$readline_funcs{$funcname}}();
-                                print OUT "$alias $protocol $name\n" if $found;
-                        } while ($found);
-                } else {
-                        import_err('Unable to open '.$filename);
-                        return 0;
-                }
-        } else {
-                import_err($funcname.' is no defined import function.');
-                return 0;
-        }
-        close OUT;
-        &{$close_funcs{$funcname}}();
-        return 1;
-}
-
-sub import_err {
-        my $msg=shift;
-        print "\nError: $msg\n";
-}
-
-sub import_open_licq {
-        my ($dir,$name)=@_;
-        return open(IN,'<'.$dir.'/users.conf');
-}
-sub import_close_licq {
-        close IN;
-}
-sub import_readline_licq {
-        my ($uin,$alias);
-        my $line;
-GETLINE:
-        $line=<IN>;
-        if ($line) {
-                while ($line && $line !~ /^User\d+/) {
-                        $line=<IN>;
-                }
-                if ($line) {
-                        if ($line =~ /^User\d+\s*=\s*(\d+)(\.Licq)?$/) { # getting UIN
-                                $uin=$1;
-                                open(ALIAS,'<'.$dirname.'/users/'.$uin.'.Licq') ||
-                                open(ALIAS,'<'.$dirname.'/users/'.$uin.'.uin') || do {
-                                        warn "unable to open userfile for $uin";
-                                        return (undef,undef,0);
-                                };
-                                while (<ALIAS>) {
-                                        if (/^Alias\s*=\s*(.*)$/) {
-                                                $alias=$1;
-                                                $alias =~ s/\s+/_/g;
-                                                last;
-                                        }
-                                }
-                                close ALIAS;
-                                $imported++;
-                                return ($uin,3,$alias,1);
-                        } else {
-                                warn('Unknown line format: '.$line);
-                                $not_imported++;
-                                goto GETLINE; #### grrrr, sometimes there are negative uins in licq files...
-                        }
-                } else {
-                        return (undef,undef,0);
-                }
-        } else {
-                return undef;
-        }
-}
-
-__END__
-
-=head1 NAME
-
-create_nicksfile.pl - Create a valid bitlbee .nicks file
-
-=head1 SYNOPSIS
-
-create_nicksfile.pl [--from=FROM] [--of=OUTPUTFILE] [--debug] FILENAME
-
-        FROM defines which application we import from.
-        Note that currently the only valid value for FROM 
-        is licq.
-
-        If of is missing, we write to bitlbee.nicks.
-
-=head1 DESCRIPTION
-
-We run thru the
-files where the contacts reside and create
-a bitlbee .nicks-file from them.
-
-=head1 DEPENDENCIES
-
-On the perlside, we need Getopt::Long.
-
-=head1 CAVEATS
-
-=head1 TODO
-
-&import_readline_... should take a filehandle as argument.
-
-Add more import functions. If you are interested,
-to do so, you need to write the following functions:
-
-=over
-
-=item *
-
-import_open_<WHATEVER>(DIR,FILENAME)
-
-=item *
-
-import_close_<WHATEVER>()
-
-=item *
-
-import_readline_<WHATEVER>()
-
-=back
-
-and add them to the hashes
-
-=over
-
-=item *
-
-%readline_funcs
-
-=item *
-
-%open_funcs
-
-=item *
-
-%close_funcs
-
-=back
-
-at the top of this script.
-
-
-=head1 AUTHORS
-
-Christian Friedl <vijeno@chello.at>
-
-Updated for the new Licq list firmat by Hugo Buddelmeijer <kmail@hugo.doemaarwat.nl>
-
-=cut
