]> jfr.im git - solanum.git/blame - ircd/send.c
free server_p->certfp, allocated in newconf.c
[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/* sendto_channel_flags()
489 *
490 * inputs - server not to send to, flags needed, source, channel, va_args
491 * outputs - message is sent to channel members
492 * side effects -
493 */
494void
495sendto_channel_flags(struct Client *one, int type, struct Client *source_p,
496 struct Channel *chptr, const char *pattern, ...)
497{
82236a2a 498 char buf[BUFSIZE];
212380e3 499 va_list args;
3b2ebd04 500 buf_head_t rb_linebuf_local;
3b2ebd04 501 buf_head_t rb_linebuf_id;
212380e3
AC
502 struct Client *target_p;
503 struct membership *msptr;
330fc5c1 504 rb_dlink_node *ptr;
637c4932 505 rb_dlink_node *next_ptr;
66769bc1 506 int current_capmask = 0;
667fb62e 507 struct MsgBuf msgbuf;
212380e3 508
3b2ebd04 509 rb_linebuf_newbuf(&rb_linebuf_local);
3b2ebd04 510 rb_linebuf_newbuf(&rb_linebuf_id);
212380e3
AC
511
512 current_serial++;
513
667fb62e 514 build_msgbuf_from(&msgbuf, source_p, NULL);
212380e3 515
667fb62e 516 va_start(args, pattern);
c8c3ac24
AC
517 vsnprintf(buf, sizeof buf, pattern, args);
518 va_end(args);
212380e3 519
c8c3ac24
AC
520 linebuf_put_msgbuf(&msgbuf, &rb_linebuf_local, NOCAPS, "%s", buf);
521 rb_linebuf_putmsg(&rb_linebuf_id, NULL, NULL, ":%s %s", use_id(source_p), buf);
212380e3 522
637c4932 523 RB_DLINK_FOREACH_SAFE(ptr, next_ptr, chptr->members.head)
212380e3
AC
524 {
525 msptr = ptr->data;
526 target_p = msptr->client_p;
527
be2ce24c
AC
528 if(!MyClient(source_p) && (IsIOError(target_p->from) || target_p->from == one))
529 continue;
530
531 if(MyClient(source_p) && !IsCapable(source_p, CLICAP_ECHO_MESSAGE) && target_p == one)
212380e3
AC
532 continue;
533
534 if(type && ((msptr->flags & type) == 0))
535 continue;
536
537 if(IsDeaf(target_p))
538 continue;
539
540 if(!MyClient(target_p))
541 {
542 /* if we've got a specific type, target must support
543 * CHW.. --fl
544 */
545 if(type && NotCapable(target_p->from, CAP_CHW))
546 continue;
547
548 if(target_p->from->serial != current_serial)
549 {
ba301eff 550 send_linebuf_remote(target_p, source_p, &rb_linebuf_id);
212380e3
AC
551 target_p->from->serial = current_serial;
552 }
553 }
554 else
667fb62e
AC
555 {
556 if (target_p->localClient->caps != current_capmask)
557 {
558 /* reset the linebuf */
559 rb_linebuf_donebuf(&rb_linebuf_local);
560 rb_linebuf_newbuf(&rb_linebuf_local);
561
562 /* render the new linebuf and attach it */
c8c3ac24 563 linebuf_put_msgbuf(&msgbuf, &rb_linebuf_local, target_p->localClient->caps, "%s", buf);
667fb62e
AC
564 current_capmask = target_p->localClient->caps;
565 }
566
3b2ebd04 567 _send_linebuf(target_p, &rb_linebuf_local);
667fb62e 568 }
212380e3
AC
569 }
570
3b2ebd04 571 rb_linebuf_donebuf(&rb_linebuf_local);
3b2ebd04 572 rb_linebuf_donebuf(&rb_linebuf_id);
212380e3
AC
573}
574
c4d2d014
JT
575/* sendto_channel_flags()
576 *
577 * inputs - server not to send to, flags needed, source, channel, va_args
578 * outputs - message is sent to channel members
579 * side effects -
580 */
581void
582sendto_channel_opmod(struct Client *one, struct Client *source_p,
583 struct Channel *chptr, const char *command,
584 const char *text)
585{
c4d2d014
JT
586 buf_head_t rb_linebuf_local;
587 buf_head_t rb_linebuf_old;
588 buf_head_t rb_linebuf_new;
589 struct Client *target_p;
590 struct membership *msptr;
591 rb_dlink_node *ptr;
592 rb_dlink_node *next_ptr;
593
594 rb_linebuf_newbuf(&rb_linebuf_local);
595 rb_linebuf_newbuf(&rb_linebuf_old);
596 rb_linebuf_newbuf(&rb_linebuf_new);
597
598 current_serial++;
599
600 if(IsServer(source_p))
601 rb_linebuf_putmsg(&rb_linebuf_local, NULL, NULL,
602 ":%s %s %s :%s",
603 source_p->name, command, chptr->chname, text);
604 else
605 rb_linebuf_putmsg(&rb_linebuf_local, NULL, NULL,
606 ":%s!%s@%s %s %s :%s",
55abcbb2 607 source_p->name, source_p->username,
c4d2d014
JT
608 source_p->host, command, chptr->chname, text);
609
610 if (chptr->mode.mode & MODE_MODERATED)
611 rb_linebuf_putmsg(&rb_linebuf_old, NULL, NULL,
612 ":%s %s %s :%s",
613 use_id(source_p), command, chptr->chname, text);
614 else
615 rb_linebuf_putmsg(&rb_linebuf_old, NULL, NULL,
616 ":%s NOTICE @%s :<%s:%s> %s",
617 use_id(source_p->servptr), chptr->chname,
618 source_p->name, chptr->chname, text);
619 rb_linebuf_putmsg(&rb_linebuf_new, NULL, NULL,
620 ":%s %s =%s :%s",
621 use_id(source_p), command, chptr->chname, text);
622
623 RB_DLINK_FOREACH_SAFE(ptr, next_ptr, chptr->members.head)
624 {
625 msptr = ptr->data;
626 target_p = msptr->client_p;
627
be2ce24c
AC
628 if(!MyClient(source_p) && (IsIOError(target_p->from) || target_p->from == one))
629 continue;
630
631 if(MyClient(source_p) && !IsCapable(source_p, CLICAP_ECHO_MESSAGE) && target_p == one)
c4d2d014
JT
632 continue;
633
634 if((msptr->flags & CHFL_CHANOP) == 0)
635 continue;
636
637 if(IsDeaf(target_p))
638 continue;
639
640 if(!MyClient(target_p))
641 {
642 /* if we've got a specific type, target must support
643 * CHW.. --fl
644 */
645 if(NotCapable(target_p->from, CAP_CHW))
646 continue;
647
648 if(target_p->from->serial != current_serial)
649 {
650 if (IsCapable(target_p->from, CAP_EOPMOD))
651 send_linebuf_remote(target_p, source_p, &rb_linebuf_new);
652 else
653 send_linebuf_remote(target_p, source_p, &rb_linebuf_old);
654 target_p->from->serial = current_serial;
655 }
656 }
657 else
658 _send_linebuf(target_p, &rb_linebuf_local);
659 }
660
661 rb_linebuf_donebuf(&rb_linebuf_local);
662 rb_linebuf_donebuf(&rb_linebuf_old);
663 rb_linebuf_donebuf(&rb_linebuf_new);
664}
212380e3
AC
665
666/* sendto_channel_local()
667 *
668 * inputs - flags to send to, channel to send to, va_args
669 * outputs - message to local channel members
670 * side effects -
671 */
672void
673sendto_channel_local(int type, struct Channel *chptr, const char *pattern, ...)
674{
675 va_list args;
676 buf_head_t linebuf;
677 struct membership *msptr;
678 struct Client *target_p;
330fc5c1 679 rb_dlink_node *ptr;
637c4932 680 rb_dlink_node *next_ptr;
55abcbb2
KB
681
682 rb_linebuf_newbuf(&linebuf);
683
212380e3 684 va_start(args, pattern);
3b2ebd04 685 rb_linebuf_putmsg(&linebuf, pattern, &args, NULL);
212380e3
AC
686 va_end(args);
687
637c4932 688 RB_DLINK_FOREACH_SAFE(ptr, next_ptr, chptr->locmembers.head)
212380e3
AC
689 {
690 msptr = ptr->data;
691 target_p = msptr->client_p;
692
693 if(IsIOError(target_p))
694 continue;
695
be29ec79
AC
696 if(type == ONLY_OPERS)
697 {
698 if (!IsOper(target_p))
699 continue;
700 }
701 else if(type && ((msptr->flags & type) == 0))
212380e3
AC
702 continue;
703
704 _send_linebuf(target_p, &linebuf);
99cca61e
AC
705 }
706
707 rb_linebuf_donebuf(&linebuf);
708}
709
a695b0e4
SB
710/*
711 * _sendto_channel_local_with_capability_butone()
99cca61e 712 *
a695b0e4 713 * Shared implementation of sendto_channel_local_with_capability and sendto_channel_local_with_capability_butone
99cca61e 714 */
a695b0e4
SB
715static void
716_sendto_channel_local_with_capability_butone(struct Client *one, int type, int caps, int negcaps, struct Channel *chptr,
717 const char *pattern, va_list * args)
99cca61e 718{
99cca61e
AC
719 buf_head_t linebuf;
720 struct membership *msptr;
721 struct Client *target_p;
722 rb_dlink_node *ptr;
723 rb_dlink_node *next_ptr;
55abcbb2 724
a695b0e4
SB
725 rb_linebuf_newbuf(&linebuf);
726 rb_linebuf_putmsg(&linebuf, pattern, args, NULL);
55abcbb2 727
99cca61e
AC
728 RB_DLINK_FOREACH_SAFE(ptr, next_ptr, chptr->locmembers.head)
729 {
730 msptr = ptr->data;
731 target_p = msptr->client_p;
732
a695b0e4
SB
733 if (target_p == one)
734 continue;
735
99cca61e
AC
736 if(IsIOError(target_p) ||
737 !IsCapable(target_p, caps) ||
e2b507ac 738 !NotCapable(target_p, negcaps))
99cca61e
AC
739 continue;
740
741 if(type && ((msptr->flags & type) == 0))
742 continue;
743
744 _send_linebuf(target_p, &linebuf);
212380e3
AC
745 }
746
3b2ebd04 747 rb_linebuf_donebuf(&linebuf);
212380e3
AC
748}
749
a695b0e4
SB
750/* sendto_channel_local_with_capability()
751 *
752 * inputs - flags to send to, caps, negate caps, channel to send to, va_args
753 * outputs - message to local channel members
754 * side effects -
755 */
756void
757sendto_channel_local_with_capability(int type, int caps, int negcaps, struct Channel *chptr, const char *pattern, ...)
758{
759 va_list args;
760
761 va_start(args, pattern);
762 _sendto_channel_local_with_capability_butone(NULL, type, caps, negcaps, chptr, pattern, &args);
763 va_end(args);
764}
765
766
767/* sendto_channel_local_with_capability()
768 *
769 * inputs - flags to send to, caps, negate caps, channel to send to, va_args
770 * outputs - message to local channel members
771 * side effects -
772 */
773void
774sendto_channel_local_with_capability_butone(struct Client *one, int type, int caps, int negcaps, struct Channel *chptr,
775 const char *pattern, ...)
776{
777 va_list args;
778
779 va_start(args, pattern);
780 _sendto_channel_local_with_capability_butone(one, type, caps, negcaps, chptr, pattern, &args);
781 va_end(args);
782}
783
784
212380e3
AC
785/* sendto_channel_local_butone()
786 *
787 * inputs - flags to send to, channel to send to, va_args
788 * - user to ignore when sending
789 * outputs - message to local channel members
790 * side effects -
791 */
792void
793sendto_channel_local_butone(struct Client *one, int type, struct Channel *chptr, const char *pattern, ...)
794{
795 va_list args;
796 buf_head_t linebuf;
797 struct membership *msptr;
798 struct Client *target_p;
5559c3cf 799 struct MsgBuf msgbuf;
330fc5c1 800 rb_dlink_node *ptr;
637c4932 801 rb_dlink_node *next_ptr;
55abcbb2
KB
802
803 rb_linebuf_newbuf(&linebuf);
804
5559c3cf
AC
805 build_msgbuf_from(&msgbuf, one, NULL);
806
212380e3 807 va_start(args, pattern);
3b2ebd04 808 rb_linebuf_putmsg(&linebuf, pattern, &args, NULL);
474f6342 809 va_end(args);
212380e3 810
637c4932 811 RB_DLINK_FOREACH_SAFE(ptr, next_ptr, chptr->locmembers.head)
212380e3
AC
812 {
813 msptr = ptr->data;
814 target_p = msptr->client_p;
815
816 if(target_p == one)
817 continue;
818
819 if(IsIOError(target_p))
820 continue;
821
822 if(type && ((msptr->flags & type) == 0))
823 continue;
824
5559c3cf 825 /* attach the present linebuf to the target */
212380e3
AC
826 _send_linebuf(target_p, &linebuf);
827 }
828
3b2ebd04 829 rb_linebuf_donebuf(&linebuf);
212380e3
AC
830}
831
832/*
833 * sendto_common_channels_local()
834 *
835 * inputs - pointer to client
7a948bda 836 * - capability mask
583f064f 837 * - negated capability mask
212380e3
AC
838 * - pattern to send
839 * output - NONE
840 * side effects - Sends a message to all people on local server who are
55abcbb2 841 * in same channel with user.
212380e3
AC
842 * used by m_nick.c and exit_one_client.
843 */
844void
583f064f 845sendto_common_channels_local(struct Client *user, int cap, int negcap, const char *pattern, ...)
212380e3
AC
846{
847 va_list args;
330fc5c1 848 rb_dlink_node *ptr;
637c4932 849 rb_dlink_node *next_ptr;
330fc5c1
AC
850 rb_dlink_node *uptr;
851 rb_dlink_node *next_uptr;
212380e3
AC
852 struct Channel *chptr;
853 struct Client *target_p;
854 struct membership *msptr;
855 struct membership *mscptr;
856 buf_head_t linebuf;
857
3b2ebd04 858 rb_linebuf_newbuf(&linebuf);
212380e3 859 va_start(args, pattern);
3b2ebd04 860 rb_linebuf_putmsg(&linebuf, pattern, &args, NULL);
212380e3
AC
861 va_end(args);
862
863 ++current_serial;
864
637c4932 865 RB_DLINK_FOREACH_SAFE(ptr, next_ptr, user->user->channel.head)
212380e3
AC
866 {
867 mscptr = ptr->data;
868 chptr = mscptr->chptr;
869
5cefa1d6 870 RB_DLINK_FOREACH_SAFE(uptr, next_uptr, chptr->locmembers.head)
212380e3
AC
871 {
872 msptr = uptr->data;
873 target_p = msptr->client_p;
874
875 if(IsIOError(target_p) ||
7a948bda 876 target_p->serial == current_serial ||
583f064f
AC
877 !IsCapable(target_p, cap) ||
878 !NotCapable(target_p, negcap))
212380e3
AC
879 continue;
880
881 target_p->serial = current_serial;
882 send_linebuf(target_p, &linebuf);
883 }
884 }
885
886 /* this can happen when the user isnt in any channels, but we still
887 * need to send them the data, ie a nick change
888 */
889 if(MyConnect(user) && (user->serial != current_serial))
890 send_linebuf(user, &linebuf);
891
3b2ebd04 892 rb_linebuf_donebuf(&linebuf);
212380e3
AC
893}
894
895/*
896 * sendto_common_channels_local_butone()
897 *
898 * inputs - pointer to client
7a948bda 899 * - capability mask
583f064f 900 * - negated capability mask
212380e3
AC
901 * - pattern to send
902 * output - NONE
903 * side effects - Sends a message to all people on local server who are
904 * in same channel with user, except for user itself.
905 */
906void
583f064f 907sendto_common_channels_local_butone(struct Client *user, int cap, int negcap, const char *pattern, ...)
212380e3
AC
908{
909 va_list args;
330fc5c1 910 rb_dlink_node *ptr;
637c4932 911 rb_dlink_node *next_ptr;
330fc5c1
AC
912 rb_dlink_node *uptr;
913 rb_dlink_node *next_uptr;
212380e3
AC
914 struct Channel *chptr;
915 struct Client *target_p;
916 struct membership *msptr;
917 struct membership *mscptr;
918 buf_head_t linebuf;
919
3b2ebd04 920 rb_linebuf_newbuf(&linebuf);
5559c3cf 921
212380e3 922 va_start(args, pattern);
3b2ebd04 923 rb_linebuf_putmsg(&linebuf, pattern, &args, NULL);
212380e3
AC
924 va_end(args);
925
926 ++current_serial;
927 /* Skip them -- jilles */
928 user->serial = current_serial;
929
637c4932 930 RB_DLINK_FOREACH_SAFE(ptr, next_ptr, user->user->channel.head)
212380e3
AC
931 {
932 mscptr = ptr->data;
933 chptr = mscptr->chptr;
934
5cefa1d6 935 RB_DLINK_FOREACH_SAFE(uptr, next_uptr, chptr->locmembers.head)
212380e3
AC
936 {
937 msptr = uptr->data;
938 target_p = msptr->client_p;
939
940 if(IsIOError(target_p) ||
7a948bda 941 target_p->serial == current_serial ||
583f064f
AC
942 !IsCapable(target_p, cap) ||
943 !NotCapable(target_p, negcap))
212380e3
AC
944 continue;
945
946 target_p->serial = current_serial;
947 send_linebuf(target_p, &linebuf);
948 }
949 }
950
3b2ebd04 951 rb_linebuf_donebuf(&linebuf);
212380e3
AC
952}
953
954/* sendto_match_butone()
955 *
956 * inputs - server not to send to, source, mask, type of mask, va_args
957 * output -
958 * side effects - message is sent to matching clients
959 */
960void
961sendto_match_butone(struct Client *one, struct Client *source_p,
962 const char *mask, int what, const char *pattern, ...)
963{
964 static char buf[BUFSIZE];
965 va_list args;
966 struct Client *target_p;
330fc5c1 967 rb_dlink_node *ptr;
637c4932 968 rb_dlink_node *next_ptr;
3b2ebd04 969 buf_head_t rb_linebuf_local;
3b2ebd04 970 buf_head_t rb_linebuf_id;
212380e3 971
3b2ebd04 972 rb_linebuf_newbuf(&rb_linebuf_local);
3b2ebd04 973 rb_linebuf_newbuf(&rb_linebuf_id);
212380e3
AC
974
975 va_start(args, pattern);
5203cba5 976 vsnprintf(buf, sizeof(buf), pattern, args);
212380e3
AC
977 va_end(args);
978
979 if(IsServer(source_p))
3b2ebd04 980 rb_linebuf_putmsg(&rb_linebuf_local, NULL, NULL,
212380e3
AC
981 ":%s %s", source_p->name, buf);
982 else
3b2ebd04 983 rb_linebuf_putmsg(&rb_linebuf_local, NULL, NULL,
212380e3 984 ":%s!%s@%s %s",
55abcbb2 985 source_p->name, source_p->username,
212380e3
AC
986 source_p->host, buf);
987
3b2ebd04 988 rb_linebuf_putmsg(&rb_linebuf_id, NULL, NULL, ":%s %s", use_id(source_p), buf);
212380e3
AC
989
990 if(what == MATCH_HOST)
991 {
637c4932 992 RB_DLINK_FOREACH_SAFE(ptr, next_ptr, lclient_list.head)
212380e3
AC
993 {
994 target_p = ptr->data;
995
996 if(match(mask, target_p->host))
3b2ebd04 997 _send_linebuf(target_p, &rb_linebuf_local);
212380e3
AC
998 }
999 }
1000 /* what = MATCH_SERVER, if it doesnt match us, just send remote */
1001 else if(match(mask, me.name))
1002 {
637c4932 1003 RB_DLINK_FOREACH_SAFE(ptr, next_ptr, lclient_list.head)
212380e3
AC
1004 {
1005 target_p = ptr->data;
3b2ebd04 1006 _send_linebuf(target_p, &rb_linebuf_local);
212380e3
AC
1007 }
1008 }
1009
5cefa1d6 1010 RB_DLINK_FOREACH(ptr, serv_list.head)
212380e3
AC
1011 {
1012 target_p = ptr->data;
1013
1014 if(target_p == one)
1015 continue;
1016
ba301eff 1017 send_linebuf_remote(target_p, source_p, &rb_linebuf_id);
212380e3
AC
1018 }
1019
3b2ebd04
JT
1020 rb_linebuf_donebuf(&rb_linebuf_local);
1021 rb_linebuf_donebuf(&rb_linebuf_id);
212380e3
AC
1022}
1023
1024/* sendto_match_servs()
1025 *
1026 * inputs - source, mask to send to, caps needed, va_args
55abcbb2 1027 * outputs -
212380e3
AC
1028 * side effects - message is sent to matching servers with caps.
1029 */
1030void
55abcbb2 1031sendto_match_servs(struct Client *source_p, const char *mask, int cap,
212380e3
AC
1032 int nocap, const char *pattern, ...)
1033{
1034 static char buf[BUFSIZE];
1035 va_list args;
330fc5c1 1036 rb_dlink_node *ptr;
212380e3 1037 struct Client *target_p;
3b2ebd04 1038 buf_head_t rb_linebuf_id;
212380e3
AC
1039
1040 if(EmptyString(mask))
1041 return;
1042
3b2ebd04 1043 rb_linebuf_newbuf(&rb_linebuf_id);
212380e3
AC
1044
1045 va_start(args, pattern);
5203cba5 1046 vsnprintf(buf, sizeof(buf), pattern, args);
212380e3
AC
1047 va_end(args);
1048
55abcbb2 1049 rb_linebuf_putmsg(&rb_linebuf_id, NULL, NULL,
212380e3 1050 ":%s %s", use_id(source_p), buf);
212380e3
AC
1051
1052 current_serial++;
1053
5cefa1d6 1054 RB_DLINK_FOREACH(ptr, global_serv_list.head)
212380e3
AC
1055 {
1056 target_p = ptr->data;
1057
1058 /* dont send to ourselves, or back to where it came from.. */
1059 if(IsMe(target_p) || target_p->from == source_p->from)
1060 continue;
1061
1062 if(target_p->from->serial == current_serial)
1063 continue;
1064
1065 if(match(mask, target_p->name))
1066 {
1067 /* if we set the serial here, then we'll never do
1068 * a match() again if !IsCapable()
1069 */
1070 target_p->from->serial = current_serial;
1071
1072 if(cap && !IsCapable(target_p->from, cap))
1073 continue;
1074
1075 if(nocap && !NotCapable(target_p->from, nocap))
1076 continue;
1077
ba301eff 1078 _send_linebuf(target_p->from, &rb_linebuf_id);
212380e3
AC
1079 }
1080 }
1081
3b2ebd04 1082 rb_linebuf_donebuf(&rb_linebuf_id);
212380e3
AC
1083}
1084
984d80c9
AC
1085/* sendto_local_clients_with_capability()
1086 *
1087 * inputs - caps needed, pattern, va_args
1088 * outputs -
1089 * side effects - message is sent to matching local clients with caps.
1090 */
1091void
1092sendto_local_clients_with_capability(int cap, const char *pattern, ...)
1093{
1094 va_list args;
1095 rb_dlink_node *ptr;
1096 struct Client *target_p;
1097 buf_head_t linebuf;
1098
1099 rb_linebuf_newbuf(&linebuf);
1100
1101 va_start(args, pattern);
1102 rb_linebuf_putmsg(&linebuf, pattern, &args, NULL);
1103 va_end(args);
1104
984d80c9
AC
1105 RB_DLINK_FOREACH(ptr, lclient_list.head)
1106 {
1107 target_p = ptr->data;
1108
bed692ca 1109 if(IsIOError(target_p) || !IsCapable(target_p, cap))
984d80c9
AC
1110 continue;
1111
984d80c9
AC
1112 send_linebuf(target_p, &linebuf);
1113 }
1114
1115 rb_linebuf_donebuf(&linebuf);
1116}
1117
8aba962d
JT
1118/* sendto_monitor()
1119 *
1120 * inputs - monitor nick to send to, format, va_args
1121 * outputs - message to local users monitoring the given nick
1122 * side effects -
1123 */
1124void
1125sendto_monitor(struct monitor *monptr, const char *pattern, ...)
1126{
1127 va_list args;
1128 buf_head_t linebuf;
1129 struct Client *target_p;
330fc5c1 1130 rb_dlink_node *ptr;
637c4932 1131 rb_dlink_node *next_ptr;
55abcbb2
KB
1132
1133 rb_linebuf_newbuf(&linebuf);
1134
8aba962d 1135 va_start(args, pattern);
3b2ebd04 1136 rb_linebuf_putmsg(&linebuf, pattern, &args, NULL);
8aba962d
JT
1137 va_end(args);
1138
637c4932 1139 RB_DLINK_FOREACH_SAFE(ptr, next_ptr, monptr->users.head)
8aba962d
JT
1140 {
1141 target_p = ptr->data;
1142
1143 if(IsIOError(target_p))
1144 continue;
1145
1146 _send_linebuf(target_p, &linebuf);
1147 }
1148
3b2ebd04 1149 rb_linebuf_donebuf(&linebuf);
8aba962d
JT
1150}
1151
212380e3
AC
1152/* sendto_anywhere()
1153 *
1154 * inputs - target, source, va_args
1155 * outputs -
1156 * side effects - client is sent message with correct prefix.
1157 */
1158void
55abcbb2 1159sendto_anywhere(struct Client *target_p, struct Client *source_p,
212380e3
AC
1160 const char *command, const char *pattern, ...)
1161{
1162 va_list args;
1163 buf_head_t linebuf;
1164
adaa9ba9
AC
1165 rb_linebuf_newbuf(&linebuf);
1166
212380e3
AC
1167 va_start(args, pattern);
1168
1169 if(MyClient(target_p))
1170 {
1171 if(IsServer(source_p))
3b2ebd04 1172 rb_linebuf_putmsg(&linebuf, pattern, &args, ":%s %s %s ",
55abcbb2 1173 source_p->name, command,
212380e3
AC
1174 target_p->name);
1175 else
5559c3cf
AC
1176 {
1177 struct MsgBuf msgbuf;
1178
1179 build_msgbuf_from(&msgbuf, source_p, command);
f2003b44
AC
1180 msgbuf.target = target_p->name;
1181
5559c3cf
AC
1182 linebuf_put_msgvbuf(&msgbuf, &linebuf, target_p->localClient->caps, pattern, &args);
1183 }
212380e3
AC
1184 }
1185 else
3b2ebd04 1186 rb_linebuf_putmsg(&linebuf, pattern, &args, ":%s %s %s ",
212380e3
AC
1187 get_id(source_p, target_p), command,
1188 get_id(target_p, target_p));
1189 va_end(args);
1190
1191 if(MyClient(target_p))
1192 _send_linebuf(target_p, &linebuf);
1193 else
1194 send_linebuf_remote(target_p, source_p, &linebuf);
1195
3b2ebd04 1196 rb_linebuf_donebuf(&linebuf);
212380e3
AC
1197}
1198
212380e3
AC
1199/* sendto_realops_snomask()
1200 *
1201 * inputs - snomask needed, level (opers/admin), va_args
1202 * output -
1203 * side effects - message is sent to opers with matching snomasks
1204 */
1205void
1206sendto_realops_snomask(int flags, int level, const char *pattern, ...)
1207{
1208 static char buf[BUFSIZE];
1209 char *snobuf;
1210 struct Client *client_p;
330fc5c1 1211 rb_dlink_node *ptr;
637c4932 1212 rb_dlink_node *next_ptr;
212380e3
AC
1213 va_list args;
1214 buf_head_t linebuf;
1215
3b2ebd04 1216 rb_linebuf_newbuf(&linebuf);
212380e3
AC
1217
1218 /* Be very sure not to do things like "Trying to send to myself"
1219 * L_NETWIDE, otherwise infinite recursion may result! -- jilles */
1220 if (level & L_NETWIDE && ConfigFileEntry.global_snotices)
1221 {
1222 /* rather a lot of copying around, oh well -- jilles */
1223 va_start(args, pattern);
5203cba5 1224 vsnprintf(buf, sizeof(buf), pattern, args);
212380e3 1225 va_end(args);
55abcbb2 1226 rb_linebuf_putmsg(&linebuf, pattern, NULL,
212380e3
AC
1227 ":%s NOTICE * :*** Notice -- %s", me.name, buf);
1228 snobuf = construct_snobuf(flags);
1229 if (snobuf[1] != '\0')
212380e3
AC
1230 sendto_server(NULL, NULL, CAP_ENCAP|CAP_TS6, NOCAPS,
1231 ":%s ENCAP * SNOTE %c :%s",
1232 me.id, snobuf[1], buf);
212380e3 1233 }
ad13bb75
JT
1234 else if (remote_rehash_oper_p != NULL)
1235 {
1236 /* rather a lot of copying around, oh well -- jilles */
1237 va_start(args, pattern);
5203cba5 1238 vsnprintf(buf, sizeof(buf), pattern, args);
ad13bb75 1239 va_end(args);
55abcbb2 1240 rb_linebuf_putmsg(&linebuf, pattern, NULL,
ad13bb75
JT
1241 ":%s NOTICE * :*** Notice -- %s", me.name, buf);
1242 sendto_one_notice(remote_rehash_oper_p, ":*** Notice -- %s", buf);
1243 }
212380e3
AC
1244 else
1245 {
1246 va_start(args, pattern);
55abcbb2 1247 rb_linebuf_putmsg(&linebuf, pattern, &args,
212380e3
AC
1248 ":%s NOTICE * :*** Notice -- ", me.name);
1249 va_end(args);
1250 }
1251 level &= ~L_NETWIDE;
1252
637c4932 1253 RB_DLINK_FOREACH_SAFE(ptr, next_ptr, local_oper_list.head)
212380e3
AC
1254 {
1255 client_p = ptr->data;
1256
1257 /* If we're sending it to opers and theyre an admin, skip.
1258 * If we're sending it to admins, and theyre not, skip.
1259 */
1260 if(((level == L_ADMIN) && !IsOperAdmin(client_p)) ||
1261 ((level == L_OPER) && IsOperAdmin(client_p)))
1262 continue;
1263
1264 if(client_p->snomask & flags)
1265 _send_linebuf(client_p, &linebuf);
1266 }
1267
3b2ebd04 1268 rb_linebuf_donebuf(&linebuf);
212380e3
AC
1269}
1270/* sendto_realops_snomask_from()
1271 *
1272 * inputs - snomask needed, level (opers/admin), source server, va_args
1273 * output -
1274 * side effects - message is sent to opers with matching snomask
1275 */
1276void
1277sendto_realops_snomask_from(int flags, int level, struct Client *source_p,
1278 const char *pattern, ...)
1279{
1280 struct Client *client_p;
330fc5c1 1281 rb_dlink_node *ptr;
637c4932 1282 rb_dlink_node *next_ptr;
212380e3
AC
1283 va_list args;
1284 buf_head_t linebuf;
1285
3b2ebd04 1286 rb_linebuf_newbuf(&linebuf);
212380e3
AC
1287
1288 va_start(args, pattern);
55abcbb2 1289 rb_linebuf_putmsg(&linebuf, pattern, &args,
212380e3
AC
1290 ":%s NOTICE * :*** Notice -- ", source_p->name);
1291 va_end(args);
1292
637c4932 1293 RB_DLINK_FOREACH_SAFE(ptr, next_ptr, local_oper_list.head)
212380e3
AC
1294 {
1295 client_p = ptr->data;
1296
1297 /* If we're sending it to opers and theyre an admin, skip.
1298 * If we're sending it to admins, and theyre not, skip.
1299 */
1300 if(((level == L_ADMIN) && !IsOperAdmin(client_p)) ||
1301 ((level == L_OPER) && IsOperAdmin(client_p)))
1302 continue;
1303
1304 if(client_p->snomask & flags)
1305 _send_linebuf(client_p, &linebuf);
1306 }
1307
3b2ebd04 1308 rb_linebuf_donebuf(&linebuf);
212380e3
AC
1309}
1310
1311/*
1312 * sendto_wallops_flags
1313 *
1314 * inputs - flag types of messages to show to real opers
1315 * - client sending request
1316 * - var args input message
1317 * output - NONE
1318 * side effects - Send a wallops to local opers
1319 */
1320void
1321sendto_wallops_flags(int flags, struct Client *source_p, const char *pattern, ...)
1322{
1323 struct Client *client_p;
330fc5c1 1324 rb_dlink_node *ptr;
637c4932 1325 rb_dlink_node *next_ptr;
212380e3
AC
1326 va_list args;
1327 buf_head_t linebuf;
1328
3b2ebd04 1329 rb_linebuf_newbuf(&linebuf);
212380e3
AC
1330
1331 va_start(args, pattern);
1332
1333 if(IsPerson(source_p))
3b2ebd04 1334 rb_linebuf_putmsg(&linebuf, pattern, &args,
212380e3
AC
1335 ":%s!%s@%s WALLOPS :", source_p->name,
1336 source_p->username, source_p->host);
1337 else
3b2ebd04 1338 rb_linebuf_putmsg(&linebuf, pattern, &args, ":%s WALLOPS :", source_p->name);
212380e3
AC
1339
1340 va_end(args);
1341
637c4932 1342 RB_DLINK_FOREACH_SAFE(ptr, next_ptr, IsPerson(source_p) && flags == UMODE_WALLOP ? lclient_list.head : local_oper_list.head)
212380e3
AC
1343 {
1344 client_p = ptr->data;
1345
1346 if(client_p->umodes & flags)
1347 _send_linebuf(client_p, &linebuf);
1348 }
1349
3b2ebd04 1350 rb_linebuf_donebuf(&linebuf);
212380e3
AC
1351}
1352
1353/* kill_client()
1354 *
1355 * input - client to send kill to, client to kill, va_args
1356 * output -
1357 * side effects - we issue a kill for the client
1358 */
1359void
1360kill_client(struct Client *target_p, struct Client *diedie, const char *pattern, ...)
1361{
1362 va_list args;
1363 buf_head_t linebuf;
1364
3b2ebd04 1365 rb_linebuf_newbuf(&linebuf);
212380e3
AC
1366
1367 va_start(args, pattern);
3b2ebd04 1368 rb_linebuf_putmsg(&linebuf, pattern, &args, ":%s KILL %s :",
212380e3
AC
1369 get_id(&me, target_p), get_id(diedie, target_p));
1370 va_end(args);
1371
1372 send_linebuf(target_p, &linebuf);
3b2ebd04 1373 rb_linebuf_donebuf(&linebuf);
212380e3
AC
1374}
1375
1376
1377/*
1378 * kill_client_serv_butone
1379 *
1380 * inputs - pointer to client to not send to
1381 * - pointer to client to kill
1382 * output - NONE
1383 * side effects - Send a KILL for the given client
1384 * message to all connected servers
1385 * except the client 'one'. Also deal with
1386 * client being unknown to leaf, as in lazylink...
1387 */
1388void
1389kill_client_serv_butone(struct Client *one, struct Client *target_p, const char *pattern, ...)
1390{
1391 static char buf[BUFSIZE];
1392 va_list args;
1393 struct Client *client_p;
330fc5c1 1394 rb_dlink_node *ptr;
637c4932 1395 rb_dlink_node *next_ptr;
3b2ebd04 1396 buf_head_t rb_linebuf_id;
212380e3 1397
3b2ebd04 1398 rb_linebuf_newbuf(&rb_linebuf_id);
55abcbb2 1399
212380e3 1400 va_start(args, pattern);
5203cba5 1401 vsnprintf(buf, sizeof(buf), pattern, args);
212380e3
AC
1402 va_end(args);
1403
3b2ebd04 1404 rb_linebuf_putmsg(&rb_linebuf_id, NULL, NULL, ":%s KILL %s :%s",
212380e3
AC
1405 use_id(&me), use_id(target_p), buf);
1406
637c4932 1407 RB_DLINK_FOREACH_SAFE(ptr, next_ptr, serv_list.head)
212380e3
AC
1408 {
1409 client_p = ptr->data;
1410
1411 /* ok, if the client we're supposed to not send to has an
1412 * ID, then we still want to issue the kill there..
1413 */
1414 if(one != NULL && (client_p == one->from) &&
1415 (!has_id(client_p) || !has_id(target_p)))
1416 continue;
1417
ba301eff 1418 _send_linebuf(client_p, &rb_linebuf_id);
212380e3
AC
1419 }
1420
3b2ebd04 1421 rb_linebuf_donebuf(&rb_linebuf_id);
212380e3 1422}