ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/ermyth/src/users.C
Revision: 1.6
Committed: Sun Sep 16 18:54:45 2007 UTC (16 years, 8 months ago) by pippijn
Content type: text/plain
Branch: MAIN
Changes since 1.5: +7 -2 lines
Log Message:
#defines to enum

File Contents

# Content
1 /*
2 * users.C: User management.
3 *
4 * Copyright © 2007 Pippijn van Steenhoven / The Ermyth Team
5 * Rights to this code are as documented in COPYING.
6 *
7 *
8 * Portions of this file were derived from sources bearing the following license:
9 * Rights to this code are documented in doc/pod/license.pod.
10 * Copyright © 2005-2007 Atheme Project (http://www.atheme.org)
11 */
12
13 static char const rcsid[] = "$Id: users.C,v 1.5 2007-09-09 20:05:53 pippijn Exp $";
14
15 #include "atheme.h"
16 #include "servers.h"
17 #include <account/mynick.h>
18 #include <account/myuser.h>
19
20 user_map userlist;
21 typedef std::map<char const * const, user_t *, str_lt> uid_map;
22 static uid_map uidlist;
23 user_t::callbacks user_t::callback;
24
25 /*
26 * init_users()
27 *
28 * Initializes the users heap and DTree.
29 *
30 * Inputs:
31 * - none
32 *
33 * Outputs:
34 * - none
35 *
36 * Side Effects:
37 * - the users heap and DTree are initialized.
38 */
39 void
40 init_users (void)
41 {
42 #if 0
43 user_heap = BlockHeapCreate (sizeof (user_t), HEAP_USER);
44 #endif
45 }
46
47 /*
48 * user_add(char const * const nick, char const * const user, char const * const host, char const * const vhost, char const * const ip,
49 * char const * const uid, char const * const gecos, server_t *server, time_t ts);
50 *
51 * User object factory.
52 *
53 * Inputs:
54 * - nickname of new user
55 * - username of new user
56 * - hostname of new user
57 * - virtual hostname of new user if applicable otherwise NULL
58 * - ip of user if applicable otherwise NULL
59 * - unique identifier (UID) of user if appliable otherwise NULL
60 * - gecos of new user
61 * - pointer to server new user is on
62 * - user's timestamp
63 *
64 * Outputs:
65 * - on success, a new user
66 * - on failure, NULL
67 *
68 * Side Effects:
69 * - if successful, a user is created and added to the users DTree.
70 *
71 * Bugs:
72 * - this function does not check if a user object by this name already exists
73 */
74 user_t *
75 user_add (char const * const nick, char const * const user, char const * const host, char const * const vhost, char const * const ip, char const * const uid, char const * const gecos, server_t *server, time_t ts)
76 {
77 user_t *u;
78
79 slog (LG_DEBUG, "user_add(): %s (%s@%s) -> %s", nick, user, host, server->name);
80
81 u = new user_t;
82
83 if (uid != NULL)
84 {
85 strlcpy (u->uid, uid, IDLEN);
86 uidlist[u->uid] = u;
87 }
88
89 strlcpy (u->nick, nick, NICKLEN);
90 strlcpy (u->user, user, USERLEN);
91 strlcpy (u->host, host, HOSTLEN);
92 strlcpy (u->gecos, gecos, GECOSLEN);
93
94 if (vhost)
95 strlcpy (u->vhost, vhost, HOSTLEN);
96 else
97 strlcpy (u->vhost, host, HOSTLEN);
98
99 if (ip && strcmp (ip, "0") && strcmp (ip, "0.0.0.0") && strcmp (ip, "255.255.255.255"))
100 strlcpy (u->ip, ip, HOSTIPLEN);
101
102 u->server = server;
103 u->server->users++;
104 node_add (u, node_create (), &u->server->userlist);
105
106 if (ts)
107 u->ts = ts;
108 else
109 u->ts = NOW;
110
111 userlist[u->nick] = u;
112
113 cnt.user++;
114
115 u->callback.add (u);
116
117 return u;
118 }
119
120 /*
121 * user_delete(user_t *u)
122 *
123 * Destroys a user object and deletes the object from the users DTree.
124 *
125 * Inputs:
126 * - user object to delete
127 *
128 * Outputs:
129 * - nothing
130 *
131 * Side Effects:
132 * - on success, a user is deleted from the users DTree.
133 */
134 void
135 user_delete (user_t *u)
136 {
137 node_t *n, *tn;
138 chanuser_t *cu;
139 mynick_t *mn;
140
141 if (!u)
142 {
143 slog (LG_DEBUG, "user_delete(): called for NULL user");
144 return;
145 }
146
147 slog (LG_DEBUG, "user_delete(): removing user: %s -> %s", u->nick, u->server->name);
148
149 u->callback.remove (u);
150
151 u->server->users--;
152 if (is_ircop (u))
153 u->server->opers--;
154 if (u->flags & UF_INVIS)
155 u->server->invis--;
156
157 /* remove the user from each channel */
158 LIST_FOREACH_SAFE (n, tn, u->channels.head)
159 {
160 cu = (chanuser_t *) n->data;
161
162 chanuser_delete (cu->chan, u);
163 }
164
165 userlist.erase (u->nick);
166
167 if (*u->uid)
168 uidlist.erase (u->uid);
169
170 n = node_find (u, &u->server->userlist);
171 node_del (n, &u->server->userlist);
172 node_free (n);
173
174 if (u->myuser)
175 {
176 u->myuser->logins.erase (u);
177 u->myuser->lastlogin = NOW;
178 if ((mn = mynick_t::find (u->nick)) != NULL && mn->owner == u->myuser)
179 mn->lastseen = NOW;
180 u->myuser = NULL;
181 }
182
183 delete u;
184
185 cnt.user--;
186 }
187
188 /*
189 * user_find(char const * const nick)
190 *
191 * Finds a user by UID or nickname.
192 *
193 * Inputs:
194 * - nickname or UID to look up
195 *
196 * Outputs:
197 * - on success, the user object that was requested
198 * - on failure, NULL
199 *
200 * Side Effects:
201 * - none
202 */
203 user_t *
204 user_find (char const * const nick)
205 {
206 user_map::iterator it;
207 uid_map::iterator idit;
208
209 if (nick == NULL)
210 return NULL;
211
212 if (ircd->uses_uid == true)
213 {
214 idit = uidlist.find (nick);
215
216 if (idit != uidlist.end ())
217 return idit->second;
218 }
219
220 it = userlist.find (nick);
221
222 if (it != userlist.end ())
223 {
224 if (ircd->uses_p10)
225 wallops (_("user_find(): found user %s by nick!"), nick);
226 return it->second;
227 }
228
229 return NULL;
230 }
231
232 /*
233 * user_find_named(char const * const nick)
234 *
235 * Finds a user by nickname. Prevents chasing users by their UID.
236 *
237 * Inputs:
238 * - nickname to look up
239 *
240 * Outputs:
241 * - on success, the user object that was requested
242 * - on failure, NULL
243 *
244 * Side Effects:
245 * - none
246 */
247 user_t *
248 user_find_named (char const * const nick)
249 {
250 user_map::iterator it = userlist.find (nick);
251
252 if (it != userlist.end ())
253 return it->second;
254
255 return NULL;
256 }
257
258 /*
259 * user_changeuid(user_t *u, char const * const uid)
260 *
261 * Changes a user object's UID.
262 *
263 * Inputs:
264 * - user object to change UID
265 * - new UID
266 *
267 * Outputs:
268 * - nothing
269 *
270 * Side Effects:
271 * - a user object's UID is changed.
272 */
273 void
274 user_changeuid (user_t *u, char const * const uid)
275 {
276 if (*u->uid)
277 uidlist.erase (u->uid);
278
279 strlcpy (u->uid, uid ? uid : "", IDLEN);
280
281 if (*u->uid)
282 uidlist[u->uid] = u;
283 }
284
285 /*
286 * user_changenick(user_t *u, char const * const uid)
287 *
288 * Changes a user object's nick and TS.
289 *
290 * Inputs:
291 * - user object to change
292 * - new nick
293 * - new TS
294 *
295 * Outputs:
296 * - nothing
297 *
298 * Side Effects:
299 * - a user object's nick and TS is changed.
300 */
301 void
302 user_changenick (user_t *u, char const * const nick, time_t ts)
303 {
304 mynick_t *mn;
305
306 if (u->myuser != NULL && (mn = mynick_t::find (u->nick)) != NULL && mn->owner == u->myuser)
307 mn->lastseen = NOW;
308 userlist.erase (u->nick);
309
310 strlcpy (u->nick, nick, NICKLEN);
311 u->ts = ts;
312
313 userlist[u->nick] = u;
314 }
315
316 /*
317 * user_mode(user_t *user, char *modes)
318 *
319 * Changes a user object's modes.
320 *
321 * Inputs:
322 * - user object to change modes on
323 * - modestring describing the usermode change
324 *
325 * Outputs:
326 * - nothing
327 *
328 * Side Effects:
329 * - on success, a user's modes are adjusted.
330 *
331 * Bugs:
332 * - this routine only tracks +i and +o usermode changes.
333 */
334 void
335 user_mode (user_t *u, char const * const modes)
336 {
337 int dir = MTYPE_ADD;
338 char const *modestring = modes;
339
340 if (!u)
341 {
342 slog (LG_DEBUG, "user_mode(): called for nonexistant user");
343 return;
344 }
345
346 while (*modestring != '\0')
347 {
348 switch (*modestring)
349 {
350 case '+':
351 dir = MTYPE_ADD;
352 break;
353 case '-':
354 dir = MTYPE_DEL;
355 break;
356 case 'i':
357 if (dir == MTYPE_ADD)
358 {
359 if (!(u->flags & UF_INVIS))
360 u->server->invis++;
361 u->flags |= UF_INVIS;
362 }
363 else if ((dir = MTYPE_DEL))
364 {
365 if (u->flags & UF_INVIS)
366 u->server->invis--;
367 u->flags &= ~UF_INVIS;
368 }
369 break;
370 case 'o':
371 if (dir == MTYPE_ADD)
372 {
373 if (!is_ircop (u))
374 {
375 u->flags |= UF_IRCOP;
376 slog (LG_DEBUG, "user_mode(): %s is now an IRCop", u->nick);
377 snoop ("OPER: %s (%s)", u->nick, u->server->name);
378 u->server->opers++;
379 u->callback.oper (u);
380 }
381 }
382 else if ((dir = MTYPE_DEL))
383 {
384 if (is_ircop (u))
385 {
386 u->flags &= ~UF_IRCOP;
387 slog (LG_DEBUG, "user_mode(): %s is no longer an IRCop", u->nick);
388 snoop ("DEOPER: %s (%s)", u->nick, u->server->name);
389 u->server->opers--;
390 u->callback.deoper (u);
391 }
392 }
393 default:
394 break;
395 }
396 modestring++;
397 }
398 }