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