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

File Contents

# Content
1 /*
2 * servers.C: Server and network state tracking.
3 *
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 * Rights to this code are documented in doc/pod/license.pod.
10 * Copyright © 2005-2007 Atheme Project (http://www.atheme.org)
11 */
12
13 static char const rcsid[] = "$Id: servers.C,v 1.6 2007-09-16 18:54:45 pippijn Exp $";
14
15 #include <boost/foreach.hpp>
16
17 #include "atheme.h"
18 #include <libermyth.h>
19 #include "servers.h"
20 #include <account/myuser.h>
21 #include <util/predicates.h>
22
23 typedef std::pair<char const * const, server_t *> server_pair;
24 typedef std::map<char const * const, server_t *, irccase_lt> server_map;
25 server_map sidlist;
26 server_map servlist;
27 tld_t::list_type tld_t::list;
28 server_t::callbacks server_t::callback;
29
30 /*
31 * init_servers()
32 *
33 * Initializes the server heap and server/sid DTree structures.
34 *
35 * Inputs:
36 * - nothing
37 *
38 * Outputs:
39 * - nothing
40 *
41 * Side Effects:
42 * - if the heap or dtrees fail to initialize, the program
43 * will abort.
44 */
45 void
46 init_servers (void)
47 {
48 #if 0
49 serv_heap = BlockHeapCreate (sizeof (server_t), HEAP_SERVER);
50 tld_heap = BlockHeapCreate (sizeof (tld_t), 4);
51 #endif
52 }
53
54 /*
55 * server_add(char const * const name, unsigned int hops, char const * const uplink,
56 * char const * const id, char const * const desc)
57 *
58 * Server object factory.
59 *
60 * Inputs:
61 * - name of server object to create
62 * - amount of hops server has from services
63 * - name of server's uplink or NULL if it's us
64 * - SID of uplink if applicable otherwise NULL
65 * - server's description
66 *
67 * Outputs:
68 * - on success, a new server object
69 *
70 * Side Effects:
71 * - the new server object is added to the server and sid DTree.
72 */
73 server_t *
74 server_add (char const * const name, unsigned int hops, char const * const uplink, char const * const id, char const * const description)
75 {
76 server_t *s, *u = NULL;
77 char const *tld;
78 char const *desc = description;
79
80 if (uplink)
81 {
82 if (id != NULL)
83 slog (LG_NETWORK, "server_add(): %s (%s), uplink %s", name, id, uplink);
84 else
85 slog (LG_NETWORK, "server_add(): %s, uplink %s", name, uplink);
86 u = server_find (uplink);
87 }
88 else
89 slog (LG_DEBUG, "server_add(): %s, root", name);
90
91 s = new server_t;
92
93 if (id != NULL)
94 {
95 s->sid = sstrdup (id);
96 sidlist[s->sid] = s;
97 }
98
99 /* check to see if it's hidden */
100 if (!strncmp (desc, "(H)", 3))
101 {
102 s->flags |= SF_HIDE;
103 desc += 3;
104 if (*desc == ' ')
105 desc++;
106 }
107
108 s->name = sstrdup (name);
109 s->desc = sstrdup (desc);
110 s->hops = hops;
111 s->connected_since = NOW;
112
113 servlist[s->name] = s;
114
115 if (u)
116 {
117 s->uplink = u;
118 node_add (s, node_create (), &u->children);
119 }
120
121 /* tld list for global noticer */
122 tld = strrchr (name, '.');
123
124 if (tld != NULL)
125 {
126 if (!tld_find (tld))
127 tld_add (tld);
128 }
129
130 cnt.server++;
131
132 return s;
133 }
134
135 void
136 server_delete (char const * const name)
137 {
138 server_t *s = server_find (name);
139 server_delete (s);
140
141 if (!s)
142 {
143 slog (LG_DEBUG, "server_delete(): called for nonexistant server: %s", name);
144
145 return;
146 }
147 }
148
149 /*
150 * server_delete(char const * const name)
151 *
152 * Finds and recursively destroys a server object.
153 *
154 * Inputs:
155 * - name of server to find and destroy
156 *
157 * Outputs:
158 * - nothing
159 *
160 * Side Effects:
161 * - all users and servers attached to the target are recursively deleted
162 */
163 void
164 server_delete (server_t *s, bool force)
165 {
166 server_t *child;
167 user_t *u;
168 node_t *n, *tn;
169
170 if (!force && s == me.me)
171 {
172 /* Deleting this would cause confusion, so let's not do it.
173 * Some ircds send SQUIT <myname> when we are squitted.
174 * -- jilles
175 */
176 slog (LG_DEBUG, "server_delete(): tried to delete myself");
177 return;
178 }
179
180 slog (me.connected ? LG_NETWORK : LG_DEBUG, "server_delete(): %s, uplink %s (%d users)", s->name, s->uplink != NULL ? s->uplink->name : "<none>", s->users);
181
182 /* first go through it's users and kill all of them */
183 LIST_FOREACH_SAFE (n, tn, s->userlist.head)
184 {
185 u = (user_t *) n->data;
186 /* This user split, allow bursted logins for the account.
187 * XXX should we do this here?
188 * -- jilles */
189 if (u->myuser != NULL)
190 u->myuser->flags &= ~MU_NOBURSTLOGIN;
191 user_delete (u);
192 }
193
194 LIST_FOREACH_SAFE (n, tn, s->children.head)
195 {
196 child = static_cast<server_t *> (n->data);
197 server_delete (child->name);
198 }
199
200 /* now remove the server */
201 servlist.erase (s->name);
202
203 if (s->sid)
204 sidlist.erase (s->sid);
205
206 if (s->uplink)
207 {
208 n = node_find (s, &s->uplink->children);
209 node_del (n, &s->uplink->children);
210 node_free (n);
211 }
212
213 /* If unconnect semantics SQUIT was confirmed, introduce the jupe
214 * now. This must be after removing the server from the dtrees.
215 * -- jilles */
216 if (s->flags & SF_JUPE_PENDING)
217 phandler->jupe (s->name, "Juped");
218
219 sfree (s->name);
220 sfree (s->desc);
221 if (s->sid)
222 sfree (s->sid);
223
224 delete s;
225
226 cnt.server--;
227 }
228
229 /*
230 * server_find(char const * const name)
231 *
232 * Finds a server object.
233 *
234 * Inputs:
235 * - name of server to find
236 *
237 * Outputs:
238 * - on success, the server object
239 * - on failure, NULL.
240 *
241 * Side Effects:
242 * - none
243 */
244 server_t *
245 server_find (char const * const name)
246 {
247 server_map::iterator it;
248
249 if (ircd->uses_uid)
250 {
251 it = sidlist.find (name);
252 if (it != sidlist.end ())
253 return it->second;
254 }
255
256 return ((it = servlist.find (name)) == servlist.end ()
257 ? NULL
258 : it->second);
259 }
260
261 /*
262 * tld_add(char const * const name)
263 *
264 * TLD object factory.
265 *
266 * Inputs:
267 * - name of TLD to cache as an object
268 *
269 * Outputs:
270 * - on success, a TLD object
271 * - on failure, NULL
272 *
273 * Side Effects:
274 * - the TLD object is registered with the TLD list.
275 */
276 tld_t *
277 tld_add (char const * const name)
278 {
279 tld_t *tld;
280
281 slog (LG_DEBUG, "tld_add(): %s", name);
282
283 tld = new tld_t;
284
285 tld_t::list.insert (tld);
286
287 tld->name = sstrdup (name);
288
289 cnt.tld++;
290
291 return tld;
292 }
293
294 /*
295 * tld_delete(char const * const name)
296 *
297 * Destroys a TLD object.
298 *
299 * Inputs:
300 * - name of TLD object to destroy
301 *
302 * Outputs:
303 * - nothing
304 *
305 * Side Effects:
306 * - the TLD object is removed and deregistered from the TLD list.
307 */
308 void
309 tld_delete (tld_t *tld)
310 {
311 slog (LG_DEBUG, "tld_delete(): %s", tld->name);
312
313 tld_t::list.erase (tld);
314
315 sfree (tld->name);
316 delete tld;
317
318 cnt.tld--;
319 }
320
321 void
322 tld_delete (char const * const name)
323 {
324 tld_t *tld = tld_find (name);
325
326 if (!tld)
327 {
328 slog (LG_DEBUG, "tld_delete(): called for nonexistant tld: %s", name);
329
330 return;
331 }
332
333 tld_delete (tld);
334 }
335
336 /*
337 * tld_find(char const * const name)
338 *
339 * Looks up a TLD object.
340 *
341 * Inputs:
342 * - name of TLD object to look up
343 *
344 * Outputs:
345 * - on success, the TLD object
346 * - on failure, NULL
347 *
348 * Side Effects:
349 * - none
350 */
351 tld_t *
352 tld_find (char const * const name)
353 {
354 if (name == NULL)
355 return NULL;
356
357 foreach (tld_t *tld, tld_t::list)
358 if (!strcasecmp (name, tld->name))
359 return tld;
360
361 return NULL;
362 }
363
364 void
365 tld_cleanup ()
366 {
367 tld_t *tld;
368
369 while (!tld_t::list.empty ())
370 {
371 tld = tld_t::list.back ();
372 sfree (tld->name);
373 delete tld;
374
375 tld_t::list.pop_back ();
376 }
377 }