]> jfr.im git - solanum.git/blame - ircd/send.c
ircd: send tags on every message
[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
JT
600 current_serial++;
601
4b1cce65
SA
602 if(IsServer(source_p)) {
603 msgbuf_cache_initf(&msgbuf_cache, &msgbuf, &strings,
604 ":%s %s %s :",
605 source_p->name, command, chptr->chname);
606 } else {
607 msgbuf_cache_initf(&msgbuf_cache, &msgbuf, &strings,
608 ":%s!%s@%s %s %s :",
55abcbb2 609 source_p->name, source_p->username,
4b1cce65
SA
610 source_p->host, command, chptr->chname);
611 }
c4d2d014 612
4b1cce65
SA
613 if (chptr->mode.mode & MODE_MODERATED) {
614 linebuf_put_msgf(&rb_linebuf_old, &strings,
615 ":%s %s %s :",
c4d2d014 616 use_id(source_p), command, chptr->chname, text);
4b1cce65
SA
617 } else {
618 linebuf_put_msgf(&rb_linebuf_old, &strings,
619 ":%s NOTICE @%s :<%s:%s> ",
c4d2d014 620 use_id(source_p->servptr), chptr->chname,
4b1cce65
SA
621 source_p->name, chptr->chname);
622 }
623 linebuf_put_msgf(&rb_linebuf_new, &strings,
624 ":%s %s =%s :",
625 use_id(source_p), command, chptr->chname);
c4d2d014
JT
626
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
AC
677
678/* sendto_channel_local()
679 *
4b1cce65 680 * inputs - source, flags to send to, channel to send to, va_args
212380e3
AC
681 * outputs - message to local channel members
682 * side effects -
683 */
684void
4b1cce65 685sendto_channel_local(struct Client *source_p, int type, struct Channel *chptr, const char *pattern, ...)
212380e3
AC
686{
687 va_list args;
212380e3
AC
688 struct membership *msptr;
689 struct Client *target_p;
330fc5c1 690 rb_dlink_node *ptr;
637c4932 691 rb_dlink_node *next_ptr;
4b1cce65
SA
692 struct MsgBuf msgbuf;
693 struct MsgBuf_cache msgbuf_cache;
694 rb_strf_t strings = { .format = pattern, .format_args = &args, .next = NULL };
55abcbb2 695
4b1cce65 696 build_msgbuf_tags(&msgbuf, source_p);
55abcbb2 697
212380e3 698 va_start(args, pattern);
4b1cce65 699 msgbuf_cache_init(&msgbuf_cache, &msgbuf, &strings);
212380e3
AC
700 va_end(args);
701
637c4932 702 RB_DLINK_FOREACH_SAFE(ptr, next_ptr, chptr->locmembers.head)
212380e3
AC
703 {
704 msptr = ptr->data;
705 target_p = msptr->client_p;
706
707 if(IsIOError(target_p))
708 continue;
709
be29ec79
AC
710 if(type == ONLY_OPERS)
711 {
712 if (!IsOper(target_p))
713 continue;
714 }
715 else if(type && ((msptr->flags & type) == 0))
212380e3
AC
716 continue;
717
4b1cce65 718 _send_linebuf(target_p, msgbuf_cache_get(&msgbuf_cache, CLIENT_CAPS_ONLY(target_p)));
99cca61e
AC
719 }
720
4b1cce65 721 msgbuf_cache_free(&msgbuf_cache);
99cca61e
AC
722}
723
a695b0e4
SB
724/*
725 * _sendto_channel_local_with_capability_butone()
99cca61e 726 *
a695b0e4 727 * Shared implementation of sendto_channel_local_with_capability and sendto_channel_local_with_capability_butone
99cca61e 728 */
a695b0e4 729static void
4b1cce65
SA
730_sendto_channel_local_with_capability_butone(struct Client *source_p, struct Client *one, int type,
731 int caps, int negcaps, struct Channel *chptr, const char *pattern, va_list * args)
99cca61e 732{
99cca61e
AC
733 struct membership *msptr;
734 struct Client *target_p;
735 rb_dlink_node *ptr;
736 rb_dlink_node *next_ptr;
4b1cce65
SA
737 struct MsgBuf msgbuf;
738 struct MsgBuf_cache msgbuf_cache;
739 rb_strf_t strings = { .format = pattern, .format_args = args, .next = NULL };
55abcbb2 740
4b1cce65
SA
741 build_msgbuf_tags(&msgbuf, source_p);
742 msgbuf_cache_init(&msgbuf_cache, &msgbuf, &strings);
55abcbb2 743
99cca61e
AC
744 RB_DLINK_FOREACH_SAFE(ptr, next_ptr, chptr->locmembers.head)
745 {
746 msptr = ptr->data;
747 target_p = msptr->client_p;
748
a695b0e4
SB
749 if (target_p == one)
750 continue;
751
99cca61e
AC
752 if(IsIOError(target_p) ||
753 !IsCapable(target_p, caps) ||
e2b507ac 754 !NotCapable(target_p, negcaps))
99cca61e
AC
755 continue;
756
757 if(type && ((msptr->flags & type) == 0))
758 continue;
759
4b1cce65 760 _send_linebuf(target_p, msgbuf_cache_get(&msgbuf_cache, CLIENT_CAPS_ONLY(target_p)));
212380e3
AC
761 }
762
4b1cce65 763 msgbuf_cache_free(&msgbuf_cache);
212380e3
AC
764}
765
a695b0e4
SB
766/* sendto_channel_local_with_capability()
767 *
4b1cce65 768 * inputs - source, flags to send to, caps, negate caps, channel to send to, va_args
a695b0e4
SB
769 * outputs - message to local channel members
770 * side effects -
771 */
772void
4b1cce65 773sendto_channel_local_with_capability(struct Client *source_p, int type, int caps, int negcaps, struct Channel *chptr, const char *pattern, ...)
a695b0e4
SB
774{
775 va_list args;
776
777 va_start(args, pattern);
4b1cce65 778 _sendto_channel_local_with_capability_butone(source_p, NULL, type, caps, negcaps, chptr, pattern, &args);
a695b0e4
SB
779 va_end(args);
780}
781
782
783/* sendto_channel_local_with_capability()
784 *
4b1cce65 785 * inputs - source, flags to send to, caps, negate caps, channel to send to, va_args
a695b0e4
SB
786 * outputs - message to local channel members
787 * side effects -
788 */
789void
4b1cce65
SA
790sendto_channel_local_with_capability_butone(struct Client *one, int type,
791 int caps, int negcaps, struct Channel *chptr, const char *pattern, ...)
a695b0e4
SB
792{
793 va_list args;
794
795 va_start(args, pattern);
4b1cce65 796 _sendto_channel_local_with_capability_butone(one, one, type, caps, negcaps, chptr, pattern, &args);
a695b0e4
SB
797 va_end(args);
798}
799
800
212380e3
AC
801/* sendto_channel_local_butone()
802 *
803 * inputs - flags to send to, channel to send to, va_args
804 * - user to ignore when sending
805 * outputs - message to local channel members
806 * side effects -
807 */
808void
809sendto_channel_local_butone(struct Client *one, int type, struct Channel *chptr, const char *pattern, ...)
810{
811 va_list args;
212380e3
AC
812 struct membership *msptr;
813 struct Client *target_p;
5559c3cf 814 struct MsgBuf msgbuf;
330fc5c1 815 rb_dlink_node *ptr;
637c4932 816 rb_dlink_node *next_ptr;
4b1cce65
SA
817 struct MsgBuf_cache msgbuf_cache;
818 rb_strf_t strings = { .format = pattern, .format_args = &args, .next = NULL };
55abcbb2 819
4b1cce65 820 build_msgbuf_tags(&msgbuf, one);
5559c3cf 821
212380e3 822 va_start(args, pattern);
4b1cce65 823 msgbuf_cache_init(&msgbuf_cache, &msgbuf, &strings);
474f6342 824 va_end(args);
212380e3 825
637c4932 826 RB_DLINK_FOREACH_SAFE(ptr, next_ptr, chptr->locmembers.head)
212380e3
AC
827 {
828 msptr = ptr->data;
829 target_p = msptr->client_p;
830
831 if(target_p == one)
832 continue;
833
834 if(IsIOError(target_p))
835 continue;
836
837 if(type && ((msptr->flags & type) == 0))
838 continue;
839
5559c3cf 840 /* attach the present linebuf to the target */
4b1cce65 841 _send_linebuf(target_p, msgbuf_cache_get(&msgbuf_cache, CLIENT_CAPS_ONLY(target_p)));
212380e3
AC
842 }
843
4b1cce65 844 msgbuf_cache_free(&msgbuf_cache);
212380e3
AC
845}
846
847/*
848 * sendto_common_channels_local()
849 *
850 * inputs - pointer to client
4b1cce65
SA
851 * - capability mask
852 * - negated capability mask
212380e3
AC
853 * - pattern to send
854 * output - NONE
855 * side effects - Sends a message to all people on local server who are
55abcbb2 856 * in same channel with user.
212380e3
AC
857 * used by m_nick.c and exit_one_client.
858 */
859void
583f064f 860sendto_common_channels_local(struct Client *user, int cap, int negcap, const char *pattern, ...)
212380e3
AC
861{
862 va_list args;
330fc5c1 863 rb_dlink_node *ptr;
637c4932 864 rb_dlink_node *next_ptr;
330fc5c1
AC
865 rb_dlink_node *uptr;
866 rb_dlink_node *next_uptr;
212380e3
AC
867 struct Channel *chptr;
868 struct Client *target_p;
869 struct membership *msptr;
870 struct membership *mscptr;
4b1cce65
SA
871 struct MsgBuf msgbuf;
872 struct MsgBuf_cache msgbuf_cache;
873 rb_strf_t strings = { .format = pattern, .format_args = &args, .next = NULL };
874
875 build_msgbuf_tags(&msgbuf, user);
212380e3 876
212380e3 877 va_start(args, pattern);
4b1cce65 878 msgbuf_cache_init(&msgbuf_cache, &msgbuf, &strings);
212380e3
AC
879 va_end(args);
880
881 ++current_serial;
882
637c4932 883 RB_DLINK_FOREACH_SAFE(ptr, next_ptr, user->user->channel.head)
212380e3
AC
884 {
885 mscptr = ptr->data;
886 chptr = mscptr->chptr;
887
5cefa1d6 888 RB_DLINK_FOREACH_SAFE(uptr, next_uptr, chptr->locmembers.head)
212380e3
AC
889 {
890 msptr = uptr->data;
891 target_p = msptr->client_p;
892
893 if(IsIOError(target_p) ||
7a948bda 894 target_p->serial == current_serial ||
583f064f
AC
895 !IsCapable(target_p, cap) ||
896 !NotCapable(target_p, negcap))
212380e3
AC
897 continue;
898
899 target_p->serial = current_serial;
4b1cce65 900 send_linebuf(target_p, msgbuf_cache_get(&msgbuf_cache, CLIENT_CAPS_ONLY(target_p)));
212380e3
AC
901 }
902 }
903
904 /* this can happen when the user isnt in any channels, but we still
905 * need to send them the data, ie a nick change
906 */
42ae8ab2 907 if(MyConnect(user) && (user->serial != current_serial)
4b1cce65
SA
908 && IsCapable(user, cap) && NotCapable(user, negcap)) {
909 send_linebuf(user, msgbuf_cache_get(&msgbuf_cache, CLIENT_CAPS_ONLY(user)));
910 }
212380e3 911
4b1cce65 912 msgbuf_cache_free(&msgbuf_cache);
212380e3
AC
913}
914
915/*
916 * sendto_common_channels_local_butone()
917 *
918 * inputs - pointer to client
4b1cce65
SA
919 * - capability mask
920 * - negated capability mask
212380e3
AC
921 * - pattern to send
922 * output - NONE
923 * side effects - Sends a message to all people on local server who are
924 * in same channel with user, except for user itself.
925 */
926void
583f064f 927sendto_common_channels_local_butone(struct Client *user, int cap, int negcap, const char *pattern, ...)
212380e3
AC
928{
929 va_list args;
330fc5c1 930 rb_dlink_node *ptr;
637c4932 931 rb_dlink_node *next_ptr;
330fc5c1
AC
932 rb_dlink_node *uptr;
933 rb_dlink_node *next_uptr;
212380e3
AC
934 struct Channel *chptr;
935 struct Client *target_p;
936 struct membership *msptr;
937 struct membership *mscptr;
4b1cce65
SA
938 struct MsgBuf msgbuf;
939 struct MsgBuf_cache msgbuf_cache;
940 rb_strf_t strings = { .format = pattern, .format_args = &args, .next = NULL };
212380e3 941
4b1cce65 942 build_msgbuf_tags(&msgbuf, user);
5559c3cf 943
212380e3 944 va_start(args, pattern);
4b1cce65 945 msgbuf_cache_init(&msgbuf_cache, &msgbuf, &strings);
212380e3
AC
946 va_end(args);
947
948 ++current_serial;
949 /* Skip them -- jilles */
950 user->serial = current_serial;
951
637c4932 952 RB_DLINK_FOREACH_SAFE(ptr, next_ptr, user->user->channel.head)
212380e3
AC
953 {
954 mscptr = ptr->data;
955 chptr = mscptr->chptr;
956
5cefa1d6 957 RB_DLINK_FOREACH_SAFE(uptr, next_uptr, chptr->locmembers.head)
212380e3
AC
958 {
959 msptr = uptr->data;
960 target_p = msptr->client_p;
961
962 if(IsIOError(target_p) ||
7a948bda 963 target_p->serial == current_serial ||
583f064f
AC
964 !IsCapable(target_p, cap) ||
965 !NotCapable(target_p, negcap))
212380e3
AC
966 continue;
967
968 target_p->serial = current_serial;
4b1cce65 969 send_linebuf(target_p, msgbuf_cache_get(&msgbuf_cache, CLIENT_CAPS_ONLY(target_p)));
212380e3
AC
970 }
971 }
972
4b1cce65 973 msgbuf_cache_free(&msgbuf_cache);
212380e3
AC
974}
975
976/* sendto_match_butone()
977 *
978 * inputs - server not to send to, source, mask, type of mask, va_args
979 * output -
980 * side effects - message is sent to matching clients
981 */
982void
983sendto_match_butone(struct Client *one, struct Client *source_p,
984 const char *mask, int what, const char *pattern, ...)
985{
986 static char buf[BUFSIZE];
987 va_list args;
988 struct Client *target_p;
330fc5c1 989 rb_dlink_node *ptr;
637c4932 990 rb_dlink_node *next_ptr;
7a06833f 991 buf_head_t rb_linebuf_remote;
4b1cce65
SA
992 struct MsgBuf msgbuf;
993 struct MsgBuf_cache msgbuf_cache;
994 rb_strf_t strings = { .format = buf, .format_args = NULL, .next = NULL };
212380e3 995
7a06833f 996 rb_linebuf_newbuf(&rb_linebuf_remote);
212380e3 997
4b1cce65
SA
998 build_msgbuf_tags(&msgbuf, source_p);
999
212380e3 1000 va_start(args, pattern);
5203cba5 1001 vsnprintf(buf, sizeof(buf), pattern, args);
212380e3
AC
1002 va_end(args);
1003
4b1cce65
SA
1004 msgbuf_cache_initf(&msgbuf_cache, &msgbuf, &strings,
1005 IsServer(source_p) ? ":%s " : ":%s!%s@%s ",
1006 source_p->name, source_p->username, source_p->host);
212380e3 1007
4b1cce65 1008 linebuf_put_msgf(&rb_linebuf_remote, &strings, ":%s ", use_id(source_p));
212380e3
AC
1009
1010 if(what == MATCH_HOST)
1011 {
637c4932 1012 RB_DLINK_FOREACH_SAFE(ptr, next_ptr, lclient_list.head)
212380e3
AC
1013 {
1014 target_p = ptr->data;
1015
1016 if(match(mask, target_p->host))
4b1cce65 1017 _send_linebuf(target_p, msgbuf_cache_get(&msgbuf_cache, CLIENT_CAPS_ONLY(target_p)));
212380e3
AC
1018 }
1019 }
1020 /* what = MATCH_SERVER, if it doesnt match us, just send remote */
1021 else if(match(mask, me.name))
1022 {
637c4932 1023 RB_DLINK_FOREACH_SAFE(ptr, next_ptr, lclient_list.head)
212380e3
AC
1024 {
1025 target_p = ptr->data;
4b1cce65 1026 _send_linebuf(target_p, msgbuf_cache_get(&msgbuf_cache, CLIENT_CAPS_ONLY(target_p)));
212380e3
AC
1027 }
1028 }
1029
5cefa1d6 1030 RB_DLINK_FOREACH(ptr, serv_list.head)
212380e3
AC
1031 {
1032 target_p = ptr->data;
1033
1034 if(target_p == one)
1035 continue;
1036
7a06833f 1037 send_linebuf_remote(target_p, source_p, &rb_linebuf_remote);
212380e3
AC
1038 }
1039
4b1cce65 1040 msgbuf_cache_free(&msgbuf_cache);
7a06833f 1041 rb_linebuf_donebuf(&rb_linebuf_remote);
212380e3
AC
1042}
1043
1044/* sendto_match_servs()
1045 *
1046 * inputs - source, mask to send to, caps needed, va_args
55abcbb2 1047 * outputs -
212380e3
AC
1048 * side effects - message is sent to matching servers with caps.
1049 */
1050void
55abcbb2 1051sendto_match_servs(struct Client *source_p, const char *mask, int cap,
212380e3
AC
1052 int nocap, const char *pattern, ...)
1053{
1054 static char buf[BUFSIZE];
1055 va_list args;
330fc5c1 1056 rb_dlink_node *ptr;
212380e3 1057 struct Client *target_p;
3b2ebd04 1058 buf_head_t rb_linebuf_id;
4b1cce65 1059 rb_strf_t strings = { .format = buf, .format_args = NULL, .next = NULL };
212380e3
AC
1060
1061 if(EmptyString(mask))
1062 return;
1063
3b2ebd04 1064 rb_linebuf_newbuf(&rb_linebuf_id);
212380e3
AC
1065
1066 va_start(args, pattern);
5203cba5 1067 vsnprintf(buf, sizeof(buf), pattern, args);
212380e3
AC
1068 va_end(args);
1069
4b1cce65 1070 linebuf_put_msgf(&rb_linebuf_id, &strings, ":%s ", use_id(source_p));
212380e3
AC
1071
1072 current_serial++;
1073
5cefa1d6 1074 RB_DLINK_FOREACH(ptr, global_serv_list.head)
212380e3
AC
1075 {
1076 target_p = ptr->data;
1077
1078 /* dont send to ourselves, or back to where it came from.. */
1079 if(IsMe(target_p) || target_p->from == source_p->from)
1080 continue;
1081
1082 if(target_p->from->serial == current_serial)
1083 continue;
1084
1085 if(match(mask, target_p->name))
1086 {
1087 /* if we set the serial here, then we'll never do
1088 * a match() again if !IsCapable()
1089 */
1090 target_p->from->serial = current_serial;
1091
1092 if(cap && !IsCapable(target_p->from, cap))
1093 continue;
1094
1095 if(nocap && !NotCapable(target_p->from, nocap))
1096 continue;
1097
ba301eff 1098 _send_linebuf(target_p->from, &rb_linebuf_id);
212380e3
AC
1099 }
1100 }
1101
3b2ebd04 1102 rb_linebuf_donebuf(&rb_linebuf_id);
212380e3
AC
1103}
1104
984d80c9
AC
1105/* sendto_local_clients_with_capability()
1106 *
1107 * inputs - caps needed, pattern, va_args
1108 * outputs -
1109 * side effects - message is sent to matching local clients with caps.
1110 */
1111void
1112sendto_local_clients_with_capability(int cap, const char *pattern, ...)
1113{
1114 va_list args;
1115 rb_dlink_node *ptr;
1116 struct Client *target_p;
4b1cce65
SA
1117 struct MsgBuf msgbuf;
1118 struct MsgBuf_cache msgbuf_cache;
1119 rb_strf_t strings = { .format = pattern, .format_args = &args, .next = NULL };
984d80c9 1120
4b1cce65 1121 build_msgbuf_tags(&msgbuf, &me);
984d80c9
AC
1122
1123 va_start(args, pattern);
4b1cce65 1124 msgbuf_cache_init(&msgbuf_cache, &msgbuf, &strings);
984d80c9
AC
1125 va_end(args);
1126
984d80c9
AC
1127 RB_DLINK_FOREACH(ptr, lclient_list.head)
1128 {
1129 target_p = ptr->data;
1130
bed692ca 1131 if(IsIOError(target_p) || !IsCapable(target_p, cap))
984d80c9
AC
1132 continue;
1133
4b1cce65 1134 send_linebuf(target_p, msgbuf_cache_get(&msgbuf_cache, CLIENT_CAPS_ONLY(target_p)));
984d80c9
AC
1135 }
1136
4b1cce65 1137 msgbuf_cache_free(&msgbuf_cache);
984d80c9
AC
1138}
1139
8aba962d
JT
1140/* sendto_monitor()
1141 *
1142 * inputs - monitor nick to send to, format, va_args
1143 * outputs - message to local users monitoring the given nick
1144 * side effects -
1145 */
1146void
4b1cce65 1147sendto_monitor(struct Client *source_p, struct monitor *monptr, const char *pattern, ...)
8aba962d
JT
1148{
1149 va_list args;
8aba962d 1150 struct Client *target_p;
330fc5c1 1151 rb_dlink_node *ptr;
637c4932 1152 rb_dlink_node *next_ptr;
4b1cce65
SA
1153 struct MsgBuf msgbuf;
1154 struct MsgBuf_cache msgbuf_cache;
1155 rb_strf_t strings = { .format = pattern, .format_args = &args, .next = NULL };
55abcbb2 1156
4b1cce65 1157 build_msgbuf_tags(&msgbuf, source_p);
55abcbb2 1158
8aba962d 1159 va_start(args, pattern);
4b1cce65 1160 msgbuf_cache_init(&msgbuf_cache, &msgbuf, &strings);
8aba962d
JT
1161 va_end(args);
1162
637c4932 1163 RB_DLINK_FOREACH_SAFE(ptr, next_ptr, monptr->users.head)
8aba962d
JT
1164 {
1165 target_p = ptr->data;
1166
1167 if(IsIOError(target_p))
1168 continue;
1169
4b1cce65 1170 _send_linebuf(target_p, msgbuf_cache_get(&msgbuf_cache, CLIENT_CAPS_ONLY(target_p)));
8aba962d
JT
1171 }
1172
4b1cce65 1173 msgbuf_cache_free(&msgbuf_cache);
8aba962d
JT
1174}
1175
e2d5ffd5 1176/* _sendto_anywhere()
212380e3 1177 *
e2d5ffd5 1178 * inputs - real_target, target, source, va_args
212380e3 1179 * outputs -
e2d5ffd5 1180 * side effects - client is sent message/own message with correct prefix.
212380e3 1181 */
e2d5ffd5
SA
1182static void
1183_sendto_anywhere(struct Client *dest_p, struct Client *target_p,
1184 struct Client *source_p, const char *command,
6396c5da 1185 const char *pattern, va_list *args)
212380e3 1186{
212380e3 1187 buf_head_t linebuf;
4b1cce65 1188 rb_strf_t strings = { .format = pattern, .format_args = args, .next = NULL };
212380e3 1189
adaa9ba9
AC
1190 rb_linebuf_newbuf(&linebuf);
1191
4b1cce65
SA
1192 if (MyClient(dest_p)) {
1193 if (IsServer(source_p)) {
1194 linebuf_put_msgf(&linebuf, &strings, ":%s %s %s ",
55abcbb2 1195 source_p->name, command,
212380e3 1196 target_p->name);
4b1cce65 1197 } else {
5559c3cf
AC
1198 struct MsgBuf msgbuf;
1199
4b1cce65 1200 build_msgbuf_tags(&msgbuf, source_p);
f2003b44 1201
4b1cce65
SA
1202 linebuf_put_tagsf(&linebuf, &msgbuf, dest_p, &strings,
1203 IsPerson(source_p) ? ":%1$s!%4$s@%5$s %2$s %3$s " : ":%1$s %2$s %3$s ",
1204 source_p->name, command, target_p->name,
1205 source_p->username, source_p->host);
5559c3cf 1206 }
4b1cce65
SA
1207
1208 _send_linebuf(dest_p, &linebuf);
1209 } else {
1210 linebuf_put_msgf(&linebuf, &strings, ":%s %s %s ",
212380e3
AC
1211 get_id(source_p, target_p), command,
1212 get_id(target_p, target_p));
212380e3 1213
e2d5ffd5 1214 send_linebuf_remote(dest_p, source_p, &linebuf);
4b1cce65 1215 }
212380e3 1216
3b2ebd04 1217 rb_linebuf_donebuf(&linebuf);
212380e3
AC
1218}
1219
e2d5ffd5
SA
1220/* sendto_anywhere()
1221 *
1222 * inputs - target, source, va_args
1223 * outputs -
1224 * side effects - client is sent message with correct prefix.
1225 */
1226void
1227sendto_anywhere(struct Client *target_p, struct Client *source_p,
1228 const char *command, const char *pattern, ...)
1229{
6396c5da
SA
1230 va_list args;
1231
1232 va_start(args, pattern);
1233 _sendto_anywhere(target_p, target_p, source_p, command, pattern, &args);
1234 va_end(args);
e2d5ffd5
SA
1235}
1236
1237/* sendto_anywhere_echo()
1238 *
1239 * inputs - target, source, va_args
1240 * outputs -
1241 * side effects - client is sent own message with correct prefix.
1242 */
1243void
1244sendto_anywhere_echo(struct Client *target_p, struct Client *source_p,
1245 const char *command, const char *pattern, ...)
1246{
6396c5da
SA
1247 va_list args;
1248
e2d5ffd5
SA
1249 s_assert(MyClient(source_p));
1250 s_assert(!IsServer(source_p));
1251
6396c5da
SA
1252 va_start(args, pattern);
1253 _sendto_anywhere(source_p, target_p, source_p, command, pattern, &args);
1254 va_end(args);
e2d5ffd5
SA
1255}
1256
212380e3
AC
1257/* sendto_realops_snomask()
1258 *
1259 * inputs - snomask needed, level (opers/admin), va_args
1260 * output -
1261 * side effects - message is sent to opers with matching snomasks
1262 */
1263void
1264sendto_realops_snomask(int flags, int level, const char *pattern, ...)
1265{
1266 static char buf[BUFSIZE];
1267 char *snobuf;
1268 struct Client *client_p;
330fc5c1 1269 rb_dlink_node *ptr;
637c4932 1270 rb_dlink_node *next_ptr;
212380e3 1271 va_list args;
4b1cce65
SA
1272 struct MsgBuf msgbuf;
1273 struct MsgBuf_cache msgbuf_cache;
212380e3 1274
4b1cce65
SA
1275 build_msgbuf_tags(&msgbuf, &me);
1276
1277 /* rather a lot of copying around, oh well -- jilles */
1278 va_start(args, pattern);
1279 vsnprintf(buf, sizeof(buf), pattern, args);
1280 va_end(args);
1281
1282 msgbuf_cache_initf(&msgbuf_cache, &msgbuf, NULL,
1283 ":%s NOTICE * :*** Notice -- %s", me.name, buf);
212380e3
AC
1284
1285 /* Be very sure not to do things like "Trying to send to myself"
1286 * L_NETWIDE, otherwise infinite recursion may result! -- jilles */
1287 if (level & L_NETWIDE && ConfigFileEntry.global_snotices)
1288 {
212380e3
AC
1289 snobuf = construct_snobuf(flags);
1290 if (snobuf[1] != '\0')
212380e3
AC
1291 sendto_server(NULL, NULL, CAP_ENCAP|CAP_TS6, NOCAPS,
1292 ":%s ENCAP * SNOTE %c :%s",
1293 me.id, snobuf[1], buf);
212380e3 1294 }
ad13bb75
JT
1295 else if (remote_rehash_oper_p != NULL)
1296 {
ad13bb75
JT
1297 sendto_one_notice(remote_rehash_oper_p, ":*** Notice -- %s", buf);
1298 }
212380e3
AC
1299 level &= ~L_NETWIDE;
1300
637c4932 1301 RB_DLINK_FOREACH_SAFE(ptr, next_ptr, local_oper_list.head)
212380e3
AC
1302 {
1303 client_p = ptr->data;
1304
1305 /* If we're sending it to opers and theyre an admin, skip.
1306 * If we're sending it to admins, and theyre not, skip.
1307 */
1308 if(((level == L_ADMIN) && !IsOperAdmin(client_p)) ||
1309 ((level == L_OPER) && IsOperAdmin(client_p)))
1310 continue;
1311
4b1cce65
SA
1312 if (client_p->snomask & flags) {
1313 _send_linebuf(client_p, msgbuf_cache_get(&msgbuf_cache, CLIENT_CAPS_ONLY(client_p)));
1314 }
212380e3
AC
1315 }
1316
4b1cce65 1317 msgbuf_cache_free(&msgbuf_cache);
212380e3
AC
1318}
1319/* sendto_realops_snomask_from()
1320 *
1321 * inputs - snomask needed, level (opers/admin), source server, va_args
1322 * output -
1323 * side effects - message is sent to opers with matching snomask
1324 */
1325void
1326sendto_realops_snomask_from(int flags, int level, struct Client *source_p,
1327 const char *pattern, ...)
1328{
1329 struct Client *client_p;
330fc5c1 1330 rb_dlink_node *ptr;
637c4932 1331 rb_dlink_node *next_ptr;
212380e3 1332 va_list args;
4b1cce65
SA
1333 struct MsgBuf msgbuf;
1334 struct MsgBuf_cache msgbuf_cache;
1335 rb_strf_t strings = { .format = pattern, .format_args = &args, .next = NULL };
212380e3 1336
4b1cce65 1337 build_msgbuf_tags(&msgbuf, &me);
212380e3
AC
1338
1339 va_start(args, pattern);
4b1cce65 1340 msgbuf_cache_initf(&msgbuf_cache, &msgbuf, &strings,
212380e3
AC
1341 ":%s NOTICE * :*** Notice -- ", source_p->name);
1342 va_end(args);
1343
637c4932 1344 RB_DLINK_FOREACH_SAFE(ptr, next_ptr, local_oper_list.head)
212380e3
AC
1345 {
1346 client_p = ptr->data;
1347
1348 /* If we're sending it to opers and theyre an admin, skip.
1349 * If we're sending it to admins, and theyre not, skip.
1350 */
1351 if(((level == L_ADMIN) && !IsOperAdmin(client_p)) ||
1352 ((level == L_OPER) && IsOperAdmin(client_p)))
1353 continue;
1354
4b1cce65
SA
1355 if (client_p->snomask & flags) {
1356 _send_linebuf(client_p, msgbuf_cache_get(&msgbuf_cache, CLIENT_CAPS_ONLY(client_p)));
1357 }
212380e3
AC
1358 }
1359
4b1cce65 1360 msgbuf_cache_free(&msgbuf_cache);
212380e3
AC
1361}
1362
1363/*
1364 * sendto_wallops_flags
1365 *
1366 * inputs - flag types of messages to show to real opers
1367 * - client sending request
1368 * - var args input message
1369 * output - NONE
1370 * side effects - Send a wallops to local opers
1371 */
1372void
1373sendto_wallops_flags(int flags, struct Client *source_p, const char *pattern, ...)
1374{
1375 struct Client *client_p;
330fc5c1 1376 rb_dlink_node *ptr;
637c4932 1377 rb_dlink_node *next_ptr;
212380e3 1378 va_list args;
4b1cce65
SA
1379 struct MsgBuf msgbuf;
1380 struct MsgBuf_cache msgbuf_cache;
1381 rb_strf_t strings = { .format = pattern, .format_args = &args, .next = NULL };
212380e3 1382
4b1cce65 1383 build_msgbuf_tags(&msgbuf, source_p);
212380e3
AC
1384
1385 va_start(args, pattern);
4b1cce65
SA
1386 if (IsPerson(source_p)) {
1387 msgbuf_cache_initf(&msgbuf_cache, &msgbuf, &strings,
212380e3
AC
1388 ":%s!%s@%s WALLOPS :", source_p->name,
1389 source_p->username, source_p->host);
4b1cce65
SA
1390 } else {
1391 msgbuf_cache_initf(&msgbuf_cache, &msgbuf, &strings,
1392 ":%s WALLOPS :", source_p->name);
1393 }
212380e3
AC
1394 va_end(args);
1395
637c4932 1396 RB_DLINK_FOREACH_SAFE(ptr, next_ptr, IsPerson(source_p) && flags == UMODE_WALLOP ? lclient_list.head : local_oper_list.head)
212380e3
AC
1397 {
1398 client_p = ptr->data;
1399
4b1cce65
SA
1400 if (client_p->umodes & flags) {
1401 _send_linebuf(client_p, msgbuf_cache_get(&msgbuf_cache, CLIENT_CAPS_ONLY(client_p)));
1402 }
212380e3
AC
1403 }
1404
4b1cce65 1405 msgbuf_cache_free(&msgbuf_cache);
212380e3
AC
1406}
1407
1408/* kill_client()
1409 *
1410 * input - client to send kill to, client to kill, va_args
1411 * output -
1412 * side effects - we issue a kill for the client
1413 */
1414void
1415kill_client(struct Client *target_p, struct Client *diedie, const char *pattern, ...)
1416{
1417 va_list args;
1418 buf_head_t linebuf;
4b1cce65
SA
1419 struct MsgBuf msgbuf;
1420 rb_strf_t strings = { .format = pattern, .format_args = &args, .next = NULL };
1421
1422 build_msgbuf_tags(&msgbuf, &me);
212380e3 1423
3b2ebd04 1424 rb_linebuf_newbuf(&linebuf);
212380e3
AC
1425
1426 va_start(args, pattern);
4b1cce65
SA
1427 linebuf_put_tagsf(&linebuf, &msgbuf, target_p, &strings,
1428 ":%s KILL %s :", get_id(&me, target_p), get_id(diedie, target_p));
212380e3
AC
1429 va_end(args);
1430
1431 send_linebuf(target_p, &linebuf);
3b2ebd04 1432 rb_linebuf_donebuf(&linebuf);
212380e3
AC
1433}
1434
1435
1436/*
1437 * kill_client_serv_butone
1438 *
1439 * inputs - pointer to client to not send to
1440 * - pointer to client to kill
1441 * output - NONE
1442 * side effects - Send a KILL for the given client
1443 * message to all connected servers
1444 * except the client 'one'. Also deal with
1445 * client being unknown to leaf, as in lazylink...
1446 */
1447void
1448kill_client_serv_butone(struct Client *one, struct Client *target_p, const char *pattern, ...)
1449{
1450 static char buf[BUFSIZE];
1451 va_list args;
1452 struct Client *client_p;
330fc5c1 1453 rb_dlink_node *ptr;
637c4932 1454 rb_dlink_node *next_ptr;
3b2ebd04 1455 buf_head_t rb_linebuf_id;
4b1cce65 1456 rb_strf_t strings = { .format = pattern, .format_args = &args, .next = NULL };
212380e3 1457
3b2ebd04 1458 rb_linebuf_newbuf(&rb_linebuf_id);
55abcbb2 1459
212380e3 1460 va_start(args, pattern);
4b1cce65 1461 linebuf_put_msgf(&rb_linebuf_id, &strings, ":%s KILL %s :%s",
212380e3 1462 use_id(&me), use_id(target_p), buf);
4b1cce65 1463 va_end(args);
212380e3 1464
637c4932 1465 RB_DLINK_FOREACH_SAFE(ptr, next_ptr, serv_list.head)
212380e3
AC
1466 {
1467 client_p = ptr->data;
1468
1469 /* ok, if the client we're supposed to not send to has an
1470 * ID, then we still want to issue the kill there..
1471 */
1472 if(one != NULL && (client_p == one->from) &&
1473 (!has_id(client_p) || !has_id(target_p)))
1474 continue;
1475
ba301eff 1476 _send_linebuf(client_p, &rb_linebuf_id);
212380e3
AC
1477 }
1478
3b2ebd04 1479 rb_linebuf_donebuf(&rb_linebuf_id);
212380e3 1480}