]> jfr.im git - solanum.git/blame - ircd/send.c
Add general::hidden_caps
[solanum.git] / ircd / send.c
CommitLineData
212380e3
AC
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
212380e3
AC
23 */
24
25#include "stdinc.h"
212380e3
AC
26#include "send.h"
27#include "channel.h"
28#include "class.h"
29#include "client.h"
4562c604 30#include "match.h"
212380e3
AC
31#include "ircd.h"
32#include "numeric.h"
e2d5ffd5 33#include "s_assert.h"
212380e3 34#include "s_serv.h"
212380e3
AC
35#include "s_conf.h"
36#include "s_newconf.h"
4016731b 37#include "logger.h"
212380e3 38#include "hook.h"
8aba962d 39#include "monitor.h"
4f8ababa 40#include "msgbuf.h"
212380e3
AC
41
42/* send the message to the link the target is attached to */
43#define send_linebuf(a,b) _send_linebuf((a->from ? a->from : a) ,b)
44
4b1cce65
SA
45#define CLIENT_CAPS_ONLY(x) ((IsClient((x)) && (x)->localClient) ? (x)->localClient->caps : 0)
46
3b2ebd04
JT
47static void send_queued_write(rb_fde_t *F, void *data);
48
212380e3
AC
49unsigned long current_serial = 0L;
50
ad13bb75
JT
51struct Client *remote_rehash_oper_p;
52
212380e3
AC
53/* send_linebuf()
54 *
55 * inputs - client to send to, linebuf to attach
56 * outputs -
57 * side effects - linebuf is attached to client
58 */
59static int
60_send_linebuf(struct Client *to, buf_head_t *linebuf)
61{
62 if(IsMe(to))
63 {
64 sendto_realops_snomask(SNO_GENERAL, L_ALL, "Trying to send message to myself!");
65 return 0;
66 }
67
68 if(!MyConnect(to) || IsIOError(to))
69 return 0;
70
912cae0c 71 if(rb_linebuf_len(&to->localClient->buf_sendq) > get_sendq(to))
212380e3
AC
72 {
73 if(IsServer(to))
74 {
75 sendto_realops_snomask(SNO_GENERAL, L_ALL,
912cae0c 76 "Max SendQ limit exceeded for %s: %u > %lu",
b3ebc7ab 77 to->name,
55abcbb2 78 rb_linebuf_len(&to->localClient->buf_sendq),
912cae0c 79 get_sendq(to));
212380e3 80
912cae0c 81 ilog(L_SERVER, "Max SendQ limit exceeded for %s: %u > %lu",
212380e3 82 log_client_name(to, SHOW_IP),
55abcbb2 83 rb_linebuf_len(&to->localClient->buf_sendq),
912cae0c 84 get_sendq(to));
212380e3
AC
85 }
86
cef7a7bc 87 dead_link(to, 1);
212380e3
AC
88 return -1;
89 }
90 else
91 {
92 /* just attach the linebuf to the sendq instead of
93 * generating a new one
94 */
3b2ebd04 95 rb_linebuf_attach(&to->localClient->buf_sendq, linebuf);
212380e3
AC
96 }
97
98 /*
99 ** Update statistics. The following is slightly incorrect
100 ** because it counts messages even if queued, but bytes
101 ** only really sent. Queued bytes get updated in SendQueued.
102 */
103 to->localClient->sendM += 1;
104 me.localClient->sendM += 1;
3b2ebd04
JT
105 if(rb_linebuf_len(&to->localClient->buf_sendq) > 0)
106 send_queued(to);
212380e3
AC
107 return 0;
108}
109
110/* send_linebuf_remote()
111 *
112 * inputs - client to attach to, sender, linebuf
113 * outputs -
114 * side effects - client has linebuf attached
115 */
116static void
117send_linebuf_remote(struct Client *to, struct Client *from, buf_head_t *linebuf)
118{
119 if(to->from)
120 to = to->from;
121
8d0d947d 122 /* we assume the caller has already tested for fake direction */
212380e3 123 _send_linebuf(to, linebuf);
212380e3
AC
124}
125
126/* send_queued_write()
127 *
128 * inputs - fd to have queue sent, client we're sending to
129 * outputs - contents of queue
130 * side effects - write is rescheduled if queue isnt emptied
131 */
132void
3b2ebd04 133send_queued(struct Client *to)
212380e3 134{
212380e3 135 int retlen;
c678fbc0 136
3b2ebd04 137 rb_fde_t *F = to->localClient->F;
5cd74a3b
AC
138 if (!F)
139 return;
140
212380e3
AC
141 /* cant write anything to a dead socket. */
142 if(IsIOError(to))
143 return;
144
8bd5767b
JT
145 /* try to flush later when the write event resets this */
146 if(IsFlush(to))
c6d72037
VY
147 return;
148
3b2ebd04 149 if(rb_linebuf_len(&to->localClient->buf_sendq))
212380e3
AC
150 {
151 while ((retlen =
3b2ebd04 152 rb_linebuf_flush(F, &to->localClient->buf_sendq)) > 0)
212380e3
AC
153 {
154 /* We have some data written .. update counters */
c6d72037
VY
155 ClearFlush(to);
156
212380e3
AC
157 to->localClient->sendB += retlen;
158 me.localClient->sendB += retlen;
159 if(to->localClient->sendB > 1023)
160 {
161 to->localClient->sendK += (to->localClient->sendB >> 10);
162 to->localClient->sendB &= 0x03ff; /* 2^10 = 1024, 3ff = 1023 */
163 }
164 else if(me.localClient->sendB > 1023)
165 {
166 me.localClient->sendK += (me.localClient->sendB >> 10);
167 me.localClient->sendB &= 0x03ff;
168 }
169 }
170
3b2ebd04 171 if(retlen == 0 || (retlen < 0 && !rb_ignore_errno(errno)))
212380e3 172 {
cef7a7bc 173 dead_link(to, 0);
212380e3
AC
174 return;
175 }
176 }
c6d72037 177
8bd5767b
JT
178 if(rb_linebuf_len(&to->localClient->buf_sendq))
179 {
180 SetFlush(to);
181 rb_setselect(to->localClient->F, RB_SELECT_WRITE,
182 send_queued_write, to);
183 }
184 else
c6d72037
VY
185 ClearFlush(to);
186}
187
8bd5767b
JT
188void
189send_pop_queue(struct Client *to)
190{
191 if(to->from != NULL)
192 to = to->from;
193 if(!MyConnect(to) || IsIOError(to))
194 return;
195 if(rb_linebuf_len(&to->localClient->buf_sendq) > 0)
196 send_queued(to);
3b2ebd04
JT
197}
198
199/* send_queued_write()
200 *
201 * inputs - fd to have queue sent, client we're sending to
202 * outputs - contents of queue
203 * side effects - write is scheduled if queue isnt emptied
204 */
205static void
206send_queued_write(rb_fde_t *F, void *data)
207{
208 struct Client *to = data;
c6d72037 209 ClearFlush(to);
3b2ebd04 210 send_queued(to);
212380e3
AC
211}
212
5559c3cf 213/*
4b1cce65 214 * linebuf_put_*
4f8ababa
AC
215 *
216 * inputs - msgbuf header, linebuf object, capability mask, pattern, arguments
217 * outputs - none
4b1cce65 218 * side effects - the linebuf object is cleared, then populated
4f8ababa
AC
219 */
220static void
4b1cce65 221linebuf_put_tags(buf_head_t *linebuf, const struct MsgBuf *msgbuf, const struct Client *target_p, rb_strf_t *message)
4f8ababa 222{
4b1cce65
SA
223 struct MsgBuf_str_data msgbuf_str_data = { .msgbuf = msgbuf, .caps = CLIENT_CAPS_ONLY(target_p) };
224 rb_strf_t strings = { .func = msgbuf_unparse_linebuf_tags, .func_args = &msgbuf_str_data, .length = TAGSLEN + 1, .next = message };
4f8ababa 225
4b1cce65
SA
226 message->length = DATALEN + 1;
227 rb_linebuf_put(linebuf, &strings);
228}
229
230static void
231linebuf_put_tagsf(buf_head_t *linebuf, const struct MsgBuf *msgbuf, const struct Client *target_p, const rb_strf_t *message, const char *format, ...)
232{
233 va_list va;
234 rb_strf_t strings = { .format = format, .format_args = &va, .next = message };
235
236 va_start(va, format);
237 linebuf_put_tags(linebuf, msgbuf, target_p, &strings);
238 va_end(va);
239}
240
241static void
242linebuf_put_msg(buf_head_t *linebuf, rb_strf_t *message)
243{
244 message->length = DATALEN + 1;
245 rb_linebuf_put(linebuf, message);
66769bc1 246}
5559c3cf 247
5559c3cf 248static void
4b1cce65 249linebuf_put_msgf(buf_head_t *linebuf, const rb_strf_t *message, const char *format, ...)
5559c3cf
AC
250{
251 va_list va;
4b1cce65 252 rb_strf_t strings = { .format = format, .format_args = &va, .next = message };
4f8ababa 253
4b1cce65
SA
254 va_start(va, format);
255 linebuf_put_msg(linebuf, &strings);
4f8ababa
AC
256 va_end(va);
257}
258
4b1cce65 259/* build_msgbuf_tags
4f8ababa
AC
260 *
261 * inputs - msgbuf object, client the message is from
262 * outputs - none
263 * side effects - a msgbuf object is populated with an origin and relevant tags
264 * notes - to make this reentrant, find a solution for `buf` below
265 */
266static void
4b1cce65 267build_msgbuf_tags(struct MsgBuf *msgbuf, struct Client *from)
4f8ababa 268{
4f8ababa
AC
269 hook_data hdata;
270
271 msgbuf_init(msgbuf);
272
4f8ababa
AC
273 hdata.client = from;
274 hdata.arg1 = msgbuf;
275
276 call_hook(h_outbound_msgbuf, &hdata);
277}
278
212380e3
AC
279/* sendto_one()
280 *
281 * inputs - client to send to, va_args
282 * outputs - client has message put into its queue
55abcbb2 283 * side effects -
212380e3
AC
284 */
285void
286sendto_one(struct Client *target_p, const char *pattern, ...)
287{
288 va_list args;
4b1cce65 289 struct MsgBuf msgbuf;
212380e3 290 buf_head_t linebuf;
4b1cce65 291 rb_strf_t strings = { .format = pattern, .format_args = &args, .next = NULL };
212380e3
AC
292
293 /* send remote if to->from non NULL */
294 if(target_p->from != NULL)
295 target_p = target_p->from;
296
297 if(IsIOError(target_p))
298 return;
299
3b2ebd04 300 rb_linebuf_newbuf(&linebuf);
212380e3 301
4b1cce65 302 build_msgbuf_tags(&msgbuf, &me);
212380e3 303 va_start(args, pattern);
4b1cce65 304 linebuf_put_tags(&linebuf, &msgbuf, target_p, &strings);
212380e3
AC
305 va_end(args);
306
307 _send_linebuf(target_p, &linebuf);
308
3b2ebd04 309 rb_linebuf_donebuf(&linebuf);
212380e3
AC
310}
311
312/* sendto_one_prefix()
313 *
314 * inputs - client to send to, va_args
315 * outputs - client has message put into its queue
316 * side effects - source(us)/target is chosen based on TS6 capability
317 */
318void
319sendto_one_prefix(struct Client *target_p, struct Client *source_p,
320 const char *command, const char *pattern, ...)
321{
0ded533d 322 struct Client *dest_p = target_p->from;
212380e3 323 va_list args;
4b1cce65 324 struct MsgBuf msgbuf;
212380e3 325 buf_head_t linebuf;
4b1cce65 326 rb_strf_t strings = { .format = pattern, .format_args = &args, .next = NULL };
212380e3 327
212380e3
AC
328 if(IsIOError(dest_p))
329 return;
330
331 if(IsMe(dest_p))
332 {
333 sendto_realops_snomask(SNO_GENERAL, L_ALL, "Trying to send to myself!");
334 return;
335 }
336
4b1cce65
SA
337 build_msgbuf_tags(&msgbuf, source_p);
338
3b2ebd04 339 rb_linebuf_newbuf(&linebuf);
212380e3 340 va_start(args, pattern);
4b1cce65
SA
341 linebuf_put_tagsf(&linebuf, &msgbuf, target_p, &strings,
342 ":%s %s %s ", get_id(source_p, target_p),
343 command, get_id(target_p, target_p));
212380e3
AC
344 va_end(args);
345
346 _send_linebuf(dest_p, &linebuf);
3b2ebd04 347 rb_linebuf_donebuf(&linebuf);
212380e3
AC
348}
349
350/* sendto_one_notice()
351 *
352 * inputs - client to send to, va_args
353 * outputs - client has a NOTICE put into its queue
354 * side effects - source(us)/target is chosen based on TS6 capability
355 */
356void
357sendto_one_notice(struct Client *target_p, const char *pattern, ...)
358{
d856535e 359 struct Client *dest_p = target_p->from;
212380e3 360 va_list args;
4b1cce65 361 struct MsgBuf msgbuf;
212380e3 362 buf_head_t linebuf;
4b1cce65 363 rb_strf_t strings = { .format = pattern, .format_args = &args, .next = NULL };
5366977b 364 char *to;
212380e3 365
212380e3
AC
366 if(IsIOError(dest_p))
367 return;
368
369 if(IsMe(dest_p))
370 {
371 sendto_realops_snomask(SNO_GENERAL, L_ALL, "Trying to send to myself!");
372 return;
373 }
374
4b1cce65
SA
375 build_msgbuf_tags(&msgbuf, &me);
376
3b2ebd04 377 rb_linebuf_newbuf(&linebuf);
212380e3 378 va_start(args, pattern);
4b1cce65
SA
379 linebuf_put_tagsf(&linebuf, &msgbuf, target_p, &strings,
380 ":%s NOTICE %s ", get_id(&me, target_p),
381 *(to = get_id(target_p, target_p)) != '\0' ? to : "*");
212380e3
AC
382 va_end(args);
383
384 _send_linebuf(dest_p, &linebuf);
3b2ebd04 385 rb_linebuf_donebuf(&linebuf);
212380e3
AC
386}
387
388
389/* sendto_one_numeric()
390 *
391 * inputs - client to send to, va_args
392 * outputs - client has message put into its queue
393 * side effects - source/target is chosen based on TS6 capability
394 */
395void
396sendto_one_numeric(struct Client *target_p, int numeric, const char *pattern, ...)
397{
0d6da1a9 398 struct Client *dest_p = target_p->from;
212380e3 399 va_list args;
4b1cce65 400 struct MsgBuf msgbuf;
212380e3 401 buf_head_t linebuf;
4b1cce65 402 rb_strf_t strings = { .format = pattern, .format_args = &args, .next = NULL };
5366977b 403 char *to;
212380e3 404
212380e3
AC
405 if(IsIOError(dest_p))
406 return;
407
408 if(IsMe(dest_p))
409 {
410 sendto_realops_snomask(SNO_GENERAL, L_ALL, "Trying to send to myself!");
411 return;
412 }
413
4b1cce65
SA
414 build_msgbuf_tags(&msgbuf, &me);
415
3b2ebd04 416 rb_linebuf_newbuf(&linebuf);
212380e3 417 va_start(args, pattern);
4b1cce65
SA
418 linebuf_put_tagsf(&linebuf, &msgbuf, target_p, &strings,
419 ":%s %03d %s ", get_id(&me, target_p), numeric,
420 *(to = get_id(target_p, target_p)) != '\0' ? to : "*");
212380e3
AC
421 va_end(args);
422
423 _send_linebuf(dest_p, &linebuf);
3b2ebd04 424 rb_linebuf_donebuf(&linebuf);
212380e3
AC
425}
426
427/*
428 * sendto_server
55abcbb2 429 *
212380e3
AC
430 * inputs - pointer to client to NOT send to
431 * - caps or'd together which must ALL be present
432 * - caps or'd together which must ALL NOT be present
433 * - printf style format string
434 * - args to format string
435 * output - NONE
436 * side effects - Send a message to all connected servers, except the
437 * client 'one' (if non-NULL), as long as the servers
438 * support ALL capabs in 'caps', and NO capabs in 'nocaps'.
55abcbb2 439 *
212380e3
AC
440 * This function was written in an attempt to merge together the other
441 * billion sendto_*serv*() functions, which sprung up with capabs, uids etc
442 * -davidt
443 */
444void
445sendto_server(struct Client *one, struct Channel *chptr, unsigned long caps,
446 unsigned long nocaps, const char *format, ...)
447{
448 va_list args;
449 struct Client *target_p;
330fc5c1 450 rb_dlink_node *ptr;
637c4932 451 rb_dlink_node *next_ptr;
212380e3 452 buf_head_t linebuf;
4b1cce65 453 rb_strf_t strings = { .format = format, .format_args = &args, .next = NULL };
212380e3
AC
454
455 /* noone to send to.. */
330fc5c1 456 if(rb_dlink_list_length(&serv_list) == 0)
212380e3
AC
457 return;
458
459 if(chptr != NULL && *chptr->chname != '#')
460 return;
461
3b2ebd04 462 rb_linebuf_newbuf(&linebuf);
212380e3 463 va_start(args, format);
4b1cce65 464 linebuf_put_msg(&linebuf, &strings);
212380e3
AC
465 va_end(args);
466
637c4932 467 RB_DLINK_FOREACH_SAFE(ptr, next_ptr, serv_list.head)
212380e3
AC
468 {
469 target_p = ptr->data;
470
471 /* check against 'one' */
472 if(one != NULL && (target_p == one->from))
473 continue;
474
475 /* check we have required capabs */
476 if(!IsCapable(target_p, caps))
477 continue;
478
479 /* check we don't have any forbidden capabs */
480 if(!NotCapable(target_p, nocaps))
481 continue;
482
483 _send_linebuf(target_p, &linebuf);
484 }
485
3b2ebd04 486 rb_linebuf_donebuf(&linebuf);
212380e3
AC
487}
488
489/* sendto_channel_flags()
490 *
491 * inputs - server not to send to, flags needed, source, channel, va_args
492 * outputs - message is sent to channel members
493 * side effects -
494 */
495void
496sendto_channel_flags(struct Client *one, int type, struct Client *source_p,
497 struct Channel *chptr, const char *pattern, ...)
498{
5ce6360b 499 static char buf[BUFSIZE];
212380e3 500 va_list args;
7a06833f 501 buf_head_t rb_linebuf_remote;
212380e3
AC
502 struct Client *target_p;
503 struct membership *msptr;
330fc5c1 504 rb_dlink_node *ptr;
637c4932 505 rb_dlink_node *next_ptr;
667fb62e 506 struct MsgBuf msgbuf;
4b1cce65
SA
507 struct MsgBuf_cache msgbuf_cache;
508 rb_strf_t strings = { .format = buf, .format_args = NULL, .next = NULL };
212380e3 509
7a06833f 510 rb_linebuf_newbuf(&rb_linebuf_remote);
212380e3
AC
511
512 current_serial++;
513
4b1cce65 514 build_msgbuf_tags(&msgbuf, source_p);
212380e3 515
667fb62e 516 va_start(args, pattern);
c8c3ac24
AC
517 vsnprintf(buf, sizeof buf, pattern, args);
518 va_end(args);
212380e3 519
4b1cce65
SA
520 linebuf_put_msgf(&rb_linebuf_remote, NULL, ":%s %s", use_id(source_p), buf);
521 msgbuf_cache_initf(&msgbuf_cache, &msgbuf, &strings,
522 IsPerson(source_p) ? ":%1$s!%2$s@%3$s " : ":%1$s ",
523 source_p->name, source_p->username, source_p->host);
212380e3 524
637c4932 525 RB_DLINK_FOREACH_SAFE(ptr, next_ptr, chptr->members.head)
212380e3
AC
526 {
527 msptr = ptr->data;
528 target_p = msptr->client_p;
529
be2ce24c
AC
530 if(!MyClient(source_p) && (IsIOError(target_p->from) || target_p->from == one))
531 continue;
532
2d8d5b05 533 if(MyClient(source_p) && target_p == one)
212380e3
AC
534 continue;
535
536 if(type && ((msptr->flags & type) == 0))
537 continue;
538
539 if(IsDeaf(target_p))
540 continue;
541
542 if(!MyClient(target_p))
543 {
544 /* if we've got a specific type, target must support
545 * CHW.. --fl
546 */
547 if(type && NotCapable(target_p->from, CAP_CHW))
548 continue;
549
550 if(target_p->from->serial != current_serial)
551 {
7a06833f 552 send_linebuf_remote(target_p, source_p, &rb_linebuf_remote);
212380e3
AC
553 target_p->from->serial = current_serial;
554 }
555 }
556 else
667fb62e 557 {
4b1cce65 558 _send_linebuf(target_p, msgbuf_cache_get(&msgbuf_cache, CLIENT_CAPS_ONLY(target_p)));
667fb62e 559 }
212380e3
AC
560 }
561
2d8d5b05
SA
562 /* source client may not be on the channel, send echo separately */
563 if(MyClient(source_p) && IsCapable(source_p, CLICAP_ECHO_MESSAGE))
564 {
565 target_p = one;
566
4b1cce65 567 _send_linebuf(target_p, msgbuf_cache_get(&msgbuf_cache, CLIENT_CAPS_ONLY(target_p)));
2d8d5b05
SA
568 }
569
7a06833f 570 rb_linebuf_donebuf(&rb_linebuf_remote);
4b1cce65 571 msgbuf_cache_free(&msgbuf_cache);
212380e3
AC
572}
573
c4d2d014
JT
574/* sendto_channel_flags()
575 *
576 * inputs - server not to send to, flags needed, source, channel, va_args
577 * outputs - message is sent to channel members
578 * side effects -
579 */
580void
581sendto_channel_opmod(struct Client *one, struct Client *source_p,
582 struct Channel *chptr, const char *command,
583 const char *text)
584{
c4d2d014
JT
585 buf_head_t rb_linebuf_old;
586 buf_head_t rb_linebuf_new;
587 struct Client *target_p;
588 struct membership *msptr;
589 rb_dlink_node *ptr;
590 rb_dlink_node *next_ptr;
4b1cce65
SA
591 struct MsgBuf msgbuf;
592 struct MsgBuf_cache msgbuf_cache;
593 rb_strf_t strings = { .format = text, .format_args = NULL, .next = NULL };
c4d2d014 594
c4d2d014
JT
595 rb_linebuf_newbuf(&rb_linebuf_old);
596 rb_linebuf_newbuf(&rb_linebuf_new);
597
4b1cce65
SA
598 build_msgbuf_tags(&msgbuf, source_p);
599
c4d2d014 600 current_serial++;
04e5ed6c 601 const char *statusmsg_prefix = (ConfigChannel.opmod_send_statusmsg ? "@" : "");
c4d2d014 602
4b1cce65
SA
603 if(IsServer(source_p)) {
604 msgbuf_cache_initf(&msgbuf_cache, &msgbuf, &strings,
04e5ed6c
JK
605 ":%s %s %s%s :",
606 source_p->name, command, statusmsg_prefix, chptr->chname);
4b1cce65
SA
607 } else {
608 msgbuf_cache_initf(&msgbuf_cache, &msgbuf, &strings,
04e5ed6c 609 ":%s!%s@%s %s %s%s :",
55abcbb2 610 source_p->name, source_p->username,
04e5ed6c 611 source_p->host, command, statusmsg_prefix, chptr->chname);
4b1cce65 612 }
c4d2d014 613
4b1cce65
SA
614 if (chptr->mode.mode & MODE_MODERATED) {
615 linebuf_put_msgf(&rb_linebuf_old, &strings,
04e5ed6c
JK
616 ":%s %s %s%s :",
617 use_id(source_p), command, statusmsg_prefix, chptr->chname, text);
4b1cce65
SA
618 } else {
619 linebuf_put_msgf(&rb_linebuf_old, &strings,
620 ":%s NOTICE @%s :<%s:%s> ",
c4d2d014 621 use_id(source_p->servptr), chptr->chname,
4b1cce65
SA
622 source_p->name, chptr->chname);
623 }
624 linebuf_put_msgf(&rb_linebuf_new, &strings,
625 ":%s %s =%s :",
626 use_id(source_p), command, chptr->chname);
c4d2d014
JT
627 RB_DLINK_FOREACH_SAFE(ptr, next_ptr, chptr->members.head)
628 {
629 msptr = ptr->data;
630 target_p = msptr->client_p;
631
be2ce24c
AC
632 if(!MyClient(source_p) && (IsIOError(target_p->from) || target_p->from == one))
633 continue;
634
2d8d5b05 635 if(MyClient(source_p) && target_p == one)
c4d2d014
JT
636 continue;
637
638 if((msptr->flags & CHFL_CHANOP) == 0)
639 continue;
640
641 if(IsDeaf(target_p))
642 continue;
643
644 if(!MyClient(target_p))
645 {
646 /* if we've got a specific type, target must support
647 * CHW.. --fl
648 */
649 if(NotCapable(target_p->from, CAP_CHW))
650 continue;
651
652 if(target_p->from->serial != current_serial)
653 {
654 if (IsCapable(target_p->from, CAP_EOPMOD))
655 send_linebuf_remote(target_p, source_p, &rb_linebuf_new);
656 else
657 send_linebuf_remote(target_p, source_p, &rb_linebuf_old);
658 target_p->from->serial = current_serial;
659 }
4b1cce65
SA
660 } else {
661 _send_linebuf(target_p, msgbuf_cache_get(&msgbuf_cache, CLIENT_CAPS_ONLY(target_p)));
c4d2d014 662 }
c4d2d014
JT
663 }
664
2d8d5b05
SA
665 /* source client may not be on the channel, send echo separately */
666 if(MyClient(source_p) && IsCapable(source_p, CLICAP_ECHO_MESSAGE))
667 {
668 target_p = one;
669
4b1cce65 670 _send_linebuf(target_p, msgbuf_cache_get(&msgbuf_cache, CLIENT_CAPS_ONLY(target_p)));
2d8d5b05
SA
671 }
672
c4d2d014
JT
673 rb_linebuf_donebuf(&rb_linebuf_old);
674 rb_linebuf_donebuf(&rb_linebuf_new);
4b1cce65 675 msgbuf_cache_free(&msgbuf_cache);
c4d2d014 676}
212380e3 677
d3fd88a4 678/* _sendto_channel_local
212380e3 679 *
d3fd88a4 680 * inputs - source, flags to send to, privs to send to, channel to send to, va_args
212380e3
AC
681 * outputs - message to local channel members
682 * side effects -
683 */
684void
d3fd88a4 685_sendto_channel_local(struct Client *source_p, int type, const char *priv, struct Channel *chptr, const char *pattern, va_list *args)
212380e3 686{
212380e3
AC
687 struct membership *msptr;
688 struct Client *target_p;
330fc5c1 689 rb_dlink_node *ptr;
637c4932 690 rb_dlink_node *next_ptr;
4b1cce65
SA
691 struct MsgBuf msgbuf;
692 struct MsgBuf_cache msgbuf_cache;
d3fd88a4 693 rb_strf_t strings = { .format = pattern, .format_args = args, .next = NULL };
55abcbb2 694
4b1cce65 695 build_msgbuf_tags(&msgbuf, source_p);
55abcbb2 696
4b1cce65 697 msgbuf_cache_init(&msgbuf_cache, &msgbuf, &strings);
212380e3 698
637c4932 699 RB_DLINK_FOREACH_SAFE(ptr, next_ptr, chptr->locmembers.head)
212380e3
AC
700 {
701 msptr = ptr->data;
702 target_p = msptr->client_p;
703
d3fd88a4 704 if (IsIOError(target_p))
212380e3
AC
705 continue;
706
d3fd88a4
EK
707 if (type && ((msptr->flags & type) == 0))
708 continue;
709
710 if (priv != NULL && !HasPrivilege(target_p, priv))
212380e3
AC
711 continue;
712
4b1cce65 713 _send_linebuf(target_p, msgbuf_cache_get(&msgbuf_cache, CLIENT_CAPS_ONLY(target_p)));
99cca61e
AC
714 }
715
4b1cce65 716 msgbuf_cache_free(&msgbuf_cache);
99cca61e
AC
717}
718
d3fd88a4
EK
719/* sendto_channel_local_priv()
720 *
721 * inputs - source, flags to send to, privs to send to, channel to send to, va_args
722 * outputs - message to local channel members
723 * side effects -
724 */
725void
726sendto_channel_local_priv(struct Client *source_p, int type, const char *priv, struct Channel *chptr, const char *pattern, ...)
727{
728 va_list args;
729 va_start(args, pattern);
730 _sendto_channel_local(source_p, type, priv, chptr, pattern, &args);
731 va_end(args);
732}
733
734/* sendto_channel_local()
735 *
736 * inputs - source, flags to send to, channel to send to, va_args
737 * outputs - message to local channel members
738 * side effects -
739 */
740void
741sendto_channel_local(struct Client *source_p, int type, struct Channel *chptr, const char *pattern, ...)
742{
743 va_list args;
744 va_start(args, pattern);
745 _sendto_channel_local(source_p, type, NULL, chptr, pattern, &args);
746 va_end(args);
747}
748
a695b0e4
SB
749/*
750 * _sendto_channel_local_with_capability_butone()
99cca61e 751 *
a695b0e4 752 * Shared implementation of sendto_channel_local_with_capability and sendto_channel_local_with_capability_butone
99cca61e 753 */
a695b0e4 754static void
4b1cce65
SA
755_sendto_channel_local_with_capability_butone(struct Client *source_p, struct Client *one, int type,
756 int caps, int negcaps, struct Channel *chptr, const char *pattern, va_list * args)
99cca61e 757{
99cca61e
AC
758 struct membership *msptr;
759 struct Client *target_p;
760 rb_dlink_node *ptr;
761 rb_dlink_node *next_ptr;
4b1cce65
SA
762 struct MsgBuf msgbuf;
763 struct MsgBuf_cache msgbuf_cache;
764 rb_strf_t strings = { .format = pattern, .format_args = args, .next = NULL };
55abcbb2 765
4b1cce65
SA
766 build_msgbuf_tags(&msgbuf, source_p);
767 msgbuf_cache_init(&msgbuf_cache, &msgbuf, &strings);
55abcbb2 768
99cca61e
AC
769 RB_DLINK_FOREACH_SAFE(ptr, next_ptr, chptr->locmembers.head)
770 {
771 msptr = ptr->data;
772 target_p = msptr->client_p;
773
a695b0e4
SB
774 if (target_p == one)
775 continue;
776
99cca61e
AC
777 if(IsIOError(target_p) ||
778 !IsCapable(target_p, caps) ||
e2b507ac 779 !NotCapable(target_p, negcaps))
99cca61e
AC
780 continue;
781
782 if(type && ((msptr->flags & type) == 0))
783 continue;
784
4b1cce65 785 _send_linebuf(target_p, msgbuf_cache_get(&msgbuf_cache, CLIENT_CAPS_ONLY(target_p)));
212380e3
AC
786 }
787
4b1cce65 788 msgbuf_cache_free(&msgbuf_cache);
212380e3
AC
789}
790
a695b0e4
SB
791/* sendto_channel_local_with_capability()
792 *
4b1cce65 793 * inputs - source, flags to send to, caps, negate caps, channel to send to, va_args
a695b0e4
SB
794 * outputs - message to local channel members
795 * side effects -
796 */
797void
4b1cce65 798sendto_channel_local_with_capability(struct Client *source_p, int type, int caps, int negcaps, struct Channel *chptr, const char *pattern, ...)
a695b0e4
SB
799{
800 va_list args;
801
802 va_start(args, pattern);
4b1cce65 803 _sendto_channel_local_with_capability_butone(source_p, NULL, type, caps, negcaps, chptr, pattern, &args);
a695b0e4
SB
804 va_end(args);
805}
806
807
808/* sendto_channel_local_with_capability()
809 *
4b1cce65 810 * inputs - source, flags to send to, caps, negate caps, channel to send to, va_args
a695b0e4
SB
811 * outputs - message to local channel members
812 * side effects -
813 */
814void
4b1cce65
SA
815sendto_channel_local_with_capability_butone(struct Client *one, int type,
816 int caps, int negcaps, struct Channel *chptr, const char *pattern, ...)
a695b0e4
SB
817{
818 va_list args;
819
820 va_start(args, pattern);
4b1cce65 821 _sendto_channel_local_with_capability_butone(one, one, type, caps, negcaps, chptr, pattern, &args);
a695b0e4
SB
822 va_end(args);
823}
824
825
212380e3
AC
826/* sendto_channel_local_butone()
827 *
828 * inputs - flags to send to, channel to send to, va_args
829 * - user to ignore when sending
830 * outputs - message to local channel members
831 * side effects -
832 */
833void
834sendto_channel_local_butone(struct Client *one, int type, struct Channel *chptr, const char *pattern, ...)
835{
836 va_list args;
212380e3
AC
837 struct membership *msptr;
838 struct Client *target_p;
5559c3cf 839 struct MsgBuf msgbuf;
330fc5c1 840 rb_dlink_node *ptr;
637c4932 841 rb_dlink_node *next_ptr;
4b1cce65
SA
842 struct MsgBuf_cache msgbuf_cache;
843 rb_strf_t strings = { .format = pattern, .format_args = &args, .next = NULL };
55abcbb2 844
4b1cce65 845 build_msgbuf_tags(&msgbuf, one);
5559c3cf 846
212380e3 847 va_start(args, pattern);
4b1cce65 848 msgbuf_cache_init(&msgbuf_cache, &msgbuf, &strings);
474f6342 849 va_end(args);
212380e3 850
637c4932 851 RB_DLINK_FOREACH_SAFE(ptr, next_ptr, chptr->locmembers.head)
212380e3
AC
852 {
853 msptr = ptr->data;
854 target_p = msptr->client_p;
855
856 if(target_p == one)
857 continue;
858
859 if(IsIOError(target_p))
860 continue;
861
862 if(type && ((msptr->flags & type) == 0))
863 continue;
864
5559c3cf 865 /* attach the present linebuf to the target */
4b1cce65 866 _send_linebuf(target_p, msgbuf_cache_get(&msgbuf_cache, CLIENT_CAPS_ONLY(target_p)));
212380e3
AC
867 }
868
4b1cce65 869 msgbuf_cache_free(&msgbuf_cache);
212380e3
AC
870}
871
872/*
873 * sendto_common_channels_local()
874 *
875 * inputs - pointer to client
4b1cce65
SA
876 * - capability mask
877 * - negated capability mask
212380e3
AC
878 * - pattern to send
879 * output - NONE
880 * side effects - Sends a message to all people on local server who are
55abcbb2 881 * in same channel with user.
212380e3
AC
882 * used by m_nick.c and exit_one_client.
883 */
884void
583f064f 885sendto_common_channels_local(struct Client *user, int cap, int negcap, const char *pattern, ...)
212380e3
AC
886{
887 va_list args;
330fc5c1 888 rb_dlink_node *ptr;
637c4932 889 rb_dlink_node *next_ptr;
330fc5c1
AC
890 rb_dlink_node *uptr;
891 rb_dlink_node *next_uptr;
212380e3
AC
892 struct Channel *chptr;
893 struct Client *target_p;
894 struct membership *msptr;
895 struct membership *mscptr;
4b1cce65
SA
896 struct MsgBuf msgbuf;
897 struct MsgBuf_cache msgbuf_cache;
898 rb_strf_t strings = { .format = pattern, .format_args = &args, .next = NULL };
899
900 build_msgbuf_tags(&msgbuf, user);
212380e3 901
212380e3 902 va_start(args, pattern);
4b1cce65 903 msgbuf_cache_init(&msgbuf_cache, &msgbuf, &strings);
212380e3
AC
904 va_end(args);
905
906 ++current_serial;
907
637c4932 908 RB_DLINK_FOREACH_SAFE(ptr, next_ptr, user->user->channel.head)
212380e3
AC
909 {
910 mscptr = ptr->data;
911 chptr = mscptr->chptr;
912
5cefa1d6 913 RB_DLINK_FOREACH_SAFE(uptr, next_uptr, chptr->locmembers.head)
212380e3
AC
914 {
915 msptr = uptr->data;
916 target_p = msptr->client_p;
917
918 if(IsIOError(target_p) ||
7a948bda 919 target_p->serial == current_serial ||
583f064f
AC
920 !IsCapable(target_p, cap) ||
921 !NotCapable(target_p, negcap))
212380e3
AC
922 continue;
923
924 target_p->serial = current_serial;
4b1cce65 925 send_linebuf(target_p, msgbuf_cache_get(&msgbuf_cache, CLIENT_CAPS_ONLY(target_p)));
212380e3
AC
926 }
927 }
928
929 /* this can happen when the user isnt in any channels, but we still
930 * need to send them the data, ie a nick change
931 */
42ae8ab2 932 if(MyConnect(user) && (user->serial != current_serial)
4b1cce65
SA
933 && IsCapable(user, cap) && NotCapable(user, negcap)) {
934 send_linebuf(user, msgbuf_cache_get(&msgbuf_cache, CLIENT_CAPS_ONLY(user)));
935 }
212380e3 936
4b1cce65 937 msgbuf_cache_free(&msgbuf_cache);
212380e3
AC
938}
939
940/*
941 * sendto_common_channels_local_butone()
942 *
943 * inputs - pointer to client
4b1cce65
SA
944 * - capability mask
945 * - negated capability mask
212380e3
AC
946 * - pattern to send
947 * output - NONE
948 * side effects - Sends a message to all people on local server who are
949 * in same channel with user, except for user itself.
950 */
951void
583f064f 952sendto_common_channels_local_butone(struct Client *user, int cap, int negcap, const char *pattern, ...)
212380e3
AC
953{
954 va_list args;
330fc5c1 955 rb_dlink_node *ptr;
637c4932 956 rb_dlink_node *next_ptr;
330fc5c1
AC
957 rb_dlink_node *uptr;
958 rb_dlink_node *next_uptr;
212380e3
AC
959 struct Channel *chptr;
960 struct Client *target_p;
961 struct membership *msptr;
962 struct membership *mscptr;
4b1cce65
SA
963 struct MsgBuf msgbuf;
964 struct MsgBuf_cache msgbuf_cache;
965 rb_strf_t strings = { .format = pattern, .format_args = &args, .next = NULL };
212380e3 966
4b1cce65 967 build_msgbuf_tags(&msgbuf, user);
5559c3cf 968
212380e3 969 va_start(args, pattern);
4b1cce65 970 msgbuf_cache_init(&msgbuf_cache, &msgbuf, &strings);
212380e3
AC
971 va_end(args);
972
973 ++current_serial;
974 /* Skip them -- jilles */
975 user->serial = current_serial;
976
637c4932 977 RB_DLINK_FOREACH_SAFE(ptr, next_ptr, user->user->channel.head)
212380e3
AC
978 {
979 mscptr = ptr->data;
980 chptr = mscptr->chptr;
981
5cefa1d6 982 RB_DLINK_FOREACH_SAFE(uptr, next_uptr, chptr->locmembers.head)
212380e3
AC
983 {
984 msptr = uptr->data;
985 target_p = msptr->client_p;
986
987 if(IsIOError(target_p) ||
7a948bda 988 target_p->serial == current_serial ||
583f064f
AC
989 !IsCapable(target_p, cap) ||
990 !NotCapable(target_p, negcap))
212380e3
AC
991 continue;
992
993 target_p->serial = current_serial;
4b1cce65 994 send_linebuf(target_p, msgbuf_cache_get(&msgbuf_cache, CLIENT_CAPS_ONLY(target_p)));
212380e3
AC
995 }
996 }
997
4b1cce65 998 msgbuf_cache_free(&msgbuf_cache);
212380e3
AC
999}
1000
1001/* sendto_match_butone()
1002 *
1003 * inputs - server not to send to, source, mask, type of mask, va_args
1004 * output -
1005 * side effects - message is sent to matching clients
1006 */
1007void
1008sendto_match_butone(struct Client *one, struct Client *source_p,
1009 const char *mask, int what, const char *pattern, ...)
1010{
1011 static char buf[BUFSIZE];
1012 va_list args;
1013 struct Client *target_p;
330fc5c1 1014 rb_dlink_node *ptr;
637c4932 1015 rb_dlink_node *next_ptr;
7a06833f 1016 buf_head_t rb_linebuf_remote;
4b1cce65
SA
1017 struct MsgBuf msgbuf;
1018 struct MsgBuf_cache msgbuf_cache;
1019 rb_strf_t strings = { .format = buf, .format_args = NULL, .next = NULL };
212380e3 1020
7a06833f 1021 rb_linebuf_newbuf(&rb_linebuf_remote);
212380e3 1022
4b1cce65
SA
1023 build_msgbuf_tags(&msgbuf, source_p);
1024
212380e3 1025 va_start(args, pattern);
5203cba5 1026 vsnprintf(buf, sizeof(buf), pattern, args);
212380e3
AC
1027 va_end(args);
1028
4b1cce65
SA
1029 msgbuf_cache_initf(&msgbuf_cache, &msgbuf, &strings,
1030 IsServer(source_p) ? ":%s " : ":%s!%s@%s ",
1031 source_p->name, source_p->username, source_p->host);
212380e3 1032
4b1cce65 1033 linebuf_put_msgf(&rb_linebuf_remote, &strings, ":%s ", use_id(source_p));
212380e3
AC
1034
1035 if(what == MATCH_HOST)
1036 {
637c4932 1037 RB_DLINK_FOREACH_SAFE(ptr, next_ptr, lclient_list.head)
212380e3
AC
1038 {
1039 target_p = ptr->data;
1040
1041 if(match(mask, target_p->host))
4b1cce65 1042 _send_linebuf(target_p, msgbuf_cache_get(&msgbuf_cache, CLIENT_CAPS_ONLY(target_p)));
212380e3
AC
1043 }
1044 }
1045 /* what = MATCH_SERVER, if it doesnt match us, just send remote */
1046 else if(match(mask, me.name))
1047 {
637c4932 1048 RB_DLINK_FOREACH_SAFE(ptr, next_ptr, lclient_list.head)
212380e3
AC
1049 {
1050 target_p = ptr->data;
4b1cce65 1051 _send_linebuf(target_p, msgbuf_cache_get(&msgbuf_cache, CLIENT_CAPS_ONLY(target_p)));
212380e3
AC
1052 }
1053 }
1054
5cefa1d6 1055 RB_DLINK_FOREACH(ptr, serv_list.head)
212380e3
AC
1056 {
1057 target_p = ptr->data;
1058
1059 if(target_p == one)
1060 continue;
1061
7a06833f 1062 send_linebuf_remote(target_p, source_p, &rb_linebuf_remote);
212380e3
AC
1063 }
1064
4b1cce65 1065 msgbuf_cache_free(&msgbuf_cache);
7a06833f 1066 rb_linebuf_donebuf(&rb_linebuf_remote);
212380e3
AC
1067}
1068
1069/* sendto_match_servs()
1070 *
1071 * inputs - source, mask to send to, caps needed, va_args
55abcbb2 1072 * outputs -
212380e3
AC
1073 * side effects - message is sent to matching servers with caps.
1074 */
1075void
55abcbb2 1076sendto_match_servs(struct Client *source_p, const char *mask, int cap,
212380e3
AC
1077 int nocap, const char *pattern, ...)
1078{
1079 static char buf[BUFSIZE];
1080 va_list args;
330fc5c1 1081 rb_dlink_node *ptr;
212380e3 1082 struct Client *target_p;
3b2ebd04 1083 buf_head_t rb_linebuf_id;
4b1cce65 1084 rb_strf_t strings = { .format = buf, .format_args = NULL, .next = NULL };
212380e3
AC
1085
1086 if(EmptyString(mask))
1087 return;
1088
3b2ebd04 1089 rb_linebuf_newbuf(&rb_linebuf_id);
212380e3
AC
1090
1091 va_start(args, pattern);
5203cba5 1092 vsnprintf(buf, sizeof(buf), pattern, args);
212380e3
AC
1093 va_end(args);
1094
4b1cce65 1095 linebuf_put_msgf(&rb_linebuf_id, &strings, ":%s ", use_id(source_p));
212380e3
AC
1096
1097 current_serial++;
1098
5cefa1d6 1099 RB_DLINK_FOREACH(ptr, global_serv_list.head)
212380e3
AC
1100 {
1101 target_p = ptr->data;
1102
1103 /* dont send to ourselves, or back to where it came from.. */
1104 if(IsMe(target_p) || target_p->from == source_p->from)
1105 continue;
1106
1107 if(target_p->from->serial == current_serial)
1108 continue;
1109
1110 if(match(mask, target_p->name))
1111 {
1112 /* if we set the serial here, then we'll never do
1113 * a match() again if !IsCapable()
1114 */
1115 target_p->from->serial = current_serial;
1116
1117 if(cap && !IsCapable(target_p->from, cap))
1118 continue;
1119
1120 if(nocap && !NotCapable(target_p->from, nocap))
1121 continue;
1122
ba301eff 1123 _send_linebuf(target_p->from, &rb_linebuf_id);
212380e3
AC
1124 }
1125 }
1126
3b2ebd04 1127 rb_linebuf_donebuf(&rb_linebuf_id);
212380e3
AC
1128}
1129
984d80c9
AC
1130/* sendto_local_clients_with_capability()
1131 *
1132 * inputs - caps needed, pattern, va_args
1133 * outputs -
1134 * side effects - message is sent to matching local clients with caps.
1135 */
1136void
1137sendto_local_clients_with_capability(int cap, const char *pattern, ...)
1138{
1139 va_list args;
1140 rb_dlink_node *ptr;
1141 struct Client *target_p;
4b1cce65
SA
1142 struct MsgBuf msgbuf;
1143 struct MsgBuf_cache msgbuf_cache;
1144 rb_strf_t strings = { .format = pattern, .format_args = &args, .next = NULL };
984d80c9 1145
4b1cce65 1146 build_msgbuf_tags(&msgbuf, &me);
984d80c9
AC
1147
1148 va_start(args, pattern);
4b1cce65 1149 msgbuf_cache_init(&msgbuf_cache, &msgbuf, &strings);
984d80c9
AC
1150 va_end(args);
1151
984d80c9
AC
1152 RB_DLINK_FOREACH(ptr, lclient_list.head)
1153 {
1154 target_p = ptr->data;
1155
bed692ca 1156 if(IsIOError(target_p) || !IsCapable(target_p, cap))
984d80c9
AC
1157 continue;
1158
4b1cce65 1159 send_linebuf(target_p, msgbuf_cache_get(&msgbuf_cache, CLIENT_CAPS_ONLY(target_p)));
984d80c9
AC
1160 }
1161
4b1cce65 1162 msgbuf_cache_free(&msgbuf_cache);
984d80c9
AC
1163}
1164
8aba962d
JT
1165/* sendto_monitor()
1166 *
1167 * inputs - monitor nick to send to, format, va_args
1168 * outputs - message to local users monitoring the given nick
1169 * side effects -
1170 */
1171void
4b1cce65 1172sendto_monitor(struct Client *source_p, struct monitor *monptr, const char *pattern, ...)
8aba962d
JT
1173{
1174 va_list args;
8aba962d 1175 struct Client *target_p;
330fc5c1 1176 rb_dlink_node *ptr;
637c4932 1177 rb_dlink_node *next_ptr;
4b1cce65
SA
1178 struct MsgBuf msgbuf;
1179 struct MsgBuf_cache msgbuf_cache;
1180 rb_strf_t strings = { .format = pattern, .format_args = &args, .next = NULL };
55abcbb2 1181
4b1cce65 1182 build_msgbuf_tags(&msgbuf, source_p);
55abcbb2 1183
8aba962d 1184 va_start(args, pattern);
4b1cce65 1185 msgbuf_cache_init(&msgbuf_cache, &msgbuf, &strings);
8aba962d
JT
1186 va_end(args);
1187
637c4932 1188 RB_DLINK_FOREACH_SAFE(ptr, next_ptr, monptr->users.head)
8aba962d
JT
1189 {
1190 target_p = ptr->data;
1191
1192 if(IsIOError(target_p))
1193 continue;
1194
4b1cce65 1195 _send_linebuf(target_p, msgbuf_cache_get(&msgbuf_cache, CLIENT_CAPS_ONLY(target_p)));
8aba962d
JT
1196 }
1197
4b1cce65 1198 msgbuf_cache_free(&msgbuf_cache);
8aba962d
JT
1199}
1200
e2d5ffd5 1201/* _sendto_anywhere()
212380e3 1202 *
e2d5ffd5 1203 * inputs - real_target, target, source, va_args
212380e3 1204 * outputs -
e2d5ffd5 1205 * side effects - client is sent message/own message with correct prefix.
212380e3 1206 */
e2d5ffd5
SA
1207static void
1208_sendto_anywhere(struct Client *dest_p, struct Client *target_p,
1209 struct Client *source_p, const char *command,
6396c5da 1210 const char *pattern, va_list *args)
212380e3 1211{
212380e3 1212 buf_head_t linebuf;
4b1cce65 1213 rb_strf_t strings = { .format = pattern, .format_args = args, .next = NULL };
212380e3 1214
adaa9ba9
AC
1215 rb_linebuf_newbuf(&linebuf);
1216
4b1cce65
SA
1217 if (MyClient(dest_p)) {
1218 if (IsServer(source_p)) {
1219 linebuf_put_msgf(&linebuf, &strings, ":%s %s %s ",
55abcbb2 1220 source_p->name, command,
212380e3 1221 target_p->name);
4b1cce65 1222 } else {
5559c3cf
AC
1223 struct MsgBuf msgbuf;
1224
4b1cce65 1225 build_msgbuf_tags(&msgbuf, source_p);
f2003b44 1226
4b1cce65
SA
1227 linebuf_put_tagsf(&linebuf, &msgbuf, dest_p, &strings,
1228 IsPerson(source_p) ? ":%1$s!%4$s@%5$s %2$s %3$s " : ":%1$s %2$s %3$s ",
1229 source_p->name, command, target_p->name,
1230 source_p->username, source_p->host);
5559c3cf 1231 }
4b1cce65
SA
1232
1233 _send_linebuf(dest_p, &linebuf);
1234 } else {
1235 linebuf_put_msgf(&linebuf, &strings, ":%s %s %s ",
212380e3
AC
1236 get_id(source_p, target_p), command,
1237 get_id(target_p, target_p));
212380e3 1238
e2d5ffd5 1239 send_linebuf_remote(dest_p, source_p, &linebuf);
4b1cce65 1240 }
212380e3 1241
3b2ebd04 1242 rb_linebuf_donebuf(&linebuf);
212380e3
AC
1243}
1244
e2d5ffd5
SA
1245/* sendto_anywhere()
1246 *
1247 * inputs - target, source, va_args
1248 * outputs -
1249 * side effects - client is sent message with correct prefix.
1250 */
1251void
1252sendto_anywhere(struct Client *target_p, struct Client *source_p,
1253 const char *command, const char *pattern, ...)
1254{
6396c5da
SA
1255 va_list args;
1256
1257 va_start(args, pattern);
1258 _sendto_anywhere(target_p, target_p, source_p, command, pattern, &args);
1259 va_end(args);
e2d5ffd5
SA
1260}
1261
1262/* sendto_anywhere_echo()
1263 *
1264 * inputs - target, source, va_args
1265 * outputs -
1266 * side effects - client is sent own message with correct prefix.
1267 */
1268void
1269sendto_anywhere_echo(struct Client *target_p, struct Client *source_p,
1270 const char *command, const char *pattern, ...)
1271{
6396c5da
SA
1272 va_list args;
1273
e2d5ffd5
SA
1274 s_assert(MyClient(source_p));
1275 s_assert(!IsServer(source_p));
1276
6396c5da
SA
1277 va_start(args, pattern);
1278 _sendto_anywhere(source_p, target_p, source_p, command, pattern, &args);
1279 va_end(args);
e2d5ffd5
SA
1280}
1281
212380e3
AC
1282/* sendto_realops_snomask()
1283 *
1284 * inputs - snomask needed, level (opers/admin), va_args
1285 * output -
1286 * side effects - message is sent to opers with matching snomasks
1287 */
1288void
1289sendto_realops_snomask(int flags, int level, const char *pattern, ...)
1290{
1291 static char buf[BUFSIZE];
1292 char *snobuf;
1293 struct Client *client_p;
330fc5c1 1294 rb_dlink_node *ptr;
637c4932 1295 rb_dlink_node *next_ptr;
212380e3 1296 va_list args;
4b1cce65
SA
1297 struct MsgBuf msgbuf;
1298 struct MsgBuf_cache msgbuf_cache;
212380e3 1299
4b1cce65
SA
1300 build_msgbuf_tags(&msgbuf, &me);
1301
1302 /* rather a lot of copying around, oh well -- jilles */
1303 va_start(args, pattern);
1304 vsnprintf(buf, sizeof(buf), pattern, args);
1305 va_end(args);
1306
1307 msgbuf_cache_initf(&msgbuf_cache, &msgbuf, NULL,
1308 ":%s NOTICE * :*** Notice -- %s", me.name, buf);
212380e3
AC
1309
1310 /* Be very sure not to do things like "Trying to send to myself"
1311 * L_NETWIDE, otherwise infinite recursion may result! -- jilles */
1312 if (level & L_NETWIDE && ConfigFileEntry.global_snotices)
1313 {
212380e3
AC
1314 snobuf = construct_snobuf(flags);
1315 if (snobuf[1] != '\0')
212380e3
AC
1316 sendto_server(NULL, NULL, CAP_ENCAP|CAP_TS6, NOCAPS,
1317 ":%s ENCAP * SNOTE %c :%s",
1318 me.id, snobuf[1], buf);
212380e3 1319 }
ad13bb75
JT
1320 else if (remote_rehash_oper_p != NULL)
1321 {
ad13bb75
JT
1322 sendto_one_notice(remote_rehash_oper_p, ":*** Notice -- %s", buf);
1323 }
212380e3
AC
1324 level &= ~L_NETWIDE;
1325
637c4932 1326 RB_DLINK_FOREACH_SAFE(ptr, next_ptr, local_oper_list.head)
212380e3
AC
1327 {
1328 client_p = ptr->data;
1329
1330 /* If we're sending it to opers and theyre an admin, skip.
1331 * If we're sending it to admins, and theyre not, skip.
1332 */
1333 if(((level == L_ADMIN) && !IsOperAdmin(client_p)) ||
1334 ((level == L_OPER) && IsOperAdmin(client_p)))
1335 continue;
1336
4b1cce65
SA
1337 if (client_p->snomask & flags) {
1338 _send_linebuf(client_p, msgbuf_cache_get(&msgbuf_cache, CLIENT_CAPS_ONLY(client_p)));
1339 }
212380e3
AC
1340 }
1341
4b1cce65 1342 msgbuf_cache_free(&msgbuf_cache);
212380e3
AC
1343}
1344/* sendto_realops_snomask_from()
1345 *
1346 * inputs - snomask needed, level (opers/admin), source server, va_args
1347 * output -
1348 * side effects - message is sent to opers with matching snomask
1349 */
1350void
1351sendto_realops_snomask_from(int flags, int level, struct Client *source_p,
1352 const char *pattern, ...)
1353{
1354 struct Client *client_p;
330fc5c1 1355 rb_dlink_node *ptr;
637c4932 1356 rb_dlink_node *next_ptr;
212380e3 1357 va_list args;
4b1cce65
SA
1358 struct MsgBuf msgbuf;
1359 struct MsgBuf_cache msgbuf_cache;
1360 rb_strf_t strings = { .format = pattern, .format_args = &args, .next = NULL };
212380e3 1361
4b1cce65 1362 build_msgbuf_tags(&msgbuf, &me);
212380e3
AC
1363
1364 va_start(args, pattern);
4b1cce65 1365 msgbuf_cache_initf(&msgbuf_cache, &msgbuf, &strings,
212380e3
AC
1366 ":%s NOTICE * :*** Notice -- ", source_p->name);
1367 va_end(args);
1368
637c4932 1369 RB_DLINK_FOREACH_SAFE(ptr, next_ptr, local_oper_list.head)
212380e3
AC
1370 {
1371 client_p = ptr->data;
1372
1373 /* If we're sending it to opers and theyre an admin, skip.
1374 * If we're sending it to admins, and theyre not, skip.
1375 */
1376 if(((level == L_ADMIN) && !IsOperAdmin(client_p)) ||
1377 ((level == L_OPER) && IsOperAdmin(client_p)))
1378 continue;
1379
4b1cce65
SA
1380 if (client_p->snomask & flags) {
1381 _send_linebuf(client_p, msgbuf_cache_get(&msgbuf_cache, CLIENT_CAPS_ONLY(client_p)));
1382 }
212380e3
AC
1383 }
1384
4b1cce65 1385 msgbuf_cache_free(&msgbuf_cache);
212380e3
AC
1386}
1387
1388/*
1389 * sendto_wallops_flags
1390 *
1391 * inputs - flag types of messages to show to real opers
1392 * - client sending request
1393 * - var args input message
1394 * output - NONE
1395 * side effects - Send a wallops to local opers
1396 */
1397void
1398sendto_wallops_flags(int flags, struct Client *source_p, const char *pattern, ...)
1399{
1400 struct Client *client_p;
330fc5c1 1401 rb_dlink_node *ptr;
637c4932 1402 rb_dlink_node *next_ptr;
212380e3 1403 va_list args;
4b1cce65
SA
1404 struct MsgBuf msgbuf;
1405 struct MsgBuf_cache msgbuf_cache;
1406 rb_strf_t strings = { .format = pattern, .format_args = &args, .next = NULL };
212380e3 1407
4b1cce65 1408 build_msgbuf_tags(&msgbuf, source_p);
212380e3
AC
1409
1410 va_start(args, pattern);
4b1cce65
SA
1411 if (IsPerson(source_p)) {
1412 msgbuf_cache_initf(&msgbuf_cache, &msgbuf, &strings,
212380e3
AC
1413 ":%s!%s@%s WALLOPS :", source_p->name,
1414 source_p->username, source_p->host);
4b1cce65
SA
1415 } else {
1416 msgbuf_cache_initf(&msgbuf_cache, &msgbuf, &strings,
1417 ":%s WALLOPS :", source_p->name);
1418 }
212380e3
AC
1419 va_end(args);
1420
637c4932 1421 RB_DLINK_FOREACH_SAFE(ptr, next_ptr, IsPerson(source_p) && flags == UMODE_WALLOP ? lclient_list.head : local_oper_list.head)
212380e3
AC
1422 {
1423 client_p = ptr->data;
1424
4b1cce65
SA
1425 if (client_p->umodes & flags) {
1426 _send_linebuf(client_p, msgbuf_cache_get(&msgbuf_cache, CLIENT_CAPS_ONLY(client_p)));
1427 }
212380e3
AC
1428 }
1429
4b1cce65 1430 msgbuf_cache_free(&msgbuf_cache);
212380e3
AC
1431}
1432
1433/* kill_client()
1434 *
1435 * input - client to send kill to, client to kill, va_args
1436 * output -
1437 * side effects - we issue a kill for the client
1438 */
1439void
1440kill_client(struct Client *target_p, struct Client *diedie, const char *pattern, ...)
1441{
1442 va_list args;
1443 buf_head_t linebuf;
4b1cce65
SA
1444 struct MsgBuf msgbuf;
1445 rb_strf_t strings = { .format = pattern, .format_args = &args, .next = NULL };
1446
1447 build_msgbuf_tags(&msgbuf, &me);
212380e3 1448
3b2ebd04 1449 rb_linebuf_newbuf(&linebuf);
212380e3
AC
1450
1451 va_start(args, pattern);
4b1cce65
SA
1452 linebuf_put_tagsf(&linebuf, &msgbuf, target_p, &strings,
1453 ":%s KILL %s :", get_id(&me, target_p), get_id(diedie, target_p));
212380e3
AC
1454 va_end(args);
1455
1456 send_linebuf(target_p, &linebuf);
3b2ebd04 1457 rb_linebuf_donebuf(&linebuf);
212380e3
AC
1458}
1459
1460
1461/*
1462 * kill_client_serv_butone
1463 *
1464 * inputs - pointer to client to not send to
1465 * - pointer to client to kill
1466 * output - NONE
1467 * side effects - Send a KILL for the given client
1468 * message to all connected servers
1469 * except the client 'one'. Also deal with
1470 * client being unknown to leaf, as in lazylink...
1471 */
1472void
1473kill_client_serv_butone(struct Client *one, struct Client *target_p, const char *pattern, ...)
1474{
1475 static char buf[BUFSIZE];
1476 va_list args;
1477 struct Client *client_p;
330fc5c1 1478 rb_dlink_node *ptr;
637c4932 1479 rb_dlink_node *next_ptr;
3b2ebd04 1480 buf_head_t rb_linebuf_id;
4b1cce65 1481 rb_strf_t strings = { .format = pattern, .format_args = &args, .next = NULL };
212380e3 1482
3b2ebd04 1483 rb_linebuf_newbuf(&rb_linebuf_id);
55abcbb2 1484
212380e3 1485 va_start(args, pattern);
4b1cce65 1486 linebuf_put_msgf(&rb_linebuf_id, &strings, ":%s KILL %s :%s",
212380e3 1487 use_id(&me), use_id(target_p), buf);
4b1cce65 1488 va_end(args);
212380e3 1489
637c4932 1490 RB_DLINK_FOREACH_SAFE(ptr, next_ptr, serv_list.head)
212380e3
AC
1491 {
1492 client_p = ptr->data;
1493
1494 /* ok, if the client we're supposed to not send to has an
1495 * ID, then we still want to issue the kill there..
1496 */
1497 if(one != NULL && (client_p == one->from) &&
1498 (!has_id(client_p) || !has_id(target_p)))
1499 continue;
1500
ba301eff 1501 _send_linebuf(client_p, &rb_linebuf_id);
212380e3
AC
1502 }
1503
3b2ebd04 1504 rb_linebuf_donebuf(&rb_linebuf_id);
212380e3 1505}