2 * ircd-ratbox: A slightly useful ircd.
3 * send.c: Functions for sending messages.
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
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.
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.
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
36 #include "s_newconf.h"
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)
45 #define CLIENT_CAPS_ONLY(x) ((IsClient((x)) && (x)->localClient) ? (x)->localClient->caps : 0)
47 static void send_queued_write(rb_fde_t
*F
, void *data
);
49 unsigned long current_serial
= 0L;
51 struct Client
*remote_rehash_oper_p
;
55 * inputs - client to send to, linebuf to attach
57 * side effects - linebuf is attached to client
60 _send_linebuf(struct Client
*to
, buf_head_t
*linebuf
)
64 sendto_realops_snomask(SNO_GENERAL
, L_ALL
, "Trying to send message to myself!");
68 if(!MyConnect(to
) || IsIOError(to
))
71 if(rb_linebuf_len(&to
->localClient
->buf_sendq
) > get_sendq(to
))
75 sendto_realops_snomask(SNO_GENERAL
, L_ALL
,
76 "Max SendQ limit exceeded for %s: %u > %lu",
78 rb_linebuf_len(&to
->localClient
->buf_sendq
),
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
),
92 /* just attach the linebuf to the sendq instead of
93 * generating a new one
95 rb_linebuf_attach(&to
->localClient
->buf_sendq
, linebuf
);
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.
103 to
->localClient
->sendM
+= 1;
104 me
.localClient
->sendM
+= 1;
105 if(rb_linebuf_len(&to
->localClient
->buf_sendq
) > 0)
110 /* send_linebuf_remote()
112 * inputs - client to attach to, sender, linebuf
114 * side effects - client has linebuf attached
117 send_linebuf_remote(struct Client
*to
, struct Client
*from
, buf_head_t
*linebuf
)
122 /* we assume the caller has already tested for fake direction */
123 _send_linebuf(to
, linebuf
);
126 /* send_queued_write()
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
133 send_queued(struct Client
*to
)
137 rb_fde_t
*F
= to
->localClient
->F
;
141 /* cant write anything to a dead socket. */
145 /* try to flush later when the write event resets this */
149 if(rb_linebuf_len(&to
->localClient
->buf_sendq
))
152 rb_linebuf_flush(F
, &to
->localClient
->buf_sendq
)) > 0)
154 /* We have some data written .. update counters */
157 to
->localClient
->sendB
+= retlen
;
158 me
.localClient
->sendB
+= retlen
;
159 if(to
->localClient
->sendB
> 1023)
161 to
->localClient
->sendK
+= (to
->localClient
->sendB
>> 10);
162 to
->localClient
->sendB
&= 0x03ff; /* 2^10 = 1024, 3ff = 1023 */
164 else if(me
.localClient
->sendB
> 1023)
166 me
.localClient
->sendK
+= (me
.localClient
->sendB
>> 10);
167 me
.localClient
->sendB
&= 0x03ff;
171 if(retlen
== 0 || (retlen
< 0 && !rb_ignore_errno(errno
)))
178 if(rb_linebuf_len(&to
->localClient
->buf_sendq
))
181 rb_setselect(to
->localClient
->F
, RB_SELECT_WRITE
,
182 send_queued_write
, to
);
189 send_pop_queue(struct Client
*to
)
193 if(!MyConnect(to
) || IsIOError(to
))
195 if(rb_linebuf_len(&to
->localClient
->buf_sendq
) > 0)
199 /* send_queued_write()
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
206 send_queued_write(rb_fde_t
*F
, void *data
)
208 struct Client
*to
= data
;
216 * inputs - msgbuf header, linebuf object, capability mask, pattern, arguments
218 * side effects - the linebuf object is cleared, then populated
221 linebuf_put_tags(buf_head_t
*linebuf
, const struct MsgBuf
*msgbuf
, const struct Client
*target_p
, rb_strf_t
*message
)
223 struct MsgBuf_str_data msgbuf_str_data
= { .msgbuf
= msgbuf
, .caps
= CLIENT_CAPS_ONLY(target_p
) };
224 rb_strf_t strings
= { .func
= msgbuf_unparse_linebuf_tags
, .func_args
= &msgbuf_str_data
, .length
= TAGSLEN
+ 1, .next
= message
};
226 message
->length
= DATALEN
+ 1;
227 rb_linebuf_put(linebuf
, &strings
);
231 linebuf_put_tagsf(buf_head_t
*linebuf
, const struct MsgBuf
*msgbuf
, const struct Client
*target_p
, const rb_strf_t
*message
, const char *format
, ...)
234 rb_strf_t strings
= { .format
= format
, .format_args
= &va
, .next
= message
};
236 va_start(va
, format
);
237 linebuf_put_tags(linebuf
, msgbuf
, target_p
, &strings
);
242 linebuf_put_msg(buf_head_t
*linebuf
, rb_strf_t
*message
)
244 message
->length
= DATALEN
+ 1;
245 rb_linebuf_put(linebuf
, message
);
249 linebuf_put_msgf(buf_head_t
*linebuf
, const rb_strf_t
*message
, const char *format
, ...)
252 rb_strf_t strings
= { .format
= format
, .format_args
= &va
, .next
= message
};
254 va_start(va
, format
);
255 linebuf_put_msg(linebuf
, &strings
);
261 * inputs - msgbuf object, client the message is from
263 * side effects - a msgbuf object is populated with an origin and relevant tags
264 * notes - to make this reentrant, find a solution for `buf` below
267 build_msgbuf_tags(struct MsgBuf
*msgbuf
, struct Client
*from
)
276 call_hook(h_outbound_msgbuf
, &hdata
);
281 * inputs - client to send to, va_args
282 * outputs - client has message put into its queue
286 sendto_one(struct Client
*target_p
, const char *pattern
, ...)
289 struct MsgBuf msgbuf
;
291 rb_strf_t strings
= { .format
= pattern
, .format_args
= &args
, .next
= NULL
};
293 /* send remote if to->from non NULL */
294 if(target_p
->from
!= NULL
)
295 target_p
= target_p
->from
;
297 if(IsIOError(target_p
))
300 rb_linebuf_newbuf(&linebuf
);
302 build_msgbuf_tags(&msgbuf
, &me
);
303 va_start(args
, pattern
);
304 linebuf_put_tags(&linebuf
, &msgbuf
, target_p
, &strings
);
307 _send_linebuf(target_p
, &linebuf
);
309 rb_linebuf_donebuf(&linebuf
);
312 /* sendto_one_prefix()
314 * inputs - client to send to, va_args
315 * outputs - client has message put into its queue
316 * side effects - source(us)/target is chosen based on TS6 capability
319 sendto_one_prefix(struct Client
*target_p
, struct Client
*source_p
,
320 const char *command
, const char *pattern
, ...)
322 struct Client
*dest_p
= target_p
->from
;
324 struct MsgBuf msgbuf
;
326 rb_strf_t strings
= { .format
= pattern
, .format_args
= &args
, .next
= NULL
};
328 if(IsIOError(dest_p
))
333 sendto_realops_snomask(SNO_GENERAL
, L_ALL
, "Trying to send to myself!");
337 build_msgbuf_tags(&msgbuf
, source_p
);
339 rb_linebuf_newbuf(&linebuf
);
340 va_start(args
, pattern
);
341 linebuf_put_tagsf(&linebuf
, &msgbuf
, target_p
, &strings
,
342 ":%s %s %s ", get_id(source_p
, target_p
),
343 command
, get_id(target_p
, target_p
));
346 _send_linebuf(dest_p
, &linebuf
);
347 rb_linebuf_donebuf(&linebuf
);
350 /* sendto_one_notice()
352 * inputs - client to send to, va_args
353 * outputs - client has a NOTICE put into its queue
354 * side effects - source(us)/target is chosen based on TS6 capability
357 sendto_one_notice(struct Client
*target_p
, const char *pattern
, ...)
359 struct Client
*dest_p
= target_p
->from
;
361 struct MsgBuf msgbuf
;
363 rb_strf_t strings
= { .format
= pattern
, .format_args
= &args
, .next
= NULL
};
366 if(IsIOError(dest_p
))
371 sendto_realops_snomask(SNO_GENERAL
, L_ALL
, "Trying to send to myself!");
375 build_msgbuf_tags(&msgbuf
, &me
);
377 rb_linebuf_newbuf(&linebuf
);
378 va_start(args
, pattern
);
379 linebuf_put_tagsf(&linebuf
, &msgbuf
, target_p
, &strings
,
380 ":%s NOTICE %s ", get_id(&me
, target_p
),
381 *(to
= get_id(target_p
, target_p
)) != '\0' ? to
: "*");
384 _send_linebuf(dest_p
, &linebuf
);
385 rb_linebuf_donebuf(&linebuf
);
389 /* sendto_one_numeric()
391 * inputs - client to send to, va_args
392 * outputs - client has message put into its queue
393 * side effects - source/target is chosen based on TS6 capability
396 sendto_one_numeric(struct Client
*target_p
, int numeric
, const char *pattern
, ...)
398 struct Client
*dest_p
= target_p
->from
;
400 struct MsgBuf msgbuf
;
402 rb_strf_t strings
= { .format
= pattern
, .format_args
= &args
, .next
= NULL
};
405 if(IsIOError(dest_p
))
410 sendto_realops_snomask(SNO_GENERAL
, L_ALL
, "Trying to send to myself!");
414 build_msgbuf_tags(&msgbuf
, &me
);
416 rb_linebuf_newbuf(&linebuf
);
417 va_start(args
, pattern
);
418 linebuf_put_tagsf(&linebuf
, &msgbuf
, target_p
, &strings
,
419 ":%s %03d %s ", get_id(&me
, target_p
), numeric
,
420 *(to
= get_id(target_p
, target_p
)) != '\0' ? to
: "*");
423 _send_linebuf(dest_p
, &linebuf
);
424 rb_linebuf_donebuf(&linebuf
);
430 * inputs - pointer to client to NOT send to
431 * - caps or'd together which must ALL be present
432 * - caps or'd together which must ALL NOT be present
433 * - printf style format string
434 * - args to format string
436 * side effects - Send a message to all connected servers, except the
437 * client 'one' (if non-NULL), as long as the servers
438 * support ALL capabs in 'caps', and NO capabs in 'nocaps'.
440 * This function was written in an attempt to merge together the other
441 * billion sendto_*serv*() functions, which sprung up with capabs, uids etc
445 sendto_server(struct Client
*one
, struct Channel
*chptr
, unsigned long caps
,
446 unsigned long nocaps
, const char *format
, ...)
449 struct Client
*target_p
;
451 rb_dlink_node
*next_ptr
;
453 rb_strf_t strings
= { .format
= format
, .format_args
= &args
, .next
= NULL
};
455 /* noone to send to.. */
456 if(rb_dlink_list_length(&serv_list
) == 0)
459 if(chptr
!= NULL
&& *chptr
->chname
!= '#')
462 rb_linebuf_newbuf(&linebuf
);
463 va_start(args
, format
);
464 linebuf_put_msg(&linebuf
, &strings
);
467 RB_DLINK_FOREACH_SAFE(ptr
, next_ptr
, serv_list
.head
)
469 target_p
= ptr
->data
;
471 /* check against 'one' */
472 if(one
!= NULL
&& (target_p
== one
->from
))
475 /* check we have required capabs */
476 if(!IsCapable(target_p
, caps
))
479 /* check we don't have any forbidden capabs */
480 if(!NotCapable(target_p
, nocaps
))
483 _send_linebuf(target_p
, &linebuf
);
486 rb_linebuf_donebuf(&linebuf
);
489 /* sendto_channel_flags()
491 * inputs - server not to send to, flags needed, source, channel, va_args
492 * outputs - message is sent to channel members
496 sendto_channel_flags(struct Client
*one
, int type
, struct Client
*source_p
,
497 struct Channel
*chptr
, const char *pattern
, ...)
499 static char buf
[BUFSIZE
];
501 buf_head_t rb_linebuf_remote
;
502 struct Client
*target_p
;
503 struct membership
*msptr
;
505 rb_dlink_node
*next_ptr
;
506 struct MsgBuf msgbuf
;
507 struct MsgBuf_cache msgbuf_cache
;
508 rb_strf_t strings
= { .format
= buf
, .format_args
= NULL
, .next
= NULL
};
510 rb_linebuf_newbuf(&rb_linebuf_remote
);
514 build_msgbuf_tags(&msgbuf
, source_p
);
516 va_start(args
, pattern
);
517 vsnprintf(buf
, sizeof buf
, pattern
, args
);
520 linebuf_put_msgf(&rb_linebuf_remote
, NULL
, ":%s %s", use_id(source_p
), buf
);
521 msgbuf_cache_initf(&msgbuf_cache
, &msgbuf
, &strings
,
522 IsPerson(source_p
) ? ":%1$s!%2$s@%3$s " : ":%1$s ",
523 source_p
->name
, source_p
->username
, source_p
->host
);
525 RB_DLINK_FOREACH_SAFE(ptr
, next_ptr
, chptr
->members
.head
)
528 target_p
= msptr
->client_p
;
530 if(!MyClient(source_p
) && (IsIOError(target_p
->from
) || target_p
->from
== one
))
533 if(MyClient(source_p
) && target_p
== one
)
536 if(type
&& ((msptr
->flags
& type
) == 0))
542 if(!MyClient(target_p
))
544 /* if we've got a specific type, target must support
547 if(type
&& NotCapable(target_p
->from
, CAP_CHW
))
550 if(target_p
->from
->serial
!= current_serial
)
552 send_linebuf_remote(target_p
, source_p
, &rb_linebuf_remote
);
553 target_p
->from
->serial
= current_serial
;
558 _send_linebuf(target_p
, msgbuf_cache_get(&msgbuf_cache
, CLIENT_CAPS_ONLY(target_p
)));
562 /* source client may not be on the channel, send echo separately */
563 if(MyClient(source_p
) && IsCapable(source_p
, CLICAP_ECHO_MESSAGE
))
567 _send_linebuf(target_p
, msgbuf_cache_get(&msgbuf_cache
, CLIENT_CAPS_ONLY(target_p
)));
570 rb_linebuf_donebuf(&rb_linebuf_remote
);
571 msgbuf_cache_free(&msgbuf_cache
);
574 /* sendto_channel_flags()
576 * inputs - server not to send to, flags needed, source, channel, va_args
577 * outputs - message is sent to channel members
581 sendto_channel_opmod(struct Client
*one
, struct Client
*source_p
,
582 struct Channel
*chptr
, const char *command
,
585 buf_head_t rb_linebuf_old
;
586 buf_head_t rb_linebuf_new
;
587 struct Client
*target_p
;
588 struct membership
*msptr
;
590 rb_dlink_node
*next_ptr
;
591 struct MsgBuf msgbuf
;
592 struct MsgBuf_cache msgbuf_cache
;
593 rb_strf_t strings
= { .format
= text
, .format_args
= NULL
, .next
= NULL
};
595 rb_linebuf_newbuf(&rb_linebuf_old
);
596 rb_linebuf_newbuf(&rb_linebuf_new
);
598 build_msgbuf_tags(&msgbuf
, source_p
);
602 if(IsServer(source_p
)) {
603 msgbuf_cache_initf(&msgbuf_cache
, &msgbuf
, &strings
,
605 source_p
->name
, command
, chptr
->chname
);
607 msgbuf_cache_initf(&msgbuf_cache
, &msgbuf
, &strings
,
609 source_p
->name
, source_p
->username
,
610 source_p
->host
, command
, chptr
->chname
);
613 if (chptr
->mode
.mode
& MODE_MODERATED
) {
614 linebuf_put_msgf(&rb_linebuf_old
, &strings
,
616 use_id(source_p
), command
, chptr
->chname
, text
);
618 linebuf_put_msgf(&rb_linebuf_old
, &strings
,
619 ":%s NOTICE @%s :<%s:%s> ",
620 use_id(source_p
->servptr
), chptr
->chname
,
621 source_p
->name
, chptr
->chname
);
623 linebuf_put_msgf(&rb_linebuf_new
, &strings
,
625 use_id(source_p
), command
, chptr
->chname
);
627 RB_DLINK_FOREACH_SAFE(ptr
, next_ptr
, chptr
->members
.head
)
630 target_p
= msptr
->client_p
;
632 if(!MyClient(source_p
) && (IsIOError(target_p
->from
) || target_p
->from
== one
))
635 if(MyClient(source_p
) && target_p
== one
)
638 if((msptr
->flags
& CHFL_CHANOP
) == 0)
644 if(!MyClient(target_p
))
646 /* if we've got a specific type, target must support
649 if(NotCapable(target_p
->from
, CAP_CHW
))
652 if(target_p
->from
->serial
!= current_serial
)
654 if (IsCapable(target_p
->from
, CAP_EOPMOD
))
655 send_linebuf_remote(target_p
, source_p
, &rb_linebuf_new
);
657 send_linebuf_remote(target_p
, source_p
, &rb_linebuf_old
);
658 target_p
->from
->serial
= current_serial
;
661 _send_linebuf(target_p
, msgbuf_cache_get(&msgbuf_cache
, CLIENT_CAPS_ONLY(target_p
)));
665 /* source client may not be on the channel, send echo separately */
666 if(MyClient(source_p
) && IsCapable(source_p
, CLICAP_ECHO_MESSAGE
))
670 _send_linebuf(target_p
, msgbuf_cache_get(&msgbuf_cache
, CLIENT_CAPS_ONLY(target_p
)));
673 rb_linebuf_donebuf(&rb_linebuf_old
);
674 rb_linebuf_donebuf(&rb_linebuf_new
);
675 msgbuf_cache_free(&msgbuf_cache
);
678 /* sendto_channel_local()
680 * inputs - source, flags to send to, channel to send to, va_args
681 * outputs - message to local channel members
685 sendto_channel_local(struct Client
*source_p
, int type
, struct Channel
*chptr
, const char *pattern
, ...)
688 struct membership
*msptr
;
689 struct Client
*target_p
;
691 rb_dlink_node
*next_ptr
;
692 struct MsgBuf msgbuf
;
693 struct MsgBuf_cache msgbuf_cache
;
694 rb_strf_t strings
= { .format
= pattern
, .format_args
= &args
, .next
= NULL
};
696 build_msgbuf_tags(&msgbuf
, source_p
);
698 va_start(args
, pattern
);
699 msgbuf_cache_init(&msgbuf_cache
, &msgbuf
, &strings
);
702 RB_DLINK_FOREACH_SAFE(ptr
, next_ptr
, chptr
->locmembers
.head
)
705 target_p
= msptr
->client_p
;
707 if(IsIOError(target_p
))
710 if(type
== ONLY_OPERS
)
712 if (!IsOper(target_p
))
715 else if(type
&& ((msptr
->flags
& type
) == 0))
718 _send_linebuf(target_p
, msgbuf_cache_get(&msgbuf_cache
, CLIENT_CAPS_ONLY(target_p
)));
721 msgbuf_cache_free(&msgbuf_cache
);
725 * _sendto_channel_local_with_capability_butone()
727 * Shared implementation of sendto_channel_local_with_capability and sendto_channel_local_with_capability_butone
730 _sendto_channel_local_with_capability_butone(struct Client
*source_p
, struct Client
*one
, int type
,
731 int caps
, int negcaps
, struct Channel
*chptr
, const char *pattern
, va_list * args
)
733 struct membership
*msptr
;
734 struct Client
*target_p
;
736 rb_dlink_node
*next_ptr
;
737 struct MsgBuf msgbuf
;
738 struct MsgBuf_cache msgbuf_cache
;
739 rb_strf_t strings
= { .format
= pattern
, .format_args
= args
, .next
= NULL
};
741 build_msgbuf_tags(&msgbuf
, source_p
);
742 msgbuf_cache_init(&msgbuf_cache
, &msgbuf
, &strings
);
744 RB_DLINK_FOREACH_SAFE(ptr
, next_ptr
, chptr
->locmembers
.head
)
747 target_p
= msptr
->client_p
;
752 if(IsIOError(target_p
) ||
753 !IsCapable(target_p
, caps
) ||
754 !NotCapable(target_p
, negcaps
))
757 if(type
&& ((msptr
->flags
& type
) == 0))
760 _send_linebuf(target_p
, msgbuf_cache_get(&msgbuf_cache
, CLIENT_CAPS_ONLY(target_p
)));
763 msgbuf_cache_free(&msgbuf_cache
);
766 /* sendto_channel_local_with_capability()
768 * inputs - source, flags to send to, caps, negate caps, channel to send to, va_args
769 * outputs - message to local channel members
773 sendto_channel_local_with_capability(struct Client
*source_p
, int type
, int caps
, int negcaps
, struct Channel
*chptr
, const char *pattern
, ...)
777 va_start(args
, pattern
);
778 _sendto_channel_local_with_capability_butone(source_p
, NULL
, type
, caps
, negcaps
, chptr
, pattern
, &args
);
783 /* sendto_channel_local_with_capability()
785 * inputs - source, flags to send to, caps, negate caps, channel to send to, va_args
786 * outputs - message to local channel members
790 sendto_channel_local_with_capability_butone(struct Client
*one
, int type
,
791 int caps
, int negcaps
, struct Channel
*chptr
, const char *pattern
, ...)
795 va_start(args
, pattern
);
796 _sendto_channel_local_with_capability_butone(one
, one
, type
, caps
, negcaps
, chptr
, pattern
, &args
);
801 /* sendto_channel_local_butone()
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
809 sendto_channel_local_butone(struct Client
*one
, int type
, struct Channel
*chptr
, const char *pattern
, ...)
812 struct membership
*msptr
;
813 struct Client
*target_p
;
814 struct MsgBuf msgbuf
;
816 rb_dlink_node
*next_ptr
;
817 struct MsgBuf_cache msgbuf_cache
;
818 rb_strf_t strings
= { .format
= pattern
, .format_args
= &args
, .next
= NULL
};
820 build_msgbuf_tags(&msgbuf
, one
);
822 va_start(args
, pattern
);
823 msgbuf_cache_init(&msgbuf_cache
, &msgbuf
, &strings
);
826 RB_DLINK_FOREACH_SAFE(ptr
, next_ptr
, chptr
->locmembers
.head
)
829 target_p
= msptr
->client_p
;
834 if(IsIOError(target_p
))
837 if(type
&& ((msptr
->flags
& type
) == 0))
840 /* attach the present linebuf to the target */
841 _send_linebuf(target_p
, msgbuf_cache_get(&msgbuf_cache
, CLIENT_CAPS_ONLY(target_p
)));
844 msgbuf_cache_free(&msgbuf_cache
);
848 * sendto_common_channels_local()
850 * inputs - pointer to client
852 * - negated capability mask
855 * side effects - Sends a message to all people on local server who are
856 * in same channel with user.
857 * used by m_nick.c and exit_one_client.
860 sendto_common_channels_local(struct Client
*user
, int cap
, int negcap
, const char *pattern
, ...)
864 rb_dlink_node
*next_ptr
;
866 rb_dlink_node
*next_uptr
;
867 struct Channel
*chptr
;
868 struct Client
*target_p
;
869 struct membership
*msptr
;
870 struct membership
*mscptr
;
871 struct MsgBuf msgbuf
;
872 struct MsgBuf_cache msgbuf_cache
;
873 rb_strf_t strings
= { .format
= pattern
, .format_args
= &args
, .next
= NULL
};
875 build_msgbuf_tags(&msgbuf
, user
);
877 va_start(args
, pattern
);
878 msgbuf_cache_init(&msgbuf_cache
, &msgbuf
, &strings
);
883 RB_DLINK_FOREACH_SAFE(ptr
, next_ptr
, user
->user
->channel
.head
)
886 chptr
= mscptr
->chptr
;
888 RB_DLINK_FOREACH_SAFE(uptr
, next_uptr
, chptr
->locmembers
.head
)
891 target_p
= msptr
->client_p
;
893 if(IsIOError(target_p
) ||
894 target_p
->serial
== current_serial
||
895 !IsCapable(target_p
, cap
) ||
896 !NotCapable(target_p
, negcap
))
899 target_p
->serial
= current_serial
;
900 send_linebuf(target_p
, msgbuf_cache_get(&msgbuf_cache
, CLIENT_CAPS_ONLY(target_p
)));
904 /* this can happen when the user isnt in any channels, but we still
905 * need to send them the data, ie a nick change
907 if(MyConnect(user
) && (user
->serial
!= current_serial
)
908 && IsCapable(user
, cap
) && NotCapable(user
, negcap
)) {
909 send_linebuf(user
, msgbuf_cache_get(&msgbuf_cache
, CLIENT_CAPS_ONLY(user
)));
912 msgbuf_cache_free(&msgbuf_cache
);
916 * sendto_common_channels_local_butone()
918 * inputs - pointer to client
920 * - negated capability mask
923 * side effects - Sends a message to all people on local server who are
924 * in same channel with user, except for user itself.
927 sendto_common_channels_local_butone(struct Client
*user
, int cap
, int negcap
, const char *pattern
, ...)
931 rb_dlink_node
*next_ptr
;
933 rb_dlink_node
*next_uptr
;
934 struct Channel
*chptr
;
935 struct Client
*target_p
;
936 struct membership
*msptr
;
937 struct membership
*mscptr
;
938 struct MsgBuf msgbuf
;
939 struct MsgBuf_cache msgbuf_cache
;
940 rb_strf_t strings
= { .format
= pattern
, .format_args
= &args
, .next
= NULL
};
942 build_msgbuf_tags(&msgbuf
, user
);
944 va_start(args
, pattern
);
945 msgbuf_cache_init(&msgbuf_cache
, &msgbuf
, &strings
);
949 /* Skip them -- jilles */
950 user
->serial
= current_serial
;
952 RB_DLINK_FOREACH_SAFE(ptr
, next_ptr
, user
->user
->channel
.head
)
955 chptr
= mscptr
->chptr
;
957 RB_DLINK_FOREACH_SAFE(uptr
, next_uptr
, chptr
->locmembers
.head
)
960 target_p
= msptr
->client_p
;
962 if(IsIOError(target_p
) ||
963 target_p
->serial
== current_serial
||
964 !IsCapable(target_p
, cap
) ||
965 !NotCapable(target_p
, negcap
))
968 target_p
->serial
= current_serial
;
969 send_linebuf(target_p
, msgbuf_cache_get(&msgbuf_cache
, CLIENT_CAPS_ONLY(target_p
)));
973 msgbuf_cache_free(&msgbuf_cache
);
976 /* sendto_match_butone()
978 * inputs - server not to send to, source, mask, type of mask, va_args
980 * side effects - message is sent to matching clients
983 sendto_match_butone(struct Client
*one
, struct Client
*source_p
,
984 const char *mask
, int what
, const char *pattern
, ...)
986 static char buf
[BUFSIZE
];
988 struct Client
*target_p
;
990 rb_dlink_node
*next_ptr
;
991 buf_head_t rb_linebuf_remote
;
992 struct MsgBuf msgbuf
;
993 struct MsgBuf_cache msgbuf_cache
;
994 rb_strf_t strings
= { .format
= buf
, .format_args
= NULL
, .next
= NULL
};
996 rb_linebuf_newbuf(&rb_linebuf_remote
);
998 build_msgbuf_tags(&msgbuf
, source_p
);
1000 va_start(args
, pattern
);
1001 vsnprintf(buf
, sizeof(buf
), pattern
, args
);
1004 msgbuf_cache_initf(&msgbuf_cache
, &msgbuf
, &strings
,
1005 IsServer(source_p
) ? ":%s " : ":%s!%s@%s ",
1006 source_p
->name
, source_p
->username
, source_p
->host
);
1008 linebuf_put_msgf(&rb_linebuf_remote
, &strings
, ":%s ", use_id(source_p
));
1010 if(what
== MATCH_HOST
)
1012 RB_DLINK_FOREACH_SAFE(ptr
, next_ptr
, lclient_list
.head
)
1014 target_p
= ptr
->data
;
1016 if(match(mask
, target_p
->host
))
1017 _send_linebuf(target_p
, msgbuf_cache_get(&msgbuf_cache
, CLIENT_CAPS_ONLY(target_p
)));
1020 /* what = MATCH_SERVER, if it doesnt match us, just send remote */
1021 else if(match(mask
, me
.name
))
1023 RB_DLINK_FOREACH_SAFE(ptr
, next_ptr
, lclient_list
.head
)
1025 target_p
= ptr
->data
;
1026 _send_linebuf(target_p
, msgbuf_cache_get(&msgbuf_cache
, CLIENT_CAPS_ONLY(target_p
)));
1030 RB_DLINK_FOREACH(ptr
, serv_list
.head
)
1032 target_p
= ptr
->data
;
1037 send_linebuf_remote(target_p
, source_p
, &rb_linebuf_remote
);
1040 msgbuf_cache_free(&msgbuf_cache
);
1041 rb_linebuf_donebuf(&rb_linebuf_remote
);
1044 /* sendto_match_servs()
1046 * inputs - source, mask to send to, caps needed, va_args
1048 * side effects - message is sent to matching servers with caps.
1051 sendto_match_servs(struct Client
*source_p
, const char *mask
, int cap
,
1052 int nocap
, const char *pattern
, ...)
1054 static char buf
[BUFSIZE
];
1057 struct Client
*target_p
;
1058 buf_head_t rb_linebuf_id
;
1059 rb_strf_t strings
= { .format
= buf
, .format_args
= NULL
, .next
= NULL
};
1061 if(EmptyString(mask
))
1064 rb_linebuf_newbuf(&rb_linebuf_id
);
1066 va_start(args
, pattern
);
1067 vsnprintf(buf
, sizeof(buf
), pattern
, args
);
1070 linebuf_put_msgf(&rb_linebuf_id
, &strings
, ":%s ", use_id(source_p
));
1074 RB_DLINK_FOREACH(ptr
, global_serv_list
.head
)
1076 target_p
= ptr
->data
;
1078 /* dont send to ourselves, or back to where it came from.. */
1079 if(IsMe(target_p
) || target_p
->from
== source_p
->from
)
1082 if(target_p
->from
->serial
== current_serial
)
1085 if(match(mask
, target_p
->name
))
1087 /* if we set the serial here, then we'll never do
1088 * a match() again if !IsCapable()
1090 target_p
->from
->serial
= current_serial
;
1092 if(cap
&& !IsCapable(target_p
->from
, cap
))
1095 if(nocap
&& !NotCapable(target_p
->from
, nocap
))
1098 _send_linebuf(target_p
->from
, &rb_linebuf_id
);
1102 rb_linebuf_donebuf(&rb_linebuf_id
);
1105 /* sendto_local_clients_with_capability()
1107 * inputs - caps needed, pattern, va_args
1109 * side effects - message is sent to matching local clients with caps.
1112 sendto_local_clients_with_capability(int cap
, const char *pattern
, ...)
1116 struct Client
*target_p
;
1117 struct MsgBuf msgbuf
;
1118 struct MsgBuf_cache msgbuf_cache
;
1119 rb_strf_t strings
= { .format
= pattern
, .format_args
= &args
, .next
= NULL
};
1121 build_msgbuf_tags(&msgbuf
, &me
);
1123 va_start(args
, pattern
);
1124 msgbuf_cache_init(&msgbuf_cache
, &msgbuf
, &strings
);
1127 RB_DLINK_FOREACH(ptr
, lclient_list
.head
)
1129 target_p
= ptr
->data
;
1131 if(IsIOError(target_p
) || !IsCapable(target_p
, cap
))
1134 send_linebuf(target_p
, msgbuf_cache_get(&msgbuf_cache
, CLIENT_CAPS_ONLY(target_p
)));
1137 msgbuf_cache_free(&msgbuf_cache
);
1142 * inputs - monitor nick to send to, format, va_args
1143 * outputs - message to local users monitoring the given nick
1147 sendto_monitor(struct Client
*source_p
, struct monitor
*monptr
, const char *pattern
, ...)
1150 struct Client
*target_p
;
1152 rb_dlink_node
*next_ptr
;
1153 struct MsgBuf msgbuf
;
1154 struct MsgBuf_cache msgbuf_cache
;
1155 rb_strf_t strings
= { .format
= pattern
, .format_args
= &args
, .next
= NULL
};
1157 build_msgbuf_tags(&msgbuf
, source_p
);
1159 va_start(args
, pattern
);
1160 msgbuf_cache_init(&msgbuf_cache
, &msgbuf
, &strings
);
1163 RB_DLINK_FOREACH_SAFE(ptr
, next_ptr
, monptr
->users
.head
)
1165 target_p
= ptr
->data
;
1167 if(IsIOError(target_p
))
1170 _send_linebuf(target_p
, msgbuf_cache_get(&msgbuf_cache
, CLIENT_CAPS_ONLY(target_p
)));
1173 msgbuf_cache_free(&msgbuf_cache
);
1176 /* _sendto_anywhere()
1178 * inputs - real_target, target, source, va_args
1180 * side effects - client is sent message/own message with correct prefix.
1183 _sendto_anywhere(struct Client
*dest_p
, struct Client
*target_p
,
1184 struct Client
*source_p
, const char *command
,
1185 const char *pattern
, va_list *args
)
1188 rb_strf_t strings
= { .format
= pattern
, .format_args
= args
, .next
= NULL
};
1190 rb_linebuf_newbuf(&linebuf
);
1192 if (MyClient(dest_p
)) {
1193 if (IsServer(source_p
)) {
1194 linebuf_put_msgf(&linebuf
, &strings
, ":%s %s %s ",
1195 source_p
->name
, command
,
1198 struct MsgBuf msgbuf
;
1200 build_msgbuf_tags(&msgbuf
, source_p
);
1202 linebuf_put_tagsf(&linebuf
, &msgbuf
, dest_p
, &strings
,
1203 IsPerson(source_p
) ? ":%1$s!%4$s@%5$s %2$s %3$s " : ":%1$s %2$s %3$s ",
1204 source_p
->name
, command
, target_p
->name
,
1205 source_p
->username
, source_p
->host
);
1208 _send_linebuf(dest_p
, &linebuf
);
1210 linebuf_put_msgf(&linebuf
, &strings
, ":%s %s %s ",
1211 get_id(source_p
, target_p
), command
,
1212 get_id(target_p
, target_p
));
1214 send_linebuf_remote(dest_p
, source_p
, &linebuf
);
1217 rb_linebuf_donebuf(&linebuf
);
1220 /* sendto_anywhere()
1222 * inputs - target, source, va_args
1224 * side effects - client is sent message with correct prefix.
1227 sendto_anywhere(struct Client
*target_p
, struct Client
*source_p
,
1228 const char *command
, const char *pattern
, ...)
1232 va_start(args
, pattern
);
1233 _sendto_anywhere(target_p
, target_p
, source_p
, command
, pattern
, &args
);
1237 /* sendto_anywhere_echo()
1239 * inputs - target, source, va_args
1241 * side effects - client is sent own message with correct prefix.
1244 sendto_anywhere_echo(struct Client
*target_p
, struct Client
*source_p
,
1245 const char *command
, const char *pattern
, ...)
1249 s_assert(MyClient(source_p
));
1250 s_assert(!IsServer(source_p
));
1252 va_start(args
, pattern
);
1253 _sendto_anywhere(source_p
, target_p
, source_p
, command
, pattern
, &args
);
1257 /* sendto_realops_snomask()
1259 * inputs - snomask needed, level (opers/admin), va_args
1261 * side effects - message is sent to opers with matching snomasks
1264 sendto_realops_snomask(int flags
, int level
, const char *pattern
, ...)
1266 static char buf
[BUFSIZE
];
1268 struct Client
*client_p
;
1270 rb_dlink_node
*next_ptr
;
1272 struct MsgBuf msgbuf
;
1273 struct MsgBuf_cache msgbuf_cache
;
1275 build_msgbuf_tags(&msgbuf
, &me
);
1277 /* rather a lot of copying around, oh well -- jilles */
1278 va_start(args
, pattern
);
1279 vsnprintf(buf
, sizeof(buf
), pattern
, args
);
1282 msgbuf_cache_initf(&msgbuf_cache
, &msgbuf
, NULL
,
1283 ":%s NOTICE * :*** Notice -- %s", me
.name
, buf
);
1285 /* Be very sure not to do things like "Trying to send to myself"
1286 * L_NETWIDE, otherwise infinite recursion may result! -- jilles */
1287 if (level
& L_NETWIDE
&& ConfigFileEntry
.global_snotices
)
1289 snobuf
= construct_snobuf(flags
);
1290 if (snobuf
[1] != '\0')
1291 sendto_server(NULL
, NULL
, CAP_ENCAP
|CAP_TS6
, NOCAPS
,
1292 ":%s ENCAP * SNOTE %c :%s",
1293 me
.id
, snobuf
[1], buf
);
1295 else if (remote_rehash_oper_p
!= NULL
)
1297 sendto_one_notice(remote_rehash_oper_p
, ":*** Notice -- %s", buf
);
1299 level
&= ~L_NETWIDE
;
1301 RB_DLINK_FOREACH_SAFE(ptr
, next_ptr
, local_oper_list
.head
)
1303 client_p
= ptr
->data
;
1305 /* If we're sending it to opers and theyre an admin, skip.
1306 * If we're sending it to admins, and theyre not, skip.
1308 if(((level
== L_ADMIN
) && !IsOperAdmin(client_p
)) ||
1309 ((level
== L_OPER
) && IsOperAdmin(client_p
)))
1312 if (client_p
->snomask
& flags
) {
1313 _send_linebuf(client_p
, msgbuf_cache_get(&msgbuf_cache
, CLIENT_CAPS_ONLY(client_p
)));
1317 msgbuf_cache_free(&msgbuf_cache
);
1319 /* sendto_realops_snomask_from()
1321 * inputs - snomask needed, level (opers/admin), source server, va_args
1323 * side effects - message is sent to opers with matching snomask
1326 sendto_realops_snomask_from(int flags
, int level
, struct Client
*source_p
,
1327 const char *pattern
, ...)
1329 struct Client
*client_p
;
1331 rb_dlink_node
*next_ptr
;
1333 struct MsgBuf msgbuf
;
1334 struct MsgBuf_cache msgbuf_cache
;
1335 rb_strf_t strings
= { .format
= pattern
, .format_args
= &args
, .next
= NULL
};
1337 build_msgbuf_tags(&msgbuf
, &me
);
1339 va_start(args
, pattern
);
1340 msgbuf_cache_initf(&msgbuf_cache
, &msgbuf
, &strings
,
1341 ":%s NOTICE * :*** Notice -- ", source_p
->name
);
1344 RB_DLINK_FOREACH_SAFE(ptr
, next_ptr
, local_oper_list
.head
)
1346 client_p
= ptr
->data
;
1348 /* If we're sending it to opers and theyre an admin, skip.
1349 * If we're sending it to admins, and theyre not, skip.
1351 if(((level
== L_ADMIN
) && !IsOperAdmin(client_p
)) ||
1352 ((level
== L_OPER
) && IsOperAdmin(client_p
)))
1355 if (client_p
->snomask
& flags
) {
1356 _send_linebuf(client_p
, msgbuf_cache_get(&msgbuf_cache
, CLIENT_CAPS_ONLY(client_p
)));
1360 msgbuf_cache_free(&msgbuf_cache
);
1364 * sendto_wallops_flags
1366 * inputs - flag types of messages to show to real opers
1367 * - client sending request
1368 * - var args input message
1370 * side effects - Send a wallops to local opers
1373 sendto_wallops_flags(int flags
, struct Client
*source_p
, const char *pattern
, ...)
1375 struct Client
*client_p
;
1377 rb_dlink_node
*next_ptr
;
1379 struct MsgBuf msgbuf
;
1380 struct MsgBuf_cache msgbuf_cache
;
1381 rb_strf_t strings
= { .format
= pattern
, .format_args
= &args
, .next
= NULL
};
1383 build_msgbuf_tags(&msgbuf
, source_p
);
1385 va_start(args
, pattern
);
1386 if (IsPerson(source_p
)) {
1387 msgbuf_cache_initf(&msgbuf_cache
, &msgbuf
, &strings
,
1388 ":%s!%s@%s WALLOPS :", source_p
->name
,
1389 source_p
->username
, source_p
->host
);
1391 msgbuf_cache_initf(&msgbuf_cache
, &msgbuf
, &strings
,
1392 ":%s WALLOPS :", source_p
->name
);
1396 RB_DLINK_FOREACH_SAFE(ptr
, next_ptr
, IsPerson(source_p
) && flags
== UMODE_WALLOP
? lclient_list
.head
: local_oper_list
.head
)
1398 client_p
= ptr
->data
;
1400 if (client_p
->umodes
& flags
) {
1401 _send_linebuf(client_p
, msgbuf_cache_get(&msgbuf_cache
, CLIENT_CAPS_ONLY(client_p
)));
1405 msgbuf_cache_free(&msgbuf_cache
);
1410 * input - client to send kill to, client to kill, va_args
1412 * side effects - we issue a kill for the client
1415 kill_client(struct Client
*target_p
, struct Client
*diedie
, const char *pattern
, ...)
1419 struct MsgBuf msgbuf
;
1420 rb_strf_t strings
= { .format
= pattern
, .format_args
= &args
, .next
= NULL
};
1422 build_msgbuf_tags(&msgbuf
, &me
);
1424 rb_linebuf_newbuf(&linebuf
);
1426 va_start(args
, pattern
);
1427 linebuf_put_tagsf(&linebuf
, &msgbuf
, target_p
, &strings
,
1428 ":%s KILL %s :", get_id(&me
, target_p
), get_id(diedie
, target_p
));
1431 send_linebuf(target_p
, &linebuf
);
1432 rb_linebuf_donebuf(&linebuf
);
1437 * kill_client_serv_butone
1439 * inputs - pointer to client to not send to
1440 * - pointer to client to kill
1442 * side effects - Send a KILL for the given client
1443 * message to all connected servers
1444 * except the client 'one'. Also deal with
1445 * client being unknown to leaf, as in lazylink...
1448 kill_client_serv_butone(struct Client
*one
, struct Client
*target_p
, const char *pattern
, ...)
1450 static char buf
[BUFSIZE
];
1452 struct Client
*client_p
;
1454 rb_dlink_node
*next_ptr
;
1455 buf_head_t rb_linebuf_id
;
1456 rb_strf_t strings
= { .format
= pattern
, .format_args
= &args
, .next
= NULL
};
1458 rb_linebuf_newbuf(&rb_linebuf_id
);
1460 va_start(args
, pattern
);
1461 linebuf_put_msgf(&rb_linebuf_id
, &strings
, ":%s KILL %s :%s",
1462 use_id(&me
), use_id(target_p
), buf
);
1465 RB_DLINK_FOREACH_SAFE(ptr
, next_ptr
, serv_list
.head
)
1467 client_p
= ptr
->data
;
1469 /* ok, if the client we're supposed to not send to has an
1470 * ID, then we still want to issue the kill there..
1472 if(one
!= NULL
&& (client_p
== one
->from
) &&
1473 (!has_id(client_p
) || !has_id(target_p
)))
1476 _send_linebuf(client_p
, &rb_linebuf_id
);
1479 rb_linebuf_donebuf(&rb_linebuf_id
);