ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/ermyth/src/account.C
Revision: 1.9
Committed: Sat Sep 22 14:27:30 2007 UTC (16 years, 8 months ago) by pippijn
Content type: text/plain
Branch: MAIN
CVS Tags: HEAD
Changes since 1.8: +2 -1 lines
Log Message:
split up ermyth into ermyth-modules, libermyth (currently just ermyth-util) and ermyth-core

File Contents

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