diff --git a/doc/RELEASE-NOTES.md b/doc/RELEASE-NOTES.md index 66072788d..682b8aab8 100644 --- a/doc/RELEASE-NOTES.md +++ b/doc/RELEASE-NOTES.md @@ -25,6 +25,7 @@ in progress and may not always be a stable version. * TODO ### Fixes: +* The whowasdb module caused `WHOWAS` entries to vanish (way too soon) * If your shell account only allowed very few file descriptors (eg: `ulimit -n` returned `150`), then UnrealIRCd would fail to boot. This, because due to reserved file descriptors you would have 0 left, or even a negative number. diff --git a/include/h.h b/include/h.h index b876a2c29..1b75dea19 100644 --- a/include/h.h +++ b/include/h.h @@ -445,6 +445,7 @@ extern void del_whowas_from_list(WhoWas **, WhoWas *); extern uint64_t hash_whowas_name(const char *name); extern void create_whowas_entry(Client *client, WhoWas *e, WhoWasEvent event); extern void free_whowas_fields(WhoWas *e); +extern void free_whowas_entry(WhoWas *e); extern int add_to_client_hash_table(const char *, Client *); extern int del_from_client_hash_table(const char *, Client *); extern int add_to_id_hash_table(const char *, Client *); diff --git a/src/modules/whowasdb.c b/src/modules/whowasdb.c index 8b4e8ddf9..cd0fe2100 100644 --- a/src/modules/whowasdb.c +++ b/src/modules/whowasdb.c @@ -588,9 +588,12 @@ int read_whowasdb(void) if (nick && username && hostname && realname) { + /* This is basically duplicating the code from create_whowas_entry() in src/whowas.c. + * But we have no choice, as we can't use that function since we don't have a Client *. + */ WhoWas *e = &WHOWAS[whowas_next]; if (e->hashv != -1) - free_whowas_fields(e); + free_whowas_entry(e); /* Set values */ //unreal_log(ULOG_DEBUG, "whowasdb", "WHOWASDB_READ_RECORD", NULL, // "[whowasdb] Adding '$nick'...", diff --git a/src/whowas.c b/src/whowas.c index 6890c1edd..1b859d9b1 100644 --- a/src/whowas.c +++ b/src/whowas.c @@ -33,6 +33,11 @@ WhoWas MODVAR *WHOWASHASH[WHOWAS_HASH_TABLE_SIZE]; MODVAR int whowas_next = 0; +/** Free all the fields previously created by create_whowas_entry(). + * NOTE: normally you want to call free_whowas_entry(). + * Calling this free_whowas_fields() function is unusual and mainly + * for whowasdb which temporarily adds and removes entries. + */ void free_whowas_fields(WhoWas *e) { safe_free(e->name); @@ -47,12 +52,17 @@ void free_whowas_fields(WhoWas *e) e->logon = 0; e->logoff = 0; e->connected_since = 0; + e->hashv = -1; +} - /* Remove from lists and reset hashv */ +/** Free whowas entry. This is the function you normally want to use. */ +void free_whowas_entry(WhoWas *e) +{ + int hashv = e->hashv; + free_whowas_fields(e); if (e->online) del_whowas_from_clist(&(e->online->user->whowas), e); - del_whowas_from_list(&WHOWASHASH[e->hashv], e); - e->hashv = -1; + del_whowas_from_list(&WHOWASHASH[hashv], e); } void create_whowas_entry(Client *client, WhoWas *e, WhoWasEvent event) @@ -90,7 +100,7 @@ void add_history(Client *client, int online, WhoWasEvent event) new = &WHOWAS[whowas_next]; if (new->hashv != -1) - free_whowas_fields(new); + free_whowas_entry(new); create_whowas_entry(client, new, event);