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