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