ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/ermyth/src/servers.C
Revision: 1.4
Committed: Tue Aug 28 17:08:12 2007 UTC (16 years, 9 months ago) by pippijn
Content type: text/plain
Branch: MAIN
Changes since 1.3: +44 -48 lines
Log Message:
- changed name
- updated the example config to the new system
- added more documentation
- enhanced documentation generators
- added a link to the pdf to the website
- added an RSS feed generator
- transitioned hooks to c++ callbacks
- did various merges with upstream along the way
- added const where appropriate
- removed the old block allocator
- fixed most memory leaks
- transitioned some dictionaries to std::map
- transitioned some lists to std::vector
- made some free functions members where appropriate
- renamed string to dynstr and added a static string ststr
- use NOW instead of time (NULL) if possible
- completely reworked database backends, crypto handlers and protocol handlers
  to use an object factory
- removed the old module system. ermyth does not do any dynamic loading anymore
- fixed most of the build system
- reworked how protocol commands work

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