]> jfr.im git - solanum.git/blob - ircd/send.c
Avoid show_iline_prefix showing leftovers (#266)
[solanum.git] / ircd / send.c
1 /*
2 * ircd-ratbox: A slightly useful ircd.
3 * send.c: Functions for sending messages.
4 *
5 * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
6 * Copyright (C) 1996-2002 Hybrid Development Team
7 * Copyright (C) 2002-2005 ircd-ratbox development team
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
22 * USA
23 */
24
25 #include "stdinc.h"
26 #include "send.h"
27 #include "channel.h"
28 #include "class.h"
29 #include "client.h"
30 #include "match.h"
31 #include "ircd.h"
32 #include "numeric.h"
33 #include "s_assert.h"
34 #include "s_serv.h"
35 #include "s_conf.h"
36 #include "s_newconf.h"
37 #include "logger.h"
38 #include "hook.h"
39 #include "monitor.h"
40 #include "msgbuf.h"
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
45 #define CLIENT_CAPS_ONLY(x) ((IsClient((x)) && (x)->localClient) ? (x)->localClient->caps : 0)
46
47 static void send_queued_write(rb_fde_t *F, void *data);
48
49 unsigned long current_serial = 0L;
50
51 struct Client *remote_rehash_oper_p;
52
53 /* send_linebuf()
54 *
55 * inputs - client to send to, linebuf to attach
56 * outputs -
57 * side effects - linebuf is attached to client
58 */
59 static 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
71 if(rb_linebuf_len(&to->localClient->buf_sendq) > get_sendq(to))
72 {
73 dead_link(to, 1);
74
75 if(IsServer(to))
76 {
77 sendto_realops_snomask(SNO_GENERAL, L_NETWIDE,
78 "Max SendQ limit exceeded for %s: %u > %lu",
79 to->name,
80 rb_linebuf_len(&to->localClient->buf_sendq),
81 get_sendq(to));
82
83 ilog(L_SERVER, "Max SendQ limit exceeded for %s: %u > %lu",
84 log_client_name(to, SHOW_IP),
85 rb_linebuf_len(&to->localClient->buf_sendq),
86 get_sendq(to));
87 }
88
89 return -1;
90 }
91 else
92 {
93 /* just attach the linebuf to the sendq instead of
94 * generating a new one
95 */
96 rb_linebuf_attach(&to->localClient->buf_sendq, linebuf);
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;
106 if(rb_linebuf_len(&to->localClient->buf_sendq) > 0)
107 send_queued(to);
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 */
117 static void
118 send_linebuf_remote(struct Client *to, struct Client *from, buf_head_t *linebuf)
119 {
120 if(to->from)
121 to = to->from;
122
123 /* we assume the caller has already tested for fake direction */
124 _send_linebuf(to, linebuf);
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 */
133 void
134 send_queued(struct Client *to)
135 {
136 int retlen;
137
138 rb_fde_t *F = to->localClient->F;
139 if (!F)
140 return;
141
142 /* cant write anything to a dead socket. */
143 if(IsIOError(to))
144 return;
145
146 /* try to flush later when the write event resets this */
147 if(IsFlush(to))
148 return;
149
150 if(rb_linebuf_len(&to->localClient->buf_sendq))
151 {
152 while ((retlen =
153 rb_linebuf_flush(F, &to->localClient->buf_sendq)) > 0)
154 {
155 /* We have some data written .. update counters */
156 ClearFlush(to);
157
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
172 if(retlen == 0 || (retlen < 0 && !rb_ignore_errno(errno)))
173 {
174 dead_link(to, 0);
175 return;
176 }
177 }
178
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
186 ClearFlush(to);
187 }
188
189 void
190 send_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);
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 */
206 static void
207 send_queued_write(rb_fde_t *F, void *data)
208 {
209 struct Client *to = data;
210 ClearFlush(to);
211 send_queued(to);
212 }
213
214 /*
215 * linebuf_put_*
216 *
217 * inputs - msgbuf header, linebuf object, capability mask, pattern, arguments
218 * outputs - none
219 * side effects - the linebuf object is cleared, then populated
220 */
221 static void
222 linebuf_put_tags(buf_head_t *linebuf, const struct MsgBuf *msgbuf, const struct Client *target_p, rb_strf_t *message)
223 {
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 };
226
227 message->length = DATALEN + 1;
228 rb_linebuf_put(linebuf, &strings);
229 }
230
231 static void
232 linebuf_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
242 static void
243 linebuf_put_msg(buf_head_t *linebuf, rb_strf_t *message)
244 {
245 message->length = DATALEN + 1;
246 rb_linebuf_put(linebuf, message);
247 }
248
249 static void
250 linebuf_put_msgf(buf_head_t *linebuf, const rb_strf_t *message, const char *format, ...)
251 {
252 va_list va;
253 rb_strf_t strings = { .format = format, .format_args = &va, .next = message };
254
255 va_start(va, format);
256 linebuf_put_msg(linebuf, &strings);
257 va_end(va);
258 }
259
260 /* build_msgbuf_tags
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 */
267 static void
268 build_msgbuf_tags(struct MsgBuf *msgbuf, struct Client *from)
269 {
270 hook_data hdata;
271
272 msgbuf_init(msgbuf);
273
274 hdata.client = from;
275 hdata.arg1 = msgbuf;
276
277 call_hook(h_outbound_msgbuf, &hdata);
278 }
279
280 /* sendto_one()
281 *
282 * inputs - client to send to, va_args
283 * outputs - client has message put into its queue
284 * side effects -
285 */
286 void
287 sendto_one(struct Client *target_p, const char *pattern, ...)
288 {
289 va_list args;
290 struct MsgBuf msgbuf;
291 buf_head_t linebuf;
292 rb_strf_t strings = { .format = pattern, .format_args = &args, .next = NULL };
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
301 rb_linebuf_newbuf(&linebuf);
302
303 build_msgbuf_tags(&msgbuf, &me);
304 va_start(args, pattern);
305 linebuf_put_tags(&linebuf, &msgbuf, target_p, &strings);
306 va_end(args);
307
308 _send_linebuf(target_p, &linebuf);
309
310 rb_linebuf_donebuf(&linebuf);
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 */
319 void
320 sendto_one_prefix(struct Client *target_p, struct Client *source_p,
321 const char *command, const char *pattern, ...)
322 {
323 struct Client *dest_p = target_p->from;
324 va_list args;
325 struct MsgBuf msgbuf;
326 buf_head_t linebuf;
327 rb_strf_t strings = { .format = pattern, .format_args = &args, .next = NULL };
328
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
338 build_msgbuf_tags(&msgbuf, source_p);
339
340 rb_linebuf_newbuf(&linebuf);
341 va_start(args, pattern);
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));
345 va_end(args);
346
347 _send_linebuf(dest_p, &linebuf);
348 rb_linebuf_donebuf(&linebuf);
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 */
357 void
358 sendto_one_notice(struct Client *target_p, const char *pattern, ...)
359 {
360 struct Client *dest_p = target_p->from;
361 va_list args;
362 struct MsgBuf msgbuf;
363 buf_head_t linebuf;
364 rb_strf_t strings = { .format = pattern, .format_args = &args, .next = NULL };
365 char *to;
366
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
376 build_msgbuf_tags(&msgbuf, &me);
377
378 rb_linebuf_newbuf(&linebuf);
379 va_start(args, pattern);
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 : "*");
383 va_end(args);
384
385 _send_linebuf(dest_p, &linebuf);
386 rb_linebuf_donebuf(&linebuf);
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 */
396 void
397 sendto_one_numeric(struct Client *target_p, int numeric, const char *pattern, ...)
398 {
399 struct Client *dest_p = target_p->from;
400 va_list args;
401 struct MsgBuf msgbuf;
402 buf_head_t linebuf;
403 rb_strf_t strings = { .format = pattern, .format_args = &args, .next = NULL };
404 char *to;
405
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
415 build_msgbuf_tags(&msgbuf, &me);
416
417 rb_linebuf_newbuf(&linebuf);
418 va_start(args, pattern);
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 : "*");
422 va_end(args);
423
424 _send_linebuf(dest_p, &linebuf);
425 rb_linebuf_donebuf(&linebuf);
426 }
427
428 /*
429 * sendto_server
430 *
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'.
440 *
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 */
445 void
446 sendto_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;
451 rb_dlink_node *ptr;
452 rb_dlink_node *next_ptr;
453 buf_head_t linebuf;
454 rb_strf_t strings = { .format = format, .format_args = &args, .next = NULL };
455
456 /* noone to send to.. */
457 if(rb_dlink_list_length(&serv_list) == 0)
458 return;
459
460 if(chptr != NULL && *chptr->chname != '#')
461 return;
462
463 rb_linebuf_newbuf(&linebuf);
464 va_start(args, format);
465 linebuf_put_msg(&linebuf, &strings);
466 va_end(args);
467
468 RB_DLINK_FOREACH_SAFE(ptr, next_ptr, serv_list.head)
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
487 rb_linebuf_donebuf(&linebuf);
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 */
496 void
497 sendto_channel_flags(struct Client *one, int type, struct Client *source_p,
498 struct Channel *chptr, const char *pattern, ...)
499 {
500 static char buf[BUFSIZE];
501 va_list args;
502 buf_head_t rb_linebuf_remote;
503 struct Client *target_p;
504 struct membership *msptr;
505 rb_dlink_node *ptr;
506 rb_dlink_node *next_ptr;
507 struct MsgBuf msgbuf;
508 struct MsgBuf_cache msgbuf_cache;
509 rb_strf_t strings = { .format = buf, .format_args = NULL, .next = NULL };
510
511 rb_linebuf_newbuf(&rb_linebuf_remote);
512
513 current_serial++;
514
515 build_msgbuf_tags(&msgbuf, source_p);
516
517 va_start(args, pattern);
518 vsnprintf(buf, sizeof buf, pattern, args);
519 va_end(args);
520
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);
525
526 RB_DLINK_FOREACH_SAFE(ptr, next_ptr, chptr->members.head)
527 {
528 msptr = ptr->data;
529 target_p = msptr->client_p;
530
531 if(!MyClient(source_p) && (IsIOError(target_p->from) || target_p->from == one))
532 continue;
533
534 if(MyClient(source_p) && target_p == one)
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 {
553 send_linebuf_remote(target_p, source_p, &rb_linebuf_remote);
554 target_p->from->serial = current_serial;
555 }
556 }
557 else
558 {
559 _send_linebuf(target_p, msgbuf_cache_get(&msgbuf_cache, CLIENT_CAPS_ONLY(target_p)));
560 }
561 }
562
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
568 _send_linebuf(target_p, msgbuf_cache_get(&msgbuf_cache, CLIENT_CAPS_ONLY(target_p)));
569 }
570
571 rb_linebuf_donebuf(&rb_linebuf_remote);
572 msgbuf_cache_free(&msgbuf_cache);
573 }
574
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 */
581 void
582 sendto_channel_opmod(struct Client *one, struct Client *source_p,
583 struct Channel *chptr, const char *command,
584 const char *text)
585 {
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;
592 struct MsgBuf msgbuf;
593 struct MsgBuf_cache msgbuf_cache;
594 rb_strf_t strings = { .format = text, .format_args = NULL, .next = NULL };
595
596 rb_linebuf_newbuf(&rb_linebuf_old);
597 rb_linebuf_newbuf(&rb_linebuf_new);
598
599 build_msgbuf_tags(&msgbuf, source_p);
600
601 current_serial++;
602 const char *statusmsg_prefix = (ConfigChannel.opmod_send_statusmsg ? "@" : "");
603
604 if(IsServer(source_p)) {
605 msgbuf_cache_initf(&msgbuf_cache, &msgbuf, &strings,
606 ":%s %s %s%s :",
607 source_p->name, command, statusmsg_prefix, chptr->chname);
608 } else {
609 msgbuf_cache_initf(&msgbuf_cache, &msgbuf, &strings,
610 ":%s!%s@%s %s %s%s :",
611 source_p->name, source_p->username,
612 source_p->host, command, statusmsg_prefix, chptr->chname);
613 }
614
615 if (chptr->mode.mode & MODE_MODERATED) {
616 linebuf_put_msgf(&rb_linebuf_old, &strings,
617 ":%s %s %s%s :",
618 use_id(source_p), command, statusmsg_prefix, chptr->chname, text);
619 } else {
620 linebuf_put_msgf(&rb_linebuf_old, &strings,
621 ":%s NOTICE @%s :<%s:%s> ",
622 use_id(source_p->servptr), chptr->chname,
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);
628 RB_DLINK_FOREACH_SAFE(ptr, next_ptr, chptr->members.head)
629 {
630 msptr = ptr->data;
631 target_p = msptr->client_p;
632
633 if(!MyClient(source_p) && (IsIOError(target_p->from) || target_p->from == one))
634 continue;
635
636 if(MyClient(source_p) && target_p == one)
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 }
661 } else {
662 _send_linebuf(target_p, msgbuf_cache_get(&msgbuf_cache, CLIENT_CAPS_ONLY(target_p)));
663 }
664 }
665
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
671 _send_linebuf(target_p, msgbuf_cache_get(&msgbuf_cache, CLIENT_CAPS_ONLY(target_p)));
672 }
673
674 rb_linebuf_donebuf(&rb_linebuf_old);
675 rb_linebuf_donebuf(&rb_linebuf_new);
676 msgbuf_cache_free(&msgbuf_cache);
677 }
678
679 /* _sendto_channel_local
680 *
681 * inputs - source, flags to send to, privs to send to, channel to send to, va_args
682 * outputs - message to local channel members
683 * side effects -
684 */
685 void
686 _sendto_channel_local(struct Client *source_p, int type, const char *priv, struct Channel *chptr, const char *pattern, va_list *args)
687 {
688 struct membership *msptr;
689 struct Client *target_p;
690 rb_dlink_node *ptr;
691 rb_dlink_node *next_ptr;
692 struct MsgBuf msgbuf;
693 struct MsgBuf_cache msgbuf_cache;
694 rb_strf_t strings = { .format = pattern, .format_args = args, .next = NULL };
695
696 build_msgbuf_tags(&msgbuf, source_p);
697
698 msgbuf_cache_init(&msgbuf_cache, &msgbuf, &strings);
699
700 RB_DLINK_FOREACH_SAFE(ptr, next_ptr, chptr->locmembers.head)
701 {
702 msptr = ptr->data;
703 target_p = msptr->client_p;
704
705 if (IsIOError(target_p))
706 continue;
707
708 if (type && ((msptr->flags & type) == 0))
709 continue;
710
711 if (priv != NULL && !HasPrivilege(target_p, priv))
712 continue;
713
714 _send_linebuf(target_p, msgbuf_cache_get(&msgbuf_cache, CLIENT_CAPS_ONLY(target_p)));
715 }
716
717 msgbuf_cache_free(&msgbuf_cache);
718 }
719
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 */
726 void
727 sendto_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 */
741 void
742 sendto_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
750 /*
751 * _sendto_channel_local_with_capability_butone()
752 *
753 * Shared implementation of sendto_channel_local_with_capability and sendto_channel_local_with_capability_butone
754 */
755 static void
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)
758 {
759 struct membership *msptr;
760 struct Client *target_p;
761 rb_dlink_node *ptr;
762 rb_dlink_node *next_ptr;
763 struct MsgBuf msgbuf;
764 struct MsgBuf_cache msgbuf_cache;
765 rb_strf_t strings = { .format = pattern, .format_args = args, .next = NULL };
766
767 build_msgbuf_tags(&msgbuf, source_p);
768 msgbuf_cache_init(&msgbuf_cache, &msgbuf, &strings);
769
770 RB_DLINK_FOREACH_SAFE(ptr, next_ptr, chptr->locmembers.head)
771 {
772 msptr = ptr->data;
773 target_p = msptr->client_p;
774
775 if (target_p == one)
776 continue;
777
778 if(IsIOError(target_p) ||
779 !IsCapable(target_p, caps) ||
780 !NotCapable(target_p, negcaps))
781 continue;
782
783 if(type && ((msptr->flags & type) == 0))
784 continue;
785
786 _send_linebuf(target_p, msgbuf_cache_get(&msgbuf_cache, CLIENT_CAPS_ONLY(target_p)));
787 }
788
789 msgbuf_cache_free(&msgbuf_cache);
790 }
791
792 /* sendto_channel_local_with_capability()
793 *
794 * inputs - source, flags to send to, caps, negate caps, channel to send to, va_args
795 * outputs - message to local channel members
796 * side effects -
797 */
798 void
799 sendto_channel_local_with_capability(struct Client *source_p, int type, int caps, int negcaps, struct Channel *chptr, const char *pattern, ...)
800 {
801 va_list args;
802
803 va_start(args, pattern);
804 _sendto_channel_local_with_capability_butone(source_p, NULL, type, caps, negcaps, chptr, pattern, &args);
805 va_end(args);
806 }
807
808
809 /* sendto_channel_local_with_capability()
810 *
811 * inputs - source, flags to send to, caps, negate caps, channel to send to, va_args
812 * outputs - message to local channel members
813 * side effects -
814 */
815 void
816 sendto_channel_local_with_capability_butone(struct Client *one, int type,
817 int caps, int negcaps, struct Channel *chptr, const char *pattern, ...)
818 {
819 va_list args;
820
821 va_start(args, pattern);
822 _sendto_channel_local_with_capability_butone(one, one, type, caps, negcaps, chptr, pattern, &args);
823 va_end(args);
824 }
825
826
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 */
834 void
835 sendto_channel_local_butone(struct Client *one, int type, struct Channel *chptr, const char *pattern, ...)
836 {
837 va_list args;
838 struct membership *msptr;
839 struct Client *target_p;
840 struct MsgBuf msgbuf;
841 rb_dlink_node *ptr;
842 rb_dlink_node *next_ptr;
843 struct MsgBuf_cache msgbuf_cache;
844 rb_strf_t strings = { .format = pattern, .format_args = &args, .next = NULL };
845
846 build_msgbuf_tags(&msgbuf, one);
847
848 va_start(args, pattern);
849 msgbuf_cache_init(&msgbuf_cache, &msgbuf, &strings);
850 va_end(args);
851
852 RB_DLINK_FOREACH_SAFE(ptr, next_ptr, chptr->locmembers.head)
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
866 /* attach the present linebuf to the target */
867 _send_linebuf(target_p, msgbuf_cache_get(&msgbuf_cache, CLIENT_CAPS_ONLY(target_p)));
868 }
869
870 msgbuf_cache_free(&msgbuf_cache);
871 }
872
873 /*
874 * sendto_common_channels_local()
875 *
876 * inputs - pointer to client
877 * - capability mask
878 * - negated capability mask
879 * - pattern to send
880 * output - NONE
881 * side effects - Sends a message to all people on local server who are
882 * in same channel with user.
883 * used by m_nick.c and exit_one_client.
884 */
885 void
886 sendto_common_channels_local(struct Client *user, int cap, int negcap, const char *pattern, ...)
887 {
888 va_list args;
889 rb_dlink_node *ptr;
890 rb_dlink_node *next_ptr;
891 rb_dlink_node *uptr;
892 rb_dlink_node *next_uptr;
893 struct Channel *chptr;
894 struct Client *target_p;
895 struct membership *msptr;
896 struct membership *mscptr;
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);
902
903 va_start(args, pattern);
904 msgbuf_cache_init(&msgbuf_cache, &msgbuf, &strings);
905 va_end(args);
906
907 ++current_serial;
908
909 RB_DLINK_FOREACH_SAFE(ptr, next_ptr, user->user->channel.head)
910 {
911 mscptr = ptr->data;
912 chptr = mscptr->chptr;
913
914 RB_DLINK_FOREACH_SAFE(uptr, next_uptr, chptr->locmembers.head)
915 {
916 msptr = uptr->data;
917 target_p = msptr->client_p;
918
919 if(IsIOError(target_p) ||
920 target_p->serial == current_serial ||
921 !IsCapable(target_p, cap) ||
922 !NotCapable(target_p, negcap))
923 continue;
924
925 target_p->serial = current_serial;
926 send_linebuf(target_p, msgbuf_cache_get(&msgbuf_cache, CLIENT_CAPS_ONLY(target_p)));
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 */
933 if(MyConnect(user) && (user->serial != current_serial)
934 && IsCapable(user, cap) && NotCapable(user, negcap)) {
935 send_linebuf(user, msgbuf_cache_get(&msgbuf_cache, CLIENT_CAPS_ONLY(user)));
936 }
937
938 msgbuf_cache_free(&msgbuf_cache);
939 }
940
941 /*
942 * sendto_common_channels_local_butone()
943 *
944 * inputs - pointer to client
945 * - capability mask
946 * - negated capability mask
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 */
952 void
953 sendto_common_channels_local_butone(struct Client *user, int cap, int negcap, const char *pattern, ...)
954 {
955 va_list args;
956 rb_dlink_node *ptr;
957 rb_dlink_node *next_ptr;
958 rb_dlink_node *uptr;
959 rb_dlink_node *next_uptr;
960 struct Channel *chptr;
961 struct Client *target_p;
962 struct membership *msptr;
963 struct membership *mscptr;
964 struct MsgBuf msgbuf;
965 struct MsgBuf_cache msgbuf_cache;
966 rb_strf_t strings = { .format = pattern, .format_args = &args, .next = NULL };
967
968 build_msgbuf_tags(&msgbuf, user);
969
970 va_start(args, pattern);
971 msgbuf_cache_init(&msgbuf_cache, &msgbuf, &strings);
972 va_end(args);
973
974 ++current_serial;
975 /* Skip them -- jilles */
976 user->serial = current_serial;
977
978 RB_DLINK_FOREACH_SAFE(ptr, next_ptr, user->user->channel.head)
979 {
980 mscptr = ptr->data;
981 chptr = mscptr->chptr;
982
983 RB_DLINK_FOREACH_SAFE(uptr, next_uptr, chptr->locmembers.head)
984 {
985 msptr = uptr->data;
986 target_p = msptr->client_p;
987
988 if(IsIOError(target_p) ||
989 target_p->serial == current_serial ||
990 !IsCapable(target_p, cap) ||
991 !NotCapable(target_p, negcap))
992 continue;
993
994 target_p->serial = current_serial;
995 send_linebuf(target_p, msgbuf_cache_get(&msgbuf_cache, CLIENT_CAPS_ONLY(target_p)));
996 }
997 }
998
999 msgbuf_cache_free(&msgbuf_cache);
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 */
1008 void
1009 sendto_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;
1015 rb_dlink_node *ptr;
1016 rb_dlink_node *next_ptr;
1017 buf_head_t rb_linebuf_remote;
1018 struct MsgBuf msgbuf;
1019 struct MsgBuf_cache msgbuf_cache;
1020 rb_strf_t strings = { .format = buf, .format_args = NULL, .next = NULL };
1021
1022 rb_linebuf_newbuf(&rb_linebuf_remote);
1023
1024 build_msgbuf_tags(&msgbuf, source_p);
1025
1026 va_start(args, pattern);
1027 vsnprintf(buf, sizeof(buf), pattern, args);
1028 va_end(args);
1029
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);
1033
1034 linebuf_put_msgf(&rb_linebuf_remote, &strings, ":%s ", use_id(source_p));
1035
1036 if(what == MATCH_HOST)
1037 {
1038 RB_DLINK_FOREACH_SAFE(ptr, next_ptr, lclient_list.head)
1039 {
1040 target_p = ptr->data;
1041
1042 if(match(mask, target_p->host))
1043 _send_linebuf(target_p, msgbuf_cache_get(&msgbuf_cache, CLIENT_CAPS_ONLY(target_p)));
1044 }
1045 }
1046 /* what = MATCH_SERVER, if it doesnt match us, just send remote */
1047 else if(match(mask, me.name))
1048 {
1049 RB_DLINK_FOREACH_SAFE(ptr, next_ptr, lclient_list.head)
1050 {
1051 target_p = ptr->data;
1052 _send_linebuf(target_p, msgbuf_cache_get(&msgbuf_cache, CLIENT_CAPS_ONLY(target_p)));
1053 }
1054 }
1055
1056 RB_DLINK_FOREACH(ptr, serv_list.head)
1057 {
1058 target_p = ptr->data;
1059
1060 if(target_p == one)
1061 continue;
1062
1063 send_linebuf_remote(target_p, source_p, &rb_linebuf_remote);
1064 }
1065
1066 msgbuf_cache_free(&msgbuf_cache);
1067 rb_linebuf_donebuf(&rb_linebuf_remote);
1068 }
1069
1070 /* sendto_match_servs()
1071 *
1072 * inputs - source, mask to send to, caps needed, va_args
1073 * outputs -
1074 * side effects - message is sent to matching servers with caps.
1075 */
1076 void
1077 sendto_match_servs(struct Client *source_p, const char *mask, int cap,
1078 int nocap, const char *pattern, ...)
1079 {
1080 static char buf[BUFSIZE];
1081 va_list args;
1082 rb_dlink_node *ptr;
1083 struct Client *target_p;
1084 buf_head_t rb_linebuf_id;
1085 rb_strf_t strings = { .format = buf, .format_args = NULL, .next = NULL };
1086
1087 if(EmptyString(mask))
1088 return;
1089
1090 rb_linebuf_newbuf(&rb_linebuf_id);
1091
1092 va_start(args, pattern);
1093 vsnprintf(buf, sizeof(buf), pattern, args);
1094 va_end(args);
1095
1096 linebuf_put_msgf(&rb_linebuf_id, &strings, ":%s ", use_id(source_p));
1097
1098 current_serial++;
1099
1100 RB_DLINK_FOREACH(ptr, global_serv_list.head)
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
1124 _send_linebuf(target_p->from, &rb_linebuf_id);
1125 }
1126 }
1127
1128 rb_linebuf_donebuf(&rb_linebuf_id);
1129 }
1130
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 */
1137 void
1138 sendto_local_clients_with_capability(int cap, const char *pattern, ...)
1139 {
1140 va_list args;
1141 rb_dlink_node *ptr;
1142 struct Client *target_p;
1143 struct MsgBuf msgbuf;
1144 struct MsgBuf_cache msgbuf_cache;
1145 rb_strf_t strings = { .format = pattern, .format_args = &args, .next = NULL };
1146
1147 build_msgbuf_tags(&msgbuf, &me);
1148
1149 va_start(args, pattern);
1150 msgbuf_cache_init(&msgbuf_cache, &msgbuf, &strings);
1151 va_end(args);
1152
1153 RB_DLINK_FOREACH(ptr, lclient_list.head)
1154 {
1155 target_p = ptr->data;
1156
1157 if(IsIOError(target_p) || !IsCapable(target_p, cap))
1158 continue;
1159
1160 send_linebuf(target_p, msgbuf_cache_get(&msgbuf_cache, CLIENT_CAPS_ONLY(target_p)));
1161 }
1162
1163 msgbuf_cache_free(&msgbuf_cache);
1164 }
1165
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 */
1172 void
1173 sendto_monitor(struct Client *source_p, struct monitor *monptr, const char *pattern, ...)
1174 {
1175 va_list args;
1176 struct Client *target_p;
1177 rb_dlink_node *ptr;
1178 rb_dlink_node *next_ptr;
1179 struct MsgBuf msgbuf;
1180 struct MsgBuf_cache msgbuf_cache;
1181 rb_strf_t strings = { .format = pattern, .format_args = &args, .next = NULL };
1182
1183 build_msgbuf_tags(&msgbuf, source_p);
1184
1185 va_start(args, pattern);
1186 msgbuf_cache_init(&msgbuf_cache, &msgbuf, &strings);
1187 va_end(args);
1188
1189 RB_DLINK_FOREACH_SAFE(ptr, next_ptr, monptr->users.head)
1190 {
1191 target_p = ptr->data;
1192
1193 if(IsIOError(target_p))
1194 continue;
1195
1196 _send_linebuf(target_p, msgbuf_cache_get(&msgbuf_cache, CLIENT_CAPS_ONLY(target_p)));
1197 }
1198
1199 msgbuf_cache_free(&msgbuf_cache);
1200 }
1201
1202 /* _sendto_anywhere()
1203 *
1204 * inputs - real_target, target, source, va_args
1205 * outputs -
1206 * side effects - client is sent message/own message with correct prefix.
1207 */
1208 static void
1209 _sendto_anywhere(struct Client *dest_p, struct Client *target_p,
1210 struct Client *source_p, const char *command,
1211 const char *pattern, va_list *args)
1212 {
1213 buf_head_t linebuf;
1214 rb_strf_t strings = { .format = pattern, .format_args = args, .next = NULL };
1215
1216 rb_linebuf_newbuf(&linebuf);
1217
1218 if (MyClient(dest_p)) {
1219 if (IsServer(source_p)) {
1220 linebuf_put_msgf(&linebuf, &strings, ":%s %s %s ",
1221 source_p->name, command,
1222 target_p->name);
1223 } else {
1224 struct MsgBuf msgbuf;
1225
1226 build_msgbuf_tags(&msgbuf, source_p);
1227
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);
1232 }
1233
1234 _send_linebuf(dest_p, &linebuf);
1235 } else {
1236 linebuf_put_msgf(&linebuf, &strings, ":%s %s %s ",
1237 get_id(source_p, target_p), command,
1238 get_id(target_p, target_p));
1239
1240 send_linebuf_remote(dest_p, source_p, &linebuf);
1241 }
1242
1243 rb_linebuf_donebuf(&linebuf);
1244 }
1245
1246 /* sendto_anywhere()
1247 *
1248 * inputs - target, source, va_args
1249 * outputs -
1250 * side effects - client is sent message with correct prefix.
1251 */
1252 void
1253 sendto_anywhere(struct Client *target_p, struct Client *source_p,
1254 const char *command, const char *pattern, ...)
1255 {
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);
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 */
1269 void
1270 sendto_anywhere_echo(struct Client *target_p, struct Client *source_p,
1271 const char *command, const char *pattern, ...)
1272 {
1273 va_list args;
1274
1275 s_assert(MyClient(source_p));
1276 s_assert(!IsServer(source_p));
1277
1278 va_start(args, pattern);
1279 _sendto_anywhere(source_p, target_p, source_p, command, pattern, &args);
1280 va_end(args);
1281 }
1282
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 */
1289 void
1290 sendto_realops_snomask(int flags, int level, const char *pattern, ...)
1291 {
1292 static char buf[BUFSIZE];
1293 char *snobuf;
1294 struct Client *client_p;
1295 rb_dlink_node *ptr;
1296 rb_dlink_node *next_ptr;
1297 va_list args;
1298 struct MsgBuf msgbuf;
1299 struct MsgBuf_cache msgbuf_cache;
1300
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);
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 {
1315 snobuf = construct_snobuf(flags);
1316 if (snobuf[1] != '\0')
1317 sendto_server(NULL, NULL, CAP_ENCAP|CAP_TS6, NOCAPS,
1318 ":%s ENCAP * SNOTE %c :%s",
1319 me.id, snobuf[1], buf);
1320 }
1321 else if (remote_rehash_oper_p != NULL)
1322 {
1323 sendto_one_notice(remote_rehash_oper_p, ":*** Notice -- %s", buf);
1324 }
1325 level &= ~L_NETWIDE;
1326
1327 RB_DLINK_FOREACH_SAFE(ptr, next_ptr, local_oper_list.head)
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
1338 if (client_p->snomask & flags) {
1339 _send_linebuf(client_p, msgbuf_cache_get(&msgbuf_cache, CLIENT_CAPS_ONLY(client_p)));
1340 }
1341 }
1342
1343 msgbuf_cache_free(&msgbuf_cache);
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 */
1351 void
1352 sendto_realops_snomask_from(int flags, int level, struct Client *source_p,
1353 const char *pattern, ...)
1354 {
1355 struct Client *client_p;
1356 rb_dlink_node *ptr;
1357 rb_dlink_node *next_ptr;
1358 va_list args;
1359 struct MsgBuf msgbuf;
1360 struct MsgBuf_cache msgbuf_cache;
1361 rb_strf_t strings = { .format = pattern, .format_args = &args, .next = NULL };
1362
1363 build_msgbuf_tags(&msgbuf, &me);
1364
1365 va_start(args, pattern);
1366 msgbuf_cache_initf(&msgbuf_cache, &msgbuf, &strings,
1367 ":%s NOTICE * :*** Notice -- ", source_p->name);
1368 va_end(args);
1369
1370 RB_DLINK_FOREACH_SAFE(ptr, next_ptr, local_oper_list.head)
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
1381 if (client_p->snomask & flags) {
1382 _send_linebuf(client_p, msgbuf_cache_get(&msgbuf_cache, CLIENT_CAPS_ONLY(client_p)));
1383 }
1384 }
1385
1386 msgbuf_cache_free(&msgbuf_cache);
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 */
1398 void
1399 sendto_wallops_flags(int flags, struct Client *source_p, const char *pattern, ...)
1400 {
1401 struct Client *client_p;
1402 rb_dlink_node *ptr;
1403 rb_dlink_node *next_ptr;
1404 va_list args;
1405 struct MsgBuf msgbuf;
1406 struct MsgBuf_cache msgbuf_cache;
1407 rb_strf_t strings = { .format = pattern, .format_args = &args, .next = NULL };
1408
1409 build_msgbuf_tags(&msgbuf, source_p);
1410
1411 va_start(args, pattern);
1412 if (IsPerson(source_p)) {
1413 msgbuf_cache_initf(&msgbuf_cache, &msgbuf, &strings,
1414 ":%s!%s@%s WALLOPS :", source_p->name,
1415 source_p->username, source_p->host);
1416 } else {
1417 msgbuf_cache_initf(&msgbuf_cache, &msgbuf, &strings,
1418 ":%s WALLOPS :", source_p->name);
1419 }
1420 va_end(args);
1421
1422 RB_DLINK_FOREACH_SAFE(ptr, next_ptr, IsPerson(source_p) && flags == UMODE_WALLOP ? lclient_list.head : local_oper_list.head)
1423 {
1424 client_p = ptr->data;
1425
1426 if (client_p->umodes & flags) {
1427 _send_linebuf(client_p, msgbuf_cache_get(&msgbuf_cache, CLIENT_CAPS_ONLY(client_p)));
1428 }
1429 }
1430
1431 msgbuf_cache_free(&msgbuf_cache);
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 */
1440 void
1441 kill_client(struct Client *target_p, struct Client *diedie, const char *pattern, ...)
1442 {
1443 va_list args;
1444 buf_head_t linebuf;
1445 struct MsgBuf msgbuf;
1446 rb_strf_t strings = { .format = pattern, .format_args = &args, .next = NULL };
1447
1448 build_msgbuf_tags(&msgbuf, &me);
1449
1450 rb_linebuf_newbuf(&linebuf);
1451
1452 va_start(args, pattern);
1453 linebuf_put_tagsf(&linebuf, &msgbuf, target_p, &strings,
1454 ":%s KILL %s :", get_id(&me, target_p), get_id(diedie, target_p));
1455 va_end(args);
1456
1457 send_linebuf(target_p, &linebuf);
1458 rb_linebuf_donebuf(&linebuf);
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 */
1473 void
1474 kill_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;
1479 rb_dlink_node *ptr;
1480 rb_dlink_node *next_ptr;
1481 buf_head_t rb_linebuf_id;
1482 rb_strf_t strings = { .format = pattern, .format_args = &args, .next = NULL };
1483
1484 rb_linebuf_newbuf(&rb_linebuf_id);
1485
1486 va_start(args, pattern);
1487 linebuf_put_msgf(&rb_linebuf_id, &strings, ":%s KILL %s :%s",
1488 use_id(&me), use_id(target_p), buf);
1489 va_end(args);
1490
1491 RB_DLINK_FOREACH_SAFE(ptr, next_ptr, serv_list.head)
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
1502 _send_linebuf(client_p, &rb_linebuf_id);
1503 }
1504
1505 rb_linebuf_donebuf(&rb_linebuf_id);
1506 }
1507
1508 static struct Client *multiline_stashed_target_p;
1509 static char multiline_prefix[DATALEN+1]; /* allow for null termination */
1510 static int multiline_prefix_len;
1511 static char multiline_separator[2];
1512 static int multiline_separator_len;
1513 static char *multiline_item_start;
1514 static char *multiline_cur;
1515 static int multiline_cur_len;
1516 static int multiline_remote_pad;
1517
1518 bool
1519 send_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
1550 bool
1551 send_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
1575 enum multiline_item_result
1576 send_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
1626 bool
1627 send_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
1670 void
1671 send_multiline_reset(void)
1672 {
1673 multiline_stashed_target_p = NULL;
1674 }