2 * ircd-ratbox: A slightly useful ircd.
3 * whowas.c: WHOWAS user cache.
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
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.
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.
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
24 * $Id: whowas.c 26 2006-09-20 18:02:06Z spb $
33 #include "irc_string.h"
35 #include "ircd_defs.h"
43 /* internally defined function */
44 static void add_whowas_to_clist(struct Whowas
**, struct Whowas
*);
45 static void del_whowas_from_clist(struct Whowas
**, struct Whowas
*);
46 static void add_whowas_to_list(struct Whowas
**, struct Whowas
*);
47 static void del_whowas_from_list(struct Whowas
**, struct Whowas
*);
49 struct Whowas WHOWAS
[NICKNAMEHISTORYLENGTH
];
50 struct Whowas
*WHOWASHASH
[WW_MAX
];
52 static int whowas_next
= 0;
54 unsigned int hash_whowas_name(const char *name
)
56 return fnv_hash_upper((const unsigned char *) name
, WW_MAX_BITS
);
59 void add_history(struct Client
*client_p
, int online
)
61 struct Whowas
*who
= &WHOWAS
[whowas_next
];
63 s_assert(NULL
!= client_p
);
71 del_whowas_from_clist(&(who
->online
->whowas
), who
);
72 del_whowas_from_list(&WHOWASHASH
[who
->hashv
], who
);
74 who
->hashv
= hash_whowas_name(client_p
->name
);
75 who
->logoff
= CurrentTime
;
77 * NOTE: strcpy ok here, the sizes in the client struct MUST
78 * match the sizes in the whowas struct
80 strlcpy(who
->name
, client_p
->name
, sizeof(who
->name
));
81 strcpy(who
->username
, client_p
->username
);
82 strcpy(who
->hostname
, client_p
->host
);
83 strcpy(who
->realname
, client_p
->info
);
84 if (!EmptyString(client_p
->sockhost
) && strcmp(client_p
->sockhost
, "0") && show_ip(NULL
, client_p
))
85 strcpy(who
->sockhost
, client_p
->sockhost
);
87 who
->sockhost
[0] = '\0';
89 who
->servername
= client_p
->user
->server
;
93 who
->online
= client_p
;
94 add_whowas_to_clist(&(client_p
->whowas
), who
);
98 add_whowas_to_list(&WHOWASHASH
[who
->hashv
], who
);
100 if(whowas_next
== NICKNAMEHISTORYLENGTH
)
104 void off_history(struct Client
*client_p
)
106 struct Whowas
*temp
, *next
;
108 for (temp
= client_p
->whowas
; temp
; temp
= next
)
112 del_whowas_from_clist(&(client_p
->whowas
), temp
);
116 struct Client
*get_history(const char *nick
, time_t timelimit
)
121 timelimit
= CurrentTime
- timelimit
;
122 blah
= hash_whowas_name(nick
);
123 temp
= WHOWASHASH
[blah
];
124 for (; temp
; temp
= temp
->next
)
126 if(irccmp(nick
, temp
->name
))
128 if(temp
->logoff
< timelimit
)
135 void count_whowas_memory(size_t * wwu
, size_t * wwum
)
142 /* count the number of used whowas structs in 'u' */
143 /* count up the memory used of whowas structs in um */
145 for (i
= 0, tmp
= &WHOWAS
[0]; i
< NICKNAMEHISTORYLENGTH
; i
++, tmp
++)
149 um
+= sizeof(struct Whowas
);
161 for (i
= 0; i
< NICKNAMEHISTORYLENGTH
; i
++)
163 memset((void *) &WHOWAS
[i
], 0, sizeof(struct Whowas
));
164 WHOWAS
[i
].hashv
= -1;
166 for (i
= 0; i
< WW_MAX
; i
++)
167 WHOWASHASH
[i
] = NULL
;
172 add_whowas_to_clist(struct Whowas
**bucket
, struct Whowas
*whowas
)
174 whowas
->cprev
= NULL
;
175 if((whowas
->cnext
= *bucket
) != NULL
)
176 whowas
->cnext
->cprev
= whowas
;
181 del_whowas_from_clist(struct Whowas
**bucket
, struct Whowas
*whowas
)
184 whowas
->cprev
->cnext
= whowas
->cnext
;
186 *bucket
= whowas
->cnext
;
188 whowas
->cnext
->cprev
= whowas
->cprev
;
192 add_whowas_to_list(struct Whowas
**bucket
, struct Whowas
*whowas
)
195 if((whowas
->next
= *bucket
) != NULL
)
196 whowas
->next
->prev
= whowas
;
201 del_whowas_from_list(struct Whowas
**bucket
, struct Whowas
*whowas
)
204 whowas
->prev
->next
= whowas
->next
;
206 *bucket
= whowas
->next
;
208 whowas
->next
->prev
= whowas
->prev
;