]> jfr.im git - solanum.git/blame - src/whowas.c
Remove s_assert definition from ircd_defs.h and add it to its own header.
[solanum.git] / src / whowas.c
CommitLineData
212380e3
AC
1/*
2 * ircd-ratbox: A slightly useful ircd.
3 * whowas.c: WHOWAS user cache.
4 *
5 * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
6 * Copyright (C) 1996-2002 Hybrid Development Team
7 * Copyright (C) 2002-2005 ircd-ratbox development team
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
22 * USA
23 *
24 * $Id: whowas.c 1717 2006-07-04 14:41:11Z jilles $
25 */
26
27#include "stdinc.h"
28
29#include "whowas.h"
30#include "client.h"
31#include "common.h"
32#include "hash.h"
4562c604 33#include "match.h"
212380e3
AC
34#include "ircd.h"
35#include "ircd_defs.h"
36#include "numeric.h"
37#include "s_serv.h"
38#include "s_user.h"
39#include "send.h"
40#include "s_conf.h"
c88cdb00 41#include "scache.h"
77d3d2db 42#include "s_assert.h"
212380e3
AC
43
44/* internally defined function */
45static void add_whowas_to_clist(struct Whowas **, struct Whowas *);
46static void del_whowas_from_clist(struct Whowas **, struct Whowas *);
47static void add_whowas_to_list(struct Whowas **, struct Whowas *);
48static void del_whowas_from_list(struct Whowas **, struct Whowas *);
49
50struct Whowas WHOWAS[NICKNAMEHISTORYLENGTH];
51struct Whowas *WHOWASHASH[WW_MAX];
52
53static int whowas_next = 0;
54
55unsigned int hash_whowas_name(const char *name)
56{
57 return fnv_hash_upper((const unsigned char *) name, WW_MAX_BITS);
58}
59
60void add_history(struct Client *client_p, int online)
61{
62 struct Whowas *who = &WHOWAS[whowas_next];
63
64 s_assert(NULL != client_p);
65
66 if(client_p == NULL)
67 return;
68
69 if(who->hashv != -1)
70 {
71 if(who->online)
72 del_whowas_from_clist(&(who->online->whowas), who);
73 del_whowas_from_list(&WHOWASHASH[who->hashv], who);
74 }
75 who->hashv = hash_whowas_name(client_p->name);
e3354945 76 who->logoff = rb_current_time();
212380e3
AC
77 /*
78 * NOTE: strcpy ok here, the sizes in the client struct MUST
79 * match the sizes in the whowas struct
80 */
f427c8b0 81 rb_strlcpy(who->name, client_p->name, sizeof(who->name));
212380e3
AC
82 strcpy(who->username, client_p->username);
83 strcpy(who->hostname, client_p->host);
84 strcpy(who->realname, client_p->info);
01b7a527 85 strcpy(who->suser, client_p->user->suser);
212380e3
AC
86 if (!EmptyString(client_p->sockhost) && strcmp(client_p->sockhost, "0") && show_ip(NULL, client_p))
87 strcpy(who->sockhost, client_p->sockhost);
88 else
89 who->sockhost[0] = '\0';
90
994544c2 91 who->servername = scache_get_name(client_p->servptr->serv->nameinfo);
212380e3
AC
92
93 if(online)
94 {
95 who->online = client_p;
96 add_whowas_to_clist(&(client_p->whowas), who);
97 }
98 else
99 who->online = NULL;
100 add_whowas_to_list(&WHOWASHASH[who->hashv], who);
101 whowas_next++;
102 if(whowas_next == NICKNAMEHISTORYLENGTH)
103 whowas_next = 0;
104}
105
106void off_history(struct Client *client_p)
107{
108 struct Whowas *temp, *next;
109
110 for (temp = client_p->whowas; temp; temp = next)
111 {
112 next = temp->cnext;
113 temp->online = NULL;
114 del_whowas_from_clist(&(client_p->whowas), temp);
115 }
116}
117
118struct Client *get_history(const char *nick, time_t timelimit)
119{
120 struct Whowas *temp;
121 int blah;
122
e3354945 123 timelimit = rb_current_time() - timelimit;
212380e3
AC
124 blah = hash_whowas_name(nick);
125 temp = WHOWASHASH[blah];
126 for (; temp; temp = temp->next)
127 {
128 if(irccmp(nick, temp->name))
129 continue;
130 if(temp->logoff < timelimit)
131 continue;
132 return temp->online;
133 }
134 return NULL;
135}
136
137void count_whowas_memory(size_t * wwu, size_t * wwum)
138{
309e4fd0
JT
139 *wwu = NICKNAMEHISTORYLENGTH;
140 *wwum = NICKNAMEHISTORYLENGTH * sizeof(struct Whowas);
212380e3
AC
141}
142
143void
144initwhowas()
145{
146 int i;
147
148 for (i = 0; i < NICKNAMEHISTORYLENGTH; i++)
149 {
150 memset((void *) &WHOWAS[i], 0, sizeof(struct Whowas));
151 WHOWAS[i].hashv = -1;
152 }
153 for (i = 0; i < WW_MAX; i++)
154 WHOWASHASH[i] = NULL;
155}
156
157
158static void
159add_whowas_to_clist(struct Whowas **bucket, struct Whowas *whowas)
160{
161 whowas->cprev = NULL;
162 if((whowas->cnext = *bucket) != NULL)
163 whowas->cnext->cprev = whowas;
164 *bucket = whowas;
165}
166
167static void
168del_whowas_from_clist(struct Whowas **bucket, struct Whowas *whowas)
169{
170 if(whowas->cprev)
171 whowas->cprev->cnext = whowas->cnext;
172 else
173 *bucket = whowas->cnext;
174 if(whowas->cnext)
175 whowas->cnext->cprev = whowas->cprev;
176}
177
178static void
179add_whowas_to_list(struct Whowas **bucket, struct Whowas *whowas)
180{
181 whowas->prev = NULL;
182 if((whowas->next = *bucket) != NULL)
183 whowas->next->prev = whowas;
184 *bucket = whowas;
185}
186
187static void
188del_whowas_from_list(struct Whowas **bucket, struct Whowas *whowas)
189{
190 if(whowas->prev)
191 whowas->prev->next = whowas->next;
192 else
193 *bucket = whowas->next;
194 if(whowas->next)
195 whowas->next->prev = whowas->prev;
196}