ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid-8/modules/core/m_server.c
Revision: 1169
Committed: Fri Aug 12 18:45:03 2011 UTC (12 years, 7 months ago) by michael
Content type: text/x-csrc
File size: 22953 byte(s)
Log Message:
- rename find_server to hash_find_server to satisfy naming convention
- pull m_services.c and m_jupe.c from contrib/
- style fixes in some places

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 = hash_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 = hash_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
429 if (IsService(source_p) || find_matching_name_conf(SERVICE_TYPE, target_p->name, NULL, NULL, 0))
430 SetService(target_p);
431
432 dlinkAdd(target_p, &target_p->node, &global_client_list);
433 dlinkAdd(target_p, make_dlink_node(), &global_serv_list);
434 dlinkAdd(target_p, &target_p->lnode, &target_p->servptr->serv->server_list);
435
436 hash_add_client(target_p);
437
438 /* Old sendto_serv_but_one() call removed because we now
439 * need to send different names to different servers
440 * (domain name matching)
441 */
442 DLINK_FOREACH_SAFE(ptr, ptr_next, serv_list.head)
443 {
444 bclient_p = ptr->data;
445
446 if (bclient_p == client_p)
447 continue;
448
449 sendto_one(bclient_p, ":%s SERVER %s %d :%s%s",
450 ID_or_name(source_p, bclient_p), target_p->name, hop + 1,
451 IsHidden(target_p) ? "(H) " : "",
452 target_p->info);
453 }
454
455 sendto_realops_flags(UMODE_EXTERNAL, L_ALL,
456 "Server %s being introduced by %s",
457 target_p->name, source_p->name);
458 }
459
460 /* ms_sid()
461 * parv[0] = sender prefix
462 * parv[1] = servername
463 * parv[2] = serverinfo/hopcount
464 * parv[3] = sid of new server
465 * parv[4] = serverinfo
466 */
467 static void
468 ms_sid(struct Client *client_p, struct Client *source_p,
469 int parc, char *parv[])
470 {
471 char info[REALLEN + 1];
472 struct Client *target_p;
473 struct Client *bclient_p;
474 struct ConfItem *conf;
475 struct MatchItem *match_item;
476 int hlined = 0;
477 int llined = 0;
478 dlink_node *ptr, *ptr_next;
479 int hop;
480
481 /* Just to be sure -A1kmm. */
482 if (!IsServer(source_p))
483 return;
484
485 if (parc < 5 || EmptyString(parv[4]))
486 {
487 sendto_one(client_p, "ERROR :No servername");
488 return;
489 }
490
491 hop = atoi(parv[2]);
492 strlcpy(info, parv[4], sizeof(info));
493
494 if (!valid_servname(parv[1]))
495 {
496 sendto_realops_flags(UMODE_ALL, L_ADMIN,
497 "Link %s introduced server with bogus server name %s",
498 get_client_name(client_p, SHOW_IP), parv[1]);
499 sendto_realops_flags(UMODE_ALL, L_OPER,
500 "Link %s introduced server with bogus server name %s",
501 get_client_name(client_p, MASK_IP), parv[1]);
502 sendto_one(client_p, "ERROR :Bogus server name introduced");
503 exit_client(client_p, &me, "Bogus server name intoduced");
504 return;
505 }
506
507 if (!valid_sid(parv[3]))
508 {
509 sendto_realops_flags(UMODE_ALL, L_ADMIN,
510 "Link %s introduced server with bogus server ID %s",
511 get_client_name(client_p, SHOW_IP), parv[3]);
512 sendto_realops_flags(UMODE_ALL, L_OPER,
513 "Link %s introduced server with bogus server ID %s",
514 get_client_name(client_p, MASK_IP), parv[3]);
515 sendto_one(client_p, "ERROR :Bogus server ID introduced");
516 exit_client(client_p, &me, "Bogus server ID intoduced");
517 return;
518 }
519
520 /* collision on SID? */
521 if ((target_p = hash_find_id(parv[3])))
522 {
523 sendto_one(client_p, "ERROR :SID %s already exists", parv[3]);
524 sendto_realops_flags(UMODE_ALL, L_ADMIN,
525 "Link %s cancelled, SID %s already exists",
526 get_client_name(client_p, SHOW_IP), parv[3]);
527 sendto_realops_flags(UMODE_ALL, L_OPER,
528 "Link %s cancelled, SID %s already exists",
529 client_p->name, parv[3]);
530 exit_client(client_p, &me, "Server Exists");
531 return;
532 }
533
534 /* collision on name? */
535 if ((target_p = hash_find_server(parv[1])))
536 {
537 sendto_one(client_p, "ERROR :Server %s already exists", parv[1]);
538 sendto_realops_flags(UMODE_ALL, L_ADMIN,
539 "Link %s cancelled, server %s already exists",
540 get_client_name(client_p, SHOW_IP), parv[1]);
541 sendto_realops_flags(UMODE_ALL, L_OPER,
542 "Link %s cancelled, server %s already exists",
543 client_p->name, parv[1]);
544 exit_client(client_p, &me, "Server Exists");
545 return;
546 }
547
548 /* XXX If somehow there is a connect in progress and
549 * a connect comes in with same name toss the pending one,
550 * but only if it's not the same client! - Dianora
551 */
552 if ((target_p = find_servconn_in_progress(parv[1])))
553 if (target_p != client_p)
554 exit_client(target_p, &me, "Overridden");
555
556 /* See if the newly found server is behind a guaranteed
557 * leaf. If so, close the link.
558 */
559 DLINK_FOREACH(ptr, leaf_items.head)
560 {
561 conf = ptr->data;
562
563 if (match(conf->name, client_p->name))
564 {
565 match_item = map_to_conf(conf);
566
567 if (match(match_item->host, parv[1]))
568 llined++;
569 }
570 }
571
572 DLINK_FOREACH(ptr, hub_items.head)
573 {
574 conf = ptr->data;
575
576 if (match(conf->name, client_p->name))
577 {
578 match_item = map_to_conf(conf);
579
580 if (match(match_item->host, parv[1]))
581 hlined++;
582 }
583 }
584
585 /* Ok, this way this works is
586 *
587 * A server can have a CONF_HUB allowing it to introduce servers
588 * behind it.
589 *
590 * connect {
591 * name = "irc.bighub.net";
592 * hub_mask="*";
593 * ...
594 *
595 * That would allow "irc.bighub.net" to introduce anything it wanted..
596 *
597 * However
598 *
599 * connect {
600 * name = "irc.somehub.fi";
601 * hub_mask="*";
602 * leaf_mask="*.edu";
603 *...
604 * Would allow this server in finland to hub anything but
605 * .edu's
606 */
607
608 /* Ok, check client_p can hub the new server, and make sure it's not a LL */
609 if (!hlined)
610 {
611 /* OOOPs nope can't HUB */
612 sendto_realops_flags(UMODE_ALL, L_ADMIN, "Non-Hub link %s introduced %s.",
613 get_client_name(client_p, SHOW_IP), parv[1]);
614 sendto_realops_flags(UMODE_ALL, L_OPER, "Non-Hub link %s introduced %s.",
615 get_client_name(client_p, MASK_IP), parv[1]);
616 exit_client(source_p, &me, "No matching hub_mask.");
617 return;
618 }
619
620 /* Check for the new server being leafed behind this HUB */
621 if (llined)
622 {
623 /* OOOPs nope can't HUB this leaf */
624 sendto_realops_flags(UMODE_ALL, L_ADMIN,
625 "Link %s introduced leafed server %s.",
626 get_client_name(client_p, SHOW_IP), parv[1]);
627 sendto_realops_flags(UMODE_ALL, L_OPER,
628 "Link %s introduced leafed server %s.",
629 get_client_name(client_p, MASK_IP), parv[1]);
630 exit_client(client_p, &me, "Leafed Server.");
631 return;
632 }
633
634 target_p = make_client(client_p);
635 make_server(target_p);
636 target_p->hopcount = hop;
637 target_p->servptr = source_p;
638
639 strlcpy(target_p->name, parv[1], sizeof(target_p->name));
640 strlcpy(target_p->id, parv[3], sizeof(target_p->id));
641
642 set_server_gecos(target_p, info);
643 SetServer(target_p);
644
645 if (IsService(source_p) || find_matching_name_conf(SERVICE_TYPE, target_p->name, NULL, NULL, 0))
646 SetService(target_p);
647
648 dlinkAdd(target_p, &target_p->node, &global_client_list);
649 dlinkAdd(target_p, make_dlink_node(), &global_serv_list);
650 dlinkAdd(target_p, &target_p->lnode, &target_p->servptr->serv->server_list);
651
652 hash_add_client(target_p);
653 hash_add_id(target_p);
654
655 DLINK_FOREACH_SAFE(ptr, ptr_next, serv_list.head)
656 {
657 bclient_p = ptr->data;
658
659 if (bclient_p == client_p)
660 continue;
661
662 if (IsCapable(bclient_p, CAP_TS6))
663 sendto_one(bclient_p, ":%s SID %s %d %s :%s%s",
664 ID_or_name(source_p, client_p), target_p->name, hop + 1,
665 parv[3], IsHidden(target_p) ? "(H) " : "",
666 target_p->info);
667 else
668 sendto_one(bclient_p, ":%s SERVER %s %d :%s%s",
669 source_p->name, target_p->name, hop + 1,
670 IsHidden(target_p) ? "(H) " : "",
671 target_p->info);
672 }
673
674 sendto_realops_flags(UMODE_EXTERNAL, L_ALL,
675 "Server %s being introduced by %s",
676 target_p->name, source_p->name);
677 }
678
679 /* set_server_gecos()
680 *
681 * input - pointer to client
682 * output - NONE
683 * side effects - servers gecos field is set
684 */
685 static void
686 set_server_gecos(struct Client *client_p, char *info)
687 {
688 /* check the info for [IP] */
689 if (info[0])
690 {
691 char *p;
692 char *s;
693 char *t;
694
695 s = info;
696
697 /* we should only check the first word for an ip */
698 if ((p = strchr(s, ' ')) != NULL)
699 *p = '\0';
700
701 /* check for a ] which would symbolise an [IP] */
702 if ((t = strchr(s, ']')) != NULL)
703 {
704 /* set s to after the first space */
705 if (p)
706 s = ++p;
707 else
708 s = NULL;
709 }
710 /* no ], put the space back */
711 else if (p)
712 *p = ' ';
713
714 /* p may have been set to a trailing space, so check s exists and that
715 * it isnt \0 */
716 if (s && (*s != '\0'))
717 {
718 /* a space? if not (H) could be the last part of info.. */
719 if ((p = strchr(s, ' ')))
720 *p = '\0';
721
722 /* check for (H) which is a hidden server */
723 if (!strcmp(s, "(H)"))
724 {
725 SetHidden(client_p);
726
727 /* if there was no space.. theres nothing to set info to */
728 if (p)
729 s = ++p;
730 else
731 s = NULL;
732 }
733 else if (p)
734 *p = ' ';
735
736 /* if there was a trailing space, s could point to \0, so check */
737 if (s && (*s != '\0'))
738 strlcpy(client_p->info, s, sizeof(client_p->info));
739 else
740 strlcpy(client_p->info, "(Unknown Location)", sizeof(client_p->info));
741 }
742 else
743 strlcpy(client_p->info, "(Unknown Location)", sizeof(client_p->info));
744 }
745 else
746 strlcpy(client_p->info, "(Unknown Location)", sizeof(client_p->info));
747 }

Properties

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