1 | /** |
1 | /** |
2 | * account.C: Account management |
2 | * account.C: Account management |
3 | * Rights to this code are documented in doc/pod/license.pod. |
3 | * Rights to this code are documented in doc/pod/license.pod. |
4 | * |
4 | * |
|
|
5 | * Copyright © 2007 Pippijn van Steenhoven / The Ermyth Team |
5 | * Copyright © 2005-2007 Atheme Project (http://www.atheme.org) |
6 | * Copyright © 2005-2007 Atheme Project (http://www.atheme.org) |
6 | */ |
7 | */ |
7 | |
8 | |
8 | static char const rcsid[] = "$Id: account.C,v 1.3 2007/07/21 13:23:21 pippijn Exp $"; |
9 | static char const rcsid[] = "$Id: account.C,v 1.4 2007/08/28 17:08:12 pippijn Exp $"; |
|
|
10 | |
|
|
11 | #include <boost/foreach.hpp> |
9 | |
12 | |
10 | #include "atheme.h" |
13 | #include "atheme.h" |
11 | #include <account/myuser.h> |
14 | #include <account/myuser.h> |
12 | #include <account/mynick.h> |
15 | #include <account/mynick.h> |
13 | #include <account/mychan.h> |
16 | #include <account/mychan.h> |
14 | #include <account/chanacs.h> |
17 | #include <account/chanacs.h> |
15 | #include "uplink.h" /* XXX, for sendq_flush(curr_uplink->conn); */ |
18 | #include "uplink.h" /* XXX, for sendq_flush(curr_uplink->conn); */ |
16 | #include "datastream.h" |
19 | #include "datastream.h" |
17 | #include "privs.h" |
20 | #include "privs.h" |
18 | |
21 | |
19 | #if 0 |
|
|
20 | static BlockHeap *myuser_heap; /* HEAP_USER */ |
|
|
21 | static BlockHeap *mynick_heap; /* HEAP_USER */ |
|
|
22 | static BlockHeap *mychan_heap; /* HEAP_CHANNEL */ |
|
|
23 | static BlockHeap *chanacs_heap; /* HEAP_CHANACS */ |
|
|
24 | static BlockHeap *metadata_heap; /* HEAP_CHANUSER */ |
|
|
25 | #endif |
|
|
26 | |
|
|
27 | /* |
22 | /* |
28 | * init_accounts() |
23 | * init_accounts() |
29 | * |
24 | * |
30 | * Initializes the accounts DTree. |
25 | * Initializes the accounts DTree. |
31 | * |
26 | * |
… | |
… | |
45 | myuser_heap = BlockHeapCreate (sizeof (myuser_t), HEAP_USER); |
40 | myuser_heap = BlockHeapCreate (sizeof (myuser_t), HEAP_USER); |
46 | mynick_heap = BlockHeapCreate (sizeof (myuser_t), HEAP_USER); |
41 | mynick_heap = BlockHeapCreate (sizeof (myuser_t), HEAP_USER); |
47 | mychan_heap = BlockHeapCreate (sizeof (mychan_t), HEAP_CHANNEL); |
42 | mychan_heap = BlockHeapCreate (sizeof (mychan_t), HEAP_CHANNEL); |
48 | chanacs_heap = BlockHeapCreate (sizeof (chanacs_t), HEAP_CHANUSER); |
43 | chanacs_heap = BlockHeapCreate (sizeof (chanacs_t), HEAP_CHANUSER); |
49 | metadata_heap = BlockHeapCreate (sizeof (metadata_t), HEAP_CHANUSER); |
44 | metadata_heap = BlockHeapCreate (sizeof (metadata_t), HEAP_CHANUSER); |
50 | |
|
|
51 | if (myuser_heap == NULL || mynick_heap == NULL || mychan_heap == NULL || chanacs_heap == NULL || metadata_heap == NULL) |
|
|
52 | { |
|
|
53 | slog (LG_ERROR, "init_accounts(): block allocator failure."); |
|
|
54 | exit (EXIT_FAILURE); |
|
|
55 | } |
|
|
56 | #endif |
45 | #endif |
57 | |
46 | |
58 | mulist = dictionary_create ("myuser", HASH_USER, irccasecmp); |
|
|
59 | nicklist = dictionary_create ("mynick", HASH_USER, irccasecmp); |
|
|
60 | mclist = dictionary_create ("mychan", HASH_CHANNEL, irccasecmp); |
47 | mclist = dictionary_create ("mychan", HASH_CHANNEL, irccasecmp); |
61 | } |
48 | } |
62 | |
49 | |
63 | static int |
50 | static int |
64 | expire_myuser_cb (dictionary_elem_t *delem, void *unused) |
51 | expire_myuser_cb (myuser_pair &mup) |
65 | { |
52 | { |
66 | myuser_t *mu = static_cast<myuser_t *> (delem->node.data); |
53 | myuser_t *mu = mup.second; |
67 | |
54 | |
68 | /* If they're logged in, update lastlogin time. |
55 | /* If they're logged in, update lastlogin time. |
69 | * To decrease db traffic, may want to only do |
56 | * To decrease db traffic, may want to only do |
70 | * this if the account would otherwise be |
57 | * this if the account would otherwise be |
71 | * deleted. -- jilles |
58 | * deleted. -- jilles |
… | |
… | |
107 | * right away -- jilles */ |
94 | * right away -- jilles */ |
108 | sendq_flush (curr_uplink->conn); |
95 | sendq_flush (curr_uplink->conn); |
109 | |
96 | |
110 | if (nicksvs.expiry != 0) |
97 | if (nicksvs.expiry != 0) |
111 | { |
98 | { |
112 | dictionary_foreach (mulist, expire_myuser_cb, NULL); |
99 | std::for_each (mulist.begin (), mulist.end (), expire_myuser_cb); |
113 | |
100 | |
114 | DICTIONARY_FOREACH (mn, mynick_t, &state, nicklist) |
101 | foreach (mynick_pair &mnp, nicklist) |
115 | { |
102 | { |
|
|
103 | mn = mnp.second; |
116 | if ((NOW - mn->lastseen) >= nicksvs.expiry) |
104 | if ((NOW - mn->lastseen) >= nicksvs.expiry) |
117 | { |
105 | { |
118 | if (MU_HOLD & mn->owner->flags) |
106 | if (MU_HOLD & mn->owner->flags) |
119 | continue; |
107 | continue; |
120 | |
108 | |
121 | /* do not drop main nick like this */ |
109 | /* do not drop main nick like this */ |
122 | if (!irccasecmp (mn->nick, mn->owner->name)) |
110 | if (!irccasecmp (mn->nick, mn->owner->name)) |
123 | continue; |
111 | continue; |
124 | |
112 | |
125 | u = user_find_named (mn->nick); |
113 | u = user_find_named (mn->nick); |
126 | if (u != NULL && u->myuser == mn->owner) |
114 | if (u != NULL && u->myuser == mn->owner) |
127 | { |
115 | { |
128 | /* still logged in, bleh */ |
116 | /* still logged in, bleh */ |
129 | mn->lastseen = NOW; |
117 | mn->lastseen = NOW; |
130 | mn->owner->lastlogin = NOW; |
118 | mn->owner->lastlogin = NOW; |
131 | continue; |
119 | continue; |
132 | } |
120 | } |
133 | |
121 | |
134 | snoop (_("EXPIRE: \2%s\2 from \2%s\2"), mn->nick, mn->owner->name); |
122 | snoop (_("EXPIRE: \2%s\2 from \2%s\2"), mn->nick, mn->owner->name); |
135 | slog (LG_REGISTER, "expire_check(): expiring nick %s (unused %ds, account %s)", mn->nick, NOW - mn->lastseen, mn->owner->name); |
123 | slog (LG_REGISTER, "expire_check(): expiring nick %s (unused %ds, account %s)", mn->nick, NOW - mn->lastseen, mn->owner->name); |
136 | object_unref (mn); |
124 | object_unref (mn); |
137 | } |
125 | } |
138 | } |
126 | } |
139 | } |
127 | } |
140 | |
128 | |
141 | if (chansvs.expiry != 0) |
129 | if (chansvs.expiry != 0) |
142 | { |
130 | { |
143 | DICTIONARY_FOREACH (mc, mychan_t, &state, mclist) |
131 | DICTIONARY_FOREACH (mc, mychan_t, &state, mclist) |
144 | { |
132 | { |
145 | if ((NOW - mc->used) >= 86400 - 3660) |
133 | if ((NOW - mc->used) >= 86400 - 3660) |
… | |
… | |
156 | } |
144 | } |
157 | } |
145 | } |
158 | |
146 | |
159 | if ((NOW - mc->used) >= chansvs.expiry) |
147 | if ((NOW - mc->used) >= chansvs.expiry) |
160 | { |
148 | { |
161 | if (MU_HOLD & mc->founder->flags) |
|
|
162 | continue; |
|
|
163 | |
|
|
164 | if (MC_HOLD & mc->flags) |
149 | if (MC_HOLD & mc->flags) |
165 | continue; |
150 | continue; |
166 | |
151 | |
167 | snoop (_("EXPIRE: \2%s\2 from \2%s\2"), mc->name, mc->founder->name); |
152 | snoop (_("EXPIRE: \2%s\2 from \2%s\2"), mc->name, mychan_founder_names (mc)); |
168 | slog (LG_REGISTER, "expire_check(): expiring channel %s (unused %ds, founder %s, chanacs %d)", mc->name, NOW - mc->used, mc->founder->name, LIST_LENGTH (&mc->chanacs)); |
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)); |
169 | |
158 | |
170 | hook_call_event ("channel_drop", mc); |
159 | mc->callback.drop (mc); |
171 | if ((config_options.chan && irccasecmp (mc->name, config_options.chan)) || !config_options.chan) |
160 | if ((config_options.chan && irccasecmp (mc->name, config_options.chan)) || !config_options.chan) |
172 | part (mc->name, chansvs.nick); |
161 | part (mc->name, chansvs.nick); |
173 | |
162 | |
174 | mc->refcnt_dec (); |
163 | mc->refcnt_dec (); |
175 | } |
164 | } |
176 | } |
165 | } |
177 | } |
166 | } |
178 | } |
167 | } |
179 | |
168 | |
180 | static int |
169 | static int |
181 | check_myuser_cb (dictionary_elem_t *delem, void *unused) |
170 | check_myuser_cb (myuser_pair &mup) |
182 | { |
171 | { |
183 | myuser_t *mu = static_cast<myuser_t *> (delem->node.data); |
172 | myuser_t *mu = mup.second; |
184 | mynick_t *mn; |
173 | mynick_t *mn; |
185 | |
174 | |
186 | if (MU_OLD_ALIAS & mu->flags) |
175 | if (MU_OLD_ALIAS & mu->flags) |
187 | { |
176 | { |
188 | slog (LG_REGISTER, "db_check(): converting previously linked nick %s to a standalone nick", mu->name); |
177 | slog (LG_REGISTER, "db_check(): converting previously linked nick %s to a standalone nick", mu->name); |
… | |
… | |
214 | } |
203 | } |
215 | |
204 | |
216 | void |
205 | void |
217 | db_check () |
206 | db_check () |
218 | { |
207 | { |
219 | mychan_t *mc; |
208 | std::for_each (mulist.begin (), mulist.end (), check_myuser_cb); |
220 | dictionary_iteration_state_t state; |
|
|
221 | |
|
|
222 | dictionary_foreach (mulist, check_myuser_cb, NULL); |
|
|
223 | |
|
|
224 | DICTIONARY_FOREACH (mc, mychan_t, &state, mclist) |
|
|
225 | { |
|
|
226 | if (!chanacs_find (mc, mc->founder, CA_FLAGS)) |
|
|
227 | { |
|
|
228 | slog (LG_REGISTER, "db_check(): adding access for founder on channel %s", mc->name); |
|
|
229 | chanacs_change_simple (mc, mc->founder, NULL, CA_FOUNDER_0, 0); |
|
|
230 | } |
|
|
231 | } |
|
|
232 | } |
209 | } |