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_set_account (struct session
*sess
, char *nick
, char *account
)
121 user
= userlist_find (sess
, nick
);
125 free (user
->account
);
127 if (strcmp (account
, "*") == 0)
128 user
->account
= NULL
;
130 user
->account
= strdup (account
);
132 /* gui doesnt currently reflect login status, maybe later
133 fe_userlist_rehash (sess, user); */
138 userlist_add_hostname (struct session
*sess
, char *nick
, char *hostname
,
139 char *realname
, char *servername
, char *account
, unsigned int away
)
143 user
= userlist_find (sess
, nick
);
146 if (!user
->hostname
&& hostname
)
147 user
->hostname
= strdup (hostname
);
148 if (!user
->realname
&& realname
)
149 user
->realname
= strdup (realname
);
150 if (!user
->servername
&& servername
)
151 user
->servername
= strdup (servername
);
152 if (!user
->account
&& account
&& strcmp (account
, "0") != 0)
153 user
->account
= strdup (account
);
157 if (prefs
.showhostname_in_userlist
|| user
->away
!= away
)
160 fe_userlist_rehash (sess
, user
);
165 fe_userlist_update (sess
, user
);
173 free_user (struct User
*user
, gpointer data
)
176 free (user
->realname
);
178 free (user
->hostname
);
179 if (user
->servername
)
180 free (user
->servername
);
182 free (user
->account
);
189 userlist_free (session
*sess
)
191 tree_foreach (sess
->usertree
, (tree_traverse_func
*)free_user
, NULL
);
192 tree_destroy (sess
->usertree
);
193 tree_destroy (sess
->usertree_alpha
);
195 sess
->usertree
= NULL
;
196 sess
->usertree_alpha
= NULL
;
206 userlist_clear (session
*sess
)
208 fe_userlist_clear (sess
);
209 userlist_free (sess
);
210 fe_userlist_numbers (sess
);
214 find_cmp (const char *name
, struct User
*user
, server
*serv
)
216 return serv
->p_cmp ((char *)name
, user
->nick
);
220 userlist_find (struct session
*sess
, char *name
)
224 if (sess
->usertree_alpha
)
225 return tree_find (sess
->usertree_alpha
, name
,
226 (tree_cmp_func
*)find_cmp
, sess
->server
, &pos
);
232 userlist_find_global (struct server
*serv
, char *name
)
236 GSList
*list
= sess_list
;
239 sess
= (session
*) list
->data
;
240 if (sess
->server
== serv
)
242 user
= userlist_find (sess
, name
);
252 update_counts (session
*sess
, struct User
*user
, char prefix
,
253 int level
, int offset
)
263 sess
->hops
+= offset
;
267 sess
->voices
+= offset
;
273 userlist_update_mode (session
*sess
, char *name
, char mode
, char sign
)
282 user
= userlist_find (sess
, name
);
286 /* remove from binary trees, before we loose track of it */
287 tree_remove (sess
->usertree
, user
, &pos
);
288 tree_remove (sess
->usertree_alpha
, user
, &pos
);
290 /* which bit number is affected? */
291 access
= mode_access (sess
->server
, mode
, &prefix
);
296 if (!(user
->access
& (1 << access
)))
299 user
->access
|= (1 << access
);
304 if (user
->access
& (1 << access
))
307 user
->access
&= ~(1 << access
);
311 /* now what is this users highest prefix? e.g. @ for ops */
312 user
->prefix
[0] = get_nick_prefix (sess
->server
, user
->access
);
314 /* update the various counts using the CHANGED prefix only */
315 update_counts (sess
, user
, prefix
, level
, offset
);
317 /* insert it back into its new place */
318 tree_insert (sess
->usertree_alpha
, user
);
319 pos
= tree_insert (sess
->usertree
, user
);
321 /* let GTK move it too */
322 fe_userlist_move (sess
, user
, pos
);
323 fe_userlist_numbers (sess
);
327 userlist_change (struct session
*sess
, char *oldname
, char *newname
)
329 struct User
*user
= userlist_find (sess
, oldname
);
334 tree_remove (sess
->usertree
, user
, &pos
);
335 tree_remove (sess
->usertree_alpha
, user
, &pos
);
337 safe_strcpy (user
->nick
, newname
, NICKLEN
);
339 tree_insert (sess
->usertree_alpha
, user
);
341 fe_userlist_move (sess
, user
, tree_insert (sess
->usertree
, user
));
342 fe_userlist_numbers (sess
);
351 userlist_remove (struct session
*sess
, char *name
)
355 user
= userlist_find (sess
, name
);
359 userlist_remove_user (sess
, user
);
364 userlist_remove_user (struct session
*sess
, struct User
*user
)
374 fe_userlist_numbers (sess
);
375 fe_userlist_remove (sess
, user
);
377 if (user
== sess
->me
)
380 tree_remove (sess
->usertree
, user
, &pos
);
381 tree_remove (sess
->usertree_alpha
, user
, &pos
);
382 free_user (user
, NULL
);
386 userlist_add (struct session
*sess
, char *name
, char *hostname
, char *account
, char *realname
)
389 int row
, prefix_chars
;
392 acc
= nick_access (sess
->server
, name
, &prefix_chars
);
394 notify_set_online (sess
->server
, name
+ prefix_chars
);
396 user
= malloc (sizeof (struct User
));
397 memset (user
, 0, sizeof (struct User
));
401 /* assume first char is the highest level nick prefix */
403 user
->prefix
[0] = name
[0];
405 /* add it to our linked list */
407 user
->hostname
= strdup (hostname
);
408 safe_strcpy (user
->nick
, name
+ prefix_chars
, NICKLEN
);
410 if (!sess
->server
->p_cmp (user
->nick
, sess
->server
->nick
))
412 /* extended join info */
413 if (sess
->server
->have_extjoin
)
415 if (account
&& strcmp (account
, "*") != 0)
416 user
->account
= strdup (account
);
418 user
->realname
= strdup (realname
);
421 row
= userlist_insertname (sess
, user
);
423 /* duplicate? some broken servers trigger this */
427 free (user
->hostname
);
429 free (user
->account
);
431 free (user
->realname
);
438 /* most ircds don't support multiple modechars infront of the nickname
439 for /NAMES - though they should. */
442 update_counts (sess
, user
, name
[0], TRUE
, 1);
450 fe_userlist_insert (sess
, user
, row
, FALSE
);
451 fe_userlist_numbers (sess
);
455 rehash_cb (struct User
*user
, session
*sess
)
457 fe_userlist_rehash (sess
, user
);
462 userlist_rehash (session
*sess
)
464 tree_foreach (sess
->usertree_alpha
, (tree_traverse_func
*)rehash_cb
, sess
);
468 flat_cb (struct User
*user
, GSList
**list
)
470 *list
= g_slist_prepend (*list
, user
);
475 userlist_flat_list (session
*sess
)
479 tree_foreach (sess
->usertree_alpha
, (tree_traverse_func
*)flat_cb
, &list
);
480 return g_slist_reverse (list
);
484 double_cb (struct User
*user
, GList
**list
)
486 *list
= g_list_prepend(*list
, user
);
491 userlist_double_list(session
*sess
)
495 tree_foreach (sess
->usertree_alpha
, (tree_traverse_func
*)double_cb
, &list
);