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