2 * Copyright (C) 1998 Peter Zelezny.
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
33 nick_cmp_az_ops (server
*serv
, struct User
*user1
, struct User
*user2
)
35 unsigned int access1
= user1
->access
;
36 unsigned int access2
= user2
->access
;
39 if (access1
!= access2
)
41 for (pos
= 0; pos
< USERACCESS_SIZE
; pos
++)
43 if ((access1
&(1<<pos
)) && (access2
&(1<<pos
)))
45 if ((access1
&(1<<pos
)) && !(access2
&(1<<pos
)))
47 if (!(access1
&(1<<pos
)) && (access2
&(1<<pos
)))
52 return serv
->p_cmp (user1
->nick
, user2
->nick
);
56 nick_cmp_alpha (struct User
*user1
, struct User
*user2
, server
*serv
)
58 return serv
->p_cmp (user1
->nick
, user2
->nick
);
62 nick_cmp (struct User
*user1
, struct User
*user2
, server
*serv
)
64 switch (prefs
.userlist_sort
)
67 return nick_cmp_az_ops (serv
, user1
, user2
);
69 return serv
->p_cmp (user1
->nick
, user2
->nick
);
71 return -1 * nick_cmp_az_ops (serv
, user1
, user2
);
73 return -1 * serv
->p_cmp (user1
->nick
, user2
->nick
);
80 insert name in appropriate place in linked list. Returns row number or:
85 userlist_insertname (session
*sess
, struct User
*newuser
)
89 sess
->usertree
= tree_new ((tree_cmp_func
*)nick_cmp
, sess
->server
);
90 sess
->usertree_alpha
= tree_new ((tree_cmp_func
*)nick_cmp_alpha
, sess
->server
);
93 tree_insert (sess
->usertree_alpha
, newuser
);
94 return tree_insert (sess
->usertree
, newuser
);
98 userlist_set_away (struct session
*sess
, char *nick
, unsigned int away
)
102 user
= userlist_find (sess
, nick
);
105 if (user
->away
!= away
)
109 fe_userlist_rehash (sess
, user
);
111 fe_userlist_update (sess
, user
);
117 userlist_add_hostname (struct session
*sess
, char *nick
, char *hostname
,
118 char *realname
, char *servername
, unsigned int away
)
122 user
= userlist_find (sess
, nick
);
125 if (!user
->hostname
&& hostname
)
126 user
->hostname
= strdup (hostname
);
127 if (!user
->realname
&& realname
)
128 user
->realname
= strdup (realname
);
129 if (!user
->servername
&& servername
)
130 user
->servername
= strdup (servername
);
134 if (prefs
.showhostname_in_userlist
|| user
->away
!= away
)
137 fe_userlist_rehash (sess
, user
);
142 fe_userlist_update (sess
, user
);
150 free_user (struct User
*user
, gpointer data
)
153 free (user
->realname
);
155 free (user
->hostname
);
156 if (user
->servername
)
157 free (user
->servername
);
164 userlist_free (session
*sess
)
166 tree_foreach (sess
->usertree
, (tree_traverse_func
*)free_user
, NULL
);
167 tree_destroy (sess
->usertree
);
168 tree_destroy (sess
->usertree_alpha
);
170 sess
->usertree
= NULL
;
171 sess
->usertree_alpha
= NULL
;
181 userlist_clear (session
*sess
)
183 fe_userlist_clear (sess
);
184 userlist_free (sess
);
185 fe_userlist_numbers (sess
);
189 find_cmp (const char *name
, struct User
*user
, server
*serv
)
191 return serv
->p_cmp ((char *)name
, user
->nick
);
195 userlist_find (struct session
*sess
, char *name
)
199 if (sess
->usertree_alpha
)
200 return tree_find (sess
->usertree_alpha
, name
,
201 (tree_cmp_func
*)find_cmp
, sess
->server
, &pos
);
207 userlist_find_global (struct server
*serv
, char *name
)
211 GSList
*list
= sess_list
;
214 sess
= (session
*) list
->data
;
215 if (sess
->server
== serv
)
217 user
= userlist_find (sess
, name
);
227 update_counts (session
*sess
, struct User
*user
, char prefix
,
228 int level
, int offset
)
238 sess
->hops
+= offset
;
242 sess
->voices
+= offset
;
248 userlist_update_mode (session
*sess
, char *name
, char mode
, char sign
)
257 user
= userlist_find (sess
, name
);
261 /* remove from binary trees, before we loose track of it */
262 tree_remove (sess
->usertree
, user
, &pos
);
263 tree_remove (sess
->usertree_alpha
, user
, &pos
);
265 /* which bit number is affected? */
266 access
= mode_access (sess
->server
, mode
, &prefix
);
271 if (!(user
->access
& (1 << access
)))
274 user
->access
|= (1 << access
);
279 if (user
->access
& (1 << access
))
282 user
->access
&= ~(1 << access
);
286 /* now what is this users highest prefix? e.g. @ for ops */
287 user
->prefix
[0] = get_nick_prefix (sess
->server
, user
->access
);
289 /* update the various counts using the CHANGED prefix only */
290 update_counts (sess
, user
, prefix
, level
, offset
);
292 /* insert it back into its new place */
293 tree_insert (sess
->usertree_alpha
, user
);
294 pos
= tree_insert (sess
->usertree
, user
);
296 /* let GTK move it too */
297 fe_userlist_move (sess
, user
, pos
);
298 fe_userlist_numbers (sess
);
302 userlist_change (struct session
*sess
, char *oldname
, char *newname
)
304 struct User
*user
= userlist_find (sess
, oldname
);
309 tree_remove (sess
->usertree
, user
, &pos
);
310 tree_remove (sess
->usertree_alpha
, user
, &pos
);
312 safe_strcpy (user
->nick
, newname
, NICKLEN
);
314 tree_insert (sess
->usertree_alpha
, user
);
316 fe_userlist_move (sess
, user
, tree_insert (sess
->usertree
, user
));
317 fe_userlist_numbers (sess
);
326 userlist_remove (struct session
*sess
, char *name
)
330 user
= userlist_find (sess
, name
);
334 userlist_remove_user (sess
, user
);
339 userlist_remove_user (struct session
*sess
, struct User
*user
)
349 fe_userlist_numbers (sess
);
350 fe_userlist_remove (sess
, user
);
352 if (user
== sess
->me
)
355 tree_remove (sess
->usertree
, user
, &pos
);
356 tree_remove (sess
->usertree_alpha
, user
, &pos
);
357 free_user (user
, NULL
);
361 userlist_add (struct session
*sess
, char *name
, char *hostname
)
364 int row
, prefix_chars
;
367 acc
= nick_access (sess
->server
, name
, &prefix_chars
);
369 notify_set_online (sess
->server
, name
+ prefix_chars
);
371 user
= malloc (sizeof (struct User
));
372 memset (user
, 0, sizeof (struct User
));
376 /* assume first char is the highest level nick prefix */
378 user
->prefix
[0] = name
[0];
380 /* add it to our linked list */
382 user
->hostname
= strdup (hostname
);
383 safe_strcpy (user
->nick
, name
+ prefix_chars
, NICKLEN
);
385 if (!sess
->server
->p_cmp (user
->nick
, sess
->server
->nick
))
387 row
= userlist_insertname (sess
, user
);
389 /* duplicate? some broken servers trigger this */
393 free (user
->hostname
);
400 /* most ircds don't support multiple modechars infront of the nickname
401 for /NAMES - though they should. */
404 update_counts (sess
, user
, name
[0], TRUE
, 1);
412 fe_userlist_insert (sess
, user
, row
, FALSE
);
413 fe_userlist_numbers (sess
);
417 rehash_cb (struct User
*user
, session
*sess
)
419 fe_userlist_rehash (sess
, user
);
424 userlist_rehash (session
*sess
)
426 tree_foreach (sess
->usertree_alpha
, (tree_traverse_func
*)rehash_cb
, sess
);
430 flat_cb (struct User
*user
, GSList
**list
)
432 *list
= g_slist_prepend (*list
, user
);
437 userlist_flat_list (session
*sess
)
441 tree_foreach (sess
->usertree_alpha
, (tree_traverse_func
*)flat_cb
, &list
);
442 return g_slist_reverse (list
);
446 double_cb (struct User
*user
, GList
**list
)
448 *list
= g_list_prepend(*list
, user
);
453 userlist_double_list(session
*sess
)
457 tree_foreach (sess
->usertree_alpha
, (tree_traverse_func
*)double_cb
, &list
);