Index: irc.c
===================================================================
--- irc.c	(revision bbb6ffb4d2f4e02d3f856f731a83cb6b911bf659)
+++ irc.c	(revision 3f9440db856c1b1cde54eb919543cfc23ea09983)
@@ -33,11 +33,8 @@
 GSList *irc_connection_list = NULL;
 
-static char *passchange( set_t *set, char *value )
-{
-	irc_t *irc = set->data;
-	
-	irc_setpass( irc, value );
-	irc_usermsg( irc, "Password successfully changed" );
-	return NULL;
+static char *passchange (irc_t *irc, void *set, char *value) 
+{
+	irc_setpass (irc, value);
+	return (NULL);
 }
 
@@ -49,8 +46,8 @@
 	char buf[128];
 #ifdef IPV6
-	struct sockaddr_in6 sock6[1];
-	unsigned int i6;
+	struct sockaddr_in6 sock[1];
+#else
+	struct sockaddr_in sock[1];
 #endif
-	struct sockaddr_in sock[1];
 	
 	irc = g_new0( irc_t, 1 );
@@ -72,46 +69,43 @@
 	
 	i = sizeof( *sock );
-#ifdef IPV6
-	i6 = sizeof( *sock6 );
-#endif
 	
 	if( global.conf->hostname )
 		irc->myhost = g_strdup( global.conf->hostname );
 #ifdef IPV6
-	else if( getsockname( irc->fd, (struct sockaddr*) sock6, &i6 ) == 0 && sock6->sin6_family == AF_INET6 )
-	{
-		if( ( peer = gethostbyaddr( (char*) &sock6->sin6_addr, sizeof( sock6->sin6_addr ), AF_INET6 ) ) )
+	else if( getsockname( irc->fd, (struct sockaddr*) sock, &i ) == 0 && sock->sin6_family == AF_INETx )
+	{
+		if( ( peer = gethostbyaddr( (char*) &sock->sin6_addr, sizeof( sock->sin6_addr ), AF_INETx ) ) )
 			irc->myhost = g_strdup( peer->h_name );
-		else if( inet_ntop( AF_INET6, &sock6->sin6_addr, buf, sizeof( buf ) - 1 ) != NULL )
+		else if( inet_ntop( AF_INETx, &sock->sin6_addr, buf, sizeof( buf ) - 1 ) != NULL )
 			irc->myhost = g_strdup( ipv6_unwrap( buf ) );
 	}
+#else
+	else if( getsockname( irc->fd, (struct sockaddr*) sock, &i ) == 0 && sock->sin_family == AF_INETx )
+	{
+		if( ( peer = gethostbyaddr( (char*) &sock->sin_addr, sizeof( sock->sin_addr ), AF_INETx ) ) )
+			irc->myhost = g_strdup( peer->h_name );
+		else if( inet_ntop( AF_INETx, &sock->sin_addr, buf, sizeof( buf ) - 1 ) != NULL )
+			irc->myhost = g_strdup( buf );
+	}
 #endif
-	else if( getsockname( irc->fd, (struct sockaddr*) sock, &i ) == 0 && sock->sin_family == AF_INET )
-	{
-		if( ( peer = gethostbyaddr( (char*) &sock->sin_addr, sizeof( sock->sin_addr ), AF_INET ) ) )
-			irc->myhost = g_strdup( peer->h_name );
-		else if( inet_ntop( AF_INET, &sock->sin_addr, buf, sizeof( buf ) - 1 ) != NULL )
-			irc->myhost = g_strdup( buf );
-	}
 	
 	i = sizeof( *sock );
 #ifdef IPV6
-	i6 = sizeof( *sock6 );
-	if( getpeername( irc->fd, (struct sockaddr*) sock6, &i6 ) == 0 && sock6->sin6_family == AF_INET6 )
-	{
-		if( ( peer = gethostbyaddr( (char*) &sock6->sin6_addr, sizeof( sock6->sin6_addr ), AF_INET6 ) ) )
+	if( getpeername( irc->fd, (struct sockaddr*) sock, &i ) == 0 && sock->sin6_family == AF_INETx )
+	{
+		if( ( peer = gethostbyaddr( (char*) &sock->sin6_addr, sizeof( sock->sin6_addr ), AF_INETx ) ) )
 			irc->host = g_strdup( peer->h_name );
-		else if( inet_ntop( AF_INET6, &sock6->sin6_addr, buf, sizeof( buf ) - 1 ) != NULL )
+		else if( inet_ntop( AF_INETx, &sock->sin6_addr, buf, sizeof( buf ) - 1 ) != NULL )
 			irc->host = g_strdup( ipv6_unwrap( buf ) );
 	}
-	else
+#else
+	if( getpeername( irc->fd, (struct sockaddr*) sock, &i ) == 0 && sock->sin_family == AF_INETx )
+	{
+		if( ( peer = gethostbyaddr( (char*) &sock->sin_addr, sizeof( sock->sin_addr ), AF_INETx ) ) )
+			irc->host = g_strdup( peer->h_name );
+		else if( inet_ntop( AF_INETx, &sock->sin_addr, buf, sizeof( buf ) - 1 ) != NULL )
+			irc->host = g_strdup( buf );
+	}
 #endif
-	if( getpeername( irc->fd, (struct sockaddr*) sock, &i ) == 0 && sock->sin_family == AF_INET )
-	{
-		if( ( peer = gethostbyaddr( (char*) &sock->sin_addr, sizeof( sock->sin_addr ), AF_INET ) ) )
-			irc->host = g_strdup( peer->h_name );
-		else if( inet_ntop( AF_INET, &sock->sin_addr, buf, sizeof( buf ) - 1 ) != NULL )
-			irc->host = g_strdup( buf );
-	}
 	
 	/* Rare, but possible. */
@@ -126,24 +120,24 @@
 	irc_connection_list = g_slist_append( irc_connection_list, irc );
 	
-	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 );
+	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);
 	
 	conf_loaddefaults( irc );
@@ -209,11 +203,13 @@
 void irc_free(irc_t * irc)
 {
-	account_t *account;
+	account_t *account, *accounttmp;
 	user_t *user, *usertmp;
+	nick_t *nick, *nicktmp;
 	help_t *helpnode, *helpnodetmp;
+	set_t *setnode, *setnodetmp;
 	
 	log_message( LOGLVL_INFO, "Destroying connection with fd %d", irc->fd );
 	
-	if( irc->status & USTATUS_IDENTIFIED && set_getbool( &irc->set, "save_on_quit" ) ) 
+	if( irc->status & USTATUS_IDENTIFIED && set_getint( irc, "save_on_quit" ) ) 
 		if( storage_save( irc, TRUE ) != STORAGE_OK )
 			irc_usermsg( irc, "Error while saving settings!" );
@@ -255,9 +251,15 @@
 		query_del(irc, irc->queries);
 	
-	while (irc->accounts)
-		account_del(irc, irc->accounts);
-	
-	while (irc->set)
-		set_del(&irc->set, irc->set->key);
+	if (irc->accounts != NULL) {
+		account = irc->accounts;
+		while (account != NULL) {
+			g_free(account->user);
+			g_free(account->pass);
+			g_free(account->server);
+			accounttmp = account;
+			account = account->next;
+			g_free(accounttmp);
+		}
+	}
 	
 	if (irc->users != NULL) {
@@ -284,4 +286,15 @@
 	g_hash_table_destroy(irc->watches);
 	
+	if (irc->nicks != NULL) {
+		nick = irc->nicks;
+		while (nick != NULL) {
+			g_free(nick->nick);
+			g_free(nick->handle);
+					
+			nicktmp = nick;
+			nick = nick->next;
+			g_free(nicktmp);
+		}
+	}
 	if (irc->help != NULL) {
 		helpnode = irc->help;
@@ -294,4 +307,16 @@
 		}
 	}
+	if (irc->set != NULL) {
+		setnode = irc->set;
+		while (setnode != NULL) {
+			g_free(setnode->key);
+			g_free(setnode->def);
+			g_free(setnode->value);
+			
+			setnodetmp = setnode;
+			setnode = setnode->next;
+			g_free(setnodetmp);
+		}
+	}
 	g_free(irc);
 	
@@ -304,8 +329,9 @@
 void irc_setpass (irc_t *irc, const char *pass) 
 {
-	g_free (irc->password);
+	if (irc->password) g_free (irc->password);
 	
 	if (pass) {
 		irc->password = g_strdup (pass);
+		irc_usermsg (irc, "Password successfully changed");
 	} else {
 		irc->password = NULL;
@@ -338,5 +364,5 @@
 			}
 			
-			if( ( cs = set_getstr( &irc->set, "charset" ) ) && ( g_strcasecmp( cs, "utf-8" ) != 0 ) )
+			if( ( cs = set_getstr( irc, "charset" ) ) && ( g_strcasecmp( cs, "utf-8" ) != 0 ) )
 			{
 				conv[IRC_MAX_LINE] = 0;
@@ -558,5 +584,5 @@
 	
 	strip_newlines( line );
-	if( ( cs = set_getstr( &irc->set, "charset" ) ) && ( g_strcasecmp( cs, "utf-8" ) != 0 ) )
+	if( ( cs = set_getstr( irc, "charset" ) ) && ( g_strcasecmp( cs, "utf-8" ) != 0 ) )
 	{
 		char conv[IRC_MAX_LINE+1];
@@ -585,9 +611,6 @@
 		   the queue. If it's FALSE, we emptied the buffer and saved ourselves some work
 		   in the event queue. */
-		/* Really can't be done as long as the code doesn't do error checking very well:
-		if( bitlbee_io_current_client_write( irc, irc->fd, GAIM_INPUT_WRITE ) ) */
-		
-		/* So just always do it via the event handler. */
-		irc->w_watch_source_id = b_input_add( irc->fd, GAIM_INPUT_WRITE, bitlbee_io_current_client_write, irc );
+		if( bitlbee_io_current_client_write( irc, irc->fd, GAIM_INPUT_WRITE ) )
+			irc->w_watch_source_id = b_input_add( irc->fd, GAIM_INPUT_WRITE, bitlbee_io_current_client_write, irc );
 	}
 	
@@ -629,5 +652,4 @@
 	char namelist[385] = "";
 	struct conversation *c = NULL;
-	char *ops = set_getstr( &irc->set, "ops" );
 	
 	/* RFCs say there is no error reply allowed on NAMES, so when the
@@ -644,9 +666,6 @@
 			}
 			
-			if( u->gc && !u->away && set_getbool( &irc->set, "away_devoice" ) )
+			if( u->gc && !u->away && set_getint( irc, "away_devoice" ) )
 				strcat( namelist, "+" );
-			else if( ( strcmp( u->nick, irc->mynick ) == 0 && ( strcmp( ops, "root" ) == 0 || strcmp( ops, "both" ) == 0 ) ) ||
-			         ( strcmp( u->nick, irc->nick ) == 0 && ( strcmp( ops, "user" ) == 0 || strcmp( ops, "both" ) == 0 ) ) )
-				strcat( namelist, "@" );
 			
 			strcat( namelist, u->nick );
@@ -657,4 +676,5 @@
 	{
 		GList *l;
+		char *ops = set_getstr( irc, "ops" );
 		
 		/* root and the user aren't in the channel userlist but should
@@ -904,11 +924,11 @@
 {
 	char *nick, *s;
-	char reason[128];
+	char reason[64];
 	
 	if( u->gc && u->gc->flags & OPT_LOGGING_OUT )
 	{
-		if( u->gc->acc->server )
+		if( u->gc->user->proto_opt[0][0] )
 			g_snprintf( reason, sizeof( reason ), "%s %s", irc->myhost,
-			            u->gc->acc->server );
+			            u->gc->user->proto_opt[0] );
 		else if( ( s = strchr( u->gc->username, '@' ) ) )
 			g_snprintf( reason, sizeof( reason ), "%s %s", irc->myhost,
@@ -916,5 +936,5 @@
 		else
 			g_snprintf( reason, sizeof( reason ), "%s %s.%s", irc->myhost,
-			            u->gc->acc->prpl->name, irc->myhost );
+			            u->gc->prpl->name, irc->myhost );
 		
 		/* proto_opt might contain garbage after the : */
@@ -992,5 +1012,5 @@
 		else if( g_strncasecmp( s + 1, "TYPING", 6 ) == 0 )
 		{
-			if( u && u->gc && u->gc->acc->prpl->send_typing && strlen( s ) >= 10 )
+			if( u && u->gc && u->gc->prpl->send_typing && strlen( s ) >= 10 )
 			{
 				time_t current_typing_notice = time( NULL );
@@ -998,5 +1018,5 @@
 				if( current_typing_notice - u->last_typing_notice >= 5 )
 				{
-					u->gc->acc->prpl->send_typing( u->gc, u->handle, s[8] == '1' );
+					u->gc->prpl->send_typing( u->gc, u->handle, s[8] == '1' );
 					u->last_typing_notice = current_typing_notice;
 				}
@@ -1031,5 +1051,5 @@
 		}
 	}
-	else if( c && c->gc && c->gc->acc && c->gc->acc->prpl )
+	else if( c && c->gc && c->gc->prpl )
 	{
 		return( bim_chat_msg( c->gc, c->id, s ) );
@@ -1063,5 +1083,5 @@
 	if( !u || !u->gc ) return;
 	
-	if( set_getbool( &irc->set, "buddy_sendbuffer" ) && set_getint( &irc->set, "buddy_sendbuffer_delay" ) > 0 )
+	if( set_getint( irc, "buddy_sendbuffer" ) && set_getint( irc, "buddy_sendbuffer_delay" ) > 0 )
 	{
 		int delay;
@@ -1090,5 +1110,5 @@
 		strcat( u->sendbuf, "\n" );
 		
-		delay = set_getint( &irc->set, "buddy_sendbuffer_delay" );
+		delay = set_getint( irc, "buddy_sendbuffer_delay" );
 		if( delay <= 5 )
 			delay *= 1000;
@@ -1155,5 +1175,5 @@
 		int len = strlen( irc->nick) + 3;
 		prefix = g_new (char, len );
-		g_snprintf( prefix, len, "%s%s", irc->nick, set_getstr( &irc->set, "to_char" ) );
+		g_snprintf( prefix, len, "%s%s", irc->nick, set_getstr( irc, "to_char" ) );
 		prefix[len-1] = 0;
 	}
