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
31 #include "irc_string.h"
33 #include "ircd_defs.h"
41 /* internally defined function */
42 static void add_whowas_to_clist(struct Whowas
**, struct Whowas
*);
43 static void del_whowas_from_clist(struct Whowas
**, struct Whowas
*);
44 static void add_whowas_to_list(struct Whowas
**, struct Whowas
*);
45 static void del_whowas_from_list(struct Whowas
**, struct Whowas
*);
47 struct Whowas WHOWAS
[NICKNAMEHISTORYLENGTH
];
48 struct Whowas
*WHOWASHASH
[WW_MAX
];
50 static int whowas_next
= 0;
52 unsigned int hash_whowas_name(const char *name
)
54 return fnv_hash_upper((const unsigned char *) name
, WW_MAX_BITS
);
57 void add_history(struct Client
*client_p
, int online
)
59 struct Whowas
*who
= &WHOWAS
[whowas_next
];
61 s_assert(NULL
!= client_p
);
69 del_whowas_from_clist(&(who
->online
->whowas
), who
);
70 del_whowas_from_list(&WHOWASHASH
[who
->hashv
], who
);
72 who
->hashv
= hash_whowas_name(client_p
->name
);
73 who
->logoff
= CurrentTime
;
75 * NOTE: strcpy ok here, the sizes in the client struct MUST
76 * match the sizes in the whowas struct
78 strlcpy(who
->name
, client_p
->name
, sizeof(who
->name
));
79 strcpy(who
->username
, client_p
->username
);
80 strcpy(who
->hostname
, client_p
->host
);
81 strcpy(who
->realname
, client_p
->info
);
82 if (!EmptyString(client_p
->sockhost
) && strcmp(client_p
->sockhost
, "0") && show_ip(NULL
, client_p
))
83 strcpy(who
->sockhost
, client_p
->sockhost
);
85 who
->sockhost
[0] = '\0';
87 who
->servername
= client_p
->user
->server
;
91 who
->online
= client_p
;
92 add_whowas_to_clist(&(client_p
->whowas
), who
);
96 add_whowas_to_list(&WHOWASHASH
[who
->hashv
], who
);
98 if(whowas_next
== NICKNAMEHISTORYLENGTH
)
102 void off_history(struct Client
*client_p
)
104 struct Whowas
*temp
, *next
;
106 for (temp
= client_p
->whowas
; temp
; temp
= next
)
110 del_whowas_from_clist(&(client_p
->whowas
), temp
);
114 struct Client
*get_history(const char *nick
, time_t timelimit
)
119 timelimit
= CurrentTime
- timelimit
;
120 blah
= hash_whowas_name(nick
);
121 temp
= WHOWASHASH
[blah
];
122 for (; temp
; temp
= temp
->next
)
124 if(irccmp(nick
, temp
->name
))
126 if(temp
->logoff
< timelimit
)
133 void count_whowas_memory(size_t * wwu
, size_t * wwum
)
140 /* count the number of used whowas structs in 'u' */
141 /* count up the memory used of whowas structs in um */
143 for (i
= 0, tmp
= &WHOWAS
[0]; i
< NICKNAMEHISTORYLENGTH
; i
++, tmp
++)
147 um
+= sizeof(struct Whowas
);
159 for (i
= 0; i
< NICKNAMEHISTORYLENGTH
; i
++)
161 memset((void *) &WHOWAS
[i
], 0, sizeof(struct Whowas
));
162 WHOWAS
[i
].hashv
= -1;
164 for (i
= 0; i
< WW_MAX
; i
++)
165 WHOWASHASH
[i
] = NULL
;
170 add_whowas_to_clist(struct Whowas
**bucket
, struct Whowas
*whowas
)
172 whowas
->cprev
= NULL
;
173 if((whowas
->cnext
= *bucket
) != NULL
)
174 whowas
->cnext
->cprev
= whowas
;
179 del_whowas_from_clist(struct Whowas
**bucket
, struct Whowas
*whowas
)
182 whowas
->cprev
->cnext
= whowas
->cnext
;
184 *bucket
= whowas
->cnext
;
186 whowas
->cnext
->cprev
= whowas
->cprev
;
190 add_whowas_to_list(struct Whowas
**bucket
, struct Whowas
*whowas
)
193 if((whowas
->next
= *bucket
) != NULL
)
194 whowas
->next
->prev
= whowas
;
199 del_whowas_from_list(struct Whowas
**bucket
, struct Whowas
*whowas
)
202 whowas
->prev
->next
= whowas
->next
;
204 *bucket
= whowas
->next
;
206 whowas
->next
->prev
= whowas
->prev
;