ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/ermyth/src/users.C
Revision: 1.5
Committed: Sun Sep 9 20:05:53 2007 UTC (16 years, 8 months ago) by pippijn
Content type: text/plain
Branch: MAIN
Changes since 1.4: +4 -3 lines
Log Message:
- changed configurations to the c++ stdlib
- more #defines to enum
- removed getopt.h and link.h from the system as they were unused
- reworked logstreams
- added an itoa with old syntax
- made klines objects
- moved some global variables into appropriate classes
- fixed boost.foreach's compiler workaround #if's
- allow other files to add exceptions with ADD_EXCEPTION
- changed mynick_t to c++ object
- moved servers.h out of atheme.h
- corrected PING from inspircd 1.2

File Contents

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