From b2a282feaa271c10295fb351f48d3fd3a4665ec4 Mon Sep 17 00:00:00 2001 From: Kevin Easton Date: Fri, 16 Oct 2009 12:35:56 +0000 Subject: [PATCH] Fix a refcounting issue in the whowas list handling. When a user in one of the whowas lists rejoins, their entry is removed from the whowas list (and added to a channel nicklist). However the count of entries in the whowas list wasn't being decremented, so eventually the client thinks the lists are full when they're really empty... at this point only one user at a time can be in the lists (so /WHOLEFT after a netsplit would only show one user). git-svn-id: svn://svn.code.sf.net/p/bitchx/code/trunk@77 13b04d17-f746-0410-82c6-800466cd88b0 --- Changelog | 5 ++++- include/whowas.h | 8 ++++---- source/names.c | 2 +- source/whowas.c | 32 ++++++++++++++++++++++---------- 4 files changed, 31 insertions(+), 16 deletions(-) diff --git a/Changelog b/Changelog index 3452863..63c27d5 100644 --- a/Changelog +++ b/Changelog @@ -1,7 +1,10 @@ [Changes 1.2c01] +* Fix a refcounting issue in the whowas list handling, which should make + the listing of users that left in a netsplit right again. (caf) + * Improve argument-handling in /hostname command - now supports doing - /hostname 2 to switch to second vhost. + /hostname 2 to switch to second vhost. (caf) * Change the display of server stats so that the averages (eg. users per channel) are correctly rounded. (caf) diff --git a/include/whowas.h b/include/whowas.h index 97e9745..f157567 100644 --- a/include/whowas.h +++ b/include/whowas.h @@ -2,9 +2,9 @@ #ifndef _WhoWas_h #define _WhoWas_h -#define whowas_userlist_max 300 -#define whowas_reg_max 500 -#define whowas_chan_max 20 +#define WHOWAS_USERLIST_MAX 300 +#define WHOWAS_REG_MAX 500 +#define WHOWAS_CHAN_MAX 20 #include "hash.h" typedef struct _whowaschan_str { @@ -38,7 +38,7 @@ typedef struct _whowas_wrap_str { HashEntry NickListTable[WHOWASLIST_HASHSIZE]; } WhowasWrapList; -WhowasList *check_whowas_buffer (char *, char *, char *, int); +WhowasList *check_whowas_buffer (char *, char *, char *); WhowasList *check_whowas_nick_buffer (char *, char *, int); WhowasList *check_whosplitin_buffer (char *, char *, char *, int); diff --git a/source/names.c b/source/names.c index cda9bbf..d0e0f92 100644 --- a/source/names.c +++ b/source/names.c @@ -357,7 +357,7 @@ ChannelList *BX_add_to_channel(char *channel, char *nick, int server, int oper, if (!(new = find_nicklist_in_channellist(nick, chan, 0))) { - if (!(whowas = check_whowas_buffer(nick, userhost, channel, 1))) + if (!(whowas = check_whowas_buffer(nick, userhost, channel))) { new = (NickList *) new_malloc(sizeof(NickList)); diff --git a/source/whowas.c b/source/whowas.c index 3f35e39..e187f9e 100644 --- a/source/whowas.c +++ b/source/whowas.c @@ -57,11 +57,23 @@ static int whowas_userlist_count = 0; static int whowas_reg_count = 0; static int whowas_chan_count = 0; -extern WhowasList *check_whowas_buffer(char *nick, char *userhost, char *channel, int unlink) +extern WhowasList *check_whowas_buffer(char *nick, char *userhost, char *channel) { - WhowasList *tmp = NULL; - if (!(tmp = find_userhost_channel(userhost, channel, unlink, &whowas_userlist_list))) - tmp = find_userhost_channel(userhost, channel, unlink, &whowas_reg_list); + WhowasList *tmp; + + tmp = find_userhost_channel(userhost, channel, 1, &whowas_userlist_list); + if (tmp) + { + whowas_userlist_count--; + return tmp; + } + + tmp = find_userhost_channel(userhost, channel, 1, &whowas_reg_list); + if (tmp) + { + whowas_reg_count--; + } + return tmp; } @@ -111,11 +123,11 @@ void add_to_whowas_buffer(NickList *nicklist, char *channel, char *server1, char if (nicklist->userlist) { - if (whowas_userlist_count >= whowas_userlist_max) + if (whowas_userlist_count >= WHOWAS_USERLIST_MAX) { whowas_userlist_count -= remove_oldest_whowas(&whowas_userlist_list, 0, - (whowas_userlist_max + 1) - whowas_userlist_count); + (whowas_userlist_count + 1) - WHOWAS_USERLIST_MAX); } new = (WhowasList *) new_malloc(sizeof(WhowasList)); new->has_ops = nick_isop(nicklist); @@ -130,11 +142,11 @@ void add_to_whowas_buffer(NickList *nicklist, char *channel, char *server1, char } else { - if (whowas_reg_count >= whowas_reg_max) + if (whowas_reg_count >= WHOWAS_REG_MAX) { whowas_reg_count -= remove_oldest_whowas(&whowas_reg_list, 0, - (whowas_reg_max + 1) - whowas_reg_count); + (whowas_reg_count + 1) - WHOWAS_REG_MAX); } new = (WhowasList *) new_malloc(sizeof(WhowasList)); new->has_ops = nick_isop(nicklist); @@ -299,11 +311,11 @@ void add_to_whowas_chan_buffer(ChannelList *channel) WhowasChanList *new; WhowasChanList **slot; - if (whowas_chan_count >= whowas_chan_max) + if (whowas_chan_count >= WHOWAS_CHAN_MAX) { whowas_chan_count -= remove_oldest_chan_whowas(&whowas_chan_list, 0, - (whowas_chan_max + 1) - whowas_chan_count); + (whowas_chan_count + 1) - WHOWAS_CHAN_MAX); } new = (WhowasChanList *) new_malloc(sizeof(WhowasChanList));