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

# User Rev Content
1 pippijn 1.1 /*
2     * users.C: User management.
3 pippijn 1.2 * Rights to this code are documented in doc/pod/license.pod.
4 pippijn 1.1 *
5 pippijn 1.4 * Copyright © 2005-2007 Atheme Project (http://www.atheme.org)
6 pippijn 1.1 */
7    
8 pippijn 1.5 static char const rcsid[] = "$Id: users.C,v 1.4 2007-08-28 17:08:12 pippijn Exp $";
9 pippijn 1.1
10     #include "atheme.h"
11 pippijn 1.5 #include "servers.h"
12 pippijn 1.1 #include <account/mynick.h>
13     #include <account/myuser.h>
14    
15 pippijn 1.4 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 pippijn 1.1
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 pippijn 1.4 #if 0
38 pippijn 1.1 user_heap = BlockHeapCreate (sizeof (user_t), HEAP_USER);
39 pippijn 1.4 #endif
40 pippijn 1.1 }
41    
42     /*
43 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,
44     * char const * const uid, char const * const gecos, server_t *server, time_t ts);
45 pippijn 1.1 *
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 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)
71 pippijn 1.1 {
72     user_t *u;
73    
74     slog (LG_DEBUG, "user_add(): %s (%s@%s) -> %s", nick, user, host, server->name);
75    
76 pippijn 1.4 u = new user_t;
77 pippijn 1.1
78     if (uid != NULL)
79     {
80     strlcpy (u->uid, uid, IDLEN);
81 pippijn 1.4 uidlist[u->uid] = u;
82 pippijn 1.1 }
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 pippijn 1.4 userlist[u->nick] = u;
107 pippijn 1.1
108     cnt.user++;
109    
110 pippijn 1.4 u->callback.add (u);
111 pippijn 1.1
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 pippijn 1.4 u->callback.remove (u);
145 pippijn 1.1
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 pippijn 1.4 userlist.erase (u->nick);
161 pippijn 1.1
162     if (*u->uid)
163 pippijn 1.4 uidlist.erase (u->uid);
164 pippijn 1.1
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 pippijn 1.5 if ((mn = mynick_t::find (u->nick)) != NULL && mn->owner == u->myuser)
174 pippijn 1.1 mn->lastseen = NOW;
175     u->myuser = NULL;
176     }
177    
178 pippijn 1.4 delete u;
179 pippijn 1.1
180     cnt.user--;
181     }
182    
183     /*
184 pippijn 1.4 * user_find(char const * const nick)
185 pippijn 1.1 *
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 pippijn 1.4 user_find (char const * const nick)
200 pippijn 1.1 {
201 pippijn 1.4 user_map::iterator it;
202     uid_map::iterator idit;
203 pippijn 1.1
204     if (nick == NULL)
205     return NULL;
206    
207     if (ircd->uses_uid == true)
208     {
209 pippijn 1.4 idit = uidlist.find (nick);
210 pippijn 1.1
211 pippijn 1.4 if (idit != uidlist.end ())
212     return idit->second;
213 pippijn 1.1 }
214    
215 pippijn 1.4 it = userlist.find (nick);
216 pippijn 1.1
217 pippijn 1.4 if (it != userlist.end ())
218 pippijn 1.1 {
219     if (ircd->uses_p10)
220     wallops (_("user_find(): found user %s by nick!"), nick);
221 pippijn 1.4 return it->second;
222 pippijn 1.1 }
223    
224     return NULL;
225     }
226    
227     /*
228 pippijn 1.4 * user_find_named(char const * const nick)
229 pippijn 1.1 *
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 pippijn 1.4 user_find_named (char const * const nick)
244 pippijn 1.1 {
245 pippijn 1.4 user_map::iterator it = userlist.find (nick);
246    
247     if (it != userlist.end ())
248     return it->second;
249    
250     return NULL;
251 pippijn 1.1 }
252    
253     /*
254 pippijn 1.4 * user_changeuid(user_t *u, char const * const uid)
255 pippijn 1.1 *
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 pippijn 1.4 user_changeuid (user_t *u, char const * const uid)
270 pippijn 1.1 {
271     if (*u->uid)
272 pippijn 1.4 uidlist.erase (u->uid);
273 pippijn 1.1
274     strlcpy (u->uid, uid ? uid : "", IDLEN);
275    
276     if (*u->uid)
277 pippijn 1.4 uidlist[u->uid] = u;
278 pippijn 1.1 }
279    
280     /*
281 pippijn 1.4 * user_changenick(user_t *u, char const * const uid)
282 pippijn 1.1 *
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 pippijn 1.4 user_changenick (user_t *u, char const * const nick, time_t ts)
298 pippijn 1.1 {
299     mynick_t *mn;
300    
301 pippijn 1.5 if (u->myuser != NULL && (mn = mynick_t::find (u->nick)) != NULL && mn->owner == u->myuser)
302 pippijn 1.1 mn->lastseen = NOW;
303 pippijn 1.4 userlist.erase (u->nick);
304 pippijn 1.1
305     strlcpy (u->nick, nick, NICKLEN);
306     u->ts = ts;
307    
308 pippijn 1.4 userlist[u->nick] = u;
309 pippijn 1.1 }
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 pippijn 1.4 user_mode (user_t *u, char const * const modes)
331 pippijn 1.1 {
332     int dir = MTYPE_ADD;
333 pippijn 1.4 char const *modestring = modes;
334 pippijn 1.1
335 pippijn 1.4 if (!u)
336 pippijn 1.1 {
337     slog (LG_DEBUG, "user_mode(): called for nonexistant user");
338     return;
339     }
340    
341 pippijn 1.4 while (*modestring != '\0')
342 pippijn 1.1 {
343 pippijn 1.4 switch (*modestring)
344 pippijn 1.1 {
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 pippijn 1.4 if (!(u->flags & UF_INVIS))
355     u->server->invis++;
356     u->flags |= UF_INVIS;
357 pippijn 1.1 }
358     else if ((dir = MTYPE_DEL))
359     {
360 pippijn 1.4 if (u->flags & UF_INVIS)
361     u->server->invis--;
362     u->flags &= ~UF_INVIS;
363 pippijn 1.1 }
364     break;
365     case 'o':
366     if (dir == MTYPE_ADD)
367     {
368 pippijn 1.4 if (!is_ircop (u))
369 pippijn 1.1 {
370 pippijn 1.4 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 pippijn 1.1 }
376     }
377     else if ((dir = MTYPE_DEL))
378     {
379 pippijn 1.4 if (is_ircop (u))
380 pippijn 1.1 {
381 pippijn 1.4 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 pippijn 1.1 }
387     }
388     default:
389     break;
390     }
391 pippijn 1.4 modestring++;
392 pippijn 1.1 }
393     }