Index: irc.c
===================================================================
--- irc.c	(revision 3f9440db856c1b1cde54eb919543cfc23ea09983)
+++ irc.c	(revision 0a3c243b6659dc10efb227e507f324c2711d6dcd)
@@ -33,8 +33,9 @@
 GSList *irc_connection_list = NULL;
 
-static char *passchange (irc_t *irc, void *set, char *value) 
-{
-	irc_setpass (irc, value);
-	return (NULL);
+static char *passchange( irc_t *irc, void *set, char *value )
+{
+	irc_setpass( irc, value );
+	irc_usermsg( irc, "Password successfully changed" );
+	return NULL;
 }
 
@@ -120,24 +121,24 @@
 	irc_connection_list = g_slist_append( irc_connection_list, irc );
 	
-	set_add( irc, "away_devoice", "true",  set_eval_away_devoice );
-	set_add( irc, "auto_connect", "true", set_eval_bool );
-	set_add( irc, "auto_reconnect", "false", set_eval_bool );
-	set_add( irc, "auto_reconnect_delay", "300", set_eval_int );
-	set_add( irc, "buddy_sendbuffer", "false", set_eval_bool );
-	set_add( irc, "buddy_sendbuffer_delay", "200", set_eval_int );
-	set_add( irc, "charset", "iso8859-1", set_eval_charset );
-	set_add( irc, "debug", "false", set_eval_bool );
-	set_add( irc, "default_target", "root", NULL );
-	set_add( irc, "display_namechanges", "false", set_eval_bool );
-	set_add( irc, "handle_unknown", "root", NULL );
-	set_add( irc, "lcnicks", "true", set_eval_bool );
-	set_add( irc, "ops", "both", set_eval_ops );
-	set_add( irc, "private", "true", set_eval_bool );
-	set_add( irc, "query_order", "lifo", NULL );
-	set_add( irc, "save_on_quit", "true", set_eval_bool );
-	set_add( irc, "strip_html", "true", NULL );
-	set_add( irc, "to_char", ": ", set_eval_to_char );
-	set_add( irc, "typing_notice", "false", set_eval_bool );
-	set_add( irc, "password", NULL, passchange);
+	set_add( &irc->set, "away_devoice", "true",  set_eval_away_devoice, irc );
+	set_add( &irc->set, "auto_connect", "true", set_eval_bool, irc );
+	set_add( &irc->set, "auto_reconnect", "false", set_eval_bool, irc );
+	set_add( &irc->set, "auto_reconnect_delay", "300", set_eval_int, irc );
+	set_add( &irc->set, "buddy_sendbuffer", "false", set_eval_bool, irc );
+	set_add( &irc->set, "buddy_sendbuffer_delay", "200", set_eval_int, irc );
+	set_add( &irc->set, "charset", "iso8859-1", set_eval_charset, irc );
+	set_add( &irc->set, "debug", "false", set_eval_bool, irc );
+	set_add( &irc->set, "default_target", "root", NULL, irc );
+	set_add( &irc->set, "display_namechanges", "false", set_eval_bool, irc );
+	set_add( &irc->set, "handle_unknown", "root", NULL, irc );
+	set_add( &irc->set, "lcnicks", "true", set_eval_bool, irc );
+	set_add( &irc->set, "ops", "both", set_eval_ops, irc );
+	set_add( &irc->set, "password", NULL, passchange, irc );
+	set_add( &irc->set, "private", "true", set_eval_bool, irc );
+	set_add( &irc->set, "query_order", "lifo", NULL, irc );
+	set_add( &irc->set, "save_on_quit", "true", set_eval_bool, irc );
+	set_add( &irc->set, "strip_html", "true", NULL, irc );
+	set_add( &irc->set, "to_char", ": ", set_eval_to_char, irc );
+	set_add( &irc->set, "typing_notice", "false", set_eval_bool, irc );
 	
 	conf_loaddefaults( irc );
@@ -211,5 +212,5 @@
 	log_message( LOGLVL_INFO, "Destroying connection with fd %d", irc->fd );
 	
-	if( irc->status & USTATUS_IDENTIFIED && set_getint( irc, "save_on_quit" ) ) 
+	if( irc->status & USTATUS_IDENTIFIED && set_getint( &irc->set, "save_on_quit" ) ) 
 		if( storage_save( irc, TRUE ) != STORAGE_OK )
 			irc_usermsg( irc, "Error while saving settings!" );
@@ -329,9 +330,8 @@
 void irc_setpass (irc_t *irc, const char *pass) 
 {
-	if (irc->password) g_free (irc->password);
+	g_free (irc->password);
 	
 	if (pass) {
 		irc->password = g_strdup (pass);
-		irc_usermsg (irc, "Password successfully changed");
 	} else {
 		irc->password = NULL;
@@ -364,5 +364,5 @@
 			}
 			
-			if( ( cs = set_getstr( irc, "charset" ) ) && ( g_strcasecmp( cs, "utf-8" ) != 0 ) )
+			if( ( cs = set_getstr( &irc->set, "charset" ) ) && ( g_strcasecmp( cs, "utf-8" ) != 0 ) )
 			{
 				conv[IRC_MAX_LINE] = 0;
@@ -584,5 +584,5 @@
 	
 	strip_newlines( line );
-	if( ( cs = set_getstr( irc, "charset" ) ) && ( g_strcasecmp( cs, "utf-8" ) != 0 ) )
+	if( ( cs = set_getstr( &irc->set, "charset" ) ) && ( g_strcasecmp( cs, "utf-8" ) != 0 ) )
 	{
 		char conv[IRC_MAX_LINE+1];
@@ -649,53 +649,54 @@
 void irc_names( irc_t *irc, char *channel )
 {
-	user_t *u;
-	char namelist[385] = "";
+	user_t *u = irc->users;
+	char *s;
+	int control = ( g_strcasecmp( channel, irc->channel ) == 0 );
 	struct conversation *c = NULL;
+	
+	if( !control )
+		c = conv_findchannel( channel );
 	
 	/* RFCs say there is no error reply allowed on NAMES, so when the
 	   channel is invalid, just give an empty reply. */
 	
-	if( g_strcasecmp( channel, irc->channel ) == 0 )
-	{
-		for( u = irc->users; u; u = u->next ) if( u->online )
-		{
-			if( strlen( namelist ) + strlen( u->nick ) > sizeof( namelist ) - 4 )
+	if( control || c ) while( u )
+	{
+		if( u->online )
+		{
+			if( u->gc && control )
 			{
-				irc_reply( irc, 353, "= %s :%s", channel, namelist );
-				*namelist = 0;
+				if( set_getint( &irc->set, "away_devoice" ) && !u->away )
+					s = "+";
+				else
+					s = "";
+				
+				irc_reply( irc, 353, "= %s :%s%s", channel, s, u->nick );
 			}
-			
-			if( u->gc && !u->away && set_getint( irc, "away_devoice" ) )
-				strcat( namelist, "+" );
-			
-			strcat( namelist, u->nick );
-			strcat( namelist, " " );
-		}
-	}
-	else if( ( c = conv_findchannel( channel ) ) )
+			else if( !u->gc )
+			{
+				if( strcmp( u->nick, irc->mynick ) == 0 && ( strcmp( set_getstr( &irc->set, "ops" ), "root" ) == 0 || strcmp( set_getstr( &irc->set, "ops" ), "both" ) == 0 ) )
+					s = "@";
+				else if( strcmp( u->nick, irc->nick ) == 0 && ( strcmp( set_getstr( &irc->set, "ops" ), "user" ) == 0 || strcmp( set_getstr( &irc->set, "ops" ), "both" ) == 0 ) )
+					s = "@";
+				else
+					s = "";
+				
+				irc_reply( irc, 353, "= %s :%s%s", channel, s, u->nick );
+			}
+		}
+		
+		u = u->next;
+	}
+	
+	/* For non-controlchannel channels (group conversations) only root and
+	   you are listed now. Time to show the channel people: */
+	if( !control && c )
 	{
 		GList *l;
-		char *ops = set_getstr( irc, "ops" );
-		
-		/* root and the user aren't in the channel userlist but should
-		   show up in /NAMES, so list them first: */
-		sprintf( namelist, "%s%s %s%s ", strcmp( ops, "root" ) == 0 || strcmp( ops, "both" ) ? "@" : "", irc->mynick,
-		                                 strcmp( ops, "user" ) == 0 || strcmp( ops, "both" ) ? "@" : "", irc->nick );
-		
-		for( l = c->in_room; l; l = l->next ) if( ( u = user_findhandle( c->gc, l->data ) ) )
-		{
-			if( strlen( namelist ) + strlen( u->nick ) > sizeof( namelist ) - 4 )
-			{
-				irc_reply( irc, 353, "= %s :%s", channel, namelist );
-				*namelist = 0;
-			}
-			
-			strcat( namelist, u->nick );
-			strcat( namelist, " " );
-		}
-	}
-	
-	if( *namelist )
-		irc_reply( irc, 353, "= %s :%s", channel, namelist );
+		
+		for( l = c->in_room; l; l = l->next )
+			if( ( u = user_findhandle( c->gc, l->data ) ) )
+				irc_reply( irc, 353, "= %s :%s%s", channel, "", u->nick );
+	}
 	
 	irc_reply( irc, 366, "%s :End of /NAMES list", channel );
@@ -924,11 +925,11 @@
 {
 	char *nick, *s;
-	char reason[64];
+	char reason[128];
 	
 	if( u->gc && u->gc->flags & OPT_LOGGING_OUT )
 	{
-		if( u->gc->user->proto_opt[0][0] )
+		if( u->gc->acc->server )
 			g_snprintf( reason, sizeof( reason ), "%s %s", irc->myhost,
-			            u->gc->user->proto_opt[0] );
+			            u->gc->acc->server );
 		else if( ( s = strchr( u->gc->username, '@' ) ) )
 			g_snprintf( reason, sizeof( reason ), "%s %s", irc->myhost,
@@ -936,5 +937,5 @@
 		else
 			g_snprintf( reason, sizeof( reason ), "%s %s.%s", irc->myhost,
-			            u->gc->prpl->name, irc->myhost );
+			            u->gc->acc->prpl->name, irc->myhost );
 		
 		/* proto_opt might contain garbage after the : */
@@ -1012,5 +1013,5 @@
 		else if( g_strncasecmp( s + 1, "TYPING", 6 ) == 0 )
 		{
-			if( u && u->gc && u->gc->prpl->send_typing && strlen( s ) >= 10 )
+			if( u && u->gc && u->gc->acc->prpl->send_typing && strlen( s ) >= 10 )
 			{
 				time_t current_typing_notice = time( NULL );
@@ -1018,5 +1019,5 @@
 				if( current_typing_notice - u->last_typing_notice >= 5 )
 				{
-					u->gc->prpl->send_typing( u->gc, u->handle, s[8] == '1' );
+					u->gc->acc->prpl->send_typing( u->gc, u->handle, s[8] == '1' );
 					u->last_typing_notice = current_typing_notice;
 				}
@@ -1051,5 +1052,5 @@
 		}
 	}
-	else if( c && c->gc && c->gc->prpl )
+	else if( c && c->gc && c->gc->acc && c->gc->acc->prpl )
 	{
 		return( bim_chat_msg( c->gc, c->id, s ) );
@@ -1083,5 +1084,5 @@
 	if( !u || !u->gc ) return;
 	
-	if( set_getint( irc, "buddy_sendbuffer" ) && set_getint( irc, "buddy_sendbuffer_delay" ) > 0 )
+	if( set_getint( &irc->set, "buddy_sendbuffer" ) && set_getint( &irc->set, "buddy_sendbuffer_delay" ) > 0 )
 	{
 		int delay;
@@ -1110,5 +1111,5 @@
 		strcat( u->sendbuf, "\n" );
 		
-		delay = set_getint( irc, "buddy_sendbuffer_delay" );
+		delay = set_getint( &irc->set, "buddy_sendbuffer_delay" );
 		if( delay <= 5 )
 			delay *= 1000;
@@ -1175,5 +1176,5 @@
 		int len = strlen( irc->nick) + 3;
 		prefix = g_new (char, len );
-		g_snprintf( prefix, len, "%s%s", irc->nick, set_getstr( irc, "to_char" ) );
+		g_snprintf( prefix, len, "%s%s", irc->nick, set_getstr( &irc->set, "to_char" ) );
 		prefix[len-1] = 0;
 	}
