ircd: import modified version of ratbox 3.1 whowas code
This commit is contained in:
parent
3de2266243
commit
b47f8a4fda
12 changed files with 205 additions and 195 deletions
|
@ -117,7 +117,8 @@ struct Client
|
||||||
struct Client *servptr; /* Points to server this Client is on */
|
struct Client *servptr; /* Points to server this Client is on */
|
||||||
struct Client *from; /* == self, if Local Client, *NEVER* NULL! */
|
struct Client *from; /* == self, if Local Client, *NEVER* NULL! */
|
||||||
|
|
||||||
struct Whowas *whowas; /* Pointers to whowas structs */
|
rb_dlink_list whowas_clist;
|
||||||
|
|
||||||
time_t tsinfo; /* TS on the nick, SVINFO on server */
|
time_t tsinfo; /* TS on the nick, SVINFO on server */
|
||||||
unsigned int umodes; /* opers, normal users subset */
|
unsigned int umodes; /* opers, normal users subset */
|
||||||
unsigned int flags; /* client flags */
|
unsigned int flags; /* client flags */
|
||||||
|
|
|
@ -131,7 +131,7 @@
|
||||||
#define NUMERIC_STR_366 ":%s 366 %s %s :End of /NAMES list."
|
#define NUMERIC_STR_366 ":%s 366 %s %s :End of /NAMES list."
|
||||||
#define NUMERIC_STR_367 ":%s 367 %s %s %s %s %lu"
|
#define NUMERIC_STR_367 ":%s 367 %s %s %s %s %lu"
|
||||||
#define NUMERIC_STR_368 ":%s 368 %s %s :End of Channel Ban List"
|
#define NUMERIC_STR_368 ":%s 368 %s %s :End of Channel Ban List"
|
||||||
#define NUMERIC_STR_369 ":%s 369 %s %s :End of WHOWAS"
|
#define NUMERIC_STR_369 "%s :End of WHOWAS"
|
||||||
#define NUMERIC_STR_371 ":%s"
|
#define NUMERIC_STR_371 ":%s"
|
||||||
#define NUMERIC_STR_372 ":%s 372 %s :- %s"
|
#define NUMERIC_STR_372 ":%s 372 %s :- %s"
|
||||||
#define NUMERIC_STR_374 ":End of /INFO list."
|
#define NUMERIC_STR_374 ":End of /INFO list."
|
||||||
|
@ -147,7 +147,7 @@
|
||||||
#define NUMERIC_STR_403 "%s :No such channel"
|
#define NUMERIC_STR_403 "%s :No such channel"
|
||||||
#define NUMERIC_STR_404 "%s :Cannot send to channel"
|
#define NUMERIC_STR_404 "%s :Cannot send to channel"
|
||||||
#define NUMERIC_STR_405 ":%s 405 %s %s :You have joined too many channels"
|
#define NUMERIC_STR_405 ":%s 405 %s %s :You have joined too many channels"
|
||||||
#define NUMERIC_STR_406 ":%s 406 %s %s :There was no such nickname"
|
#define NUMERIC_STR_406 ":%s :There was no such nickname"
|
||||||
#define NUMERIC_STR_407 ":%s 407 %s %s :Too many recipients."
|
#define NUMERIC_STR_407 ":%s 407 %s %s :Too many recipients."
|
||||||
#define NUMERIC_STR_409 ":%s 409 %s :No origin specified"
|
#define NUMERIC_STR_409 ":%s 409 %s :No origin specified"
|
||||||
#define NUMERIC_STR_410 ":%s 410 %s %s :Invalid CAP subcommand"
|
#define NUMERIC_STR_410 ":%s 410 %s %s :Invalid CAP subcommand"
|
||||||
|
|
|
@ -31,13 +31,6 @@
|
||||||
|
|
||||||
#include "setup.h"
|
#include "setup.h"
|
||||||
|
|
||||||
/*
|
|
||||||
* Whowas hash table size
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
#define WW_MAX_BITS 16
|
|
||||||
#define WW_MAX 65536
|
|
||||||
|
|
||||||
struct User;
|
struct User;
|
||||||
struct Client;
|
struct Client;
|
||||||
|
|
||||||
|
@ -48,7 +41,10 @@ struct Client;
|
||||||
*/
|
*/
|
||||||
struct Whowas
|
struct Whowas
|
||||||
{
|
{
|
||||||
int hashv;
|
struct whowas_top *wtop;
|
||||||
|
rb_dlink_node wnode; /* for the wtop linked list */
|
||||||
|
rb_dlink_node cnode; /* node for online clients */
|
||||||
|
rb_dlink_node whowas_node; /* node for the whowas linked list */
|
||||||
char name[NICKLEN + 1];
|
char name[NICKLEN + 1];
|
||||||
char username[USERLEN + 1];
|
char username[USERLEN + 1];
|
||||||
char hostname[HOSTLEN + 1];
|
char hostname[HOSTLEN + 1];
|
||||||
|
@ -59,10 +55,6 @@ struct Whowas
|
||||||
const char *servername;
|
const char *servername;
|
||||||
time_t logoff;
|
time_t logoff;
|
||||||
struct Client *online; /* Pointer to new nickname for chasing or NULL */
|
struct Client *online; /* Pointer to new nickname for chasing or NULL */
|
||||||
struct Whowas *next; /* for hash table... */
|
|
||||||
struct Whowas *prev; /* for hash table... */
|
|
||||||
struct Whowas *cnext; /* for client struct linked list */
|
|
||||||
struct Whowas *cprev; /* for client struct linked list */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Flags */
|
/* Flags */
|
||||||
|
@ -72,7 +64,7 @@ struct Whowas
|
||||||
/*
|
/*
|
||||||
** initwhowas
|
** initwhowas
|
||||||
*/
|
*/
|
||||||
extern void initwhowas(void);
|
extern void whowas_init(void);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** add_history
|
** add_history
|
||||||
|
@ -81,7 +73,7 @@ extern void initwhowas(void);
|
||||||
** Client must be a fully registered user (specifically,
|
** Client must be a fully registered user (specifically,
|
||||||
** the user structure must have been allocated).
|
** the user structure must have been allocated).
|
||||||
*/
|
*/
|
||||||
void add_history(struct Client *, int);
|
void whowas_add_history(struct Client *, int);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** off_history
|
** off_history
|
||||||
|
@ -90,7 +82,7 @@ void add_history(struct Client *, int);
|
||||||
** structures and it must know when they cease to exist. This
|
** structures and it must know when they cease to exist. This
|
||||||
** also implicitly calls AddHistory.
|
** also implicitly calls AddHistory.
|
||||||
*/
|
*/
|
||||||
void off_history(struct Client *);
|
void whowas_off_history(struct Client *);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** get_history
|
** get_history
|
||||||
|
@ -98,18 +90,12 @@ void off_history(struct Client *);
|
||||||
** nickname within the timelimit. Returns NULL, if no
|
** nickname within the timelimit. Returns NULL, if no
|
||||||
** one found...
|
** one found...
|
||||||
*/
|
*/
|
||||||
struct Client *get_history(const char *, time_t);
|
struct Client *whowas_get_history(const char *, time_t);
|
||||||
/* Nick name */
|
/* Nick name */
|
||||||
/* Time limit in seconds */
|
/* Time limit in seconds */
|
||||||
|
|
||||||
/*
|
rb_dlink_list *whowas_get_list(const char *name);
|
||||||
** for debugging...counts related structures stored in whowas array.
|
void whowas_set_size(int whowas_length);
|
||||||
*/
|
void whowas_memory_usage(size_t *count, size_t *memused);
|
||||||
void count_whowas_memory(size_t *, size_t *);
|
|
||||||
|
|
||||||
/* XXX m_whowas.c in modules needs these */
|
|
||||||
extern struct Whowas WHOWAS[];
|
|
||||||
extern struct Whowas *WHOWASHASH[];
|
|
||||||
extern unsigned int hash_whowas_name(const char *name);
|
|
||||||
|
|
||||||
#endif /* INCLUDED_whowas_h */
|
#endif /* INCLUDED_whowas_h */
|
||||||
|
|
|
@ -672,7 +672,7 @@ resv_nick_fnc(const char *mask, const char *reason, int temp_time)
|
||||||
|
|
||||||
/* Do all of the nick-changing gymnastics. */
|
/* Do all of the nick-changing gymnastics. */
|
||||||
client_p->tsinfo = rb_current_time();
|
client_p->tsinfo = rb_current_time();
|
||||||
add_history(client_p, 1);
|
whowas_add_history(client_p, 1);
|
||||||
|
|
||||||
monitor_signoff(client_p);
|
monitor_signoff(client_p);
|
||||||
|
|
||||||
|
@ -872,7 +872,7 @@ find_chasing(struct Client *source_p, const char *user, int *chasing)
|
||||||
if(who || IsDigit(*user))
|
if(who || IsDigit(*user))
|
||||||
return who;
|
return who;
|
||||||
|
|
||||||
if(!(who = get_history(user, (long) KILLCHASETIMELIMIT)))
|
if(!(who = whowas_get_history(user, (long) KILLCHASETIMELIMIT)))
|
||||||
{
|
{
|
||||||
sendto_one_numeric(source_p, ERR_NOSUCHNICK,
|
sendto_one_numeric(source_p, ERR_NOSUCHNICK,
|
||||||
form_str(ERR_NOSUCHNICK), user);
|
form_str(ERR_NOSUCHNICK), user);
|
||||||
|
@ -1247,8 +1247,8 @@ exit_generic_client(struct Client *client_p, struct Client *source_p, struct Cli
|
||||||
/* Clean up allow lists */
|
/* Clean up allow lists */
|
||||||
del_all_accepts(source_p);
|
del_all_accepts(source_p);
|
||||||
|
|
||||||
add_history(source_p, 0);
|
whowas_add_history(source_p, 0);
|
||||||
off_history(source_p);
|
whowas_off_history(source_p);
|
||||||
|
|
||||||
monitor_signoff(source_p);
|
monitor_signoff(source_p);
|
||||||
|
|
||||||
|
|
|
@ -653,7 +653,7 @@ charybdis_main(int argc, char *argv[])
|
||||||
init_hook();
|
init_hook();
|
||||||
init_channels();
|
init_channels();
|
||||||
initclass();
|
initclass();
|
||||||
initwhowas();
|
whowas_init();
|
||||||
init_reject();
|
init_reject();
|
||||||
init_cache();
|
init_cache();
|
||||||
init_monitor();
|
init_monitor();
|
||||||
|
|
|
@ -1513,7 +1513,7 @@ change_nick_user_host(struct Client *target_p, const char *nick, const char *use
|
||||||
rb_strlcpy(target_p->host, host, sizeof target_p->host);
|
rb_strlcpy(target_p->host, host, sizeof target_p->host);
|
||||||
|
|
||||||
if (changed)
|
if (changed)
|
||||||
add_history(target_p, 1);
|
whowas_add_history(target_p, 1);
|
||||||
|
|
||||||
del_from_client_hash(target_p->name, target_p);
|
del_from_client_hash(target_p->name, target_p);
|
||||||
rb_strlcpy(target_p->name, nick, NICKLEN);
|
rb_strlcpy(target_p->name, nick, NICKLEN);
|
||||||
|
|
246
ircd/whowas.c
246
ircd/whowas.c
|
@ -4,7 +4,8 @@
|
||||||
*
|
*
|
||||||
* Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
|
* Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
|
||||||
* Copyright (C) 1996-2002 Hybrid Development Team
|
* Copyright (C) 1996-2002 Hybrid Development Team
|
||||||
* Copyright (C) 2002-2005 ircd-ratbox development team
|
* Copyright (C) 2002-2012 ircd-ratbox development team
|
||||||
|
* Copyright (C) 2016 William Pitcock <nenolod@dereferenced.org>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -18,178 +19,203 @@
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
|
||||||
* USA
|
* USA
|
||||||
*
|
|
||||||
* $Id: whowas.c 1717 2006-07-04 14:41:11Z jilles $
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "stdinc.h"
|
#include "stdinc.h"
|
||||||
|
|
||||||
#include "whowas.h"
|
|
||||||
#include "client.h"
|
|
||||||
#include "common.h"
|
|
||||||
#include "hash.h"
|
#include "hash.h"
|
||||||
|
#include "whowas.h"
|
||||||
#include "match.h"
|
#include "match.h"
|
||||||
#include "ircd.h"
|
#include "ircd.h"
|
||||||
#include "ircd_defs.h"
|
|
||||||
#include "numeric.h"
|
#include "numeric.h"
|
||||||
|
#include "s_assert.h"
|
||||||
#include "s_serv.h"
|
#include "s_serv.h"
|
||||||
#include "s_user.h"
|
#include "s_user.h"
|
||||||
#include "send.h"
|
#include "send.h"
|
||||||
#include "s_conf.h"
|
#include "s_conf.h"
|
||||||
|
#include "client.h"
|
||||||
|
#include "send.h"
|
||||||
|
#include "logger.h"
|
||||||
#include "scache.h"
|
#include "scache.h"
|
||||||
#include "s_assert.h"
|
#include "irc_radixtree.h"
|
||||||
|
|
||||||
/* internally defined function */
|
struct whowas_top
|
||||||
static void add_whowas_to_clist(struct Whowas **, struct Whowas *);
|
|
||||||
static void del_whowas_from_clist(struct Whowas **, struct Whowas *);
|
|
||||||
static void add_whowas_to_list(struct Whowas **, struct Whowas *);
|
|
||||||
static void del_whowas_from_list(struct Whowas **, struct Whowas *);
|
|
||||||
|
|
||||||
struct Whowas WHOWAS[NICKNAMEHISTORYLENGTH];
|
|
||||||
struct Whowas *WHOWASHASH[WW_MAX];
|
|
||||||
|
|
||||||
static int whowas_next = 0;
|
|
||||||
|
|
||||||
unsigned int hash_whowas_name(const char *name)
|
|
||||||
{
|
{
|
||||||
return fnv_hash_upper((const unsigned char *) name, WW_MAX_BITS);
|
char *name;
|
||||||
|
rb_dlink_list wwlist;
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct irc_radixtree *whowas_tree = NULL;
|
||||||
|
static rb_dlink_list whowas_list = {NULL, NULL, 0};
|
||||||
|
static unsigned int whowas_list_length = NICKNAMEHISTORYLENGTH;
|
||||||
|
static void whowas_trim(void *unused);
|
||||||
|
|
||||||
|
static void
|
||||||
|
whowas_free_wtop(struct whowas_top *wtop)
|
||||||
|
{
|
||||||
|
if(rb_dlink_list_length(&wtop->wwlist) == 0)
|
||||||
|
{
|
||||||
|
irc_radixtree_delete(whowas_tree, wtop->name);
|
||||||
|
rb_free(wtop->name);
|
||||||
|
rb_free(wtop);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void add_history(struct Client *client_p, int online)
|
static struct whowas_top *
|
||||||
|
whowas_get_top(const char *name)
|
||||||
{
|
{
|
||||||
struct Whowas *who = &WHOWAS[whowas_next];
|
struct whowas_top *wtop;
|
||||||
|
|
||||||
|
wtop = irc_radixtree_retrieve(whowas_tree, name);
|
||||||
|
if (wtop != NULL)
|
||||||
|
return wtop;
|
||||||
|
|
||||||
|
wtop = rb_malloc(sizeof(struct whowas_top));
|
||||||
|
wtop->name = rb_strdup(name);
|
||||||
|
irc_radixtree_add(whowas_tree, wtop->name, wtop);
|
||||||
|
|
||||||
|
return wtop;
|
||||||
|
}
|
||||||
|
|
||||||
|
rb_dlink_list *
|
||||||
|
whowas_get_list(const char *name)
|
||||||
|
{
|
||||||
|
struct whowas_top *wtop;
|
||||||
|
wtop = irc_radixtree_retrieve(whowas_tree, name);
|
||||||
|
if(wtop == NULL)
|
||||||
|
return NULL;
|
||||||
|
return &wtop->wwlist;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
whowas_add_history(struct Client *client_p, int online)
|
||||||
|
{
|
||||||
|
struct whowas_top *wtop;
|
||||||
|
struct Whowas *who;
|
||||||
s_assert(NULL != client_p);
|
s_assert(NULL != client_p);
|
||||||
|
|
||||||
if(client_p == NULL)
|
if(client_p == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if(who->hashv != -1)
|
/* trim some of the entries if we're getting well over our history length */
|
||||||
{
|
if(rb_dlink_list_length(&whowas_list) > whowas_list_length + 100)
|
||||||
if(who->online)
|
whowas_trim(NULL);
|
||||||
del_whowas_from_clist(&(who->online->whowas), who);
|
|
||||||
del_whowas_from_list(&WHOWASHASH[who->hashv], who);
|
wtop = whowas_get_top(client_p->name);
|
||||||
}
|
who = rb_malloc(sizeof(struct Whowas));
|
||||||
who->hashv = hash_whowas_name(client_p->name);
|
who->wtop = wtop;
|
||||||
who->logoff = rb_current_time();
|
who->logoff = rb_current_time();
|
||||||
/*
|
|
||||||
* NOTE: strcpy ok here, the sizes in the client struct MUST
|
|
||||||
* match the sizes in the whowas struct
|
|
||||||
*/
|
|
||||||
rb_strlcpy(who->name, client_p->name, sizeof(who->name));
|
rb_strlcpy(who->name, client_p->name, sizeof(who->name));
|
||||||
strcpy(who->username, client_p->username);
|
rb_strlcpy(who->username, client_p->username, sizeof(who->username));
|
||||||
strcpy(who->hostname, client_p->host);
|
rb_strlcpy(who->hostname, client_p->host, sizeof(who->hostname));
|
||||||
strcpy(who->realname, client_p->info);
|
rb_strlcpy(who->realname, client_p->info, sizeof(who->realname));
|
||||||
strcpy(who->suser, client_p->user->suser);
|
rb_strlcpy(who->sockhost, client_p->sockhost, sizeof(who->sockhost));
|
||||||
strcpy(who->sockhost, client_p->sockhost);
|
|
||||||
who->flags = (IsIPSpoof(client_p) ? WHOWAS_IP_SPOOFING : 0) |
|
who->flags = (IsIPSpoof(client_p) ? WHOWAS_IP_SPOOFING : 0) |
|
||||||
(IsDynSpoof(client_p) ? WHOWAS_DYNSPOOF : 0);
|
(IsDynSpoof(client_p) ? WHOWAS_DYNSPOOF : 0);
|
||||||
|
|
||||||
|
/* this is safe do to with the servername cache */
|
||||||
who->servername = scache_get_name(client_p->servptr->serv->nameinfo);
|
who->servername = scache_get_name(client_p->servptr->serv->nameinfo);
|
||||||
|
|
||||||
if(online)
|
if(online)
|
||||||
{
|
{
|
||||||
who->online = client_p;
|
who->online = client_p;
|
||||||
add_whowas_to_clist(&(client_p->whowas), who);
|
rb_dlinkAdd(who, &who->cnode, &client_p->whowas_clist);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
who->online = NULL;
|
who->online = NULL;
|
||||||
add_whowas_to_list(&WHOWASHASH[who->hashv], who);
|
|
||||||
whowas_next++;
|
rb_dlinkAdd(who, &who->wnode, &wtop->wwlist);
|
||||||
if(whowas_next == NICKNAMEHISTORYLENGTH)
|
rb_dlinkAdd(who, &who->whowas_node, &whowas_list);
|
||||||
whowas_next = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void off_history(struct Client *client_p)
|
|
||||||
{
|
|
||||||
struct Whowas *temp, *next;
|
|
||||||
|
|
||||||
for (temp = client_p->whowas; temp; temp = next)
|
void
|
||||||
|
whowas_off_history(struct Client *client_p)
|
||||||
|
{
|
||||||
|
rb_dlink_node *ptr, *next;
|
||||||
|
|
||||||
|
RB_DLINK_FOREACH_SAFE(ptr, next, client_p->whowas_clist.head)
|
||||||
{
|
{
|
||||||
next = temp->cnext;
|
struct Whowas *who = ptr->data;
|
||||||
temp->online = NULL;
|
who->online = NULL;
|
||||||
del_whowas_from_clist(&(client_p->whowas), temp);
|
rb_dlinkDelete(&who->cnode, &client_p->whowas_clist);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Client *get_history(const char *nick, time_t timelimit)
|
struct Client *
|
||||||
|
whowas_get_history(const char *nick, time_t timelimit)
|
||||||
{
|
{
|
||||||
struct Whowas *temp;
|
struct whowas_top *wtop;
|
||||||
int blah;
|
rb_dlink_node *ptr;
|
||||||
|
|
||||||
|
wtop = irc_radixtree_retrieve(whowas_tree, nick);
|
||||||
|
if(wtop == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
timelimit = rb_current_time() - timelimit;
|
timelimit = rb_current_time() - timelimit;
|
||||||
blah = hash_whowas_name(nick);
|
|
||||||
temp = WHOWASHASH[blah];
|
RB_DLINK_FOREACH_PREV(ptr, wtop->wwlist.tail)
|
||||||
for (; temp; temp = temp->next)
|
|
||||||
{
|
{
|
||||||
if(irccmp(nick, temp->name))
|
struct Whowas *who = ptr->data;
|
||||||
continue;
|
if(who->logoff >= timelimit)
|
||||||
if(temp->logoff < timelimit)
|
{
|
||||||
continue;
|
return who->online;
|
||||||
return temp->online;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void count_whowas_memory(size_t * wwu, size_t * wwum)
|
static void
|
||||||
|
whowas_trim(void *unused)
|
||||||
{
|
{
|
||||||
*wwu = NICKNAMEHISTORYLENGTH;
|
long over;
|
||||||
*wwum = NICKNAMEHISTORYLENGTH * sizeof(struct Whowas);
|
|
||||||
|
if(rb_dlink_list_length(&whowas_list) < whowas_list_length)
|
||||||
|
return;
|
||||||
|
over = rb_dlink_list_length(&whowas_list) - whowas_list_length;
|
||||||
|
|
||||||
|
/* remove whowas entries over the configured length */
|
||||||
|
for(long i = 0; i < over; i++)
|
||||||
|
{
|
||||||
|
if(whowas_list.tail != NULL && whowas_list.tail->data != NULL)
|
||||||
|
{
|
||||||
|
struct Whowas *twho = whowas_list.tail->data;
|
||||||
|
if(twho->online != NULL)
|
||||||
|
rb_dlinkDelete(&twho->cnode, &twho->online->whowas_clist);
|
||||||
|
rb_dlinkDelete(&twho->wnode, &twho->wtop->wwlist);
|
||||||
|
rb_dlinkDelete(&twho->whowas_node, &whowas_list);
|
||||||
|
whowas_free_wtop(twho->wtop);
|
||||||
|
rb_free(twho);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
initwhowas()
|
whowas_init(void)
|
||||||
{
|
{
|
||||||
int i;
|
whowas_tree = irc_radixtree_create("whowas", irc_radixtree_irccasecanon);
|
||||||
|
if(whowas_list_length == 0)
|
||||||
for (i = 0; i < NICKNAMEHISTORYLENGTH; i++)
|
|
||||||
{
|
{
|
||||||
memset((void *) &WHOWAS[i], 0, sizeof(struct Whowas));
|
whowas_list_length = NICKNAMEHISTORYLENGTH;
|
||||||
WHOWAS[i].hashv = -1;
|
|
||||||
}
|
}
|
||||||
for (i = 0; i < WW_MAX; i++)
|
rb_event_add("whowas_trim", whowas_trim, NULL, 10);
|
||||||
WHOWASHASH[i] = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
static void
|
whowas_set_size(int len)
|
||||||
add_whowas_to_clist(struct Whowas **bucket, struct Whowas *whowas)
|
|
||||||
{
|
{
|
||||||
whowas->cprev = NULL;
|
whowas_list_length = len;
|
||||||
if((whowas->cnext = *bucket) != NULL)
|
whowas_trim(NULL);
|
||||||
whowas->cnext->cprev = whowas;
|
|
||||||
*bucket = whowas;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
void
|
||||||
del_whowas_from_clist(struct Whowas **bucket, struct Whowas *whowas)
|
whowas_memory_usage(size_t * count, size_t * memused)
|
||||||
{
|
{
|
||||||
if(whowas->cprev)
|
*count = rb_dlink_list_length(&whowas_list);
|
||||||
whowas->cprev->cnext = whowas->cnext;
|
*memused += *count * sizeof(struct Whowas);
|
||||||
else
|
*memused += sizeof(struct whowas_top) * irc_radixtree_size(whowas_tree);
|
||||||
*bucket = whowas->cnext;
|
|
||||||
if(whowas->cnext)
|
|
||||||
whowas->cnext->cprev = whowas->cprev;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
add_whowas_to_list(struct Whowas **bucket, struct Whowas *whowas)
|
|
||||||
{
|
|
||||||
whowas->prev = NULL;
|
|
||||||
if((whowas->next = *bucket) != NULL)
|
|
||||||
whowas->next->prev = whowas;
|
|
||||||
*bucket = whowas;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
del_whowas_from_list(struct Whowas **bucket, struct Whowas *whowas)
|
|
||||||
{
|
|
||||||
if(whowas->prev)
|
|
||||||
whowas->prev->next = whowas->next;
|
|
||||||
else
|
|
||||||
*bucket = whowas->next;
|
|
||||||
if(whowas->next)
|
|
||||||
whowas->next->prev = whowas->prev;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -102,7 +102,7 @@ mo_kill(struct Client *client_p, struct Client *source_p, int parc, const char *
|
||||||
** rewrite the KILL for this new nickname--this keeps
|
** rewrite the KILL for this new nickname--this keeps
|
||||||
** servers in synch when nick change and kill collide
|
** servers in synch when nick change and kill collide
|
||||||
*/
|
*/
|
||||||
if((target_p = get_history(user, (long) KILLCHASETIMELIMIT)) == NULL)
|
if((target_p = whowas_get_history(user, (long) KILLCHASETIMELIMIT)) == NULL)
|
||||||
{
|
{
|
||||||
if (strchr(user, '.'))
|
if (strchr(user, '.'))
|
||||||
sendto_one_numeric(source_p, ERR_CANTKILLSERVER, form_str(ERR_CANTKILLSERVER));
|
sendto_one_numeric(source_p, ERR_CANTKILLSERVER, form_str(ERR_CANTKILLSERVER));
|
||||||
|
@ -221,7 +221,7 @@ ms_kill(struct Client *client_p, struct Client *source_p, int parc, const char *
|
||||||
* not an uid, automatically rewrite the KILL for this new nickname.
|
* not an uid, automatically rewrite the KILL for this new nickname.
|
||||||
* --this keeps servers in synch when nick change and kill collide
|
* --this keeps servers in synch when nick change and kill collide
|
||||||
*/
|
*/
|
||||||
if(IsDigit(*user) || (!(target_p = get_history(user, (long) KILLCHASETIMELIMIT))))
|
if(IsDigit(*user) || (!(target_p = whowas_get_history(user, (long) KILLCHASETIMELIMIT))))
|
||||||
{
|
{
|
||||||
sendto_one_numeric(source_p, ERR_NOSUCHNICK,
|
sendto_one_numeric(source_p, ERR_NOSUCHNICK,
|
||||||
form_str(ERR_NOSUCHNICK), IsDigit(*user) ? "*" : user);
|
form_str(ERR_NOSUCHNICK), IsDigit(*user) ? "*" : user);
|
||||||
|
|
|
@ -685,7 +685,7 @@ change_local_nick(struct Client *client_p, struct Client *source_p,
|
||||||
/* send the nick change to servers.. */
|
/* send the nick change to servers.. */
|
||||||
if(source_p->user)
|
if(source_p->user)
|
||||||
{
|
{
|
||||||
add_history(source_p, 1);
|
whowas_add_history(source_p, 1);
|
||||||
|
|
||||||
if (dosend)
|
if (dosend)
|
||||||
{
|
{
|
||||||
|
@ -745,7 +745,7 @@ change_remote_nick(struct Client *client_p, struct Client *source_p,
|
||||||
|
|
||||||
if(source_p->user)
|
if(source_p->user)
|
||||||
{
|
{
|
||||||
add_history(source_p, 1);
|
whowas_add_history(source_p, 1);
|
||||||
if (dosend)
|
if (dosend)
|
||||||
{
|
{
|
||||||
sendto_server(client_p, NULL, CAP_TS6, NOCAPS, ":%s NICK %s :%ld",
|
sendto_server(client_p, NULL, CAP_TS6, NOCAPS, ":%s NICK %s :%ld",
|
||||||
|
|
|
@ -244,7 +244,7 @@ doit:
|
||||||
target_p->name, target_p->username,
|
target_p->name, target_p->username,
|
||||||
target_p->host, parv[2]);
|
target_p->host, parv[2]);
|
||||||
|
|
||||||
add_history(target_p, 1);
|
whowas_add_history(target_p, 1);
|
||||||
sendto_server(NULL, NULL, CAP_TS6, NOCAPS, ":%s NICK %s :%ld",
|
sendto_server(NULL, NULL, CAP_TS6, NOCAPS, ":%s NICK %s :%ld",
|
||||||
use_id(target_p), parv[2], (long) target_p->tsinfo);
|
use_id(target_p), parv[2], (long) target_p->tsinfo);
|
||||||
|
|
||||||
|
|
|
@ -1267,7 +1267,7 @@ stats_memory (struct Client *source_p)
|
||||||
|
|
||||||
size_t total_memory = 0;
|
size_t total_memory = 0;
|
||||||
|
|
||||||
count_whowas_memory(&ww, &wwm);
|
whowas_memory_usage(&ww, &wwm);
|
||||||
|
|
||||||
RB_DLINK_FOREACH(ptr, global_client_list.head)
|
RB_DLINK_FOREACH(ptr, global_client_list.head)
|
||||||
{
|
{
|
||||||
|
|
|
@ -58,9 +58,10 @@ DECLARE_MODULE_AV1(whowas, NULL, NULL, whowas_clist, NULL, NULL, "$Revision: 171
|
||||||
static int
|
static int
|
||||||
m_whowas(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
|
m_whowas(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
|
||||||
{
|
{
|
||||||
struct Whowas *temp;
|
rb_dlink_list *whowas_list;
|
||||||
|
rb_dlink_node *ptr;
|
||||||
int cur = 0;
|
int cur = 0;
|
||||||
int max = -1, found = 0;
|
int max = -1;
|
||||||
char *p;
|
char *p;
|
||||||
const char *nick;
|
const char *nick;
|
||||||
char tbuf[26];
|
char tbuf[26];
|
||||||
|
@ -76,8 +77,8 @@ m_whowas(struct Client *client_p, struct Client *source_p, int parc, const char
|
||||||
{
|
{
|
||||||
sendto_one(source_p, form_str(RPL_LOAD2HI),
|
sendto_one(source_p, form_str(RPL_LOAD2HI),
|
||||||
me.name, source_p->name, "WHOWAS");
|
me.name, source_p->name, "WHOWAS");
|
||||||
sendto_one(source_p, form_str(RPL_ENDOFWHOWAS),
|
sendto_one_numeric(source_p, RPL_ENDOFWHOWAS, form_str(RPL_ENDOFWHOWAS),
|
||||||
me.name, source_p->name, parv[1]);
|
parv[1]);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -101,54 +102,50 @@ m_whowas(struct Client *client_p, struct Client *source_p, int parc, const char
|
||||||
nick = parv[1];
|
nick = parv[1];
|
||||||
|
|
||||||
sendq_limit = get_sendq(client_p) * 9 / 10;
|
sendq_limit = get_sendq(client_p) * 9 / 10;
|
||||||
|
whowas_list = whowas_get_list(nick);
|
||||||
|
|
||||||
temp = WHOWASHASH[hash_whowas_name(nick)];
|
if(whowas_list == NULL)
|
||||||
found = 0;
|
|
||||||
for (; temp; temp = temp->next)
|
|
||||||
{
|
{
|
||||||
if(!irccmp(nick, temp->name))
|
sendto_one_numeric(source_p, ERR_WASNOSUCHNICK, form_str(ERR_WASNOSUCHNICK), nick);
|
||||||
|
sendto_one_numeric(source_p, RPL_ENDOFWHOWAS, form_str(RPL_ENDOFWHOWAS), parv[1]);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
RB_DLINK_FOREACH(ptr, whowas_list->head)
|
||||||
|
{
|
||||||
|
struct Whowas *temp = ptr->data;
|
||||||
|
if(cur > 0 && rb_linebuf_len(&client_p->localClient->buf_sendq) > sendq_limit)
|
||||||
{
|
{
|
||||||
if(cur > 0 && rb_linebuf_len(&client_p->localClient->buf_sendq) > sendq_limit)
|
sendto_one(source_p, form_str(ERR_TOOMANYMATCHES),
|
||||||
{
|
me.name, source_p->name, "WHOWAS");
|
||||||
sendto_one(source_p, form_str(ERR_TOOMANYMATCHES),
|
break;
|
||||||
me.name, source_p->name, "WHOWAS");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
sendto_one(source_p, form_str(RPL_WHOWASUSER),
|
|
||||||
me.name, source_p->name, temp->name,
|
|
||||||
temp->username, temp->hostname, temp->realname);
|
|
||||||
if (!EmptyString(temp->sockhost) &&
|
|
||||||
strcmp(temp->sockhost, "0") &&
|
|
||||||
show_ip_whowas(temp, source_p))
|
|
||||||
#if 0
|
|
||||||
sendto_one(source_p, form_str(RPL_WHOWASREAL),
|
|
||||||
me.name, source_p->name, temp->name,
|
|
||||||
"<untracked>", temp->sockhost);
|
|
||||||
#else
|
|
||||||
sendto_one_numeric(source_p, RPL_WHOISACTUALLY,
|
|
||||||
form_str(RPL_WHOISACTUALLY),
|
|
||||||
temp->name, temp->sockhost);
|
|
||||||
#endif
|
|
||||||
if (!EmptyString(temp->suser))
|
|
||||||
sendto_one_numeric(source_p, RPL_WHOISLOGGEDIN,
|
|
||||||
"%s %s :was logged in as",
|
|
||||||
temp->name, temp->suser);
|
|
||||||
sendto_one_numeric(source_p, RPL_WHOISSERVER,
|
|
||||||
form_str(RPL_WHOISSERVER),
|
|
||||||
temp->name, temp->servername,
|
|
||||||
rb_ctime(temp->logoff, tbuf, sizeof(tbuf)));
|
|
||||||
cur++;
|
|
||||||
found++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sendto_one(source_p, form_str(RPL_WHOWASUSER),
|
||||||
|
me.name, source_p->name, temp->name,
|
||||||
|
temp->username, temp->hostname, temp->realname);
|
||||||
|
if (!EmptyString(temp->sockhost) &&
|
||||||
|
strcmp(temp->sockhost, "0") &&
|
||||||
|
show_ip_whowas(temp, source_p))
|
||||||
|
sendto_one_numeric(source_p, RPL_WHOISACTUALLY,
|
||||||
|
form_str(RPL_WHOISACTUALLY),
|
||||||
|
temp->name, temp->sockhost);
|
||||||
|
|
||||||
|
if (!EmptyString(temp->suser))
|
||||||
|
sendto_one_numeric(source_p, RPL_WHOISLOGGEDIN,
|
||||||
|
"%s %s :was logged in as",
|
||||||
|
temp->name, temp->suser);
|
||||||
|
|
||||||
|
sendto_one_numeric(source_p, RPL_WHOISSERVER,
|
||||||
|
form_str(RPL_WHOISSERVER),
|
||||||
|
temp->name, temp->servername,
|
||||||
|
rb_ctime(temp->logoff, tbuf, sizeof(tbuf)));
|
||||||
|
|
||||||
|
cur++;
|
||||||
if(max > 0 && cur >= max)
|
if(max > 0 && cur >= max)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!found)
|
sendto_one_numeric(source_p, RPL_ENDOFWHOWAS, form_str(RPL_ENDOFWHOWAS), parv[1]);
|
||||||
sendto_one(source_p, form_str(ERR_WASNOSUCHNICK),
|
|
||||||
me.name, source_p->name, nick);
|
|
||||||
|
|
||||||
sendto_one(source_p, form_str(RPL_ENDOFWHOWAS),
|
|
||||||
me.name, source_p->name, parv[1]);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue