ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/src/whowas.c
Revision: 9101
Committed: Wed Jan 1 09:58:45 2020 UTC (5 years, 7 months ago) by michael
Content type: text/x-csrc
File size: 5965 byte(s)
Log Message:
- Bump copyright years everywhere

File Contents

# User Rev Content
1 adx 30 /*
2 michael 2916 * ircd-hybrid: an advanced, lightweight Internet Relay Chat Daemon (ircd)
3 adx 30 *
4 michael 9101 * Copyright (c) 1997-2020 ircd-hybrid development team
5 adx 30 *
6     * This program is free software; you can redistribute it and/or modify
7     * it under the terms of the GNU General Public License as published by
8     * the Free Software Foundation; either version 2 of the License, or
9     * (at your option) any later version.
10     *
11     * This program is distributed in the hope that it will be useful,
12     * but WITHOUT ANY WARRANTY; without even the implied warranty of
13     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14     * GNU General Public License for more details.
15     *
16     * You should have received a copy of the GNU General Public License
17     * along with this program; if not, write to the Free Software
18 michael 4565 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
19 adx 30 * USA
20     */
21    
22 michael 2916 /*! \file whowas.c
23     * \brief WHOWAS user cache.
24     * \version $Id$
25     */
26    
27 adx 30 #include "stdinc.h"
28 michael 1358 #include "list.h"
29 michael 8385 #include "memory.h"
30 adx 30 #include "whowas.h"
31     #include "client.h"
32     #include "hash.h"
33     #include "irc_string.h"
34     #include "ircd.h"
35 michael 7437 #include "conf.h"
36 adx 30
37    
38 michael 7437 static dlink_list whowas_list; /*! Chain of struct Whowas pointers */
39 michael 7449 static dlink_list whowas_hash[HASHSIZE];
40 adx 30
41    
42 michael 7449 /*! \brief Returns a slot of the whowas_hash by the hash value associated with it.
43 michael 8949 * \param hash_value Hash value.
44 michael 7449 */
45     const dlink_list *
46 michael 8949 whowas_get_hash(unsigned int hash_value)
47 michael 7449 {
48 michael 8949 if (hash_value >= HASHSIZE)
49 michael 7449 return NULL;
50    
51 michael 8949 return &whowas_hash[hash_value];
52 michael 7449 }
53    
54 michael 7437 /*! \brief Unlinks a Whowas struct from its associated lists.
55 michael 7442 * \param whowas Pointer to Whowas struct to be unlinked.
56 michael 7437 */
57     static struct Whowas *
58     whowas_unlink(struct Whowas *whowas)
59     {
60     if (whowas->online)
61 michael 7486 dlinkDelete(&whowas->cnode, &whowas->online->whowas_list);
62 michael 7437
63 michael 8949 dlinkDelete(&whowas->hnode, &whowas_hash[whowas->hash_value]);
64 michael 7437 dlinkDelete(&whowas->lnode, &whowas_list);
65    
66     return whowas;
67     }
68    
69     /*! \brief Unlinks a Whowas struct from its associated lists
70 michael 8385 * and frees memory.
71 michael 7442 * \param whowas Pointer to Whowas struct to be unlinked and freed.
72 michael 7437 */
73     static void
74     whowas_free(struct Whowas *whowas)
75     {
76     whowas_unlink(whowas);
77 michael 8385 xfree(whowas);
78 michael 7437 }
79    
80     /*! \brief Returns a Whowas struct for further use. Either allocates
81     * a new one, or returns the oldest entry from the whowas_list
82     * if it ran over ConfigGeneral.whowas_history_length
83     */
84     static struct Whowas *
85     whowas_make(void)
86     {
87     struct Whowas *whowas;
88    
89 michael 7497 if (dlink_list_length(&whowas_list) &&
90     dlink_list_length(&whowas_list) >= ConfigGeneral.whowas_history_length)
91 michael 7441 whowas = whowas_unlink(whowas_list.tail->data); /* Re-use oldest item */
92 michael 7437 else
93 michael 8385 whowas = xcalloc(sizeof(*whowas));
94 michael 7437
95     return whowas;
96     }
97    
98     /*! \brief Trims the whowas_list if necessary until there are no
99     * more than ConfigGeneral.whowas_history_length Whowas
100     * struct items.
101     */
102     void
103     whowas_trim(void)
104     {
105 michael 7495 while (dlink_list_length(&whowas_list) &&
106     dlink_list_length(&whowas_list) >= ConfigGeneral.whowas_history_length)
107 michael 7437 whowas_free(whowas_list.tail->data);
108     }
109    
110 michael 7393 /*! \brief Adds the currently defined name of the client to history.
111     * Usually called before changing to a new name (nick).
112     * Client must be a fully registered user.
113 michael 7442 * \param client_p Pointer to Client struct to add to whowas history
114     * \param online Either 1 if it's a nick change or 0 on client exit
115 michael 7393 */
116 michael 1997 void
117 michael 8664 whowas_add_history(struct Client *client_p, bool online)
118 adx 30 {
119 michael 7437 struct Whowas *whowas = whowas_make();
120 adx 30
121 michael 3273 assert(IsClient(client_p));
122 adx 30
123 michael 8949 whowas->hash_value = strhash(client_p->name);
124 michael 8926 whowas->logoff = event_base->time.sec_real;
125 michael 8653 whowas->server_hidden = IsHidden(client_p->servptr) != 0;
126 adx 30
127 michael 6654 strlcpy(whowas->account, client_p->account, sizeof(whowas->account));
128     strlcpy(whowas->name, client_p->name, sizeof(whowas->name));
129     strlcpy(whowas->username, client_p->username, sizeof(whowas->username));
130     strlcpy(whowas->hostname, client_p->host, sizeof(whowas->hostname));
131 michael 8214 strlcpy(whowas->realhost, client_p->realhost, sizeof(whowas->realhost));
132 michael 6654 strlcpy(whowas->sockhost, client_p->sockhost, sizeof(whowas->sockhost));
133     strlcpy(whowas->realname, client_p->info, sizeof(whowas->realname));
134     strlcpy(whowas->servername, client_p->servptr->name, sizeof(whowas->servername));
135 adx 30
136 michael 8664 if (online == true)
137 adx 30 {
138 michael 6654 whowas->online = client_p;
139 michael 7486 dlinkAdd(whowas, &whowas->cnode, &client_p->whowas_list);
140 adx 30 }
141     else
142 michael 6654 whowas->online = NULL;
143 adx 30
144 michael 8949 dlinkAdd(whowas, &whowas->hnode, &whowas_hash[whowas->hash_value]);
145 michael 7437 dlinkAdd(whowas, &whowas->lnode, &whowas_list);
146 adx 30 }
147    
148 michael 7393 /*! \brief This must be called when the client structure is about to
149     * be released. History mechanism keeps pointers to client
150     * structures and it must know when they cease to exist.
151 michael 7442 * \param client_p Pointer to Client struct
152 michael 7393 */
153 adx 30 void
154 michael 2300 whowas_off_history(struct Client *client_p)
155 adx 30 {
156 michael 7486 while (client_p->whowas_list.head)
157 adx 30 {
158 michael 7486 struct Whowas *whowas = client_p->whowas_list.head->data;
159 michael 1358
160 michael 6654 whowas->online = NULL;
161 michael 7486 dlinkDelete(&whowas->cnode, &client_p->whowas_list);
162 adx 30 }
163     }
164    
165 michael 7393 /*! \brief Returns the current client that was using the given
166     * nickname within the timelimit. Returns NULL, if no
167 michael 7437 * one found.
168 michael 7442 * \param name Name of the nick
169     * \param timelimit Maximum age for a client since log-off
170 michael 7393 */
171 adx 30 struct Client *
172 michael 7394 whowas_get_history(const char *name, uintmax_t timelimit)
173 adx 30 {
174 michael 7797 dlink_node *node;
175 adx 30
176 michael 8926 timelimit = event_base->time.sec_real - timelimit;
177 adx 30
178 michael 7449 DLINK_FOREACH(node, whowas_hash[strhash(name)].head)
179 adx 30 {
180 michael 6654 struct Whowas *whowas = node->data;
181 michael 1358
182 michael 6654 if (whowas->logoff < timelimit)
183 michael 1358 continue;
184 michael 7394 if (irccmp(name, whowas->name))
185 adx 30 continue;
186 michael 6654 return whowas->online;
187 adx 30 }
188    
189 michael 1298 return NULL;
190 adx 30 }
191    
192 michael 7437 /*! \brief For debugging. Counts allocated structures stored in whowas_list
193 michael 7393 */
194 adx 30 void
195 michael 6719 whowas_count_memory(unsigned int *const count, size_t *const bytes)
196 adx 30 {
197 michael 7437 (*count) = dlink_list_length(&whowas_list);
198     (*bytes) = dlink_list_length(&whowas_list) * sizeof(struct Whowas);
199 adx 30 }

Properties

Name Value
svn:eol-style native
svn:keywords Id