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