ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/src/whowas.c
Revision: 8214
Committed: Sun Apr 16 11:44:44 2017 UTC (8 years, 4 months ago) by michael
Content type: text/x-csrc
File size: 6119 byte(s)
Log Message:
- Store real host information in Client.realhost and extend the UID message to send the actual host.
  This allows operators to see the real host of a client in /whois and /whowas.

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 7924 * Copyright (c) 1997-2017 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 7437 #include "mempool.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 mp_pool_t *whowas_pool;
39    
40     static dlink_list whowas_list; /*! Chain of struct Whowas pointers */
41 michael 7449 static dlink_list whowas_hash[HASHSIZE];
42 adx 30
43    
44 michael 7442 /*! \brief Initializes the whowas memory pool.
45 michael 7393 */
46 adx 30 void
47 michael 1997 whowas_init(void)
48     {
49 michael 7442 whowas_pool = mp_pool_new(sizeof(struct Whowas), MP_CHUNK_SIZE_WHOWAS);
50 michael 1997 }
51    
52 michael 7449 /*! \brief Returns a slot of the whowas_hash by the hash value associated with it.
53     * \param hashv Hash value.
54     */
55     const dlink_list *
56     whowas_get_hash(unsigned int hashv)
57     {
58     if (hashv >= HASHSIZE)
59     return NULL;
60    
61     return &whowas_hash[hashv];
62     }
63    
64 michael 7437 /*! \brief Unlinks a Whowas struct from its associated lists.
65 michael 7442 * \param whowas Pointer to Whowas struct to be unlinked.
66 michael 7437 */
67     static struct Whowas *
68     whowas_unlink(struct Whowas *whowas)
69     {
70     if (whowas->online)
71 michael 7486 dlinkDelete(&whowas->cnode, &whowas->online->whowas_list);
72 michael 7437
73 michael 7449 dlinkDelete(&whowas->hnode, &whowas_hash[whowas->hashv]);
74 michael 7437 dlinkDelete(&whowas->lnode, &whowas_list);
75    
76     return whowas;
77     }
78    
79     /*! \brief Unlinks a Whowas struct from its associated lists
80     * and returns memory back to the pooling allocator.
81 michael 7442 * \param whowas Pointer to Whowas struct to be unlinked and freed.
82 michael 7437 */
83     static void
84     whowas_free(struct Whowas *whowas)
85     {
86     whowas_unlink(whowas);
87     mp_pool_release(whowas);
88     }
89    
90     /*! \brief Returns a Whowas struct for further use. Either allocates
91     * a new one, or returns the oldest entry from the whowas_list
92     * if it ran over ConfigGeneral.whowas_history_length
93     */
94     static struct Whowas *
95     whowas_make(void)
96     {
97     struct Whowas *whowas;
98    
99 michael 7497 if (dlink_list_length(&whowas_list) &&
100     dlink_list_length(&whowas_list) >= ConfigGeneral.whowas_history_length)
101 michael 7441 whowas = whowas_unlink(whowas_list.tail->data); /* Re-use oldest item */
102 michael 7437 else
103     whowas = mp_pool_get(whowas_pool);
104    
105     return whowas;
106     }
107    
108     /*! \brief Trims the whowas_list if necessary until there are no
109     * more than ConfigGeneral.whowas_history_length Whowas
110     * struct items.
111     */
112     void
113     whowas_trim(void)
114     {
115 michael 7495 while (dlink_list_length(&whowas_list) &&
116     dlink_list_length(&whowas_list) >= ConfigGeneral.whowas_history_length)
117 michael 7437 whowas_free(whowas_list.tail->data);
118     }
119    
120 michael 7393 /*! \brief Adds the currently defined name of the client to history.
121     * Usually called before changing to a new name (nick).
122     * Client must be a fully registered user.
123 michael 7442 * \param client_p Pointer to Client struct to add to whowas history
124     * \param online Either 1 if it's a nick change or 0 on client exit
125 michael 7393 */
126 michael 1997 void
127 michael 2300 whowas_add_history(struct Client *client_p, const int online)
128 adx 30 {
129 michael 7437 struct Whowas *whowas = whowas_make();
130 adx 30
131 michael 3273 assert(IsClient(client_p));
132 adx 30
133 michael 6654 whowas->hashv = strhash(client_p->name);
134     whowas->shide = IsHidden(client_p->servptr) != 0;
135     whowas->logoff = CurrentTime;
136 adx 30
137 michael 6654 strlcpy(whowas->account, client_p->account, sizeof(whowas->account));
138     strlcpy(whowas->name, client_p->name, sizeof(whowas->name));
139     strlcpy(whowas->username, client_p->username, sizeof(whowas->username));
140     strlcpy(whowas->hostname, client_p->host, sizeof(whowas->hostname));
141 michael 8214 strlcpy(whowas->realhost, client_p->realhost, sizeof(whowas->realhost));
142 michael 6654 strlcpy(whowas->sockhost, client_p->sockhost, sizeof(whowas->sockhost));
143     strlcpy(whowas->realname, client_p->info, sizeof(whowas->realname));
144     strlcpy(whowas->servername, client_p->servptr->name, sizeof(whowas->servername));
145 adx 30
146     if (online)
147     {
148 michael 6654 whowas->online = client_p;
149 michael 7486 dlinkAdd(whowas, &whowas->cnode, &client_p->whowas_list);
150 adx 30 }
151     else
152 michael 6654 whowas->online = NULL;
153 adx 30
154 michael 7449 dlinkAdd(whowas, &whowas->hnode, &whowas_hash[whowas->hashv]);
155 michael 7437 dlinkAdd(whowas, &whowas->lnode, &whowas_list);
156 adx 30 }
157    
158 michael 7393 /*! \brief This must be called when the client structure is about to
159     * be released. History mechanism keeps pointers to client
160     * structures and it must know when they cease to exist.
161 michael 7442 * \param client_p Pointer to Client struct
162 michael 7393 */
163 adx 30 void
164 michael 2300 whowas_off_history(struct Client *client_p)
165 adx 30 {
166 michael 7486 while (client_p->whowas_list.head)
167 adx 30 {
168 michael 7486 struct Whowas *whowas = client_p->whowas_list.head->data;
169 michael 1358
170 michael 6654 whowas->online = NULL;
171 michael 7486 dlinkDelete(&whowas->cnode, &client_p->whowas_list);
172 adx 30 }
173     }
174    
175 michael 7393 /*! \brief Returns the current client that was using the given
176     * nickname within the timelimit. Returns NULL, if no
177 michael 7437 * one found.
178 michael 7442 * \param name Name of the nick
179     * \param timelimit Maximum age for a client since log-off
180 michael 7393 */
181 adx 30 struct Client *
182 michael 7394 whowas_get_history(const char *name, uintmax_t timelimit)
183 adx 30 {
184 michael 7797 dlink_node *node;
185 adx 30
186     timelimit = CurrentTime - timelimit;
187    
188 michael 7449 DLINK_FOREACH(node, whowas_hash[strhash(name)].head)
189 adx 30 {
190 michael 6654 struct Whowas *whowas = node->data;
191 michael 1358
192 michael 6654 if (whowas->logoff < timelimit)
193 michael 1358 continue;
194 michael 7394 if (irccmp(name, whowas->name))
195 adx 30 continue;
196 michael 6654 return whowas->online;
197 adx 30 }
198    
199 michael 1298 return NULL;
200 adx 30 }
201    
202 michael 7437 /*! \brief For debugging. Counts allocated structures stored in whowas_list
203 michael 7393 */
204 adx 30 void
205 michael 6719 whowas_count_memory(unsigned int *const count, size_t *const bytes)
206 adx 30 {
207 michael 7437 (*count) = dlink_list_length(&whowas_list);
208     (*bytes) = dlink_list_length(&whowas_list) * sizeof(struct Whowas);
209 adx 30 }

Properties

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