ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/ermyth/src/servers.C
Revision: 1.2
Committed: Sat Jul 21 01:29:12 2007 UTC (16 years, 10 months ago) by pippijn
Content type: text/plain
Branch: MAIN
Changes since 1.1: +1 -1 lines
Log Message:
- moved to new documentation system
- fixed small build error

File Contents

# Content
1 /*
2 * servers.C: Server and network state tracking.
3 * Rights to this code are documented in doc/pod/license.pod.
4 *
5 * Copyright © 2005-2007 Atheme Project (http://www.atheme.org)
6 */
7
8 static char const rcsid[] = "$Id";
9
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 */