Files
ircu2.9.32/ircd/whowas.c

225 lines
4.9 KiB
C

/************************************************************************
* IRC - Internet Relay Chat, ircd/whowas.c
* Copyright (C) 1990 Markku Savela
*
* 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
* the Free Software Foundation; either version 1, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
* --- avalon --- 6th April 1992
* rewritten to scrap linked lists and use a table of structures which
* is referenced like a circular loop. Should be faster and more efficient.
*/
#ifndef lint
static char sccsid[] = "@(#)whowas.c 2.16 08 Nov 1993 (C) 1988 Markku Savela";
#endif
#include "struct.h"
#include "common.h"
#include "sys.h"
#include "numeric.h"
#include "whowas.h"
#include "h.h"
static aName was[NICKNAMEHISTORYLENGTH];
static int ww_index = 0;
void add_history(cptr)
Reg1 aClient *cptr;
{
aName ntmp;
Reg2 aName *np = &ntmp, *np2;
strncpyzt(np->ww_nick, cptr->name, NICKLEN+1);
strncpyzt(np->ww_info, cptr->info, REALLEN+1);
np->ww_user = cptr->user;
np->ww_logout = now;
np->ww_online = (cptr->from != NULL) ? cptr : NULL;
np->ww_user->refcnt++;
np->ww_server = (char *)MyMalloc(strlen(np->ww_user->server->name)+1);
strcpy(np->ww_server, np->ww_user->server->name);
np2 = &was[ww_index];
if (np2->ww_user)
{
free_user(np2->ww_user, np2->ww_online);
MyFree(np2->ww_server);
}
bcopy((char *)&ntmp, (char *)np2, sizeof(aName));
ww_index++;
if (ww_index >= NICKNAMEHISTORYLENGTH)
ww_index = 0;
return;
}
/*
** get_history
** Return the current client that was using the given
** nickname within the timelimit. Returns NULL, if no
** one found...
*/
aClient *get_history(nick, timelimit)
char *nick;
time_t timelimit;
{
Reg1 aName *wp, *wp2;
Reg2 int i = 0;
if (ww_index == 0)
wp = wp2 = &was[NICKNAMEHISTORYLENGTH - 1];
else
wp = wp2 = &was[ww_index - 1];
timelimit = now-timelimit;
do {
if (!strcasecmp(nick, wp->ww_nick) && wp->ww_logout >= timelimit)
break;
if (wp == was)
{
i = 1;
wp = &was[NICKNAMEHISTORYLENGTH - 1];
}
else
wp--;
} while (wp != wp2);
if (wp != wp2 || !i)
return (wp->ww_online);
return (NULL);
}
void off_history(cptr)
Reg3 aClient *cptr;
{
Reg1 aName *wp;
Reg2 int i;
for (i = NICKNAMEHISTORYLENGTH, wp = was; i; wp++, i--)
if (wp->ww_online == cptr)
wp->ww_online = NULL;
return;
}
void initwhowas()
{
bzero((char *)was, NICKNAMEHISTORYLENGTH * sizeof(aName));
}
/*
** m_whowas
** parv[0] = sender prefix
** parv[1] = nickname queried
*/
int m_whowas(cptr, sptr, parc, parv)
aClient *cptr, *sptr;
int parc;
char *parv[];
{
Reg1 aName *wp, *wp2 = NULL;
Reg2 int j = 0;
Reg3 anUser *up = NULL;
int max = -1;
char *p, *nick, *s;
if (parc < 2)
{
sendto_one(sptr, err_str(ERR_NONICKNAMEGIVEN),
me.name, parv[0]);
return 0;
}
if (parc > 2)
max = atoi(parv[2]);
if (parc > 3)
if (hunt_server(cptr,sptr,":%s WHOWAS %s %s :%s", 3,parc,parv))
return 0;
for (s = parv[1]; (nick = strtoken(&p, s, ",")); s = NULL)
{
wp = wp2 = &was[ww_index - 1];
do {
if (wp < was)
wp = &was[NICKNAMEHISTORYLENGTH - 1];
if (strcasecmp(nick, wp->ww_nick) == 0)
{
up = wp->ww_user;
sendto_one(sptr, rpl_str(RPL_WHOWASUSER),
me.name, parv[0], wp->ww_nick,
up->username,
up->host, wp->ww_info);
sendto_one(sptr, rpl_str(RPL_WHOISSERVER),
me.name, parv[0], wp->ww_nick,
wp->ww_server,
myctime(wp->ww_logout));
if (up->away)
sendto_one(sptr, rpl_str(RPL_AWAY),
me.name, parv[0],
wp->ww_nick, up->away);
j++;
}
if (max > 0 && j >= max)
break;
wp--;
} while (wp != wp2);
if (up == NULL)
sendto_one(sptr, err_str(ERR_WASNOSUCHNICK),
me.name, parv[0], nick);
up = NULL;
if (p)
p[-1] = ',';
}
sendto_one(sptr, rpl_str(RPL_ENDOFWHOWAS), me.name, parv[0], parv[1]);
return 0;
}
void count_whowas_memory(wwu, wwa, wwam)
int *wwu, *wwa;
u_long *wwam;
{
Reg1 anUser *tmp;
Reg2 int i, j;
int u = 0, a = 0;
u_long am = 0;
for (i = 0; i < NICKNAMEHISTORYLENGTH; i++)
if ((tmp = was[i].ww_user))
if (!was[i].ww_online)
{
for (j = 0; j < i; j++)
if (was[j].ww_user == tmp)
break;
if (j < i)
continue;
u++;
if (tmp->away)
{
a++;
am += (strlen(tmp->away)+1);
}
}
*wwu = u;
*wwa = a;
*wwam = am;
return;
}