ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/ermyth/src/account.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: +45 -68 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

# User Rev Content
1 pippijn 1.1 /**
2     * account.C: Account 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 © 2007 Pippijn van Steenhoven / The Ermyth Team
6     * Copyright © 2005-2007 Atheme Project (http://www.atheme.org)
7 pippijn 1.1 */
8    
9 pippijn 1.4 static char const rcsid[] = "$Id: account.C,v 1.3 2007-07-21 13:23:21 pippijn Exp $";
10    
11     #include <boost/foreach.hpp>
12 pippijn 1.1
13     #include "atheme.h"
14     #include <account/myuser.h>
15     #include <account/mynick.h>
16     #include <account/mychan.h>
17     #include <account/chanacs.h>
18     #include "uplink.h" /* XXX, for sendq_flush(curr_uplink->conn); */
19     #include "datastream.h"
20     #include "privs.h"
21    
22     /*
23     * init_accounts()
24     *
25     * Initializes the accounts DTree.
26     *
27     * Inputs:
28     * - none
29     *
30     * Outputs:
31     * - none
32     *
33     * Side Effects:
34     * - if the DTree initialization fails, services will abort.
35     */
36     void
37     init_accounts (void)
38     {
39     #if 0
40     myuser_heap = BlockHeapCreate (sizeof (myuser_t), HEAP_USER);
41     mynick_heap = BlockHeapCreate (sizeof (myuser_t), HEAP_USER);
42     mychan_heap = BlockHeapCreate (sizeof (mychan_t), HEAP_CHANNEL);
43     chanacs_heap = BlockHeapCreate (sizeof (chanacs_t), HEAP_CHANUSER);
44     metadata_heap = BlockHeapCreate (sizeof (metadata_t), HEAP_CHANUSER);
45     #endif
46    
47     mclist = dictionary_create ("mychan", HASH_CHANNEL, irccasecmp);
48     }
49    
50     static int
51 pippijn 1.4 expire_myuser_cb (myuser_pair &mup)
52 pippijn 1.1 {
53 pippijn 1.4 myuser_t *mu = mup.second;
54 pippijn 1.1
55     /* If they're logged in, update lastlogin time.
56     * To decrease db traffic, may want to only do
57     * this if the account would otherwise be
58     * deleted. -- jilles
59     */
60     if (!mu->logins.empty ())
61     {
62     mu->lastlogin = NOW;
63     return 0;
64     }
65    
66     if (MU_HOLD & mu->flags)
67     return 0;
68    
69     if (((NOW - mu->lastlogin) >= nicksvs.expiry) || ((mu->flags & MU_WAITAUTH) && (NOW - mu->registered >= 86400)))
70     {
71     /* Don't expire accounts with privs on them in atheme.conf,
72     * otherwise someone can reregister
73     * them and take the privs -- jilles */
74     if (is_conf_soper (mu))
75     return 0;
76    
77     snoop (_("EXPIRE: \2%s\2 from \2%s\2 "), mu->name, mu->email);
78     slog (LG_REGISTER, "expire_check(): expiring account %s (unused %ds, email %s, nicks %d, chanacs %d)", mu->name, (int) (NOW - mu->lastlogin), mu->email, LIST_LENGTH (&mu->nicks), LIST_LENGTH (&mu->chanacs));
79     mu->refcnt_dec ();
80     }
81    
82     return 0;
83     }
84    
85     void
86     expire_check (void *arg)
87     {
88     mynick_t *mn;
89     mychan_t *mc;
90     user_t *u;
91     dictionary_iteration_state_t state;
92    
93     /* Let them know about this and the likely subsequent db_save()
94     * right away -- jilles */
95     sendq_flush (curr_uplink->conn);
96    
97     if (nicksvs.expiry != 0)
98     {
99 pippijn 1.4 std::for_each (mulist.begin (), mulist.end (), expire_myuser_cb);
100 pippijn 1.1
101 pippijn 1.4 foreach (mynick_pair &mnp, nicklist)
102     {
103     mn = mnp.second;
104     if ((NOW - mn->lastseen) >= nicksvs.expiry)
105     {
106     if (MU_HOLD & mn->owner->flags)
107     continue;
108    
109     /* do not drop main nick like this */
110     if (!irccasecmp (mn->nick, mn->owner->name))
111     continue;
112    
113     u = user_find_named (mn->nick);
114     if (u != NULL && u->myuser == mn->owner)
115     {
116     /* still logged in, bleh */
117     mn->lastseen = NOW;
118     mn->owner->lastlogin = NOW;
119     continue;
120     }
121    
122     snoop (_("EXPIRE: \2%s\2 from \2%s\2"), mn->nick, mn->owner->name);
123     slog (LG_REGISTER, "expire_check(): expiring nick %s (unused %ds, account %s)", mn->nick, NOW - mn->lastseen, mn->owner->name);
124     object_unref (mn);
125     }
126     }
127 pippijn 1.1 }
128 pippijn 1.4
129 pippijn 1.1 if (chansvs.expiry != 0)
130     {
131     DICTIONARY_FOREACH (mc, mychan_t, &state, mclist)
132     {
133     if ((NOW - mc->used) >= 86400 - 3660)
134     {
135     /* keep last used time accurate to
136     * within a day, making sure an active
137     * channel will never get "Last used"
138     * in /cs info -- jilles */
139     if (mychan_isused (mc))
140     {
141     mc->used = NOW;
142     slog (LG_DEBUG, "expire_check(): updating last used time on %s because it appears to be still in use", mc->name);
143     continue;
144     }
145     }
146    
147     if ((NOW - mc->used) >= chansvs.expiry)
148     {
149     if (MC_HOLD & mc->flags)
150     continue;
151    
152 pippijn 1.4 snoop (_("EXPIRE: \2%s\2 from \2%s\2"), mc->name, mychan_founder_names (mc));
153     slog (LG_REGISTER, "expire_check(): expiring channel %s (unused %ds, founder %s, chanacs %d)",
154     mc->name,
155     NOW - mc->used,
156     mychan_founder_names (mc),
157     LIST_LENGTH (&mc->chanacs));
158 pippijn 1.1
159 pippijn 1.4 mc->callback.drop (mc);
160 pippijn 1.1 if ((config_options.chan && irccasecmp (mc->name, config_options.chan)) || !config_options.chan)
161     part (mc->name, chansvs.nick);
162    
163     mc->refcnt_dec ();
164     }
165     }
166     }
167     }
168    
169     static int
170 pippijn 1.4 check_myuser_cb (myuser_pair &mup)
171 pippijn 1.1 {
172 pippijn 1.4 myuser_t *mu = mup.second;
173 pippijn 1.1 mynick_t *mn;
174    
175     if (MU_OLD_ALIAS & mu->flags)
176     {
177     slog (LG_REGISTER, "db_check(): converting previously linked nick %s to a standalone nick", mu->name);
178     mu->flags &= ~MU_OLD_ALIAS;
179     mu->del_metadata ("private:alias:parent");
180     }
181    
182     if (!nicksvs.no_nick_ownership)
183     {
184     mn = mynick_find (mu->name);
185     if (mn == NULL)
186     {
187     slog (LG_REGISTER, "db_check(): adding missing nick %s", mu->name);
188     mn = mynick_add (mu, mu->name);
189     mn->registered = mu->registered;
190     mn->lastseen = mu->lastlogin;
191     }
192     else if (mn->owner != mu)
193     {
194     slog (LG_REGISTER, "db_check(): replacing nick %s owned by %s with %s", mn->nick, mn->owner->name, mu->name);
195     object_unref (mn);
196     mn = mynick_add (mu, mu->name);
197     mn->registered = mu->registered;
198     mn->lastseen = mu->lastlogin;
199     }
200     }
201    
202     return 0;
203     }
204    
205     void
206     db_check ()
207     {
208 pippijn 1.4 std::for_each (mulist.begin (), mulist.end (), check_myuser_cb);
209 pippijn 1.1 }