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