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