ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid-7.3/modules/core/m_server.c
Revision: 1121
Committed: Sun Jan 9 11:03:03 2011 UTC (13 years, 2 months ago) by michael
Content type: text/x-csrc
File size: 22685 byte(s)
Log Message:
- removed all instances of STATIC_MODULES since we don't have
  static modules anymore
- removed m_mkpasswd module from contrib

File Contents

# Content
1 /*
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 * $Id$
23 */
24
25 #include "stdinc.h"
26 #include "list.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 "numeric.h" /* ERR_xxx */
35 #include "s_conf.h" /* struct AccessItem */
36 #include "s_log.h" /* log level defines */
37 #include "s_serv.h" /* server_estab, check_server */
38 #include "s_user.h"
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 void set_server_gecos(struct Client *, char *);
51
52 struct Message server_msgtab = {
53 "SERVER", 0, 0, 4, 0, MFLG_SLOW | MFLG_UNREG, 0,
54 {mr_server, m_registered, ms_server, m_ignore, m_registered, m_ignore}
55 };
56
57 struct Message sid_msgtab = {
58 "SID", 0, 0, 5, 0, MFLG_SLOW, 0,
59 {rfc1459_command_send_error, m_ignore, ms_sid, m_ignore, m_ignore, m_ignore}
60 };
61
62 void
63 _modinit(void)
64 {
65 mod_add_cmd(&server_msgtab);
66 mod_add_cmd(&sid_msgtab);
67 }
68
69 void
70 _moddeinit(void)
71 {
72 mod_del_cmd(&server_msgtab);
73 mod_del_cmd(&sid_msgtab);
74 }
75
76 const char *_version = "$Revision$";
77
78
79 /* mr_server()
80 * parv[0] = sender prefix
81 * parv[1] = servername
82 * parv[2] = serverinfo/hopcount
83 * parv[3] = serverinfo
84 */
85 static void
86 mr_server(struct Client *client_p, struct Client *source_p,
87 int parc, char *parv[])
88 {
89 char info[REALLEN + 1];
90 char *name;
91 struct Client *target_p;
92 int hop;
93
94 if (parc < 4 || EmptyString(parv[3]))
95 {
96 sendto_one(client_p, "ERROR :No servername");
97 exit_client(client_p, client_p, "Wrong number of args");
98 return;
99 }
100
101 name = parv[1];
102 hop = atoi(parv[2]);
103 strlcpy(info, parv[3], sizeof(info));
104
105 /*
106 * Reject a direct nonTS server connection if we're TS_ONLY -orabidoo
107 */
108 if (!DoesTS(client_p))
109 {
110 sendto_realops_flags(UMODE_ALL, L_ADMIN,
111 "Unauthorized server connection attempt from %s: Non-TS server "
112 "for server %s", get_client_name(client_p, HIDE_IP), name);
113 sendto_realops_flags(UMODE_ALL, L_OPER,
114 "Unauthorized server connection attempt from %s: Non-TS server "
115 "for server %s", get_client_name(client_p, MASK_IP), name);
116 exit_client(client_p, client_p, "Non-TS server");
117 return;
118 }
119
120 if (!valid_servname(name))
121 {
122 sendto_realops_flags(UMODE_ALL, L_ADMIN,
123 "Unauthorized server connection attempt from %s: Bogus server name "
124 "for server %s", get_client_name(client_p, HIDE_IP), name);
125 sendto_realops_flags(UMODE_ALL, L_OPER,
126 "Unauthorized server connection attempt from %s: Bogus server name "
127 "for server %s", get_client_name(client_p, MASK_IP), name);
128 exit_client(client_p, client_p, "Bogus server name");
129 return;
130 }
131
132 /* Now we just have to call check_server and everything should
133 * be check for us... -A1kmm.
134 */
135 switch (check_server(name, client_p, CHECK_SERVER_NOCRYPTLINK))
136 {
137 case -1:
138 if (ConfigFileEntry.warn_no_nline)
139 {
140 sendto_realops_flags(UMODE_ALL, L_ADMIN,
141 "Unauthorized server connection attempt from %s: No entry for "
142 "servername %s", get_client_name(client_p, HIDE_IP), name);
143
144 sendto_realops_flags(UMODE_ALL, L_OPER,
145 "Unauthorized server connection attempt from %s: No entry for "
146 "servername %s", get_client_name(client_p, MASK_IP), name);
147 }
148
149 exit_client(client_p, client_p, "Invalid servername.");
150 return;
151 /* NOT REACHED */
152 break;
153
154 case -2:
155 sendto_realops_flags(UMODE_ALL, L_ADMIN,
156 "Unauthorized server connection attempt from %s: Bad password "
157 "for server %s", get_client_name(client_p, HIDE_IP), name);
158
159 sendto_realops_flags(UMODE_ALL, L_OPER,
160 "Unauthorized server connection attempt from %s: Bad password "
161 "for server %s", get_client_name(client_p, MASK_IP), name);
162
163 exit_client(client_p, client_p, "Invalid password.");
164 return;
165 /* NOT REACHED */
166 break;
167
168 case -3:
169 sendto_realops_flags(UMODE_ALL, L_ADMIN,
170 "Unauthorized server connection attempt from %s: Invalid host "
171 "for server %s", get_client_name(client_p, HIDE_IP), name);
172
173 sendto_realops_flags(UMODE_ALL, L_OPER,
174 "Unauthorized server connection attempt from %s: Invalid host "
175 "for server %s", get_client_name(client_p, MASK_IP), name);
176
177 exit_client(client_p, client_p, "Invalid host.");
178 return;
179 /* NOT REACHED */
180 break;
181
182 /* servername is > HOSTLEN */
183 case -4:
184 sendto_realops_flags(UMODE_ALL, L_ADMIN,
185 "Invalid servername %s from %s",
186 name, get_client_name(client_p, HIDE_IP));
187 sendto_realops_flags(UMODE_ALL, L_OPER,
188 "Invalid servername %s from %s",
189 name, get_client_name(client_p, MASK_IP));
190
191 exit_client(client_p, client_p, "Invalid servername.");
192 return;
193 /* NOT REACHED */
194 break;
195 }
196
197 if ((client_p->id[0] && (target_p = hash_find_id(client_p->id)))
198 || (target_p = find_server(name)))
199 {
200 /* This link is trying feed me a server that I already have
201 * access through another path -- multiple paths not accepted
202 * currently, kill this link immediately!!
203 *
204 * Rather than KILL the link which introduced it, KILL the
205 * youngest of the two links. -avalon
206 *
207 * Definitely don't do that here. This is from an unregistered
208 * connect - A1kmm.
209 */
210 sendto_realops_flags(UMODE_ALL, L_ADMIN,
211 "Attempt to re-introduce server %s SID %s from %s",
212 name, client_p->id,
213 get_client_name(client_p, HIDE_IP));
214 sendto_realops_flags(UMODE_ALL, L_OPER,
215 "Attempt to re-introduce server %s SID %s from %s",
216 name, client_p->id,
217 get_client_name(client_p, MASK_IP));
218 sendto_one(client_p, "ERROR :Server ID already exists.");
219 exit_client(client_p, client_p, "Server ID Exists");
220 return;
221 }
222
223 /* XXX If somehow there is a connect in progress and
224 * a connect comes in with same name toss the pending one,
225 * but only if it's not the same client! - Dianora
226 */
227 if ((target_p = find_servconn_in_progress(name)))
228 if (target_p != client_p)
229 exit_client(target_p, &me, "Overridden");
230
231 /* if we are connecting (Handshake), we already have the name from the
232 * connect{} block in client_p->name
233 */
234 strlcpy(client_p->name, name, sizeof(client_p->name));
235 set_server_gecos(client_p, info);
236 client_p->hopcount = hop;
237 server_estab(client_p);
238 }
239
240 /* ms_server()
241 * parv[0] = sender prefix
242 * parv[1] = servername
243 * parv[2] = serverinfo/hopcount
244 * parv[3] = serverinfo
245 */
246 static void
247 ms_server(struct Client *client_p, struct Client *source_p,
248 int parc, char *parv[])
249 {
250 char info[REALLEN + 1];
251 char *name;
252 struct Client *target_p;
253 struct Client *bclient_p;
254 struct ConfItem *conf;
255 struct MatchItem *match_item;
256 int hop;
257 int hlined = 0;
258 int llined = 0;
259 dlink_node *ptr, *ptr_next;
260
261 /* Just to be sure -A1kmm. */
262 if (!IsServer(source_p))
263 return;
264
265 if (parc < 4 || EmptyString(parv[3]))
266 {
267 sendto_one(client_p, "ERROR :No servername");
268 return;
269 }
270
271 name = parv[1];
272 hop = atoi(parv[2]);
273 strlcpy(info, parv[3], sizeof(info));
274
275 if (!valid_servname(name))
276 {
277 sendto_realops_flags(UMODE_ALL, L_ADMIN,
278 "Link %s introduced server with bogus server name %s",
279 get_client_name(client_p, SHOW_IP), name);
280 sendto_realops_flags(UMODE_ALL, L_OPER,
281 "Link %s introduced server with bogus server name %s",
282 get_client_name(client_p, MASK_IP), name);
283 sendto_one(client_p, "ERROR :Bogus server name introduced");
284 exit_client(client_p, &me, "Bogus server name intoduced");
285 return;
286 }
287
288 if ((target_p = find_server(name)))
289 {
290 /* This link is trying feed me a server that I already have
291 * access through another path -- multiple paths not accepted
292 * currently, kill this link immediately!!
293 *
294 * Rather than KILL the link which introduced it, KILL the
295 * youngest of the two links. -avalon
296 *
297 * I think that we should exit the link itself, not the introducer,
298 * and we should always exit the most recently received(i.e. the
299 * one we are receiving this SERVER for. -A1kmm
300 *
301 * You *cant* do this, if you link somewhere, it bursts you a server
302 * that already exists, then sends you a client burst, you squit the
303 * server, but you keep getting the burst of clients on a server that
304 * doesnt exist, although ircd can handle it, its not a realistic
305 * solution.. --fl_
306 */
307 /* It is behind a host-masked server. Completely ignore the
308 * server message(don't propagate or we will delink from whoever
309 * we propagate to). -A1kmm
310 */
311 if (irccmp(target_p->name, name) && target_p->from == client_p)
312 return;
313
314 sendto_one(client_p, "ERROR :Server %s already exists", name);
315 sendto_realops_flags(UMODE_ALL, L_ADMIN,
316 "Link %s cancelled, server %s already exists",
317 get_client_name(client_p, SHOW_IP), name);
318 sendto_realops_flags(UMODE_ALL, L_OPER,
319 "Link %s cancelled, server %s already exists",
320 client_p->name, name);
321 exit_client(client_p, &me, "Server Exists");
322 return;
323 }
324
325 /* XXX If somehow there is a connect in progress and
326 * a connect comes in with same name toss the pending one,
327 * but only if it's not the same client! - Dianora
328 */
329 if ((target_p = find_servconn_in_progress(name)))
330 if (target_p != client_p)
331 exit_client(target_p, &me, "Overridden");
332
333 /* See if the newly found server is behind a guaranteed
334 * leaf. If so, close the link.
335 */
336 DLINK_FOREACH(ptr, leaf_items.head)
337 {
338 conf = ptr->data;
339
340 if (match(conf->name, client_p->name))
341 {
342 match_item = map_to_conf(conf);
343
344 if (match(match_item->host, name))
345 llined++;
346 }
347 }
348
349 DLINK_FOREACH(ptr, hub_items.head)
350 {
351 conf = ptr->data;
352
353 if (match(conf->name, client_p->name))
354 {
355 match_item = map_to_conf(conf);
356
357 if (match(match_item->host, name))
358 hlined++;
359 }
360 }
361
362 /* Ok, this way this works is
363 *
364 * A server can have a CONF_HUB allowing it to introduce servers
365 * behind it.
366 *
367 * connect {
368 * name = "irc.bighub.net";
369 * hub_mask="*";
370 * ...
371 *
372 * That would allow "irc.bighub.net" to introduce anything it wanted..
373 *
374 * However
375 *
376 * connect {
377 * name = "irc.somehub.fi";
378 * hub_mask="*";
379 * leaf_mask="*.edu";
380 *...
381 * Would allow this server in finland to hub anything but
382 * .edu's
383 */
384
385 /* Ok, check client_p can hub the new server */
386 if (!hlined)
387 {
388 /* OOOPs nope can't HUB */
389 sendto_realops_flags(UMODE_ALL, L_ADMIN, "Non-Hub link %s introduced %s.",
390 get_client_name(client_p, HIDE_IP), name);
391 sendto_realops_flags(UMODE_ALL, L_OPER, "Non-Hub link %s introduced %s.",
392 get_client_name(client_p, MASK_IP), name);
393 exit_client(source_p, &me, "No matching hub_mask.");
394 return;
395 }
396
397 /* Check for the new server being leafed behind this HUB */
398 if (llined)
399 {
400 /* OOOPs nope can't HUB this leaf */
401 sendto_realops_flags(UMODE_ALL, L_ADMIN,
402 "Link %s introduced leafed server %s.",
403 get_client_name(client_p, HIDE_IP), name);
404 sendto_realops_flags(UMODE_ALL, L_OPER,
405 "Link %s introduced leafed server %s.",
406 get_client_name(client_p, MASK_IP), name);
407 /* If it is new, we are probably misconfigured, so split the
408 * non-hub server introducing this. Otherwise, split the new
409 * server. -A1kmm.
410 */
411 /* wastes too much bandwidth, generates too many errors on
412 * larger networks, dont bother. --fl_
413 */
414 exit_client(client_p, &me, "Leafed Server.");
415 return;
416 }
417
418 target_p = make_client(client_p);
419 make_server(target_p);
420 target_p->hopcount = hop;
421 target_p->servptr = source_p;
422
423 strlcpy(target_p->name, name, sizeof(target_p->name));
424
425 set_server_gecos(target_p, info);
426 SetServer(target_p);
427
428 dlinkAdd(target_p, &target_p->node, &global_client_list);
429 dlinkAdd(target_p, make_dlink_node(), &global_serv_list);
430 dlinkAdd(target_p, &target_p->lnode, &target_p->servptr->serv->server_list);
431
432 hash_add_client(target_p);
433
434 /* Old sendto_serv_but_one() call removed because we now
435 * need to send different names to different servers
436 * (domain name matching)
437 */
438 DLINK_FOREACH_SAFE(ptr, ptr_next, serv_list.head)
439 {
440 bclient_p = ptr->data;
441
442 if (bclient_p == client_p)
443 continue;
444
445 sendto_one(bclient_p, ":%s SERVER %s %d :%s%s",
446 ID_or_name(source_p, bclient_p), target_p->name, hop + 1,
447 IsHidden(target_p) ? "(H) " : "",
448 target_p->info);
449 }
450
451 sendto_realops_flags(UMODE_EXTERNAL, L_ALL,
452 "Server %s being introduced by %s",
453 target_p->name, source_p->name);
454 }
455
456 /* ms_sid()
457 * parv[0] = sender prefix
458 * parv[1] = servername
459 * parv[2] = serverinfo/hopcount
460 * parv[3] = sid of new server
461 * parv[4] = serverinfo
462 */
463 static void
464 ms_sid(struct Client *client_p, struct Client *source_p,
465 int parc, char *parv[])
466 {
467 char info[REALLEN + 1];
468 struct Client *target_p;
469 struct Client *bclient_p;
470 struct ConfItem *conf;
471 struct MatchItem *match_item;
472 int hlined = 0;
473 int llined = 0;
474 dlink_node *ptr, *ptr_next;
475 int hop;
476
477 /* Just to be sure -A1kmm. */
478 if (!IsServer(source_p))
479 return;
480
481 if (parc < 5 || EmptyString(parv[4]))
482 {
483 sendto_one(client_p, "ERROR :No servername");
484 return;
485 }
486
487 hop = atoi(parv[2]);
488 strlcpy(info, parv[4], sizeof(info));
489
490 if (!valid_servname(parv[1]))
491 {
492 sendto_realops_flags(UMODE_ALL, L_ADMIN,
493 "Link %s introduced server with bogus server name %s",
494 get_client_name(client_p, SHOW_IP), parv[1]);
495 sendto_realops_flags(UMODE_ALL, L_OPER,
496 "Link %s introduced server with bogus server name %s",
497 get_client_name(client_p, MASK_IP), parv[1]);
498 sendto_one(client_p, "ERROR :Bogus server name introduced");
499 exit_client(client_p, &me, "Bogus server name intoduced");
500 return;
501 }
502
503 if (!valid_sid(parv[3]))
504 {
505 sendto_realops_flags(UMODE_ALL, L_ADMIN,
506 "Link %s introduced server with bogus server ID %s",
507 get_client_name(client_p, SHOW_IP), parv[3]);
508 sendto_realops_flags(UMODE_ALL, L_OPER,
509 "Link %s introduced server with bogus server ID %s",
510 get_client_name(client_p, MASK_IP), parv[3]);
511 sendto_one(client_p, "ERROR :Bogus server ID introduced");
512 exit_client(client_p, &me, "Bogus server ID intoduced");
513 return;
514 }
515
516 /* collision on SID? */
517 if ((target_p = hash_find_id(parv[3])))
518 {
519 sendto_one(client_p, "ERROR :SID %s already exists", parv[3]);
520 sendto_realops_flags(UMODE_ALL, L_ADMIN,
521 "Link %s cancelled, SID %s already exists",
522 get_client_name(client_p, SHOW_IP), parv[3]);
523 sendto_realops_flags(UMODE_ALL, L_OPER,
524 "Link %s cancelled, SID %s already exists",
525 client_p->name, parv[3]);
526 exit_client(client_p, &me, "Server Exists");
527 return;
528 }
529
530 /* collision on name? */
531 if ((target_p = find_server(parv[1])))
532 {
533 sendto_one(client_p, "ERROR :Server %s already exists", parv[1]);
534 sendto_realops_flags(UMODE_ALL, L_ADMIN,
535 "Link %s cancelled, server %s already exists",
536 get_client_name(client_p, SHOW_IP), parv[1]);
537 sendto_realops_flags(UMODE_ALL, L_OPER,
538 "Link %s cancelled, server %s already exists",
539 client_p->name, parv[1]);
540 exit_client(client_p, &me, "Server Exists");
541 return;
542 }
543
544 /* XXX If somehow there is a connect in progress and
545 * a connect comes in with same name toss the pending one,
546 * but only if it's not the same client! - Dianora
547 */
548 if ((target_p = find_servconn_in_progress(parv[1])))
549 if (target_p != client_p)
550 exit_client(target_p, &me, "Overridden");
551
552 /* See if the newly found server is behind a guaranteed
553 * leaf. If so, close the link.
554 */
555 DLINK_FOREACH(ptr, leaf_items.head)
556 {
557 conf = ptr->data;
558
559 if (match(conf->name, client_p->name))
560 {
561 match_item = map_to_conf(conf);
562
563 if (match(match_item->host, parv[1]))
564 llined++;
565 }
566 }
567
568 DLINK_FOREACH(ptr, hub_items.head)
569 {
570 conf = ptr->data;
571
572 if (match(conf->name, client_p->name))
573 {
574 match_item = map_to_conf(conf);
575
576 if (match(match_item->host, parv[1]))
577 hlined++;
578 }
579 }
580
581 /* Ok, this way this works is
582 *
583 * A server can have a CONF_HUB allowing it to introduce servers
584 * behind it.
585 *
586 * connect {
587 * name = "irc.bighub.net";
588 * hub_mask="*";
589 * ...
590 *
591 * That would allow "irc.bighub.net" to introduce anything it wanted..
592 *
593 * However
594 *
595 * connect {
596 * name = "irc.somehub.fi";
597 * hub_mask="*";
598 * leaf_mask="*.edu";
599 *...
600 * Would allow this server in finland to hub anything but
601 * .edu's
602 */
603
604 /* Ok, check client_p can hub the new server, and make sure it's not a LL */
605 if (!hlined)
606 {
607 /* OOOPs nope can't HUB */
608 sendto_realops_flags(UMODE_ALL, L_ADMIN, "Non-Hub link %s introduced %s.",
609 get_client_name(client_p, SHOW_IP), parv[1]);
610 sendto_realops_flags(UMODE_ALL, L_OPER, "Non-Hub link %s introduced %s.",
611 get_client_name(client_p, MASK_IP), parv[1]);
612 exit_client(source_p, &me, "No matching hub_mask.");
613 return;
614 }
615
616 /* Check for the new server being leafed behind this HUB */
617 if (llined)
618 {
619 /* OOOPs nope can't HUB this leaf */
620 sendto_realops_flags(UMODE_ALL, L_ADMIN,
621 "Link %s introduced leafed server %s.",
622 get_client_name(client_p, SHOW_IP), parv[1]);
623 sendto_realops_flags(UMODE_ALL, L_OPER,
624 "Link %s introduced leafed server %s.",
625 get_client_name(client_p, MASK_IP), parv[1]);
626 exit_client(client_p, &me, "Leafed Server.");
627 return;
628 }
629
630 target_p = make_client(client_p);
631 make_server(target_p);
632 target_p->hopcount = hop;
633 target_p->servptr = source_p;
634
635 strlcpy(target_p->name, parv[1], sizeof(target_p->name));
636 strlcpy(target_p->id, parv[3], sizeof(target_p->id));
637
638 set_server_gecos(target_p, info);
639 SetServer(target_p);
640
641 dlinkAdd(target_p, &target_p->node, &global_client_list);
642 dlinkAdd(target_p, make_dlink_node(), &global_serv_list);
643 dlinkAdd(target_p, &target_p->lnode, &target_p->servptr->serv->server_list);
644
645 hash_add_client(target_p);
646 hash_add_id(target_p);
647
648 DLINK_FOREACH_SAFE(ptr, ptr_next, serv_list.head)
649 {
650 bclient_p = ptr->data;
651
652 if (bclient_p == client_p)
653 continue;
654
655 if (IsCapable(bclient_p, CAP_TS6))
656 sendto_one(bclient_p, ":%s SID %s %d %s :%s%s",
657 ID_or_name(source_p, client_p), target_p->name, hop + 1,
658 parv[3], IsHidden(target_p) ? "(H) " : "",
659 target_p->info);
660 else
661 sendto_one(bclient_p, ":%s SERVER %s %d :%s%s",
662 source_p->name, target_p->name, hop + 1,
663 IsHidden(target_p) ? "(H) " : "",
664 target_p->info);
665 }
666
667 sendto_realops_flags(UMODE_EXTERNAL, L_ALL,
668 "Server %s being introduced by %s",
669 target_p->name, source_p->name);
670 }
671
672 /* set_server_gecos()
673 *
674 * input - pointer to client
675 * output - NONE
676 * side effects - servers gecos field is set
677 */
678 static void
679 set_server_gecos(struct Client *client_p, char *info)
680 {
681 /* check the info for [IP] */
682 if (info[0])
683 {
684 char *p;
685 char *s;
686 char *t;
687
688 s = info;
689
690 /* we should only check the first word for an ip */
691 if ((p = strchr(s, ' ')) != NULL)
692 *p = '\0';
693
694 /* check for a ] which would symbolise an [IP] */
695 if ((t = strchr(s, ']')) != NULL)
696 {
697 /* set s to after the first space */
698 if (p)
699 s = ++p;
700 else
701 s = NULL;
702 }
703 /* no ], put the space back */
704 else if (p)
705 *p = ' ';
706
707 /* p may have been set to a trailing space, so check s exists and that
708 * it isnt \0 */
709 if (s && (*s != '\0'))
710 {
711 /* a space? if not (H) could be the last part of info.. */
712 if ((p = strchr(s, ' ')))
713 *p = '\0';
714
715 /* check for (H) which is a hidden server */
716 if (!strcmp(s, "(H)"))
717 {
718 SetHidden(client_p);
719
720 /* if there was no space.. theres nothing to set info to */
721 if (p)
722 s = ++p;
723 else
724 s = NULL;
725 }
726 else if (p)
727 *p = ' ';
728
729 /* if there was a trailing space, s could point to \0, so check */
730 if (s && (*s != '\0'))
731 strlcpy(client_p->info, s, sizeof(client_p->info));
732 else
733 strlcpy(client_p->info, "(Unknown Location)", sizeof(client_p->info));
734 }
735 else
736 strlcpy(client_p->info, "(Unknown Location)", sizeof(client_p->info));
737 }
738 else
739 strlcpy(client_p->info, "(Unknown Location)", sizeof(client_p->info));
740 }

Properties

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