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