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

# User Rev Content
1 pippijn 1.1 /*
2     * users.C: User management.
3 pippijn 1.6 *
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 pippijn 1.2 * Rights to this code are documented in doc/pod/license.pod.
10 pippijn 1.4 * Copyright © 2005-2007 Atheme Project (http://www.atheme.org)
11 pippijn 1.1 */
12    
13 pippijn 1.6 static char const rcsid[] = "$Id: users.C,v 1.5 2007-09-09 20:05:53 pippijn Exp $";
14 pippijn 1.1
15     #include "atheme.h"
16 pippijn 1.5 #include "servers.h"
17 pippijn 1.1 #include <account/mynick.h>
18     #include <account/myuser.h>
19    
20 pippijn 1.4 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 pippijn 1.1
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 pippijn 1.4 #if 0
43 pippijn 1.1 user_heap = BlockHeapCreate (sizeof (user_t), HEAP_USER);
44 pippijn 1.4 #endif
45 pippijn 1.1 }
46    
47     /*
48 pippijn 1.4 * 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 pippijn 1.1 *
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 pippijn 1.4 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 pippijn 1.1 {
77     user_t *u;
78    
79     slog (LG_DEBUG, "user_add(): %s (%s@%s) -> %s", nick, user, host, server->name);
80    
81 pippijn 1.4 u = new user_t;
82 pippijn 1.1
83     if (uid != NULL)
84     {
85     strlcpy (u->uid, uid, IDLEN);
86 pippijn 1.4 uidlist[u->uid] = u;
87 pippijn 1.1 }
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 pippijn 1.4 userlist[u->nick] = u;
112 pippijn 1.1
113     cnt.user++;
114    
115 pippijn 1.4 u->callback.add (u);
116 pippijn 1.1
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 pippijn 1.4 u->callback.remove (u);
150 pippijn 1.1
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 pippijn 1.4 userlist.erase (u->nick);
166 pippijn 1.1
167     if (*u->uid)
168 pippijn 1.4 uidlist.erase (u->uid);
169 pippijn 1.1
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 pippijn 1.5 if ((mn = mynick_t::find (u->nick)) != NULL && mn->owner == u->myuser)
179 pippijn 1.1 mn->lastseen = NOW;
180     u->myuser = NULL;
181     }
182    
183 pippijn 1.4 delete u;
184 pippijn 1.1
185     cnt.user--;
186     }
187    
188     /*
189 pippijn 1.4 * user_find(char const * const nick)
190 pippijn 1.1 *
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 pippijn 1.4 user_find (char const * const nick)
205 pippijn 1.1 {
206 pippijn 1.4 user_map::iterator it;
207     uid_map::iterator idit;
208 pippijn 1.1
209     if (nick == NULL)
210     return NULL;
211    
212     if (ircd->uses_uid == true)
213     {
214 pippijn 1.4 idit = uidlist.find (nick);
215 pippijn 1.1
216 pippijn 1.4 if (idit != uidlist.end ())
217     return idit->second;
218 pippijn 1.1 }
219    
220 pippijn 1.4 it = userlist.find (nick);
221 pippijn 1.1
222 pippijn 1.4 if (it != userlist.end ())
223 pippijn 1.1 {
224     if (ircd->uses_p10)
225     wallops (_("user_find(): found user %s by nick!"), nick);
226 pippijn 1.4 return it->second;
227 pippijn 1.1 }
228    
229     return NULL;
230     }
231    
232     /*
233 pippijn 1.4 * user_find_named(char const * const nick)
234 pippijn 1.1 *
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 pippijn 1.4 user_find_named (char const * const nick)
249 pippijn 1.1 {
250 pippijn 1.4 user_map::iterator it = userlist.find (nick);
251    
252     if (it != userlist.end ())
253     return it->second;
254    
255     return NULL;
256 pippijn 1.1 }
257    
258     /*
259 pippijn 1.4 * user_changeuid(user_t *u, char const * const uid)
260 pippijn 1.1 *
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 pippijn 1.4 user_changeuid (user_t *u, char const * const uid)
275 pippijn 1.1 {
276     if (*u->uid)
277 pippijn 1.4 uidlist.erase (u->uid);
278 pippijn 1.1
279     strlcpy (u->uid, uid ? uid : "", IDLEN);
280    
281     if (*u->uid)
282 pippijn 1.4 uidlist[u->uid] = u;
283 pippijn 1.1 }
284    
285     /*
286 pippijn 1.4 * user_changenick(user_t *u, char const * const uid)
287 pippijn 1.1 *
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 pippijn 1.4 user_changenick (user_t *u, char const * const nick, time_t ts)
303 pippijn 1.1 {
304     mynick_t *mn;
305    
306 pippijn 1.5 if (u->myuser != NULL && (mn = mynick_t::find (u->nick)) != NULL && mn->owner == u->myuser)
307 pippijn 1.1 mn->lastseen = NOW;
308 pippijn 1.4 userlist.erase (u->nick);
309 pippijn 1.1
310     strlcpy (u->nick, nick, NICKLEN);
311     u->ts = ts;
312    
313 pippijn 1.4 userlist[u->nick] = u;
314 pippijn 1.1 }
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 pippijn 1.4 user_mode (user_t *u, char const * const modes)
336 pippijn 1.1 {
337     int dir = MTYPE_ADD;
338 pippijn 1.4 char const *modestring = modes;
339 pippijn 1.1
340 pippijn 1.4 if (!u)
341 pippijn 1.1 {
342     slog (LG_DEBUG, "user_mode(): called for nonexistant user");
343     return;
344     }
345    
346 pippijn 1.4 while (*modestring != '\0')
347 pippijn 1.1 {
348 pippijn 1.4 switch (*modestring)
349 pippijn 1.1 {
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 pippijn 1.4 if (!(u->flags & UF_INVIS))
360     u->server->invis++;
361     u->flags |= UF_INVIS;
362 pippijn 1.1 }
363     else if ((dir = MTYPE_DEL))
364     {
365 pippijn 1.4 if (u->flags & UF_INVIS)
366     u->server->invis--;
367     u->flags &= ~UF_INVIS;
368 pippijn 1.1 }
369     break;
370     case 'o':
371     if (dir == MTYPE_ADD)
372     {
373 pippijn 1.4 if (!is_ircop (u))
374 pippijn 1.1 {
375 pippijn 1.4 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 pippijn 1.1 }
381     }
382     else if ((dir = MTYPE_DEL))
383     {
384 pippijn 1.4 if (is_ircop (u))
385 pippijn 1.1 {
386 pippijn 1.4 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 pippijn 1.1 }
392     }
393     default:
394     break;
395     }
396 pippijn 1.4 modestring++;
397 pippijn 1.1 }
398     }