ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/ermyth/src/servers.C
Revision: 1.3
Committed: Sat Jul 21 13:23:22 2007 UTC (16 years, 10 months ago) by pippijn
Content type: text/plain
Branch: MAIN
Changes since 1.2: +1 -1 lines
Log Message:
- added rcsid to some files
- more documentation tweaks
- made most protocol commands local to phandler.C
- added ircd metadata (inspircd only for now)
- added inspircd swhois support

File Contents

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