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, 8 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

# User Rev Content
1 pippijn 1.1 /*
2     * servers.C: Server and network state tracking.
3 pippijn 1.6 *
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.7 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 pippijn 1.1
17     #include "atheme.h"
18 pippijn 1.7 #include <libermyth.h>
19 pippijn 1.5 #include "servers.h"
20 pippijn 1.1 #include <account/myuser.h>
21 pippijn 1.7 #include <util/predicates.h>
22 pippijn 1.1
23 pippijn 1.4 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 pippijn 1.7 tld_t::list_type tld_t::list;
28 pippijn 1.4 server_t::callbacks server_t::callback;
29 pippijn 1.1
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 pippijn 1.4 #if 0
49 pippijn 1.1 serv_heap = BlockHeapCreate (sizeof (server_t), HEAP_SERVER);
50     tld_heap = BlockHeapCreate (sizeof (tld_t), 4);
51 pippijn 1.4 #endif
52 pippijn 1.1 }
53    
54     /*
55 pippijn 1.4 * server_add(char const * const name, unsigned int hops, char const * const uplink,
56     * char const * const id, char const * const desc)
57 pippijn 1.1 *
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 pippijn 1.4 server_add (char const * const name, unsigned int hops, char const * const uplink, char const * const id, char const * const description)
75 pippijn 1.1 {
76     server_t *s, *u = NULL;
77 pippijn 1.4 char const *tld;
78     char const *desc = description;
79 pippijn 1.1
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 pippijn 1.4 s = new server_t;
92 pippijn 1.1
93     if (id != NULL)
94     {
95     s->sid = sstrdup (id);
96 pippijn 1.4 sidlist[s->sid] = s;
97 pippijn 1.1 }
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 pippijn 1.4 servlist[s->name] = s;
114 pippijn 1.1
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 pippijn 1.5 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 pippijn 1.1 /*
150 pippijn 1.4 * server_delete(char const * const name)
151 pippijn 1.1 *
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 pippijn 1.5 server_delete (server_t *s, bool force)
165 pippijn 1.1 {
166     server_t *child;
167     user_t *u;
168     node_t *n, *tn;
169    
170 pippijn 1.5 if (!force && s == me.me)
171 pippijn 1.1 {
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 pippijn 1.4 servlist.erase (s->name);
202 pippijn 1.1
203     if (s->sid)
204 pippijn 1.4 sidlist.erase (s->sid);
205 pippijn 1.1
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 pippijn 1.4 phandler->jupe (s->name, "Juped");
218 pippijn 1.1
219 pippijn 1.4 sfree (s->name);
220     sfree (s->desc);
221 pippijn 1.1 if (s->sid)
222 pippijn 1.4 sfree (s->sid);
223 pippijn 1.1
224 pippijn 1.4 delete s;
225 pippijn 1.1
226     cnt.server--;
227     }
228    
229     /*
230 pippijn 1.4 * server_find(char const * const name)
231 pippijn 1.1 *
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 pippijn 1.4 server_find (char const * const name)
246 pippijn 1.1 {
247 pippijn 1.4 server_map::iterator it;
248 pippijn 1.1
249     if (ircd->uses_uid)
250     {
251 pippijn 1.4 it = sidlist.find (name);
252     if (it != sidlist.end ())
253     return it->second;
254 pippijn 1.1 }
255    
256 pippijn 1.4 return ((it = servlist.find (name)) == servlist.end ()
257     ? NULL
258     : it->second);
259 pippijn 1.1 }
260    
261     /*
262 pippijn 1.4 * tld_add(char const * const name)
263 pippijn 1.1 *
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 pippijn 1.4 tld_add (char const * const name)
278 pippijn 1.1 {
279     tld_t *tld;
280    
281     slog (LG_DEBUG, "tld_add(): %s", name);
282    
283 pippijn 1.4 tld = new tld_t;
284 pippijn 1.1
285 pippijn 1.7 tld_t::list.insert (tld);
286 pippijn 1.1
287     tld->name = sstrdup (name);
288    
289     cnt.tld++;
290    
291     return tld;
292     }
293    
294     /*
295 pippijn 1.4 * tld_delete(char const * const name)
296 pippijn 1.1 *
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 pippijn 1.7 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 pippijn 1.4 tld_delete (char const * const name)
323 pippijn 1.1 {
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 pippijn 1.7 tld_delete (tld);
334 pippijn 1.1 }
335    
336     /*
337 pippijn 1.4 * tld_find(char const * const name)
338 pippijn 1.1 *
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 pippijn 1.4 tld_find (char const * const name)
353 pippijn 1.1 {
354     if (name == NULL)
355     return NULL;
356    
357 pippijn 1.7 foreach (tld_t *tld, tld_t::list)
358 pippijn 1.1 if (!strcasecmp (name, tld->name))
359     return tld;
360    
361     return NULL;
362     }
363    
364 pippijn 1.7 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     }