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