]> jfr.im git - irc/rqf/shadowircd.git/blame - src/send.c
Fix some split servers not appearing in oper /map.
[irc/rqf/shadowircd.git] / src / send.c
CommitLineData
212380e3 1/*
2 * ircd-ratbox: A slightly useful ircd.
3 * send.c: Functions for sending messages.
4 *
5 * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
6 * Copyright (C) 1996-2002 Hybrid Development Team
7 * Copyright (C) 2002-2005 ircd-ratbox development team
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
22 * USA
23 *
8aba962d 24 * $Id: send.c 3520 2007-06-30 22:15:35Z jilles $
212380e3 25 */
26
27#include "stdinc.h"
28#include "tools.h"
29#include "send.h"
30#include "channel.h"
31#include "class.h"
32#include "client.h"
33#include "common.h"
34#include "irc_string.h"
35#include "ircd.h"
36#include "numeric.h"
37#include "commio.h"
38#include "s_serv.h"
39#include "sprintf_irc.h"
40#include "s_conf.h"
41#include "s_newconf.h"
42#include "linebuf.h"
43#include "s_log.h"
44#include "memory.h"
45#include "hook.h"
8aba962d 46#include "monitor.h"
212380e3 47
48#define LOG_BUFSIZE 2048
49
50/* send the message to the link the target is attached to */
51#define send_linebuf(a,b) _send_linebuf((a->from ? a->from : a) ,b)
52
53unsigned long current_serial = 0L;
54
55/* send_linebuf()
56 *
57 * inputs - client to send to, linebuf to attach
58 * outputs -
59 * side effects - linebuf is attached to client
60 */
61static int
62_send_linebuf(struct Client *to, buf_head_t *linebuf)
63{
64 if(IsMe(to))
65 {
66 sendto_realops_snomask(SNO_GENERAL, L_ALL, "Trying to send message to myself!");
67 return 0;
68 }
69
70 if(!MyConnect(to) || IsIOError(to))
71 return 0;
72
73 if(linebuf_len(&to->localClient->buf_sendq) > get_sendq(to))
74 {
75 if(IsServer(to))
76 {
77 sendto_realops_snomask(SNO_GENERAL, L_ALL,
78 "Max SendQ limit exceeded for %s: %u > %lu",
79 get_server_name(to, HIDE_IP),
80 linebuf_len(&to->localClient->buf_sendq),
81 get_sendq(to));
82
83 ilog(L_SERVER, "Max SendQ limit exceeded for %s: %u > %lu",
84 log_client_name(to, SHOW_IP),
85 linebuf_len(&to->localClient->buf_sendq),
86 get_sendq(to));
87 }
88
89 if(IsClient(to))
90 to->flags |= FLAGS_SENDQEX;
91
92 dead_link(to);
93 return -1;
94 }
95 else
96 {
97 /* just attach the linebuf to the sendq instead of
98 * generating a new one
99 */
100 linebuf_attach(&to->localClient->buf_sendq, linebuf);
101 }
102
103 /*
104 ** Update statistics. The following is slightly incorrect
105 ** because it counts messages even if queued, but bytes
106 ** only really sent. Queued bytes get updated in SendQueued.
107 */
108 to->localClient->sendM += 1;
109 me.localClient->sendM += 1;
110 if(linebuf_len(&to->localClient->buf_sendq) > 0)
de057244 111 send_queued_write(to->localClient->F->fd, to);
212380e3 112 return 0;
113}
114
115/* send_linebuf_remote()
116 *
117 * inputs - client to attach to, sender, linebuf
118 * outputs -
119 * side effects - client has linebuf attached
120 */
121static void
122send_linebuf_remote(struct Client *to, struct Client *from, buf_head_t *linebuf)
123{
124 if(to->from)
125 to = to->from;
126
127 /* test for fake direction */
128 if(!MyClient(from) && IsPerson(to) && (to == from->from))
129 {
130 if(IsServer(from))
131 {
132 sendto_realops_snomask(SNO_GENERAL, L_ALL,
133 "Send message to %s[%s] dropped from %s(Fake Dir)",
134 to->name, to->from->name, from->name);
135 return;
136 }
137
138 sendto_realops_snomask(SNO_GENERAL, L_ALL,
139 "Ghosted: %s[%s@%s] from %s[%s@%s] (%s)",
140 to->name, to->username, to->host,
141 from->name, from->username, from->host, to->from->name);
142 kill_client_serv_butone(NULL, to, "%s (%s[%s@%s] Ghosted %s)",
143 me.name, to->name, to->username,
144 to->host, to->from->name);
145
146 to->flags |= FLAGS_KILLED;
147
148 exit_client(NULL, to, &me, "Ghosted client");
149 return;
150 }
151
152 _send_linebuf(to, linebuf);
153 return;
154}
155
156/* send_queued_write()
157 *
158 * inputs - fd to have queue sent, client we're sending to
159 * outputs - contents of queue
160 * side effects - write is rescheduled if queue isnt emptied
161 */
162void
163send_queued_write(int fd, void *data)
164{
165 struct Client *to = data;
166 int retlen;
167 int flags;
168#ifdef USE_IODEBUG_HOOKS
169 hook_data_int hd;
170#endif
de057244 171 fde_t *F = comm_locate_fd(to->localClient->F->fd);
5cd74a3b
WP
172 if (!F)
173 return;
174
212380e3 175 /* cant write anything to a dead socket. */
176 if(IsIOError(to))
177 return;
178
179#ifdef USE_IODEBUG_HOOKS
180 hd.client = to;
181 if(to->localClient->buf_sendq.list.head)
182 hd.arg1 = ((buf_line_t *) to->localClient->buf_sendq.list.head->data)->buf +
183 to->localClient->buf_sendq.writeofs;
184#endif
185
186 if(linebuf_len(&to->localClient->buf_sendq))
187 {
188 while ((retlen =
5cd74a3b 189 linebuf_flush(F, &to->localClient->buf_sendq)) > 0)
212380e3 190 {
191 /* We have some data written .. update counters */
192#ifdef USE_IODEBUG_HOOKS
193 hd.arg2 = retlen;
194 call_hook(h_iosend_id, &hd);
195
196 if(to->localClient->buf_sendq.list.head)
197 hd.arg1 =
198 ((buf_line_t *) to->localClient->buf_sendq.list.head->
199 data)->buf + to->localClient->buf_sendq.writeofs;
200#endif
201
202
203 to->localClient->sendB += retlen;
204 me.localClient->sendB += retlen;
205 if(to->localClient->sendB > 1023)
206 {
207 to->localClient->sendK += (to->localClient->sendB >> 10);
208 to->localClient->sendB &= 0x03ff; /* 2^10 = 1024, 3ff = 1023 */
209 }
210 else if(me.localClient->sendB > 1023)
211 {
212 me.localClient->sendK += (me.localClient->sendB >> 10);
213 me.localClient->sendB &= 0x03ff;
214 }
215 }
216
217 if(retlen == 0 || (retlen < 0 && !ignoreErrno(errno)))
218 {
219 dead_link(to);
220 return;
221 }
222 }
223 if(ignoreErrno(errno))
224 flags = COMM_SELECT_WRITE|COMM_SELECT_RETRY;
225 else
226 flags = COMM_SELECT_WRITE;
227 if(linebuf_len(&to->localClient->buf_sendq))
228 comm_setselect(fd, FDLIST_IDLECLIENT, flags,
229 send_queued_write, to, 0);
230}
231
232/* send_queued_slink_write()
233 *
234 * inputs - fd to have queue sent, client we're sending to
235 * outputs - contents of queue
236 * side effects - write is rescheduled if queue isnt emptied
237 */
238void
239send_queued_slink_write(int fd, void *data)
240{
241 struct Client *to = data;
242 int retlen;
243
244 /*
245 ** Once socket is marked dead, we cannot start writing to it,
246 ** even if the error is removed...
247 */
248 if(IsIOError(to))
249 return;
250
251 /* Next, lets try to write some data */
252 if(to->localClient->slinkq)
253 {
254 retlen = write(to->localClient->ctrlfd,
255 to->localClient->slinkq + to->localClient->slinkq_ofs,
256 to->localClient->slinkq_len);
257
258 if(retlen < 0)
259 {
260 /* If we have a fatal error */
261 if(!ignoreErrno(errno))
262 {
263 dead_link(to);
264 return;
265 }
266 }
267 /* 0 bytes is an EOF .. */
268 else if(retlen == 0)
269 {
270 dead_link(to);
271 return;
272 }
273 else
274 {
275 to->localClient->slinkq_len -= retlen;
276
277 s_assert(to->localClient->slinkq_len >= 0);
278 if(to->localClient->slinkq_len)
279 to->localClient->slinkq_ofs += retlen;
280 else
281 {
282 to->localClient->slinkq_ofs = 0;
283 MyFree(to->localClient->slinkq);
284 to->localClient->slinkq = NULL;
285 }
286 }
287 }
288
289 /* if we have any more data, reschedule a write */
290 if(to->localClient->slinkq_len)
291 comm_setselect(to->localClient->ctrlfd, FDLIST_IDLECLIENT,
292 COMM_SELECT_WRITE|COMM_SELECT_RETRY, send_queued_slink_write, to, 0);
293}
294
295/* sendto_one()
296 *
297 * inputs - client to send to, va_args
298 * outputs - client has message put into its queue
299 * side effects -
300 */
301void
302sendto_one(struct Client *target_p, const char *pattern, ...)
303{
304 va_list args;
305 buf_head_t linebuf;
306
307 /* send remote if to->from non NULL */
308 if(target_p->from != NULL)
309 target_p = target_p->from;
310
311 if(IsIOError(target_p))
312 return;
313
314 linebuf_newbuf(&linebuf);
315
316 va_start(args, pattern);
317 linebuf_putmsg(&linebuf, pattern, &args, NULL);
318 va_end(args);
319
320 _send_linebuf(target_p, &linebuf);
321
322 linebuf_donebuf(&linebuf);
323
324}
325
326/* sendto_one_prefix()
327 *
328 * inputs - client to send to, va_args
329 * outputs - client has message put into its queue
330 * side effects - source(us)/target is chosen based on TS6 capability
331 */
332void
333sendto_one_prefix(struct Client *target_p, struct Client *source_p,
334 const char *command, const char *pattern, ...)
335{
336 struct Client *dest_p;
337 va_list args;
338 buf_head_t linebuf;
339
340 /* send remote if to->from non NULL */
341 if(target_p->from != NULL)
342 dest_p = target_p->from;
343 else
344 dest_p = target_p;
345
346 if(IsIOError(dest_p))
347 return;
348
349 if(IsMe(dest_p))
350 {
351 sendto_realops_snomask(SNO_GENERAL, L_ALL, "Trying to send to myself!");
352 return;
353 }
354
355 linebuf_newbuf(&linebuf);
356 va_start(args, pattern);
357 linebuf_putmsg(&linebuf, pattern, &args,
358 ":%s %s %s ",
359 get_id(source_p, target_p),
360 command, get_id(target_p, target_p));
361 va_end(args);
362
363 _send_linebuf(dest_p, &linebuf);
364 linebuf_donebuf(&linebuf);
365}
366
367/* sendto_one_notice()
368 *
369 * inputs - client to send to, va_args
370 * outputs - client has a NOTICE put into its queue
371 * side effects - source(us)/target is chosen based on TS6 capability
372 */
373void
374sendto_one_notice(struct Client *target_p, const char *pattern, ...)
375{
376 struct Client *dest_p;
377 va_list args;
378 buf_head_t linebuf;
5366977b 379 char *to;
212380e3 380
381 /* send remote if to->from non NULL */
382 if(target_p->from != NULL)
383 dest_p = target_p->from;
384 else
385 dest_p = target_p;
386
387 if(IsIOError(dest_p))
388 return;
389
390 if(IsMe(dest_p))
391 {
392 sendto_realops_snomask(SNO_GENERAL, L_ALL, "Trying to send to myself!");
393 return;
394 }
395
396 linebuf_newbuf(&linebuf);
397 va_start(args, pattern);
398 linebuf_putmsg(&linebuf, pattern, &args,
399 ":%s NOTICE %s ",
5366977b 400 get_id(&me, target_p), *(to = get_id(target_p, target_p)) != '\0' ? to : "*");
212380e3 401 va_end(args);
402
403 _send_linebuf(dest_p, &linebuf);
404 linebuf_donebuf(&linebuf);
405}
406
407
408/* sendto_one_numeric()
409 *
410 * inputs - client to send to, va_args
411 * outputs - client has message put into its queue
412 * side effects - source/target is chosen based on TS6 capability
413 */
414void
415sendto_one_numeric(struct Client *target_p, int numeric, const char *pattern, ...)
416{
417 struct Client *dest_p;
418 va_list args;
419 buf_head_t linebuf;
5366977b 420 char *to;
212380e3 421
422 /* send remote if to->from non NULL */
423 if(target_p->from != NULL)
424 dest_p = target_p->from;
425 else
426 dest_p = target_p;
427
428 if(IsIOError(dest_p))
429 return;
430
431 if(IsMe(dest_p))
432 {
433 sendto_realops_snomask(SNO_GENERAL, L_ALL, "Trying to send to myself!");
434 return;
435 }
436
437 linebuf_newbuf(&linebuf);
438 va_start(args, pattern);
439 linebuf_putmsg(&linebuf, pattern, &args,
440 ":%s %03d %s ",
441 get_id(&me, target_p),
5366977b 442 numeric, *(to = get_id(target_p, target_p)) != '\0' ? to : "*");
212380e3 443 va_end(args);
444
445 _send_linebuf(dest_p, &linebuf);
446 linebuf_donebuf(&linebuf);
447}
448
449/*
450 * sendto_server
451 *
452 * inputs - pointer to client to NOT send to
453 * - caps or'd together which must ALL be present
454 * - caps or'd together which must ALL NOT be present
455 * - printf style format string
456 * - args to format string
457 * output - NONE
458 * side effects - Send a message to all connected servers, except the
459 * client 'one' (if non-NULL), as long as the servers
460 * support ALL capabs in 'caps', and NO capabs in 'nocaps'.
461 *
462 * This function was written in an attempt to merge together the other
463 * billion sendto_*serv*() functions, which sprung up with capabs, uids etc
464 * -davidt
465 */
466void
467sendto_server(struct Client *one, struct Channel *chptr, unsigned long caps,
468 unsigned long nocaps, const char *format, ...)
469{
470 va_list args;
471 struct Client *target_p;
472 dlink_node *ptr;
473 dlink_node *next_ptr;
474 buf_head_t linebuf;
475
476 /* noone to send to.. */
477 if(dlink_list_length(&serv_list) == 0)
478 return;
479
480 if(chptr != NULL && *chptr->chname != '#')
481 return;
482
483 linebuf_newbuf(&linebuf);
484 va_start(args, format);
485 linebuf_putmsg(&linebuf, format, &args, NULL);
486 va_end(args);
487
488 DLINK_FOREACH_SAFE(ptr, next_ptr, serv_list.head)
489 {
490 target_p = ptr->data;
491
492 /* check against 'one' */
493 if(one != NULL && (target_p == one->from))
494 continue;
495
496 /* check we have required capabs */
497 if(!IsCapable(target_p, caps))
498 continue;
499
500 /* check we don't have any forbidden capabs */
501 if(!NotCapable(target_p, nocaps))
502 continue;
503
504 _send_linebuf(target_p, &linebuf);
505 }
506
507 linebuf_donebuf(&linebuf);
508
509}
510
511/* sendto_channel_flags()
512 *
513 * inputs - server not to send to, flags needed, source, channel, va_args
514 * outputs - message is sent to channel members
515 * side effects -
516 */
517void
518sendto_channel_flags(struct Client *one, int type, struct Client *source_p,
519 struct Channel *chptr, const char *pattern, ...)
520{
521 static char buf[BUFSIZE];
522 va_list args;
523 buf_head_t linebuf_local;
524 buf_head_t linebuf_name;
525 buf_head_t linebuf_id;
526 struct Client *target_p;
527 struct membership *msptr;
528 dlink_node *ptr;
529 dlink_node *next_ptr;
530
531 linebuf_newbuf(&linebuf_local);
532 linebuf_newbuf(&linebuf_name);
533 linebuf_newbuf(&linebuf_id);
534
535 current_serial++;
536
537 va_start(args, pattern);
538 ircvsnprintf(buf, sizeof(buf), pattern, args);
539 va_end(args);
540
541 if(IsServer(source_p))
542 linebuf_putmsg(&linebuf_local, NULL, NULL,
543 ":%s %s", source_p->name, buf);
544 else
545 linebuf_putmsg(&linebuf_local, NULL, NULL,
546 ":%s!%s@%s %s",
547 source_p->name, source_p->username,
548 source_p->host, buf);
549
550 linebuf_putmsg(&linebuf_name, NULL, NULL, ":%s %s", source_p->name, buf);
551 linebuf_putmsg(&linebuf_id, NULL, NULL, ":%s %s", use_id(source_p), buf);
552
553 DLINK_FOREACH_SAFE(ptr, next_ptr, chptr->members.head)
554 {
555 msptr = ptr->data;
556 target_p = msptr->client_p;
557
558 if(IsIOError(target_p->from) || target_p->from == one)
559 continue;
560
561 if(type && ((msptr->flags & type) == 0))
562 continue;
563
564 if(IsDeaf(target_p))
565 continue;
566
567 if(!MyClient(target_p))
568 {
569 /* if we've got a specific type, target must support
570 * CHW.. --fl
571 */
572 if(type && NotCapable(target_p->from, CAP_CHW))
573 continue;
574
575 if(target_p->from->serial != current_serial)
576 {
577 if(has_id(target_p->from))
578 send_linebuf_remote(target_p, source_p, &linebuf_id);
579 else
580 send_linebuf_remote(target_p, source_p, &linebuf_name);
581
582 target_p->from->serial = current_serial;
583 }
584 }
585 else
586 _send_linebuf(target_p, &linebuf_local);
587 }
588
589 linebuf_donebuf(&linebuf_local);
590 linebuf_donebuf(&linebuf_name);
591 linebuf_donebuf(&linebuf_id);
592}
593
594
595/* sendto_channel_local()
596 *
597 * inputs - flags to send to, channel to send to, va_args
598 * outputs - message to local channel members
599 * side effects -
600 */
601void
602sendto_channel_local(int type, struct Channel *chptr, const char *pattern, ...)
603{
604 va_list args;
605 buf_head_t linebuf;
606 struct membership *msptr;
607 struct Client *target_p;
608 dlink_node *ptr;
609 dlink_node *next_ptr;
610
611 linebuf_newbuf(&linebuf);
612
613 va_start(args, pattern);
614 linebuf_putmsg(&linebuf, pattern, &args, NULL);
615 va_end(args);
616
617 DLINK_FOREACH_SAFE(ptr, next_ptr, chptr->locmembers.head)
618 {
619 msptr = ptr->data;
620 target_p = msptr->client_p;
621
622 if(IsIOError(target_p))
623 continue;
624
625 if(type && ((msptr->flags & type) == 0))
626 continue;
627
628 _send_linebuf(target_p, &linebuf);
629 }
630
631 linebuf_donebuf(&linebuf);
632}
633
634/* sendto_channel_local_butone()
635 *
636 * inputs - flags to send to, channel to send to, va_args
637 * - user to ignore when sending
638 * outputs - message to local channel members
639 * side effects -
640 */
641void
642sendto_channel_local_butone(struct Client *one, int type, struct Channel *chptr, const char *pattern, ...)
643{
644 va_list args;
645 buf_head_t linebuf;
646 struct membership *msptr;
647 struct Client *target_p;
648 dlink_node *ptr;
649 dlink_node *next_ptr;
650
651 linebuf_newbuf(&linebuf);
652
653 va_start(args, pattern);
654 linebuf_putmsg(&linebuf, pattern, &args, NULL);
655 va_end(args);
656
657 DLINK_FOREACH_SAFE(ptr, next_ptr, chptr->locmembers.head)
658 {
659 msptr = ptr->data;
660 target_p = msptr->client_p;
661
662 if(target_p == one)
663 continue;
664
665 if(IsIOError(target_p))
666 continue;
667
668 if(type && ((msptr->flags & type) == 0))
669 continue;
670
671 _send_linebuf(target_p, &linebuf);
672 }
673
674 linebuf_donebuf(&linebuf);
675}
676
677/*
678 * sendto_common_channels_local()
679 *
680 * inputs - pointer to client
681 * - pattern to send
682 * output - NONE
683 * side effects - Sends a message to all people on local server who are
684 * in same channel with user.
685 * used by m_nick.c and exit_one_client.
686 */
687void
688sendto_common_channels_local(struct Client *user, const char *pattern, ...)
689{
690 va_list args;
691 dlink_node *ptr;
692 dlink_node *next_ptr;
693 dlink_node *uptr;
694 dlink_node *next_uptr;
695 struct Channel *chptr;
696 struct Client *target_p;
697 struct membership *msptr;
698 struct membership *mscptr;
699 buf_head_t linebuf;
700
701 linebuf_newbuf(&linebuf);
702 va_start(args, pattern);
703 linebuf_putmsg(&linebuf, pattern, &args, NULL);
704 va_end(args);
705
706 ++current_serial;
707
708 DLINK_FOREACH_SAFE(ptr, next_ptr, user->user->channel.head)
709 {
710 mscptr = ptr->data;
711 chptr = mscptr->chptr;
712
713 DLINK_FOREACH_SAFE(uptr, next_uptr, chptr->locmembers.head)
714 {
715 msptr = uptr->data;
716 target_p = msptr->client_p;
717
718 if(IsIOError(target_p) ||
719 target_p->serial == current_serial)
720 continue;
721
722 target_p->serial = current_serial;
723 send_linebuf(target_p, &linebuf);
724 }
725 }
726
727 /* this can happen when the user isnt in any channels, but we still
728 * need to send them the data, ie a nick change
729 */
730 if(MyConnect(user) && (user->serial != current_serial))
731 send_linebuf(user, &linebuf);
732
733 linebuf_donebuf(&linebuf);
734}
735
736/*
737 * sendto_common_channels_local_butone()
738 *
739 * inputs - pointer to client
740 * - pattern to send
741 * output - NONE
742 * side effects - Sends a message to all people on local server who are
743 * in same channel with user, except for user itself.
744 */
745void
746sendto_common_channels_local_butone(struct Client *user, const char *pattern, ...)
747{
748 va_list args;
749 dlink_node *ptr;
750 dlink_node *next_ptr;
751 dlink_node *uptr;
752 dlink_node *next_uptr;
753 struct Channel *chptr;
754 struct Client *target_p;
755 struct membership *msptr;
756 struct membership *mscptr;
757 buf_head_t linebuf;
758
759 linebuf_newbuf(&linebuf);
760 va_start(args, pattern);
761 linebuf_putmsg(&linebuf, pattern, &args, NULL);
762 va_end(args);
763
764 ++current_serial;
765 /* Skip them -- jilles */
766 user->serial = current_serial;
767
768 DLINK_FOREACH_SAFE(ptr, next_ptr, user->user->channel.head)
769 {
770 mscptr = ptr->data;
771 chptr = mscptr->chptr;
772
773 DLINK_FOREACH_SAFE(uptr, next_uptr, chptr->locmembers.head)
774 {
775 msptr = uptr->data;
776 target_p = msptr->client_p;
777
778 if(IsIOError(target_p) ||
779 target_p->serial == current_serial)
780 continue;
781
782 target_p->serial = current_serial;
783 send_linebuf(target_p, &linebuf);
784 }
785 }
786
787 linebuf_donebuf(&linebuf);
788}
789
790/* sendto_match_butone()
791 *
792 * inputs - server not to send to, source, mask, type of mask, va_args
793 * output -
794 * side effects - message is sent to matching clients
795 */
796void
797sendto_match_butone(struct Client *one, struct Client *source_p,
798 const char *mask, int what, const char *pattern, ...)
799{
800 static char buf[BUFSIZE];
801 va_list args;
802 struct Client *target_p;
803 dlink_node *ptr;
804 dlink_node *next_ptr;
805 buf_head_t linebuf_local;
806 buf_head_t linebuf_name;
807 buf_head_t linebuf_id;
808
809 linebuf_newbuf(&linebuf_local);
810 linebuf_newbuf(&linebuf_name);
811 linebuf_newbuf(&linebuf_id);
812
813 va_start(args, pattern);
814 ircvsnprintf(buf, sizeof(buf), pattern, args);
815 va_end(args);
816
817 if(IsServer(source_p))
818 linebuf_putmsg(&linebuf_local, NULL, NULL,
819 ":%s %s", source_p->name, buf);
820 else
821 linebuf_putmsg(&linebuf_local, NULL, NULL,
822 ":%s!%s@%s %s",
823 source_p->name, source_p->username,
824 source_p->host, buf);
825
826 linebuf_putmsg(&linebuf_name, NULL, NULL, ":%s %s", source_p->name, buf);
827 linebuf_putmsg(&linebuf_id, NULL, NULL, ":%s %s", use_id(source_p), buf);
828
829 if(what == MATCH_HOST)
830 {
831 DLINK_FOREACH_SAFE(ptr, next_ptr, lclient_list.head)
832 {
833 target_p = ptr->data;
834
835 if(match(mask, target_p->host))
836 _send_linebuf(target_p, &linebuf_local);
837 }
838 }
839 /* what = MATCH_SERVER, if it doesnt match us, just send remote */
840 else if(match(mask, me.name))
841 {
842 DLINK_FOREACH_SAFE(ptr, next_ptr, lclient_list.head)
843 {
844 target_p = ptr->data;
845 _send_linebuf(target_p, &linebuf_local);
846 }
847 }
848
849 DLINK_FOREACH(ptr, serv_list.head)
850 {
851 target_p = ptr->data;
852
853 if(target_p == one)
854 continue;
855
856 if(has_id(target_p))
857 send_linebuf_remote(target_p, source_p, &linebuf_id);
858 else
859 send_linebuf_remote(target_p, source_p, &linebuf_name);
860 }
861
862 linebuf_donebuf(&linebuf_local);
863 linebuf_donebuf(&linebuf_id);
864 linebuf_donebuf(&linebuf_name);
865}
866
867/* sendto_match_servs()
868 *
869 * inputs - source, mask to send to, caps needed, va_args
870 * outputs -
871 * side effects - message is sent to matching servers with caps.
872 */
873void
874sendto_match_servs(struct Client *source_p, const char *mask, int cap,
875 int nocap, const char *pattern, ...)
876{
877 static char buf[BUFSIZE];
878 va_list args;
879 dlink_node *ptr;
880 struct Client *target_p;
881 buf_head_t linebuf_id;
882 buf_head_t linebuf_name;
883
884 if(EmptyString(mask))
885 return;
886
887 linebuf_newbuf(&linebuf_id);
888 linebuf_newbuf(&linebuf_name);
889
890 va_start(args, pattern);
891 ircvsnprintf(buf, sizeof(buf), pattern, args);
892 va_end(args);
893
894 linebuf_putmsg(&linebuf_id, NULL, NULL,
895 ":%s %s", use_id(source_p), buf);
896 linebuf_putmsg(&linebuf_name, NULL, NULL,
897 ":%s %s", source_p->name, buf);
898
899 current_serial++;
900
901 DLINK_FOREACH(ptr, global_serv_list.head)
902 {
903 target_p = ptr->data;
904
905 /* dont send to ourselves, or back to where it came from.. */
906 if(IsMe(target_p) || target_p->from == source_p->from)
907 continue;
908
909 if(target_p->from->serial == current_serial)
910 continue;
911
912 if(match(mask, target_p->name))
913 {
914 /* if we set the serial here, then we'll never do
915 * a match() again if !IsCapable()
916 */
917 target_p->from->serial = current_serial;
918
919 if(cap && !IsCapable(target_p->from, cap))
920 continue;
921
922 if(nocap && !NotCapable(target_p->from, nocap))
923 continue;
924
925 if(has_id(target_p->from))
926 _send_linebuf(target_p->from, &linebuf_id);
927 else
928 _send_linebuf(target_p->from, &linebuf_name);
929 }
930 }
931
932 linebuf_donebuf(&linebuf_id);
933 linebuf_donebuf(&linebuf_name);
934}
935
8aba962d 936/* sendto_monitor()
937 *
938 * inputs - monitor nick to send to, format, va_args
939 * outputs - message to local users monitoring the given nick
940 * side effects -
941 */
942void
943sendto_monitor(struct monitor *monptr, const char *pattern, ...)
944{
945 va_list args;
946 buf_head_t linebuf;
947 struct Client *target_p;
948 dlink_node *ptr;
949 dlink_node *next_ptr;
950
951 linebuf_newbuf(&linebuf);
952
953 va_start(args, pattern);
954 linebuf_putmsg(&linebuf, pattern, &args, NULL);
955 va_end(args);
956
957 DLINK_FOREACH_SAFE(ptr, next_ptr, monptr->users.head)
958 {
959 target_p = ptr->data;
960
961 if(IsIOError(target_p))
962 continue;
963
964 _send_linebuf(target_p, &linebuf);
965 }
966
967 linebuf_donebuf(&linebuf);
968}
969
212380e3 970/* sendto_anywhere()
971 *
972 * inputs - target, source, va_args
973 * outputs -
974 * side effects - client is sent message with correct prefix.
975 */
976void
977sendto_anywhere(struct Client *target_p, struct Client *source_p,
978 const char *command, const char *pattern, ...)
979{
980 va_list args;
981 buf_head_t linebuf;
982
983 linebuf_newbuf(&linebuf);
984
985 va_start(args, pattern);
986
987 if(MyClient(target_p))
988 {
989 if(IsServer(source_p))
990 linebuf_putmsg(&linebuf, pattern, &args, ":%s %s %s ",
991 source_p->name, command,
992 target_p->name);
993 else
994 linebuf_putmsg(&linebuf, pattern, &args,
995 ":%s!%s@%s %s %s ",
996 source_p->name, source_p->username,
997 source_p->host, command,
998 target_p->name);
999 }
1000 else
1001 linebuf_putmsg(&linebuf, pattern, &args, ":%s %s %s ",
1002 get_id(source_p, target_p), command,
1003 get_id(target_p, target_p));
1004 va_end(args);
1005
1006 if(MyClient(target_p))
1007 _send_linebuf(target_p, &linebuf);
1008 else
1009 send_linebuf_remote(target_p, source_p, &linebuf);
1010
1011 linebuf_donebuf(&linebuf);
1012}
1013
1014/* sendto_realops_flags()
1015 *
1016 * inputs - umode needed, level (opers/admin), va_args
1017 * output -
1018 * side effects - message is sent to opers with matching umodes
1019 */
1020void
1021sendto_realops_flags(int flags, int level, const char *pattern, ...)
1022{
1023 struct Client *client_p;
1024 dlink_node *ptr;
1025 dlink_node *next_ptr;
1026 va_list args;
1027 buf_head_t linebuf;
1028
1029 linebuf_newbuf(&linebuf);
1030
1031 va_start(args, pattern);
1032 linebuf_putmsg(&linebuf, pattern, &args,
1033 ":%s NOTICE * :*** Notice -- ", me.name);
1034 va_end(args);
1035
1036 DLINK_FOREACH_SAFE(ptr, next_ptr, local_oper_list.head)
1037 {
1038 client_p = ptr->data;
1039
1040 /* If we're sending it to opers and theyre an admin, skip.
1041 * If we're sending it to admins, and theyre not, skip.
1042 */
1043 if(((level == L_ADMIN) && !IsOperAdmin(client_p)) ||
1044 ((level == L_OPER) && IsOperAdmin(client_p)))
1045 continue;
1046
1047 if(client_p->umodes & flags)
1048 _send_linebuf(client_p, &linebuf);
1049 }
1050
1051 linebuf_donebuf(&linebuf);
1052}
1053
1054/* sendto_realops_snomask()
1055 *
1056 * inputs - snomask needed, level (opers/admin), va_args
1057 * output -
1058 * side effects - message is sent to opers with matching snomasks
1059 */
1060void
1061sendto_realops_snomask(int flags, int level, const char *pattern, ...)
1062{
1063 static char buf[BUFSIZE];
1064 char *snobuf;
1065 struct Client *client_p;
1066 dlink_node *ptr;
1067 dlink_node *next_ptr;
1068 va_list args;
1069 buf_head_t linebuf;
1070
1071 linebuf_newbuf(&linebuf);
1072
1073 /* Be very sure not to do things like "Trying to send to myself"
1074 * L_NETWIDE, otherwise infinite recursion may result! -- jilles */
1075 if (level & L_NETWIDE && ConfigFileEntry.global_snotices)
1076 {
1077 /* rather a lot of copying around, oh well -- jilles */
1078 va_start(args, pattern);
1079 ircvsnprintf(buf, sizeof(buf), pattern, args);
1080 va_end(args);
1081 linebuf_putmsg(&linebuf, pattern, NULL,
1082 ":%s NOTICE * :*** Notice -- %s", me.name, buf);
1083 snobuf = construct_snobuf(flags);
1084 if (snobuf[1] != '\0')
1085 {
1086 sendto_server(NULL, NULL, CAP_ENCAP|CAP_TS6, NOCAPS,
1087 ":%s ENCAP * SNOTE %c :%s",
1088 me.id, snobuf[1], buf);
1089 sendto_server(NULL, NULL, CAP_ENCAP, CAP_TS6,
1090 ":%s ENCAP * SNOTE %c :%s",
1091 me.name, snobuf[1], buf);
1092 }
1093 }
1094 else
1095 {
1096 va_start(args, pattern);
1097 linebuf_putmsg(&linebuf, pattern, &args,
1098 ":%s NOTICE * :*** Notice -- ", me.name);
1099 va_end(args);
1100 }
1101 level &= ~L_NETWIDE;
1102
1103 DLINK_FOREACH_SAFE(ptr, next_ptr, local_oper_list.head)
1104 {
1105 client_p = ptr->data;
1106
1107 /* If we're sending it to opers and theyre an admin, skip.
1108 * If we're sending it to admins, and theyre not, skip.
1109 */
1110 if(((level == L_ADMIN) && !IsOperAdmin(client_p)) ||
1111 ((level == L_OPER) && IsOperAdmin(client_p)))
1112 continue;
1113
1114 if(client_p->snomask & flags)
1115 _send_linebuf(client_p, &linebuf);
1116 }
1117
1118 linebuf_donebuf(&linebuf);
1119}
1120/* sendto_realops_snomask_from()
1121 *
1122 * inputs - snomask needed, level (opers/admin), source server, va_args
1123 * output -
1124 * side effects - message is sent to opers with matching snomask
1125 */
1126void
1127sendto_realops_snomask_from(int flags, int level, struct Client *source_p,
1128 const char *pattern, ...)
1129{
1130 struct Client *client_p;
1131 dlink_node *ptr;
1132 dlink_node *next_ptr;
1133 va_list args;
1134 buf_head_t linebuf;
1135
1136 linebuf_newbuf(&linebuf);
1137
1138 va_start(args, pattern);
1139 linebuf_putmsg(&linebuf, pattern, &args,
1140 ":%s NOTICE * :*** Notice -- ", source_p->name);
1141 va_end(args);
1142
1143 DLINK_FOREACH_SAFE(ptr, next_ptr, local_oper_list.head)
1144 {
1145 client_p = ptr->data;
1146
1147 /* If we're sending it to opers and theyre an admin, skip.
1148 * If we're sending it to admins, and theyre not, skip.
1149 */
1150 if(((level == L_ADMIN) && !IsOperAdmin(client_p)) ||
1151 ((level == L_OPER) && IsOperAdmin(client_p)))
1152 continue;
1153
1154 if(client_p->snomask & flags)
1155 _send_linebuf(client_p, &linebuf);
1156 }
1157
1158 linebuf_donebuf(&linebuf);
1159}
1160
1161/*
1162 * sendto_wallops_flags
1163 *
1164 * inputs - flag types of messages to show to real opers
1165 * - client sending request
1166 * - var args input message
1167 * output - NONE
1168 * side effects - Send a wallops to local opers
1169 */
1170void
1171sendto_wallops_flags(int flags, struct Client *source_p, const char *pattern, ...)
1172{
1173 struct Client *client_p;
1174 dlink_node *ptr;
1175 dlink_node *next_ptr;
1176 va_list args;
1177 buf_head_t linebuf;
1178
1179 linebuf_newbuf(&linebuf);
1180
1181 va_start(args, pattern);
1182
1183 if(IsPerson(source_p))
1184 linebuf_putmsg(&linebuf, pattern, &args,
1185 ":%s!%s@%s WALLOPS :", source_p->name,
1186 source_p->username, source_p->host);
1187 else
1188 linebuf_putmsg(&linebuf, pattern, &args, ":%s WALLOPS :", source_p->name);
1189
1190 va_end(args);
1191
1192 DLINK_FOREACH_SAFE(ptr, next_ptr, IsPerson(source_p) && flags == UMODE_WALLOP ? lclient_list.head : local_oper_list.head)
1193 {
1194 client_p = ptr->data;
1195
1196 if(client_p->umodes & flags)
1197 _send_linebuf(client_p, &linebuf);
1198 }
1199
1200 linebuf_donebuf(&linebuf);
1201}
1202
1203/* kill_client()
1204 *
1205 * input - client to send kill to, client to kill, va_args
1206 * output -
1207 * side effects - we issue a kill for the client
1208 */
1209void
1210kill_client(struct Client *target_p, struct Client *diedie, const char *pattern, ...)
1211{
1212 va_list args;
1213 buf_head_t linebuf;
1214
1215 linebuf_newbuf(&linebuf);
1216
1217 va_start(args, pattern);
1218 linebuf_putmsg(&linebuf, pattern, &args, ":%s KILL %s :",
1219 get_id(&me, target_p), get_id(diedie, target_p));
1220 va_end(args);
1221
1222 send_linebuf(target_p, &linebuf);
1223 linebuf_donebuf(&linebuf);
1224}
1225
1226
1227/*
1228 * kill_client_serv_butone
1229 *
1230 * inputs - pointer to client to not send to
1231 * - pointer to client to kill
1232 * output - NONE
1233 * side effects - Send a KILL for the given client
1234 * message to all connected servers
1235 * except the client 'one'. Also deal with
1236 * client being unknown to leaf, as in lazylink...
1237 */
1238void
1239kill_client_serv_butone(struct Client *one, struct Client *target_p, const char *pattern, ...)
1240{
1241 static char buf[BUFSIZE];
1242 va_list args;
1243 struct Client *client_p;
1244 dlink_node *ptr;
1245 dlink_node *next_ptr;
1246 buf_head_t linebuf_id;
1247 buf_head_t linebuf_name;
1248
1249 linebuf_newbuf(&linebuf_name);
1250 linebuf_newbuf(&linebuf_id);
1251
1252 va_start(args, pattern);
1253 ircvsnprintf(buf, sizeof(buf), pattern, args);
1254 va_end(args);
1255
1256 linebuf_putmsg(&linebuf_name, NULL, NULL, ":%s KILL %s :%s",
1257 me.name, target_p->name, buf);
1258 linebuf_putmsg(&linebuf_id, NULL, NULL, ":%s KILL %s :%s",
1259 use_id(&me), use_id(target_p), buf);
1260
1261 DLINK_FOREACH_SAFE(ptr, next_ptr, serv_list.head)
1262 {
1263 client_p = ptr->data;
1264
1265 /* ok, if the client we're supposed to not send to has an
1266 * ID, then we still want to issue the kill there..
1267 */
1268 if(one != NULL && (client_p == one->from) &&
1269 (!has_id(client_p) || !has_id(target_p)))
1270 continue;
1271
1272 if(has_id(client_p))
1273 _send_linebuf(client_p, &linebuf_id);
1274 else
1275 _send_linebuf(client_p, &linebuf_name);
1276 }
1277
1278 linebuf_donebuf(&linebuf_id);
1279 linebuf_donebuf(&linebuf_name);
1280}