Index: conf.c
===================================================================
--- conf.c	(revision 171946457cccb7280f0918201093e79bbc9eac72)
+++ conf.c	(revision 5c9512ffa716f2bc8bbf9e2c31ee40624a0ff842)
@@ -323,5 +323,5 @@
 		if( g_strcasecmp( ini->section, "defaults" ) == 0 )
 		{
-			set_t *s = set_find( irc, ini->key );
+			set_t *s = set_find( &irc->set, ini->key );
 			
 			if( s )
Index: irc.c
===================================================================
--- irc.c	(revision 171946457cccb7280f0918201093e79bbc9eac72)
+++ irc.c	(revision 5c9512ffa716f2bc8bbf9e2c31ee40624a0ff842)
@@ -121,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 );
@@ -212,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!" );
@@ -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];
@@ -666,5 +666,5 @@
 			if( u->gc && control )
 			{
-				if( set_getint( irc, "away_devoice" ) && !u->away )
+				if( set_getint( &irc->set, "away_devoice" ) && !u->away )
 					s = "+";
 				else
@@ -675,7 +675,7 @@
 			else if( !u->gc )
 			{
-				if( strcmp( u->nick, irc->mynick ) == 0 && ( strcmp( set_getstr( irc, "ops" ), "root" ) == 0 || strcmp( set_getstr( irc, "ops" ), "both" ) == 0 ) )
+				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, "ops" ), "user" ) == 0 || strcmp( set_getstr( irc, "ops" ), "both" ) == 0 ) )
+				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
@@ -1084,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;
@@ -1111,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;
@@ -1176,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;
 	}
Index: irc_commands.c
===================================================================
--- irc_commands.c	(revision 171946457cccb7280f0918201093e79bbc9eac72)
+++ irc_commands.c	(revision 5c9512ffa716f2bc8bbf9e2c31ee40624a0ff842)
@@ -230,5 +230,5 @@
 		{
 			unsigned int i;
-			char *t = set_getstr( irc, "default_target" );
+			char *t = set_getstr( &irc->set, "default_target" );
 			
 			if( g_strcasecmp( t, "last" ) == 0 && irc->last_target )
Index: nick.c
===================================================================
--- nick.c	(revision 171946457cccb7280f0918201093e79bbc9eac72)
+++ nick.c	(revision 5c9512ffa716f2bc8bbf9e2c31ee40624a0ff842)
@@ -86,5 +86,5 @@
 		
 		nick_strip( nick );
-		if (set_getint(irc, "lcnicks")) 
+		if( set_getint( &irc->set, "lcnicks" ) )
 			nick_lc( nick );
 	}
Index: protocols/nogaim.c
===================================================================
--- protocols/nogaim.c	(revision 171946457cccb7280f0918201093e79bbc9eac72)
+++ protocols/nogaim.c	(revision 5c9512ffa716f2bc8bbf9e2c31ee40624a0ff842)
@@ -220,6 +220,6 @@
 	va_end( params );
 
-	if( ( g_strcasecmp( set_getstr( gc->irc, "strip_html" ), "always" ) == 0 ) ||
-	    ( ( gc->flags & OPT_CONN_HTML ) && set_getint( gc->irc, "strip_html" ) ) )
+	if( ( g_strcasecmp( set_getstr( &gc->irc->set, "strip_html" ), "always" ) == 0 ) ||
+	    ( ( gc->flags & OPT_CONN_HTML ) && set_getint( &gc->irc->set, "strip_html" ) ) )
 		strip_html( text );
 	
@@ -324,7 +324,7 @@
 		/* Uhm... This is very sick. */
 	}
-	else if( !gc->wants_to_die && set_getint( irc, "auto_reconnect" ) )
-	{
-		int delay = set_getint( irc, "auto_reconnect_delay" );
+	else if( !gc->wants_to_die && set_getint( &irc->set, "auto_reconnect" ) )
+	{
+		int delay = set_getint( &irc->set, "auto_reconnect_delay" );
 		
 		serv_got_crap( gc, "Reconnecting in %d seconds..", delay );
@@ -365,10 +365,10 @@
 	irc_t *irc = gc->irc;
 	
-	if( set_getint( irc, "debug" ) && 0 ) /* This message is too useless */
+	if( set_getint( &irc->set, "debug" ) && 0 ) /* This message is too useless */
 		serv_got_crap( gc, "Receiving user add from handle: %s", handle );
 	
 	if( user_findhandle( gc, handle ) )
 	{
-		if( set_getint( irc, "debug" ) )
+		if( set_getint( &irc->set, "debug" ) )
 			serv_got_crap( gc, "User already exists, ignoring add request: %s", handle );
 		
@@ -458,5 +458,5 @@
 		u->realname = g_strdup( realname );
 		
-		if( ( gc->flags & OPT_LOGGED_IN ) && set_getint( gc->irc, "display_namechanges" ) )
+		if( ( gc->flags & OPT_LOGGED_IN ) && set_getint( &gc->irc->set, "display_namechanges" ) )
 			serv_got_crap( gc, "User `%s' changed name to `%s'", u->nick, u->realname );
 	}
@@ -514,5 +514,5 @@
 	if( !u )
 	{
-		if( g_strcasecmp( set_getstr( gc->irc, "handle_unknown" ), "add" ) == 0 )
+		if( g_strcasecmp( set_getstr( &gc->irc->set, "handle_unknown" ), "add" ) == 0 )
 		{
 			add_buddy( gc, NULL, handle, NULL );
@@ -521,5 +521,5 @@
 		else
 		{
-			if( set_getint( gc->irc, "debug" ) || g_strcasecmp( set_getstr( gc->irc, "handle_unknown" ), "ignore" ) != 0 )
+			if( set_getint( &gc->irc->set, "debug" ) || g_strcasecmp( set_getstr( &gc->irc->set, "handle_unknown" ), "ignore" ) != 0 )
 			{
 				serv_got_crap( gc, "serv_got_update() for handle %s:", handle );
@@ -580,5 +580,5 @@
 	
 	/* LISPy... */
-	if( ( set_getint( gc->irc, "away_devoice" ) ) &&		/* Don't do a thing when user doesn't want it */
+	if( ( set_getint( &gc->irc->set, "away_devoice" ) ) &&		/* Don't do a thing when user doesn't want it */
 	    ( u->online ) &&						/* Don't touch offline people */
 	    ( ( ( u->online != oo ) && !u->away ) ||			/* Voice joining people */
@@ -599,9 +599,9 @@
 	if( !u )
 	{
-		char *h = set_getstr( irc, "handle_unknown" );
+		char *h = set_getstr( &irc->set, "handle_unknown" );
 		
 		if( g_strcasecmp( h, "ignore" ) == 0 )
 		{
-			if( set_getint( irc, "debug" ) )
+			if( set_getint( &irc->set, "debug" ) )
 				serv_got_crap( gc, "Ignoring message from unknown handle %s", handle );
 			
@@ -610,5 +610,5 @@
 		else if( g_strncasecmp( h, "add", 3 ) == 0 )
 		{
-			int private = set_getint( irc, "private" );
+			int private = set_getint( &irc->set, "private" );
 			
 			if( h[3] )
@@ -631,6 +631,6 @@
 	}
 	
-	if( ( g_strcasecmp( set_getstr( gc->irc, "strip_html" ), "always" ) == 0 ) ||
-	    ( ( gc->flags & OPT_CONN_HTML ) && set_getint( gc->irc, "strip_html" ) ) )
+	if( ( g_strcasecmp( set_getstr( &gc->irc->set, "strip_html" ), "always" ) == 0 ) ||
+	    ( ( gc->flags & OPT_CONN_HTML ) && set_getint( &gc->irc->set, "strip_html" ) ) )
 		strip_html( msg );
 
@@ -672,5 +672,5 @@
 	user_t *u;
 	
-	if( !set_getint( gc->irc, "typing_notice" ) )
+	if( !set_getint( &gc->irc->set, "typing_notice" ) )
 		return;
 	
@@ -694,5 +694,5 @@
 	GList *ir;
 	
-	if( set_getint( gc->irc, "debug" ) )
+	if( set_getint( &gc->irc->set, "debug" ) )
 		serv_got_crap( gc, "You were removed from conversation %d", (int) id );
 	
@@ -739,6 +739,6 @@
 	for( c = gc->conversations; c && c->id != id; c = c->next );
 	
-	if( ( g_strcasecmp( set_getstr( gc->irc, "strip_html" ), "always" ) == 0 ) ||
-	    ( ( gc->flags & OPT_CONN_HTML ) && set_getint( gc->irc, "strip_html" ) ) )
+	if( ( g_strcasecmp( set_getstr( &gc->irc->set, "strip_html" ), "always" ) == 0 ) ||
+	    ( ( gc->flags & OPT_CONN_HTML ) && set_getint( &gc->irc->set, "strip_html" ) ) )
 		strip_html( msg );
 	
@@ -773,5 +773,5 @@
 	g_free( s );
 	
-	if( set_getint( gc->irc, "debug" ) )
+	if( set_getint( &gc->irc->set, "debug" ) )
 		serv_got_crap( gc, "Creating new conversation: (id=%d,handle=%s)", id, handle );
 	
@@ -787,5 +787,5 @@
 	int me = 0;
 	
-	if( set_getint( b->gc->irc, "debug" ) )
+	if( set_getint( &b->gc->irc->set, "debug" ) )
 		serv_got_crap( b->gc, "User %s added to conversation %d", handle, b->id );
 	
@@ -821,5 +821,5 @@
 	int me = 0;
 	
-	if( set_getint( b->gc->irc, "debug" ) )
+	if( set_getint( &b->gc->irc->set, "debug" ) )
 		serv_got_crap( b->gc, "User %s removed from conversation %d (%s)", handle, b->id, reason ? reason : "" );
 	
@@ -883,6 +883,7 @@
 }
 
-char *set_eval_away_devoice( irc_t *irc, set_t *set, char *value )
-{
+char *set_eval_away_devoice( set_t *set, char *value )
+{
+	irc_t *irc = set->data;
 	int st;
 	
@@ -898,5 +899,5 @@
 	/* Horror.... */
 	
-	if( st != set_getint( irc, "away_devoice" ) )
+	if( st != set_getint( &irc->set, "away_devoice" ) )
 	{
 		char list[80] = "";
@@ -938,5 +939,5 @@
 	}
 	
-	return( set_eval_bool( irc, set, value ) );
+	return( set_eval_bool( set, value ) );
 }
 
@@ -1018,5 +1019,5 @@
 		{
 			gc->prpl->set_away( gc, s, away );
-			if( set_getint( gc->irc, "debug" ) )
+			if( set_getint( &gc->irc->set, "debug" ) )
 				serv_got_crap( gc, "Setting away state to %s", s );
 		}
Index: protocols/nogaim.h
===================================================================
--- protocols/nogaim.h	(revision 171946457cccb7280f0918201093e79bbc9eac72)
+++ protocols/nogaim.h	(revision 5c9512ffa716f2bc8bbf9e2c31ee40624a0ff842)
@@ -206,5 +206,5 @@
 
 void nogaim_init();
-char *set_eval_away_devoice( irc_t *irc, set_t *set, char *value );
+char *set_eval_away_devoice( set_t *set, char *value );
 
 gboolean auto_reconnect( gpointer data, gint fd, b_input_condition cond );
Index: query.c
===================================================================
--- query.c	(revision 171946457cccb7280f0918201093e79bbc9eac72)
+++ query.c	(revision 5c9512ffa716f2bc8bbf9e2c31ee40624a0ff842)
@@ -63,5 +63,5 @@
 	}
 	
-	if( g_strcasecmp( set_getstr( irc, "query_order" ), "lifo" ) == 0 || irc->queries == q )
+	if( g_strcasecmp( set_getstr( &irc->set, "query_order" ), "lifo" ) == 0 || irc->queries == q )
 		query_display( irc, q );
 	
@@ -172,5 +172,5 @@
 	query_t *q;
 	
-	if( g_strcasecmp( set_getstr( irc, "query_order" ), "fifo" ) == 0 )
+	if( g_strcasecmp( set_getstr( &irc->set, "query_order" ), "fifo" ) == 0 )
 		q = irc->queries;
 	else
Index: root_commands.c
===================================================================
--- root_commands.c	(revision 171946457cccb7280f0918201093e79bbc9eac72)
+++ root_commands.c	(revision 5c9512ffa716f2bc8bbf9e2c31ee40624a0ff842)
@@ -144,5 +144,5 @@
 		irc_usermsg( irc, "Password accepted, settings and accounts loaded" );
 		irc_umode_set( irc, "+R", 1 );
-		if( set_getint( irc, "auto_connect" ) )
+		if( set_getint( &irc->set, "auto_connect" ) )
 			cmd_account( irc, account_on );
 		break;
@@ -672,5 +672,5 @@
 	if( cmd[1] && cmd[2] )
 	{
-		set_setstr( irc, cmd[1], cmd[2] );
+		set_setstr( &irc->set, cmd[1], cmd[2] );
 		
 		if( ( strcmp( cmd[2], "=" ) ) == 0 && cmd[3] )
@@ -679,5 +679,5 @@
 	if( cmd[1] ) /* else 'forgotten' on purpose.. Must show new value after changing */
 	{
-		char *s = set_getstr( irc, cmd[1] );
+		char *s = set_getstr( &irc->set, cmd[1] );
 		if( s )
 			irc_usermsg( irc, "%s = `%s'", cmd[1], s );
Index: set.c
===================================================================
--- set.c	(revision 171946457cccb7280f0918201093e79bbc9eac72)
+++ set.c	(revision 5c9512ffa716f2bc8bbf9e2c31ee40624a0ff842)
@@ -26,21 +26,22 @@
 #include "bitlbee.h"
 
-set_t *set_add( irc_t *irc, char *key, char *def, void *eval )
-{
-	set_t *s = set_find( irc, key );
-	
+set_t *set_add( set_t **head, char *key, char *def, void *eval, void *data )
+{
+	set_t *s = set_find( head, key );
+	
+	/* Possibly the setting already exists. If it doesn't exist yet,
+	   we create it. If it does, we'll just change the default. */
 	if( !s )
 	{
-		if( ( s = irc->set ) )
+		if( ( s = *head ) )
 		{
 			while( s->next ) s = s->next;
-			s->next = g_new ( set_t, 1 );
+			s->next = g_new0( set_t, 1 );
 			s = s->next;
 		}
 		else
 		{
-			s = irc->set = g_new( set_t, 1 );
+			s = *head = g_new0( set_t, 1 );
 		}
-		memset( s, 0, sizeof( set_t ) );
 		s->key = g_strdup( key );
 	}
@@ -53,17 +54,13 @@
 	if( def ) s->def = g_strdup( def );
 	
-	if( s->eval )
-	{
-		g_free( s->eval );
-		s->eval = NULL;
-	}
-	if( eval ) s->eval = eval;
-	
-	return( s );
-}
-
-set_t *set_find( irc_t *irc, char *key )
-{
-	set_t *s = irc->set;
+	s->eval = eval;
+	s->data = data;
+	
+	return s;
+}
+
+set_t *set_find( set_t **head, char *key )
+{
+	set_t *s = *head;
 	
 	while( s )
@@ -74,44 +71,44 @@
 	}
 	
-	return( s );
-}
-
-char *set_getstr( irc_t *irc, char *key )
-{
-	set_t *s = set_find( irc, key );
+	return s;
+}
+
+char *set_getstr( set_t **head, char *key )
+{
+	set_t *s = set_find( head, key );
 	
 	if( !s || ( !s->value && !s->def ) )
-		return( NULL );
-	
-	return( s->value?s->value:s->def );
-}
-
-int set_getint( irc_t *irc, char *key )
-{
-	char *s = set_getstr( irc, key );
+		return NULL;
+	
+	return s->value ? s->value : s->def;
+}
+
+int set_getint( set_t **head, char *key )
+{
+	char *s = set_getstr( head, key );
 	int i = 0;
 	
 	if( !s )
-		return( 0 );
+		return 0;
 	
 	if( ( g_strcasecmp( s, "true" ) == 0 ) || ( g_strcasecmp( s, "yes" ) == 0 ) || ( g_strcasecmp( s, "on" ) == 0 ) )
-		return( 1 );
+		return 1;
 	
 	if( sscanf( s, "%d", &i ) != 1 )
-		return( 0 );
-	
-	return( i );
-}
-
-int set_setstr( irc_t *irc, char *key, char *value )
-{
-	set_t *s = set_find( irc, key );
+		return 0;
+	
+	return i;
+}
+
+int set_setstr( set_t **head, char *key, char *value )
+{
+	set_t *s = set_find( head, key );
 	char *nv = value;
 	
 	if( !s )
-		s = set_add( irc, key, NULL, NULL );
-	
-	if( s->eval && !( nv = s->eval( irc, s, value ) ) )
-		return( 0 );
+		s = set_add( head, key, NULL, NULL, NULL );
+	
+	if( s->eval && !( nv = s->eval( s, value ) ) )
+		return 0;
 	
 	if( s->value )
@@ -121,4 +118,6 @@
 	}
 	
+	/* If there's a default setting and it's equal to what we're trying to
+	   set, stick with s->value = NULL. Otherwise, remember the setting. */
 	if( !s->def || ( strcmp( nv, s->def ) != 0 ) )
 		s->value = g_strdup( nv );
@@ -127,18 +126,18 @@
 		g_free( nv );
 	
-	return( 1 );
-}
-
-int set_setint( irc_t *irc, char *key, int value )
+	return 1;
+}
+
+int set_setint( set_t **head, char *key, int value )
 {
 	char s[24];	/* Not quite 128-bit clean eh? ;-) */
 	
-	sprintf( s, "%d", value );
-	return( set_setstr( irc, key, s ) );
-}
-
-void set_del( irc_t *irc, char *key )
-{
-	set_t *s = irc->set, *t = NULL;
+	g_snprintf( s, sizeof( s ), "%d", value );
+	return set_setstr( head, key, s );
+}
+
+void set_del( set_t **head, char *key )
+{
+	set_t *s = *head, *t = NULL;
 	
 	while( s )
@@ -153,5 +152,5 @@
 			t->next = s->next;
 		else
-			irc->set = s->next;
+			*head = s->next;
 		
 		g_free( s->key );
@@ -162,16 +161,16 @@
 }
 
-char *set_eval_int( irc_t *irc, set_t *set, char *value )
-{
-	char *s = value;
-	
-	for( ; *s; s ++ )
+char *set_eval_int( set_t *set, char *value )
+{
+	char *s;
+	
+	for( s = value; *s; s ++ )
 		if( *s < '0' || *s > '9' )
-			return( NULL );
-	
-	return( value );
-}
-
-char *set_eval_bool( irc_t *irc, set_t *set, char *value )
+			return NULL;
+	
+	return value;
+}
+
+char *set_eval_bool( set_t *set, char *value )
 {
 	if( ( g_strcasecmp( value, "true" ) == 0 ) || ( g_strcasecmp( value, "yes" ) == 0 ) || ( g_strcasecmp( value, "on" ) == 0 ) )
@@ -179,8 +178,8 @@
 	if( ( g_strcasecmp( value, "false" ) == 0 ) || ( g_strcasecmp( value, "no" ) == 0 ) || ( g_strcasecmp( value, "off" ) == 0 ) )
 		return( value );
-	return( set_eval_int( irc, set, value ) );
-}
-
-char *set_eval_to_char( irc_t *irc, set_t *set, char *value )
+	return( set_eval_int( set, value ) );
+}
+
+char *set_eval_to_char( set_t *set, char *value )
 {
 	char *s = g_new( char, 3 );
@@ -191,49 +190,41 @@
 		sprintf( s, "%c ", *value );
 	
-	return( s );
-}
-
-char *set_eval_ops( irc_t *irc, set_t *set, char *value )
-{
+	return s;
+}
+
+char *set_eval_ops( set_t *set, char *value )
+{
+	irc_t *irc = set->data;
+	
 	if( g_strcasecmp( value, "user" ) == 0 )
-	{
 		irc_write( irc, ":%s!%s@%s MODE %s %s %s %s", irc->mynick, irc->mynick, irc->myhost,
 		                                              irc->channel, "+o-o", irc->nick, irc->mynick );
-		return( value );
-	}
 	else if( g_strcasecmp( value, "root" ) == 0 )
-	{
 		irc_write( irc, ":%s!%s@%s MODE %s %s %s %s", irc->mynick, irc->mynick, irc->myhost,
 		                                              irc->channel, "-o+o", irc->nick, irc->mynick );
-		return( value );
-	}
 	else if( g_strcasecmp( value, "both" ) == 0 )
-	{
 		irc_write( irc, ":%s!%s@%s MODE %s %s %s %s", irc->mynick, irc->mynick, irc->myhost,
 		                                              irc->channel, "+oo", irc->nick, irc->mynick );
-		return( value );
-	}
 	else if( g_strcasecmp( value, "none" ) == 0 )
-	{
 		irc_write( irc, ":%s!%s@%s MODE %s %s %s %s", irc->mynick, irc->mynick, irc->myhost,
 		                                              irc->channel, "-oo", irc->nick, irc->mynick );
-		return( value );
-	}
-	
-	return( NULL );
-}
-
-char *set_eval_charset( irc_t *irc, set_t *set, char *value )
+	else
+		return NULL;
+	
+	return value;
+}
+
+char *set_eval_charset( set_t *set, char *value )
 {
 	GIConv cd;
 
 	if ( g_strncasecmp( value, "none", 4 ) == 0 )
-		return( value );
+		return value;
 
 	cd = g_iconv_open( "UTF-8", value );
 	if( cd == (GIConv) -1 )
-		return( NULL );
+		return NULL;
 
 	g_iconv_close( cd );
-	return( value );
-}
+	return value;
+}
Index: set.h
===================================================================
--- set.h	(revision 171946457cccb7280f0918201093e79bbc9eac72)
+++ set.h	(revision 5c9512ffa716f2bc8bbf9e2c31ee40624a0ff842)
@@ -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                *
   \********************************************************************/
 
@@ -26,27 +26,29 @@
 typedef struct set
 {
+	void *data;
+	
 	char *key;
 	char *value;
 	char *def;	/* Default */
 	
-	/* Eval: Returns NULL if the value is incorrect. Can return a
-	   corrected value. set_setstr() should be able to free() the
-	   returned string! */
-	char *(*eval) ( irc_t *irc, struct set *set, char *value );
+	/* Eval: Returns NULL if the value is incorrect or exactly the
+	   passed value variable. When returning a corrected value,
+	   set_setstr() should be able to free() the returned string! */
+	char *(*eval) ( struct set *set, char *value );
 	struct set *next;
 } set_t;
 
-set_t *set_add( irc_t *irc, char *key, char *def, void *eval );
-G_MODULE_EXPORT set_t *set_find( irc_t *irc, char *key );
-G_MODULE_EXPORT char *set_getstr( irc_t *irc, char *key );
-G_MODULE_EXPORT int set_getint( irc_t *irc, char *key );
-int set_setstr( irc_t *irc, char *key, char *value );
-int set_setint( irc_t *irc, char *key, int value );
-void set_del( irc_t *irc, char *key );
+set_t *set_add( set_t **head, char *key, char *def, void *eval, void *data );
+G_MODULE_EXPORT set_t *set_find( set_t **head, char *key );
+G_MODULE_EXPORT char *set_getstr( set_t **head, char *key );
+G_MODULE_EXPORT int set_getint( set_t **head, char *key );
+int set_setstr( set_t **head, char *key, char *value );
+int set_setint( set_t **head, char *key, int value );
+void set_del( set_t **head, char *key );
 
-char *set_eval_int( irc_t *irc, set_t *set, char *value );
-char *set_eval_bool( irc_t *irc, set_t *set, char *value );
+char *set_eval_int( set_t *set, char *value );
+char *set_eval_bool( set_t *set, char *value );
 
-char *set_eval_to_char( irc_t *irc, set_t *set, char *value );
-char *set_eval_ops( irc_t *irc, set_t *set, char *value );
-char *set_eval_charset( irc_t *irc, set_t *set, char *value );
+char *set_eval_to_char( set_t *set, char *value );
+char *set_eval_ops( set_t *set, char *value );
+char *set_eval_charset( set_t *set, char *value );
Index: storage_xml.c
===================================================================
--- storage_xml.c	(revision 171946457cccb7280f0918201093e79bbc9eac72)
+++ storage_xml.c	(revision 5c9512ffa716f2bc8bbf9e2c31ee40624a0ff842)
@@ -246,5 +246,5 @@
 	         xd->current_setting && xd->current_account == NULL )
 	{
-		set_setstr( irc, xd->current_setting, (char*) text );
+		set_setstr( &irc->set, xd->current_setting, (char*) text );
 		g_free( xd->current_setting );
 		xd->current_setting = NULL;
@@ -421,12 +421,11 @@
 		pass_len = rc4_encode( (unsigned char*) acc->pass, strlen( acc->pass ), (unsigned char**) &pass_rc4, irc->password );
 		pass_b64 = base64_encode( pass_rc4, pass_len );
+		g_free( pass_rc4 );
 		
 		if( !xml_printf( fd, "\t<account protocol=\"%s\" handle=\"%s\" password=\"%s\" autoconnect=\"%d\"", acc->prpl->name, acc->user, pass_b64, acc->auto_connect ) )
 		{
-			g_free( pass_rc4 );
 			g_free( pass_b64 );
 			goto write_error;
 		}
-		g_free( pass_rc4 );
 		g_free( pass_b64 );
 		
Index: user.c
===================================================================
--- user.c	(revision 171946457cccb7280f0918201093e79bbc9eac72)
+++ user.c	(revision 5c9512ffa716f2bc8bbf9e2c31ee40624a0ff842)
@@ -67,5 +67,5 @@
 	
 	u->user = u->realname = u->host = u->nick = g_strdup( nick );
-	u->is_private = set_getint( irc, "private" );
+	u->is_private = set_getint( &irc->set, "private" );
 	
 	key = g_strdup( nick );
