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