1 /********************************************************************\
2 * BitlBee -- An IRC to other IM-networks gateway *
4 * Copyright 2002-2004 Wilmer van der Gaast and others *
5 \********************************************************************/
7 /* Stuff to handle, save and search buddies */
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License with
21 the Debian GNU/Linux distribution in /usr/share/common-licenses/GPL;
22 if not, write to the Free Software Foundation, Inc., 59 Temple Place,
23 Suite 330, Boston, MA 02111-1307 USA
29 user_t
*user_add( irc_t
*irc
, char *nick
)
31 user_t
*u
, *lu
= NULL
;
34 if( !nick_ok( nick
) )
37 if( user_find( irc
, nick
) != NULL
)
40 if( ( u
= irc
->users
) )
44 if( nick_cmp( nick
, u
->nick
) < 0 )
51 u
= g_new0( user_t
, 1 );
65 irc
->users
= u
= g_new0( user_t
, 1 );
68 u
->user
= u
->realname
= u
->host
= u
->nick
= g_strdup( nick
);
69 u
->is_private
= set_getbool( &irc
->set
, "private" );
71 key
= g_strdup( nick
);
73 g_hash_table_insert( irc
->userhash
, key
, u
);
78 int user_del( irc_t
*irc
, char *nick
)
82 gpointer okey
, ovalue
;
84 if( !nick_ok( nick
) )
91 if( nick_cmp( u
->nick
, nick
) == 0 )
93 /* Get this key now already, since "nick" might be free()d
94 at the time we start playing with the hash... */
95 key
= g_strdup( nick
);
101 irc
->users
= u
->next
;
105 if( u
->nick
!= u
->user
) g_free( u
->user
);
106 if( u
->nick
!= u
->host
) g_free( u
->host
);
107 if( u
->nick
!= u
->realname
) g_free( u
->realname
);
111 g_free( u
->sendbuf
);
112 if( u
->sendbuf_timer
) b_event_remove( u
->sendbuf_timer
);
115 if( !g_hash_table_lookup_extended( irc
->userhash
, key
, &okey
, &ovalue
) || ovalue
!= u
)
118 return( 1 ); /* Although this is a severe error, the user is removed from the list... */
120 g_hash_table_remove( irc
->userhash
, key
);
132 user_t
*user_find( irc_t
*irc
, char *nick
)
136 strncpy( key
, nick
, sizeof( key
) - 1 );
138 return( g_hash_table_lookup( irc
->userhash
, key
) );
143 user_t
*user_findhandle( struct im_connection
*ic
, const char *handle
)
148 /* First, let's try a hash lookup. If it works, it's probably faster. */
149 if( ( nick
= g_hash_table_lookup( ic
->acc
->nicks
, handle
) ) &&
150 ( u
= user_find( ic
->irc
, nick
) ) &&
151 ( ic
->acc
->prpl
->handle_cmp( handle
, u
->handle
) == 0 ) )
154 /* However, it doesn't always work, so in that case we'll have to dig
155 through the whole userlist. :-( */
156 for( u
= ic
->irc
->users
; u
; u
= u
->next
)
157 if( u
->ic
== ic
&& u
->handle
&& ic
->acc
->prpl
->handle_cmp( u
->handle
, handle
) == 0 )
163 /* DO NOT PASS u->nick FOR oldnick !!! */
164 void user_rename( irc_t
*irc
, char *oldnick
, char *newnick
)
166 user_t
*u
= user_find( irc
, oldnick
);
167 gpointer okey
, ovalue
;
170 if( !u
) return; /* Should've been checked by the caller... */
173 if( u
->nick
== u
->user
) u
->user
= NULL
;
174 if( u
->nick
== u
->host
) u
->host
= NULL
;
175 if( u
->nick
== u
->realname
) u
->realname
= NULL
;
176 u
->nick
= g_strdup( newnick
);
177 if( !u
->user
) u
->user
= u
->nick
;
178 if( !u
->host
) u
->host
= u
->nick
;
179 if( !u
->realname
) u
->realname
= u
->nick
;
181 /* Remove the old reference to this user from the hash and create a
182 new one with the new nick. This is indeed a bit messy. */
183 key
= g_strdup( oldnick
);
185 if( !g_hash_table_lookup_extended( irc
->userhash
, key
, &okey
, &ovalue
) || ovalue
!= u
)
188 return; /* This really shouldn't happen! */
190 g_hash_table_remove( irc
->userhash
, key
);
194 key
= g_strdup( newnick
);
196 g_hash_table_insert( irc
->userhash
, key
, u
);
198 /* Also, let's try to keep the linked list nicely sorted. Fear this
199 code. If my teacher would see this, she would cry. ;-) */
203 /* Remove the user from the old position in the chain. */
204 if( u
== irc
->users
)
206 irc
->users
= u
->next
;
211 for( lu1
= irc
->users
; lu1
->next
!= u1
; lu1
= lu1
->next
);
212 lu1
->next
= u1
->next
;
215 /* Search for the new position. */
216 for( lu1
= NULL
, u1
= irc
->users
; u1
; u1
= u1
->next
)
218 if( nick_cmp( newnick
, u1
->nick
) < 0 )
224 /* Insert it at this new position. */