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