ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid-8/modules/core/m_server.c
Revision: 946
Committed: Mon Jul 20 23:18:04 2009 UTC (17 years ago) by michael
Content type: text/x-csrc
Original Path: ircd-hybrid-7.2/modules/core/m_server.c
File size: 26871 byte(s)
Log Message:
- move m_error.c to modules/


File Contents

# User Rev Content
1 adx 30 /*
2     * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd).
3     * m_server.c: Introduces a server.
4     *
5     * Copyright (C) 2002 by the past and present ircd coders, and others.
6     *
7     * This program is free software; you can redistribute it and/or modify
8     * it under the terms of the GNU General Public License as published by
9     * the Free Software Foundation; either version 2 of the License, or
10     * (at your option) any later version.
11     *
12     * This program is distributed in the hope that it will be useful,
13     * but WITHOUT ANY WARRANTY; without even the implied warranty of
14     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15     * GNU General Public License for more details.
16     *
17     * You should have received a copy of the GNU General Public License
18     * along with this program; if not, write to the Free Software
19     * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
20     * USA
21     *
22 knight 31 * $Id$
23 adx 30 */
24    
25     #include "stdinc.h"
26     #include "tools.h"
27     #include "handlers.h" /* m_server prototype */
28     #include "client.h" /* client struct */
29     #include "common.h" /* TRUE bleah */
30     #include "event.h"
31     #include "hash.h" /* add_to_client_hash_table */
32     #include "irc_string.h"
33     #include "ircd.h" /* me */
34     #include "list.h" /* make_server */
35     #include "numeric.h" /* ERR_xxx */
36     #include "s_conf.h" /* struct AccessItem */
37     #include "s_log.h" /* log level defines */
38     #include "s_serv.h" /* server_estab, check_server, my_name_for_link */
39     #include "send.h" /* sendto_one */
40     #include "motd.h"
41     #include "msg.h"
42     #include "parse.h"
43     #include "modules.h"
44    
45    
46     static void mr_server(struct Client *, struct Client *, int, char **);
47     static void ms_server(struct Client *, struct Client *, int, char **);
48     static void ms_sid(struct Client *, struct Client *, int, char **);
49    
50     static int bogus_host(char *host);
51     static void set_server_gecos(struct Client *, char *);
52     static struct Client *server_exists(char *);
53    
54     struct Message server_msgtab = {
55     "SERVER", 0, 0, 4, 0, MFLG_SLOW | MFLG_UNREG, 0,
56     {mr_server, m_registered, ms_server, m_ignore, m_registered, m_ignore}
57     };
58    
59     struct Message sid_msgtab = {
60     "SID", 0, 0, 5, 0, MFLG_SLOW, 0,
61 michael 946 {rfc1459_command_send_error, m_ignore, ms_sid, m_ignore, m_ignore, m_ignore}
62 adx 30 };
63    
64     #ifndef STATIC_MODULES
65     void
66     _modinit(void)
67     {
68     mod_add_cmd(&server_msgtab);
69     mod_add_cmd(&sid_msgtab);
70     }
71    
72     void
73     _moddeinit(void)
74     {
75     mod_del_cmd(&server_msgtab);
76     mod_del_cmd(&sid_msgtab);
77     }
78    
79 knight 31 const char *_version = "$Revision$";
80 adx 30 #endif
81    
82    
83     /* mr_server()
84     * parv[0] = sender prefix
85     * parv[1] = servername
86     * parv[2] = serverinfo/hopcount
87     * parv[3] = serverinfo
88     */
89     static void
90     mr_server(struct Client *client_p, struct Client *source_p,
91     int parc, char *parv[])
92     {
93     char info[REALLEN + 1];
94     char *name;
95     struct Client *target_p;
96     int hop;
97    
98     if (parc < 4)
99     {
100     sendto_one(client_p, "ERROR :No servername");
101     exit_client(client_p, client_p, "Wrong number of args");
102     return;
103     }
104    
105     name = parv[1];
106     hop = atoi(parv[2]);
107     strlcpy(info, parv[3], sizeof(info));
108    
109     /* Reject a direct nonTS server connection if we're TS_ONLY -orabidoo
110     */
111     if (!DoesTS(client_p))
112     {
113     sendto_realops_flags(UMODE_ALL, L_ADMIN, "Link %s dropped, non-TS server",
114     get_client_name(client_p, HIDE_IP));
115     sendto_realops_flags(UMODE_ALL, L_OPER, "Link %s dropped, non-TS server",
116     get_client_name(client_p, MASK_IP));
117     exit_client(client_p, client_p, "Non-TS server");
118     return;
119     }
120    
121     if (bogus_host(name))
122     {
123     exit_client(client_p, client_p, "Bogus server name");
124     return;
125     }
126    
127     /* Now we just have to call check_server and everything should
128     * be check for us... -A1kmm.
129     */
130     switch (check_server(name, client_p, CHECK_SERVER_NOCRYPTLINK))
131     {
132     case -1:
133     if (ConfigFileEntry.warn_no_nline)
134     {
135     sendto_realops_flags(UMODE_ALL, L_ADMIN,
136     "Unauthorized server connection attempt from %s: No entry for "
137     "servername %s", get_client_name(client_p, HIDE_IP), name);
138    
139     sendto_realops_flags(UMODE_ALL, L_OPER,
140     "Unauthorized server connection attempt from %s: No entry for "
141     "servername %s", get_client_name(client_p, MASK_IP), name);
142     }
143    
144     exit_client(client_p, client_p, "Invalid servername.");
145     return;
146     /* NOT REACHED */
147     break;
148    
149     case -2:
150     sendto_realops_flags(UMODE_ALL, L_ADMIN,
151     "Unauthorized server connection attempt from %s: Bad password "
152     "for server %s", get_client_name(client_p, HIDE_IP), name);
153    
154     sendto_realops_flags(UMODE_ALL, L_OPER,
155     "Unauthorized server connection attempt from %s: Bad password "
156     "for server %s", get_client_name(client_p, MASK_IP), name);
157    
158     exit_client(client_p, client_p, "Invalid password.");
159     return;
160     /* NOT REACHED */
161     break;
162    
163     case -3:
164     sendto_realops_flags(UMODE_ALL, L_ADMIN,
165     "Unauthorized server connection attempt from %s: Invalid host "
166     "for server %s", get_client_name(client_p, HIDE_IP), name);
167    
168     sendto_realops_flags(UMODE_ALL, L_OPER,
169     "Unauthorized server connection attempt from %s: Invalid host "
170     "for server %s", get_client_name(client_p, MASK_IP), name);
171    
172     exit_client(client_p, client_p, "Invalid host.");
173     return;
174     /* NOT REACHED */
175     break;
176    
177     /* servername is > HOSTLEN */
178     case -4:
179     sendto_realops_flags(UMODE_ALL, L_ADMIN,
180     "Invalid servername %s from %s",
181     name, get_client_name(client_p, HIDE_IP));
182     sendto_realops_flags(UMODE_ALL, L_OPER,
183     "Invalid servername %s from %s",
184     name, get_client_name(client_p, MASK_IP));
185    
186     exit_client(client_p, client_p, "Invalid servername.");
187     return;
188     /* NOT REACHED */
189     break;
190     }
191    
192     if ((me.id[0] && client_p->id[0] && (target_p = hash_find_id(client_p->id)))
193     || (target_p = server_exists(name)))
194     {
195     /* This link is trying feed me a server that I already have
196     * access through another path -- multiple paths not accepted
197     * currently, kill this link immediately!!
198     *
199     * Rather than KILL the link which introduced it, KILL the
200     * youngest of the two links. -avalon
201     *
202     * Definitely don't do that here. This is from an unregistered
203     * connect - A1kmm.
204     */
205     sendto_realops_flags(UMODE_ALL, L_ADMIN,
206     "Attempt to re-introduce server %s SID %s from %s",
207     name, client_p->id,
208     get_client_name(client_p, HIDE_IP));
209     sendto_realops_flags(UMODE_ALL, L_OPER,
210     "Attempt to re-introduce server %s SID %s from %s",
211     name, client_p->id,
212     get_client_name(client_p, MASK_IP));
213     sendto_one(client_p, "ERROR :Server ID already exists.");
214     exit_client(client_p, client_p, "Server ID Exists");
215     return;
216     }
217    
218     /* XXX If somehow there is a connect in progress and
219     * a connect comes in with same name toss the pending one,
220     * but only if it's not the same client! - Dianora
221     */
222     if ((target_p = find_servconn_in_progress(name)))
223     if (target_p != client_p)
224     exit_client(target_p, &me, "Overridden");
225    
226     /* if we are connecting (Handshake), we already have the name from the
227     * connect{} block in client_p->name
228     */
229     strlcpy(client_p->name, name, sizeof(client_p->name));
230     set_server_gecos(client_p, info);
231     client_p->hopcount = hop;
232     server_estab(client_p);
233     }
234    
235     /* ms_server()
236     * parv[0] = sender prefix
237     * parv[1] = servername
238     * parv[2] = serverinfo/hopcount
239     * parv[3] = serverinfo
240     */
241     static void
242     ms_server(struct Client *client_p, struct Client *source_p,
243     int parc, char *parv[])
244     {
245     char info[REALLEN + 1];
246     char *name;
247     struct Client *target_p;
248     struct Client *bclient_p;
249     struct ConfItem *conf;
250     struct MatchItem *match_item;
251     int hop;
252     int hlined = 0;
253     int llined = 0;
254     dlink_node *ptr, *ptr_next;
255    
256     /* Just to be sure -A1kmm. */
257     if (!IsServer(source_p))
258     return;
259    
260     if (parc < 4)
261     {
262     sendto_one(client_p, "ERROR :No servername");
263     return;
264     }
265    
266     name = parv[1];
267     hop = atoi(parv[2]);
268     strlcpy(info, parv[3], sizeof(info));
269    
270     if ((target_p = server_exists(name)))
271     {
272     /* This link is trying feed me a server that I already have
273     * access through another path -- multiple paths not accepted
274     * currently, kill this link immediately!!
275     *
276     * Rather than KILL the link which introduced it, KILL the
277     * youngest of the two links. -avalon
278     *
279     * I think that we should exit the link itself, not the introducer,
280     * and we should always exit the most recently received(i.e. the
281     * one we are receiving this SERVER for. -A1kmm
282     *
283     * You *cant* do this, if you link somewhere, it bursts you a server
284     * that already exists, then sends you a client burst, you squit the
285     * server, but you keep getting the burst of clients on a server that
286     * doesnt exist, although ircd can handle it, its not a realistic
287     * solution.. --fl_
288     */
289     /* It is behind a host-masked server. Completely ignore the
290     * server message(don't propagate or we will delink from whoever
291     * we propagate to). -A1kmm
292     */
293     if (irccmp(target_p->name, name) && target_p->from == client_p)
294     return;
295    
296     sendto_one(client_p, "ERROR :Server %s already exists", name);
297     sendto_realops_flags(UMODE_ALL, L_ADMIN,
298     "Link %s cancelled, server %s already exists",
299     get_client_name(client_p, SHOW_IP), name);
300     sendto_realops_flags(UMODE_ALL, L_OPER,
301     "Link %s cancelled, server %s already exists",
302     client_p->name, name);
303     exit_client(client_p, &me, "Server Exists");
304     return;
305     }
306    
307     /* XXX If somehow there is a connect in progress and
308     * a connect comes in with same name toss the pending one,
309     * but only if it's not the same client! - Dianora
310     */
311     if ((target_p = find_servconn_in_progress(name)))
312     if (target_p != client_p)
313     exit_client(target_p, &me, "Overridden");
314    
315     /* User nicks never have '.' in them and server names
316     * must always have '.' in them.
317     */
318     if (strchr(name, '.') == NULL)
319     {
320     /* Server trying to use the same name as a person. Would
321     * cause a fair bit of confusion. Enough to make it hellish
322     * for a while and servers to send stuff to the wrong place.
323     */
324     sendto_one(client_p,"ERROR :Nickname %s already exists!", name);
325     sendto_realops_flags(UMODE_ALL, L_ADMIN,
326     "Link %s cancelled: Server/nick collision on %s",
327     /* inpath */ get_client_name(client_p, HIDE_IP), name);
328     sendto_realops_flags(UMODE_ALL, L_OPER,
329     "Link %s cancelled: Server/nick collision on %s",
330     get_client_name(client_p, MASK_IP), name);
331     exit_client(client_p, client_p, "Nick as Server");
332     return;
333     }
334    
335     if (strlen(name) > HOSTLEN)
336     {
337     sendto_realops_flags(UMODE_ALL, L_ADMIN,
338     "Link %s introduced server with invalid servername %s",
339     get_client_name(client_p, HIDE_IP), name);
340     sendto_realops_flags(UMODE_ALL, L_OPER,
341     "Link %s introduced server with invalid servername %s",
342     client_p->name, name);
343     exit_client(client_p, &me, "Invalid servername introduced.");
344     return;
345     }
346    
347     /* Server is informing about a new server behind
348     * this link. Create REMOTE server structure,
349     * add it to list and propagate word to my other
350     * server links...
351     */
352     if (parc == 1 || info[0] == '\0')
353     {
354     sendto_one(client_p, "ERROR :No server info specified for %s", name);
355     return;
356     }
357    
358     /* See if the newly found server is behind a guaranteed
359     * leaf. If so, close the link.
360     */
361     DLINK_FOREACH(ptr, leaf_items.head)
362     {
363     conf = ptr->data;
364    
365     if (match(conf->name, client_p->name))
366     {
367     match_item = (struct MatchItem *)map_to_conf(conf);
368     if (match(match_item->host, name))
369     llined++;
370     }
371     }
372    
373     DLINK_FOREACH(ptr, hub_items.head)
374     {
375     conf = ptr->data;
376    
377     if (match(conf->name, client_p->name))
378     {
379     match_item = (struct MatchItem *)map_to_conf(conf);
380    
381     if (match(match_item->host, name))
382     hlined++;
383     }
384     }
385    
386     /* Ok, this way this works is
387     *
388     * A server can have a CONF_HUB allowing it to introduce servers
389     * behind it.
390     *
391     * connect {
392     * name = "irc.bighub.net";
393     * hub_mask="*";
394     * ...
395     *
396     * That would allow "irc.bighub.net" to introduce anything it wanted..
397     *
398     * However
399     *
400     * connect {
401     * name = "irc.somehub.fi";
402     * hub_mask="*";
403     * leaf_mask="*.edu";
404     *...
405     * Would allow this server in finland to hub anything but
406     * .edu's
407     */
408    
409 michael 885 /* Ok, check client_p can hub the new server */
410     if (!hlined)
411 adx 30 {
412     /* OOOPs nope can't HUB */
413     sendto_realops_flags(UMODE_ALL, L_ADMIN, "Non-Hub link %s introduced %s.",
414     get_client_name(client_p, HIDE_IP), name);
415     sendto_realops_flags(UMODE_ALL, L_OPER, "Non-Hub link %s introduced %s.",
416     get_client_name(client_p, MASK_IP), name);
417     exit_client(source_p, &me, "No matching hub_mask.");
418     return;
419     }
420    
421     /* Check for the new server being leafed behind this HUB */
422     if (llined)
423     {
424     /* OOOPs nope can't HUB this leaf */
425     sendto_realops_flags(UMODE_ALL, L_ADMIN,
426     "Link %s introduced leafed server %s.",
427     get_client_name(client_p, HIDE_IP), name);
428     sendto_realops_flags(UMODE_ALL, L_OPER,
429     "Link %s introduced leafed server %s.",
430     client_p->name, name);
431     /* If it is new, we are probably misconfigured, so split the
432     * non-hub server introducing this. Otherwise, split the new
433     * server. -A1kmm.
434     */
435     /* wastes too much bandwidth, generates too many errors on
436     * larger networks, dont bother. --fl_
437     */
438     exit_client(client_p, &me, "Leafed Server.");
439     return;
440     }
441    
442     target_p = make_client(client_p);
443     make_server(target_p);
444     target_p->hopcount = hop;
445    
446     strlcpy(target_p->name, name, sizeof(target_p->name));
447    
448     set_server_gecos(target_p, info);
449    
450     target_p->servptr = source_p;
451    
452     SetServer(target_p);
453    
454     if ((target_p->node.prev != NULL) || (target_p->node.next != NULL))
455     {
456     sendto_realops_flags(UMODE_ALL, L_OPER,
457     "already linked %s at %s:%d", target_p->name,
458     __FILE__, __LINE__);
459     ilog(L_ERROR, "already linked client %s at %s:%d", target_p->name,
460     __FILE__, __LINE__);
461     assert(0==1);
462     }
463     else
464     {
465     dlinkAdd(target_p, &target_p->node, &global_client_list);
466     dlinkAdd(target_p, make_dlink_node(), &global_serv_list);
467     }
468    
469     hash_add_client(target_p);
470     /* XXX test that target_p->lnode.prev and .next are NULL as well? */
471     if ((target_p->lnode.prev != NULL) || (target_p->lnode.next != NULL))
472     {
473     sendto_realops_flags(UMODE_ALL, L_OPER,
474     "already lnode linked %s at %s:%d", target_p->name,
475     __FILE__, __LINE__);
476     ilog(L_ERROR, "already lnode linked %s at %s:%d", target_p->name,
477     __FILE__, __LINE__);
478     assert(0==2);
479     }
480     else
481 michael 889 dlinkAdd(target_p, &target_p->lnode, &target_p->servptr->serv->server_list);
482 adx 30
483     /* Old sendto_serv_but_one() call removed because we now
484     * need to send different names to different servers
485     * (domain name matching)
486     */
487     DLINK_FOREACH_SAFE(ptr, ptr_next, serv_list.head)
488     {
489     bclient_p = ptr->data;
490    
491     if (bclient_p == client_p)
492     continue;
493    
494     if ((conf = bclient_p->serv->sconf) == NULL)
495     {
496     sendto_realops_flags(UMODE_ALL, L_ADMIN,
497     "Lost connect{} block for %s on %s. Closing",
498     get_client_name(client_p, HIDE_IP), name);
499     sendto_realops_flags(UMODE_ALL, L_OPER,
500     "Lost connect{} block for %s on %s. Closing",
501     get_client_name(client_p, MASK_IP), name);
502     exit_client(client_p, client_p, "Lost connect{} block");
503     continue;
504     }
505    
506     if (match(my_name_for_link(conf), target_p->name))
507     continue;
508    
509     sendto_one(bclient_p, ":%s SERVER %s %d :%s%s",
510     ID_or_name(source_p, bclient_p), target_p->name, hop + 1,
511     IsHidden(target_p) ? "(H) " : "",
512     target_p->info);
513     }
514    
515     sendto_realops_flags(UMODE_EXTERNAL, L_ALL,
516     "Server %s being introduced by %s",
517     target_p->name, source_p->name);
518     }
519    
520     /* ms_sid()
521     * parv[0] = sender prefix
522     * parv[1] = servername
523     * parv[2] = serverinfo/hopcount
524     * parv[3] = sid of new server
525     * parv[4] = serverinfo
526     */
527     static void
528     ms_sid(struct Client *client_p, struct Client *source_p,
529     int parc, char *parv[])
530     {
531     char info[REALLEN + 1];
532     struct Client *target_p;
533     struct Client *bclient_p;
534     struct ConfItem *conf;
535     struct MatchItem *match_item;
536     int hlined = 0;
537     int llined = 0;
538     dlink_node *ptr, *ptr_next;
539     int hop;
540     #define SID_NAME parv[1]
541     #define SID_HOP parv[2]
542     #define SID_SID parv[3]
543     #define SID_GECOS parv[4]
544    
545     hop = atoi(SID_HOP);
546    
547     /* Just to be sure -A1kmm. */
548     if (!IsServer(source_p))
549     return;
550    
551     strlcpy(info, SID_GECOS, sizeof(info));
552    
553     /* collision on SID? */
554     if ((target_p = hash_find_id(SID_SID)) != NULL)
555     {
556     sendto_one(client_p, "ERROR :SID %s already exists", SID_SID);
557     sendto_realops_flags(UMODE_ALL, L_ADMIN,
558     "Link %s cancelled, SID %s already exists",
559     get_client_name(client_p, SHOW_IP), SID_SID);
560     sendto_realops_flags(UMODE_ALL, L_OPER,
561     "Link %s cancelled, SID %s already exists",
562     client_p->name, SID_SID);
563     exit_client(client_p, &me, "Server Exists");
564     return;
565     }
566    
567     /* collision on name? */
568     if ((target_p = server_exists(SID_NAME)) != NULL)
569     {
570     sendto_one(client_p, "ERROR :Server %s already exists", SID_NAME);
571     sendto_realops_flags(UMODE_ALL, L_ADMIN,
572     "Link %s cancelled, server %s already exists",
573     get_client_name(client_p, SHOW_IP), SID_NAME);
574     sendto_realops_flags(UMODE_ALL, L_OPER,
575     "Link %s cancelled, server %s already exists",
576     client_p->name, SID_NAME);
577     exit_client(client_p, &me, "Server Exists");
578     return;
579     }
580    
581     /* XXX If somehow there is a connect in progress and
582     * a connect comes in with same name toss the pending one,
583     * but only if it's not the same client! - Dianora
584     */
585     if ((target_p = find_servconn_in_progress(SID_NAME)))
586     if (target_p != client_p)
587     exit_client(target_p, &me, "Overridden");
588    
589     /* User nicks never have '.' in them and server names
590     * must always have '.' in them.
591     */
592     if (strchr(SID_NAME, '.') == NULL || /* servernames must have a '.' and nicks must not */
593     strlen(SID_NAME) > HOSTLEN) /* ensure the name of the server is not too long */
594     {
595     /* Server trying to use the same name as a person. Would
596     * cause a fair bit of confusion. Enough to make it hellish
597     * for a while and servers to send stuff to the wrong place.
598     */
599     sendto_one(client_p, "ERROR :Invalid servername");
600     sendto_realops_flags(UMODE_ALL, L_ADMIN,
601     "Link %s cancelled: servername name %s invalid",
602     get_client_name(client_p, SHOW_IP), SID_NAME);
603     sendto_realops_flags(UMODE_ALL, L_OPER,
604     "Link %s cancelled: servername name %s invalid",
605     get_client_name(client_p, MASK_IP), SID_NAME);
606     exit_client(client_p, client_p, "Nick as Server");
607     return;
608     }
609    
610     /* Server is informing about a new server behind
611     * this link. Create REMOTE server structure,
612     * add it to list and propagate word to my other
613     * server links...
614     */
615     if (parc == 1 || info[0] == '\0')
616     {
617     sendto_one(client_p, "ERROR :No server info specified for %s", SID_NAME);
618     return;
619     }
620    
621     /* See if the newly found server is behind a guaranteed
622     * leaf. If so, close the link.
623     */
624     DLINK_FOREACH(ptr, leaf_items.head)
625     {
626     conf = ptr->data;
627    
628     if (match(conf->name, client_p->name))
629     {
630     match_item = (struct MatchItem *)map_to_conf(conf);
631     if (match(match_item->host, SID_NAME))
632     llined++;
633     }
634     }
635    
636     DLINK_FOREACH(ptr, hub_items.head)
637     {
638     conf = ptr->data;
639    
640     if (match(conf->name, client_p->name))
641     {
642     match_item = (struct MatchItem *)map_to_conf(conf);
643    
644     if (match(match_item->host, SID_NAME))
645     hlined++;
646     }
647     }
648    
649     /* Ok, this way this works is
650     *
651     * A server can have a CONF_HUB allowing it to introduce servers
652     * behind it.
653     *
654     * connect {
655     * name = "irc.bighub.net";
656     * hub_mask="*";
657     * ...
658     *
659     * That would allow "irc.bighub.net" to introduce anything it wanted..
660     *
661     * However
662     *
663     * connect {
664     * name = "irc.somehub.fi";
665     * hub_mask="*";
666     * leaf_mask="*.edu";
667     *...
668     * Would allow this server in finland to hub anything but
669     * .edu's
670     */
671    
672     /* Ok, check client_p can hub the new server, and make sure it's not a LL */
673 michael 885 if (!hlined)
674 adx 30 {
675     /* OOOPs nope can't HUB */
676     sendto_realops_flags(UMODE_ALL, L_ADMIN, "Non-Hub link %s introduced %s.",
677     get_client_name(client_p, SHOW_IP), SID_NAME);
678     sendto_realops_flags(UMODE_ALL, L_OPER, "Non-Hub link %s introduced %s.",
679     get_client_name(client_p, MASK_IP), SID_NAME);
680     exit_client(source_p, &me, "No matching hub_mask.");
681     return;
682     }
683    
684     /* Check for the new server being leafed behind this HUB */
685     if (llined)
686     {
687     /* OOOPs nope can't HUB this leaf */
688     sendto_realops_flags(UMODE_ALL, L_ADMIN,
689     "Link %s introduced leafed server %s.",
690     get_client_name(client_p, SHOW_IP), SID_NAME);
691     sendto_realops_flags(UMODE_ALL, L_OPER,
692     "Link %s introduced leafed server %s.",
693     client_p->name, SID_NAME);
694     exit_client(client_p, &me, "Leafed Server.");
695     return;
696     }
697    
698     target_p = make_client(client_p);
699     make_server(target_p);
700     target_p->hopcount = hop;
701    
702     strlcpy(target_p->name, SID_NAME, sizeof(target_p->name));
703     strlcpy(target_p->id, SID_SID, sizeof(target_p->id));
704    
705     set_server_gecos(target_p, info);
706    
707     target_p->servptr = source_p;
708    
709     SetServer(target_p);
710    
711     if ((target_p->node.prev != NULL) || (target_p->node.next != NULL))
712     {
713     sendto_realops_flags(UMODE_ALL, L_ADMIN,
714     "already linked %s at %s:%d", target_p->name,
715     __FILE__, __LINE__);
716     ilog(L_ERROR, "already linked %s at %s:%d", target_p->name,
717     __FILE__, __LINE__);
718     assert(0==3);
719     }
720     else
721     {
722     dlinkAdd(target_p, &target_p->node, &global_client_list);
723     dlinkAdd(target_p, make_dlink_node(), &global_serv_list);
724     }
725    
726     hash_add_client(target_p);
727     /* XXX test that target_p->lnode.prev and next are NULL as well? */
728     if ((target_p->lnode.prev != NULL) || (target_p->lnode.next != NULL))
729     {
730     sendto_realops_flags(UMODE_ALL, L_OPER,
731     "already lnode linked %s at %s:%d", target_p->name,
732     __FILE__, __LINE__);
733     ilog(L_ERROR, "already lnode linked %s at %s:%d", target_p->name,
734     __FILE__, __LINE__);
735     assert(0==4);
736     }
737     else
738 michael 889 dlinkAdd(target_p, &target_p->lnode, &target_p->servptr->serv->server_list);
739 adx 30
740     hash_add_id(target_p);
741    
742     DLINK_FOREACH_SAFE(ptr, ptr_next, serv_list.head)
743     {
744     bclient_p = ptr->data;
745    
746     if (bclient_p == client_p)
747     continue;
748    
749     if ((conf = bclient_p->serv->sconf) == NULL)
750     {
751     sendto_realops_flags(UMODE_ALL, L_ADMIN,
752     "Lost connect{} block for %s on %s. Closing",
753     get_client_name(client_p, HIDE_IP), SID_NAME);
754     sendto_realops_flags(UMODE_ALL, L_OPER,
755     "Lost connect{} block for %s on %s. Closing",
756     get_client_name(client_p, MASK_IP), SID_NAME);
757     exit_client(client_p, client_p, "Lost connect{} block");
758     continue;
759     }
760    
761     if (match(my_name_for_link(conf), target_p->name))
762     continue;
763    
764     if (IsCapable(bclient_p, CAP_TS6))
765     sendto_one(bclient_p, ":%s SID %s %d %s :%s%s",
766     ID_or_name(source_p, client_p), target_p->name, hop + 1,
767     SID_SID, IsHidden(target_p) ? "(H) " : "",
768     target_p->info);
769     else
770     sendto_one(bclient_p, ":%s SERVER %s %d :%s%s",
771     source_p->name, target_p->name, hop + 1,
772     IsHidden(target_p) ? "(H) " : "",
773     target_p->info);
774     }
775    
776     sendto_realops_flags(UMODE_EXTERNAL, L_ALL,
777     "Server %s being introduced by %s",
778     target_p->name, source_p->name);
779     }
780    
781     /* set_server_gecos()
782     *
783     * input - pointer to client
784     * output - NONE
785     * side effects - servers gecos field is set
786     */
787     static void
788     set_server_gecos(struct Client *client_p, char *info)
789     {
790     /* check the info for [IP] */
791     if (info[0])
792     {
793     char *p;
794     char *s;
795     char *t;
796    
797     s = info;
798    
799     /* we should only check the first word for an ip */
800     if ((p = strchr(s, ' ')) != NULL)
801     *p = '\0';
802    
803     /* check for a ] which would symbolise an [IP] */
804     if ((t = strchr(s, ']')) != NULL)
805     {
806     /* set s to after the first space */
807     if (p)
808     s = ++p;
809     else
810     s = NULL;
811     }
812     /* no ], put the space back */
813     else if (p)
814     *p = ' ';
815    
816     /* p may have been set to a trailing space, so check s exists and that
817     * it isnt \0 */
818     if (s && (*s != '\0'))
819     {
820     /* a space? if not (H) could be the last part of info.. */
821     if ((p = strchr(s, ' ')))
822     *p = '\0';
823    
824     /* check for (H) which is a hidden server */
825     if (!strcmp(s, "(H)"))
826     {
827     SetHidden(client_p);
828    
829     /* if there was no space.. theres nothing to set info to */
830     if (p)
831     s = ++p;
832     else
833     s = NULL;
834     }
835     else if (p)
836     *p = ' ';
837    
838     /* if there was a trailing space, s could point to \0, so check */
839     if (s && (*s != '\0'))
840     strlcpy(client_p->info, s, sizeof(client_p->info));
841     else
842     strlcpy(client_p->info, "(Unknown Location)", sizeof(client_p->info));
843     }
844     else
845     strlcpy(client_p->info, "(Unknown Location)", sizeof(client_p->info));
846     }
847     else
848     strlcpy(client_p->info, "(Unknown Location)", sizeof(client_p->info));
849     }
850    
851     /* bogus_host()
852     *
853     * inputs - hostname
854     * output - 1 if a bogus hostname input,
855     * - 0 if its valid
856     * side effects - none
857     */
858     static int
859     bogus_host(char *host)
860     {
861     unsigned int dots = 0;
862     char *s;
863    
864     for (s = host; *s; s++)
865     {
866     if (!IsServChar(*s))
867     return(1);
868    
869     if ('.' == *s)
870     ++dots;
871     }
872    
873     return(!dots);
874     }
875    
876     /* server_exists()
877     *
878     * inputs - servername
879     * output - 1 if server exists, 0 if doesnt exist
880     */
881     static struct Client *
882     server_exists(char *servername)
883     {
884     struct Client *target_p;
885     dlink_node *ptr;
886    
887     DLINK_FOREACH(ptr, global_serv_list.head)
888     {
889     target_p = ptr->data;
890    
891     if (match(target_p->name, servername) ||
892     match(servername, target_p->name))
893     return(target_p);
894     }
895    
896     return(NULL);
897     }

Properties

Name Value
svn:eol-style native
svn:keywords Id Revision