ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/ermyth/src/users.C
Revision: 1.4
Committed: Tue Aug 28 17:08:12 2007 UTC (16 years, 9 months ago) by pippijn
Content type: text/plain
Branch: MAIN
Changes since 1.3: +69 -69 lines
Log Message:
- changed name
- updated the example config to the new system
- added more documentation
- enhanced documentation generators
- added a link to the pdf to the website
- added an RSS feed generator
- transitioned hooks to c++ callbacks
- did various merges with upstream along the way
- added const where appropriate
- removed the old block allocator
- fixed most memory leaks
- transitioned some dictionaries to std::map
- transitioned some lists to std::vector
- made some free functions members where appropriate
- renamed string to dynstr and added a static string ststr
- use NOW instead of time (NULL) if possible
- completely reworked database backends, crypto handlers and protocol handlers
  to use an object factory
- removed the old module system. ermyth does not do any dynamic loading anymore
- fixed most of the build system
- reworked how protocol commands work

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