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
))
77 sendto_realops_snomask(SNO_GENERAL
, L_NETWIDE
,
78 "Max SendQ limit exceeded for %s: %u > %lu",
80 rb_linebuf_len(&to
->localClient
->buf_sendq
),
83 ilog(L_SERVER
, "Max SendQ limit exceeded for %s: %u > %lu",
84 log_client_name(to
, SHOW_IP
),
85 rb_linebuf_len(&to
->localClient
->buf_sendq
),
93 /* just attach the linebuf to the sendq instead of
94 * generating a new one
96 rb_linebuf_attach(&to
->localClient
->buf_sendq
, linebuf
);
100 ** Update statistics. The following is slightly incorrect
101 ** because it counts messages even if queued, but bytes
102 ** only really sent. Queued bytes get updated in SendQueued.
104 to
->localClient
->sendM
+= 1;
105 me
.localClient
->sendM
+= 1;
106 if(rb_linebuf_len(&to
->localClient
->buf_sendq
) > 0)
111 /* send_linebuf_remote()
113 * inputs - client to attach to, sender, linebuf
115 * side effects - client has linebuf attached
118 send_linebuf_remote(struct Client
*to
, struct Client
*from
, buf_head_t
*linebuf
)
123 /* we assume the caller has already tested for fake direction */
124 _send_linebuf(to
, linebuf
);
127 /* send_queued_write()
129 * inputs - fd to have queue sent, client we're sending to
130 * outputs - contents of queue
131 * side effects - write is rescheduled if queue isnt emptied
134 send_queued(struct Client
*to
)
138 rb_fde_t
*F
= to
->localClient
->F
;
142 /* cant write anything to a dead socket. */
146 /* try to flush later when the write event resets this */
150 if(rb_linebuf_len(&to
->localClient
->buf_sendq
))
153 rb_linebuf_flush(F
, &to
->localClient
->buf_sendq
)) > 0)
155 /* We have some data written .. update counters */
158 to
->localClient
->sendB
+= retlen
;
159 me
.localClient
->sendB
+= retlen
;
160 if(to
->localClient
->sendB
> 1023)
162 to
->localClient
->sendK
+= (to
->localClient
->sendB
>> 10);
163 to
->localClient
->sendB
&= 0x03ff; /* 2^10 = 1024, 3ff = 1023 */
165 else if(me
.localClient
->sendB
> 1023)
167 me
.localClient
->sendK
+= (me
.localClient
->sendB
>> 10);
168 me
.localClient
->sendB
&= 0x03ff;
172 if(retlen
== 0 || (retlen
< 0 && !rb_ignore_errno(errno
)))
179 if(rb_linebuf_len(&to
->localClient
->buf_sendq
))
182 rb_setselect(to
->localClient
->F
, RB_SELECT_WRITE
,
183 send_queued_write
, to
);
190 send_pop_queue(struct Client
*to
)
194 if(!MyConnect(to
) || IsIOError(to
))
196 if(rb_linebuf_len(&to
->localClient
->buf_sendq
) > 0)
200 /* send_queued_write()
202 * inputs - fd to have queue sent, client we're sending to
203 * outputs - contents of queue
204 * side effects - write is scheduled if queue isnt emptied
207 send_queued_write(rb_fde_t
*F
, void *data
)
209 struct Client
*to
= data
;
217 * inputs - msgbuf header, linebuf object, capability mask, pattern, arguments
219 * side effects - the linebuf object is cleared, then populated
222 linebuf_put_tags(buf_head_t
*linebuf
, const struct MsgBuf
*msgbuf
, const struct Client
*target_p
, rb_strf_t
*message
)
224 struct MsgBuf_str_data msgbuf_str_data
= { .msgbuf
= msgbuf
, .caps
= CLIENT_CAPS_ONLY(target_p
) };
225 rb_strf_t strings
= { .func
= msgbuf_unparse_linebuf_tags
, .func_args
= &msgbuf_str_data
, .length
= TAGSLEN
+ 1, .next
= message
};
227 message
->length
= DATALEN
+ 1;
228 rb_linebuf_put(linebuf
, &strings
);
232 linebuf_put_tagsf(buf_head_t
*linebuf
, const struct MsgBuf
*msgbuf
, const struct Client
*target_p
, const rb_strf_t
*message
, const char *format
, ...)
235 rb_strf_t strings
= { .format
= format
, .format_args
= &va
, .next
= message
};
237 va_start(va
, format
);
238 linebuf_put_tags(linebuf
, msgbuf
, target_p
, &strings
);
243 linebuf_put_msg(buf_head_t
*linebuf
, rb_strf_t
*message
)
245 message
->length
= DATALEN
+ 1;
246 rb_linebuf_put(linebuf
, message
);
250 linebuf_put_msgf(buf_head_t
*linebuf
, const rb_strf_t
*message
, const char *format
, ...)
253 rb_strf_t strings
= { .format
= format
, .format_args
= &va
, .next
= message
};
255 va_start(va
, format
);
256 linebuf_put_msg(linebuf
, &strings
);
262 * inputs - msgbuf object, client the message is from
264 * side effects - a msgbuf object is populated with an origin and relevant tags
265 * notes - to make this reentrant, find a solution for `buf` below
268 build_msgbuf_tags(struct MsgBuf
*msgbuf
, struct Client
*from
)
277 call_hook(h_outbound_msgbuf
, &hdata
);
282 * inputs - client to send to, va_args
283 * outputs - client has message put into its queue
287 sendto_one(struct Client
*target_p
, const char *pattern
, ...)
290 struct MsgBuf msgbuf
;
292 rb_strf_t strings
= { .format
= pattern
, .format_args
= &args
, .next
= NULL
};
294 /* send remote if to->from non NULL */
295 if(target_p
->from
!= NULL
)
296 target_p
= target_p
->from
;
298 if(IsIOError(target_p
))
301 rb_linebuf_newbuf(&linebuf
);
303 build_msgbuf_tags(&msgbuf
, &me
);
304 va_start(args
, pattern
);
305 linebuf_put_tags(&linebuf
, &msgbuf
, target_p
, &strings
);
308 _send_linebuf(target_p
, &linebuf
);
310 rb_linebuf_donebuf(&linebuf
);
313 /* sendto_one_prefix()
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
320 sendto_one_prefix(struct Client
*target_p
, struct Client
*source_p
,
321 const char *command
, const char *pattern
, ...)
323 struct Client
*dest_p
= target_p
->from
;
325 struct MsgBuf msgbuf
;
327 rb_strf_t strings
= { .format
= pattern
, .format_args
= &args
, .next
= NULL
};
329 if(IsIOError(dest_p
))
334 sendto_realops_snomask(SNO_GENERAL
, L_ALL
, "Trying to send to myself!");
338 build_msgbuf_tags(&msgbuf
, source_p
);
340 rb_linebuf_newbuf(&linebuf
);
341 va_start(args
, pattern
);
342 linebuf_put_tagsf(&linebuf
, &msgbuf
, target_p
, &strings
,
343 ":%s %s %s ", get_id(source_p
, target_p
),
344 command
, get_id(target_p
, target_p
));
347 _send_linebuf(dest_p
, &linebuf
);
348 rb_linebuf_donebuf(&linebuf
);
351 /* sendto_one_notice()
353 * inputs - client to send to, va_args
354 * outputs - client has a NOTICE put into its queue
355 * side effects - source(us)/target is chosen based on TS6 capability
358 sendto_one_notice(struct Client
*target_p
, const char *pattern
, ...)
360 struct Client
*dest_p
= target_p
->from
;
362 struct MsgBuf msgbuf
;
364 rb_strf_t strings
= { .format
= pattern
, .format_args
= &args
, .next
= NULL
};
367 if(IsIOError(dest_p
))
372 sendto_realops_snomask(SNO_GENERAL
, L_ALL
, "Trying to send to myself!");
376 build_msgbuf_tags(&msgbuf
, &me
);
378 rb_linebuf_newbuf(&linebuf
);
379 va_start(args
, pattern
);
380 linebuf_put_tagsf(&linebuf
, &msgbuf
, target_p
, &strings
,
381 ":%s NOTICE %s ", get_id(&me
, target_p
),
382 *(to
= get_id(target_p
, target_p
)) != '\0' ? to
: "*");
385 _send_linebuf(dest_p
, &linebuf
);
386 rb_linebuf_donebuf(&linebuf
);
390 /* sendto_one_numeric()
392 * inputs - client to send to, va_args
393 * outputs - client has message put into its queue
394 * side effects - source/target is chosen based on TS6 capability
397 sendto_one_numeric(struct Client
*target_p
, int numeric
, const char *pattern
, ...)
399 struct Client
*dest_p
= target_p
->from
;
401 struct MsgBuf msgbuf
;
403 rb_strf_t strings
= { .format
= pattern
, .format_args
= &args
, .next
= NULL
};
406 if(IsIOError(dest_p
))
411 sendto_realops_snomask(SNO_GENERAL
, L_ALL
, "Trying to send to myself!");
415 build_msgbuf_tags(&msgbuf
, &me
);
417 rb_linebuf_newbuf(&linebuf
);
418 va_start(args
, pattern
);
419 linebuf_put_tagsf(&linebuf
, &msgbuf
, target_p
, &strings
,
420 ":%s %03d %s ", get_id(&me
, target_p
), numeric
,
421 *(to
= get_id(target_p
, target_p
)) != '\0' ? to
: "*");
424 _send_linebuf(dest_p
, &linebuf
);
425 rb_linebuf_donebuf(&linebuf
);
431 * inputs - pointer to client to NOT send to
432 * - caps or'd together which must ALL be present
433 * - caps or'd together which must ALL NOT be present
434 * - printf style format string
435 * - args to format string
437 * side effects - Send a message to all connected servers, except the
438 * client 'one' (if non-NULL), as long as the servers
439 * support ALL capabs in 'caps', and NO capabs in 'nocaps'.
441 * This function was written in an attempt to merge together the other
442 * billion sendto_*serv*() functions, which sprung up with capabs, uids etc
446 sendto_server(struct Client
*one
, struct Channel
*chptr
, unsigned long caps
,
447 unsigned long nocaps
, const char *format
, ...)
450 struct Client
*target_p
;
452 rb_dlink_node
*next_ptr
;
454 rb_strf_t strings
= { .format
= format
, .format_args
= &args
, .next
= NULL
};
456 /* noone to send to.. */
457 if(rb_dlink_list_length(&serv_list
) == 0)
460 if(chptr
!= NULL
&& *chptr
->chname
!= '#')
463 rb_linebuf_newbuf(&linebuf
);
464 va_start(args
, format
);
465 linebuf_put_msg(&linebuf
, &strings
);
468 RB_DLINK_FOREACH_SAFE(ptr
, next_ptr
, serv_list
.head
)
470 target_p
= ptr
->data
;
472 /* check against 'one' */
473 if(one
!= NULL
&& (target_p
== one
->from
))
476 /* check we have required capabs */
477 if(!IsCapable(target_p
, caps
))
480 /* check we don't have any forbidden capabs */
481 if(!NotCapable(target_p
, nocaps
))
484 _send_linebuf(target_p
, &linebuf
);
487 rb_linebuf_donebuf(&linebuf
);
490 /* sendto_channel_flags()
492 * inputs - server not to send to, flags needed, source, channel, va_args
493 * outputs - message is sent to channel members
497 sendto_channel_flags(struct Client
*one
, int type
, struct Client
*source_p
,
498 struct Channel
*chptr
, const char *pattern
, ...)
500 static char buf
[BUFSIZE
];
502 buf_head_t rb_linebuf_remote
;
503 struct Client
*target_p
;
504 struct membership
*msptr
;
506 rb_dlink_node
*next_ptr
;
507 struct MsgBuf msgbuf
;
508 struct MsgBuf_cache msgbuf_cache
;
509 rb_strf_t strings
= { .format
= buf
, .format_args
= NULL
, .next
= NULL
};
511 rb_linebuf_newbuf(&rb_linebuf_remote
);
515 build_msgbuf_tags(&msgbuf
, source_p
);
517 va_start(args
, pattern
);
518 vsnprintf(buf
, sizeof buf
, pattern
, args
);
521 linebuf_put_msgf(&rb_linebuf_remote
, NULL
, ":%s %s", use_id(source_p
), buf
);
522 msgbuf_cache_initf(&msgbuf_cache
, &msgbuf
, &strings
,
523 IsPerson(source_p
) ? ":%1$s!%2$s@%3$s " : ":%1$s ",
524 source_p
->name
, source_p
->username
, source_p
->host
);
526 RB_DLINK_FOREACH_SAFE(ptr
, next_ptr
, chptr
->members
.head
)
529 target_p
= msptr
->client_p
;
531 if(!MyClient(source_p
) && (IsIOError(target_p
->from
) || target_p
->from
== one
))
534 if(MyClient(source_p
) && target_p
== one
)
537 if(type
&& ((msptr
->flags
& type
) == 0))
543 if(!MyClient(target_p
))
545 /* if we've got a specific type, target must support
548 if(type
&& NotCapable(target_p
->from
, CAP_CHW
))
551 if(target_p
->from
->serial
!= current_serial
)
553 send_linebuf_remote(target_p
, source_p
, &rb_linebuf_remote
);
554 target_p
->from
->serial
= current_serial
;
559 _send_linebuf(target_p
, msgbuf_cache_get(&msgbuf_cache
, CLIENT_CAPS_ONLY(target_p
)));
563 /* source client may not be on the channel, send echo separately */
564 if(MyClient(source_p
) && IsCapable(source_p
, CLICAP_ECHO_MESSAGE
))
568 _send_linebuf(target_p
, msgbuf_cache_get(&msgbuf_cache
, CLIENT_CAPS_ONLY(target_p
)));
571 rb_linebuf_donebuf(&rb_linebuf_remote
);
572 msgbuf_cache_free(&msgbuf_cache
);
575 /* sendto_channel_flags()
577 * inputs - server not to send to, flags needed, source, channel, va_args
578 * outputs - message is sent to channel members
582 sendto_channel_opmod(struct Client
*one
, struct Client
*source_p
,
583 struct Channel
*chptr
, const char *command
,
586 buf_head_t rb_linebuf_old
;
587 buf_head_t rb_linebuf_new
;
588 struct Client
*target_p
;
589 struct membership
*msptr
;
591 rb_dlink_node
*next_ptr
;
592 struct MsgBuf msgbuf
;
593 struct MsgBuf_cache msgbuf_cache
;
594 rb_strf_t strings
= { .format
= text
, .format_args
= NULL
, .next
= NULL
};
596 rb_linebuf_newbuf(&rb_linebuf_old
);
597 rb_linebuf_newbuf(&rb_linebuf_new
);
599 build_msgbuf_tags(&msgbuf
, source_p
);
602 const char *statusmsg_prefix
= (ConfigChannel
.opmod_send_statusmsg
? "@" : "");
604 if(IsServer(source_p
)) {
605 msgbuf_cache_initf(&msgbuf_cache
, &msgbuf
, &strings
,
607 source_p
->name
, command
, statusmsg_prefix
, chptr
->chname
);
609 msgbuf_cache_initf(&msgbuf_cache
, &msgbuf
, &strings
,
610 ":%s!%s@%s %s %s%s :",
611 source_p
->name
, source_p
->username
,
612 source_p
->host
, command
, statusmsg_prefix
, chptr
->chname
);
615 if (chptr
->mode
.mode
& MODE_MODERATED
) {
616 linebuf_put_msgf(&rb_linebuf_old
, &strings
,
618 use_id(source_p
), command
, statusmsg_prefix
, chptr
->chname
, text
);
620 linebuf_put_msgf(&rb_linebuf_old
, &strings
,
621 ":%s NOTICE @%s :<%s:%s> ",
622 use_id(source_p
->servptr
), chptr
->chname
,
623 source_p
->name
, chptr
->chname
);
625 linebuf_put_msgf(&rb_linebuf_new
, &strings
,
627 use_id(source_p
), command
, chptr
->chname
);
628 RB_DLINK_FOREACH_SAFE(ptr
, next_ptr
, chptr
->members
.head
)
631 target_p
= msptr
->client_p
;
633 if(!MyClient(source_p
) && (IsIOError(target_p
->from
) || target_p
->from
== one
))
636 if(MyClient(source_p
) && target_p
== one
)
639 if((msptr
->flags
& CHFL_CHANOP
) == 0)
645 if(!MyClient(target_p
))
647 /* if we've got a specific type, target must support
650 if(NotCapable(target_p
->from
, CAP_CHW
))
653 if(target_p
->from
->serial
!= current_serial
)
655 if (IsCapable(target_p
->from
, CAP_EOPMOD
))
656 send_linebuf_remote(target_p
, source_p
, &rb_linebuf_new
);
658 send_linebuf_remote(target_p
, source_p
, &rb_linebuf_old
);
659 target_p
->from
->serial
= current_serial
;
662 _send_linebuf(target_p
, msgbuf_cache_get(&msgbuf_cache
, CLIENT_CAPS_ONLY(target_p
)));
666 /* source client may not be on the channel, send echo separately */
667 if(MyClient(source_p
) && IsCapable(source_p
, CLICAP_ECHO_MESSAGE
))
671 _send_linebuf(target_p
, msgbuf_cache_get(&msgbuf_cache
, CLIENT_CAPS_ONLY(target_p
)));
674 rb_linebuf_donebuf(&rb_linebuf_old
);
675 rb_linebuf_donebuf(&rb_linebuf_new
);
676 msgbuf_cache_free(&msgbuf_cache
);
679 /* _sendto_channel_local
681 * inputs - source, flags to send to, privs to send to, channel to send to, va_args
682 * outputs - message to local channel members
686 _sendto_channel_local(struct Client
*source_p
, int type
, const char *priv
, struct Channel
*chptr
, const char *pattern
, va_list *args
)
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 msgbuf_cache_init(&msgbuf_cache
, &msgbuf
, &strings
);
700 RB_DLINK_FOREACH_SAFE(ptr
, next_ptr
, chptr
->locmembers
.head
)
703 target_p
= msptr
->client_p
;
705 if (IsIOError(target_p
))
708 if (type
&& ((msptr
->flags
& type
) == 0))
711 if (priv
!= NULL
&& !HasPrivilege(target_p
, priv
))
714 _send_linebuf(target_p
, msgbuf_cache_get(&msgbuf_cache
, CLIENT_CAPS_ONLY(target_p
)));
717 msgbuf_cache_free(&msgbuf_cache
);
720 /* sendto_channel_local_priv()
722 * inputs - source, flags to send to, privs to send to, channel to send to, va_args
723 * outputs - message to local channel members
727 sendto_channel_local_priv(struct Client
*source_p
, int type
, const char *priv
, struct Channel
*chptr
, const char *pattern
, ...)
730 va_start(args
, pattern
);
731 _sendto_channel_local(source_p
, type
, priv
, chptr
, pattern
, &args
);
735 /* sendto_channel_local()
737 * inputs - source, flags to send to, channel to send to, va_args
738 * outputs - message to local channel members
742 sendto_channel_local(struct Client
*source_p
, int type
, struct Channel
*chptr
, const char *pattern
, ...)
745 va_start(args
, pattern
);
746 _sendto_channel_local(source_p
, type
, NULL
, chptr
, pattern
, &args
);
751 * _sendto_channel_local_with_capability_butone()
753 * Shared implementation of sendto_channel_local_with_capability and sendto_channel_local_with_capability_butone
756 _sendto_channel_local_with_capability_butone(struct Client
*source_p
, struct Client
*one
, int type
,
757 int caps
, int negcaps
, struct Channel
*chptr
, const char *pattern
, va_list * args
)
759 struct membership
*msptr
;
760 struct Client
*target_p
;
762 rb_dlink_node
*next_ptr
;
763 struct MsgBuf msgbuf
;
764 struct MsgBuf_cache msgbuf_cache
;
765 rb_strf_t strings
= { .format
= pattern
, .format_args
= args
, .next
= NULL
};
767 build_msgbuf_tags(&msgbuf
, source_p
);
768 msgbuf_cache_init(&msgbuf_cache
, &msgbuf
, &strings
);
770 RB_DLINK_FOREACH_SAFE(ptr
, next_ptr
, chptr
->locmembers
.head
)
773 target_p
= msptr
->client_p
;
778 if(IsIOError(target_p
) ||
779 !IsCapable(target_p
, caps
) ||
780 !NotCapable(target_p
, negcaps
))
783 if(type
&& ((msptr
->flags
& type
) == 0))
786 _send_linebuf(target_p
, msgbuf_cache_get(&msgbuf_cache
, CLIENT_CAPS_ONLY(target_p
)));
789 msgbuf_cache_free(&msgbuf_cache
);
792 /* sendto_channel_local_with_capability()
794 * inputs - source, flags to send to, caps, negate caps, channel to send to, va_args
795 * outputs - message to local channel members
799 sendto_channel_local_with_capability(struct Client
*source_p
, int type
, int caps
, int negcaps
, struct Channel
*chptr
, const char *pattern
, ...)
803 va_start(args
, pattern
);
804 _sendto_channel_local_with_capability_butone(source_p
, NULL
, type
, caps
, negcaps
, chptr
, pattern
, &args
);
809 /* sendto_channel_local_with_capability()
811 * inputs - source, flags to send to, caps, negate caps, channel to send to, va_args
812 * outputs - message to local channel members
816 sendto_channel_local_with_capability_butone(struct Client
*one
, int type
,
817 int caps
, int negcaps
, struct Channel
*chptr
, const char *pattern
, ...)
821 va_start(args
, pattern
);
822 _sendto_channel_local_with_capability_butone(one
, one
, type
, caps
, negcaps
, chptr
, pattern
, &args
);
827 /* sendto_channel_local_butone()
829 * inputs - flags to send to, channel to send to, va_args
830 * - user to ignore when sending
831 * outputs - message to local channel members
835 sendto_channel_local_butone(struct Client
*one
, int type
, struct Channel
*chptr
, const char *pattern
, ...)
838 struct membership
*msptr
;
839 struct Client
*target_p
;
840 struct MsgBuf msgbuf
;
842 rb_dlink_node
*next_ptr
;
843 struct MsgBuf_cache msgbuf_cache
;
844 rb_strf_t strings
= { .format
= pattern
, .format_args
= &args
, .next
= NULL
};
846 build_msgbuf_tags(&msgbuf
, one
);
848 va_start(args
, pattern
);
849 msgbuf_cache_init(&msgbuf_cache
, &msgbuf
, &strings
);
852 RB_DLINK_FOREACH_SAFE(ptr
, next_ptr
, chptr
->locmembers
.head
)
855 target_p
= msptr
->client_p
;
860 if(IsIOError(target_p
))
863 if(type
&& ((msptr
->flags
& type
) == 0))
866 /* attach the present linebuf to the target */
867 _send_linebuf(target_p
, msgbuf_cache_get(&msgbuf_cache
, CLIENT_CAPS_ONLY(target_p
)));
870 msgbuf_cache_free(&msgbuf_cache
);
874 * sendto_common_channels_local()
876 * inputs - pointer to client
878 * - negated capability mask
881 * side effects - Sends a message to all people on local server who are
882 * in same channel with user.
883 * used by m_nick.c and exit_one_client.
886 sendto_common_channels_local(struct Client
*user
, int cap
, int negcap
, const char *pattern
, ...)
890 rb_dlink_node
*next_ptr
;
892 rb_dlink_node
*next_uptr
;
893 struct Channel
*chptr
;
894 struct Client
*target_p
;
895 struct membership
*msptr
;
896 struct membership
*mscptr
;
897 struct MsgBuf msgbuf
;
898 struct MsgBuf_cache msgbuf_cache
;
899 rb_strf_t strings
= { .format
= pattern
, .format_args
= &args
, .next
= NULL
};
901 build_msgbuf_tags(&msgbuf
, user
);
903 va_start(args
, pattern
);
904 msgbuf_cache_init(&msgbuf_cache
, &msgbuf
, &strings
);
909 RB_DLINK_FOREACH_SAFE(ptr
, next_ptr
, user
->user
->channel
.head
)
912 chptr
= mscptr
->chptr
;
914 RB_DLINK_FOREACH_SAFE(uptr
, next_uptr
, chptr
->locmembers
.head
)
917 target_p
= msptr
->client_p
;
919 if(IsIOError(target_p
) ||
920 target_p
->serial
== current_serial
||
921 !IsCapable(target_p
, cap
) ||
922 !NotCapable(target_p
, negcap
))
925 target_p
->serial
= current_serial
;
926 send_linebuf(target_p
, msgbuf_cache_get(&msgbuf_cache
, CLIENT_CAPS_ONLY(target_p
)));
930 /* this can happen when the user isnt in any channels, but we still
931 * need to send them the data, ie a nick change
933 if(MyConnect(user
) && (user
->serial
!= current_serial
)
934 && IsCapable(user
, cap
) && NotCapable(user
, negcap
)) {
935 send_linebuf(user
, msgbuf_cache_get(&msgbuf_cache
, CLIENT_CAPS_ONLY(user
)));
938 msgbuf_cache_free(&msgbuf_cache
);
942 * sendto_common_channels_local_butone()
944 * inputs - pointer to client
946 * - negated capability mask
949 * side effects - Sends a message to all people on local server who are
950 * in same channel with user, except for user itself.
953 sendto_common_channels_local_butone(struct Client
*user
, int cap
, int negcap
, const char *pattern
, ...)
957 rb_dlink_node
*next_ptr
;
959 rb_dlink_node
*next_uptr
;
960 struct Channel
*chptr
;
961 struct Client
*target_p
;
962 struct membership
*msptr
;
963 struct membership
*mscptr
;
964 struct MsgBuf msgbuf
;
965 struct MsgBuf_cache msgbuf_cache
;
966 rb_strf_t strings
= { .format
= pattern
, .format_args
= &args
, .next
= NULL
};
968 build_msgbuf_tags(&msgbuf
, user
);
970 va_start(args
, pattern
);
971 msgbuf_cache_init(&msgbuf_cache
, &msgbuf
, &strings
);
975 /* Skip them -- jilles */
976 user
->serial
= current_serial
;
978 RB_DLINK_FOREACH_SAFE(ptr
, next_ptr
, user
->user
->channel
.head
)
981 chptr
= mscptr
->chptr
;
983 RB_DLINK_FOREACH_SAFE(uptr
, next_uptr
, chptr
->locmembers
.head
)
986 target_p
= msptr
->client_p
;
988 if(IsIOError(target_p
) ||
989 target_p
->serial
== current_serial
||
990 !IsCapable(target_p
, cap
) ||
991 !NotCapable(target_p
, negcap
))
994 target_p
->serial
= current_serial
;
995 send_linebuf(target_p
, msgbuf_cache_get(&msgbuf_cache
, CLIENT_CAPS_ONLY(target_p
)));
999 msgbuf_cache_free(&msgbuf_cache
);
1002 /* sendto_match_butone()
1004 * inputs - server not to send to, source, mask, type of mask, va_args
1006 * side effects - message is sent to matching clients
1009 sendto_match_butone(struct Client
*one
, struct Client
*source_p
,
1010 const char *mask
, int what
, const char *pattern
, ...)
1012 static char buf
[BUFSIZE
];
1014 struct Client
*target_p
;
1016 rb_dlink_node
*next_ptr
;
1017 buf_head_t rb_linebuf_remote
;
1018 struct MsgBuf msgbuf
;
1019 struct MsgBuf_cache msgbuf_cache
;
1020 rb_strf_t strings
= { .format
= buf
, .format_args
= NULL
, .next
= NULL
};
1022 rb_linebuf_newbuf(&rb_linebuf_remote
);
1024 build_msgbuf_tags(&msgbuf
, source_p
);
1026 va_start(args
, pattern
);
1027 vsnprintf(buf
, sizeof(buf
), pattern
, args
);
1030 msgbuf_cache_initf(&msgbuf_cache
, &msgbuf
, &strings
,
1031 IsServer(source_p
) ? ":%s " : ":%s!%s@%s ",
1032 source_p
->name
, source_p
->username
, source_p
->host
);
1034 linebuf_put_msgf(&rb_linebuf_remote
, &strings
, ":%s ", use_id(source_p
));
1036 if(what
== MATCH_HOST
)
1038 RB_DLINK_FOREACH_SAFE(ptr
, next_ptr
, lclient_list
.head
)
1040 target_p
= ptr
->data
;
1042 if(match(mask
, target_p
->host
))
1043 _send_linebuf(target_p
, msgbuf_cache_get(&msgbuf_cache
, CLIENT_CAPS_ONLY(target_p
)));
1046 /* what = MATCH_SERVER, if it doesnt match us, just send remote */
1047 else if(match(mask
, me
.name
))
1049 RB_DLINK_FOREACH_SAFE(ptr
, next_ptr
, lclient_list
.head
)
1051 target_p
= ptr
->data
;
1052 _send_linebuf(target_p
, msgbuf_cache_get(&msgbuf_cache
, CLIENT_CAPS_ONLY(target_p
)));
1056 RB_DLINK_FOREACH(ptr
, serv_list
.head
)
1058 target_p
= ptr
->data
;
1063 send_linebuf_remote(target_p
, source_p
, &rb_linebuf_remote
);
1066 msgbuf_cache_free(&msgbuf_cache
);
1067 rb_linebuf_donebuf(&rb_linebuf_remote
);
1070 /* sendto_match_servs()
1072 * inputs - source, mask to send to, caps needed, va_args
1074 * side effects - message is sent to matching servers with caps.
1077 sendto_match_servs(struct Client
*source_p
, const char *mask
, int cap
,
1078 int nocap
, const char *pattern
, ...)
1080 static char buf
[BUFSIZE
];
1083 struct Client
*target_p
;
1084 buf_head_t rb_linebuf_id
;
1085 rb_strf_t strings
= { .format
= buf
, .format_args
= NULL
, .next
= NULL
};
1087 if(EmptyString(mask
))
1090 rb_linebuf_newbuf(&rb_linebuf_id
);
1092 va_start(args
, pattern
);
1093 vsnprintf(buf
, sizeof(buf
), pattern
, args
);
1096 linebuf_put_msgf(&rb_linebuf_id
, &strings
, ":%s ", use_id(source_p
));
1100 RB_DLINK_FOREACH(ptr
, global_serv_list
.head
)
1102 target_p
= ptr
->data
;
1104 /* dont send to ourselves, or back to where it came from.. */
1105 if(IsMe(target_p
) || target_p
->from
== source_p
->from
)
1108 if(target_p
->from
->serial
== current_serial
)
1111 if(match(mask
, target_p
->name
))
1113 /* if we set the serial here, then we'll never do
1114 * a match() again if !IsCapable()
1116 target_p
->from
->serial
= current_serial
;
1118 if(cap
&& !IsCapable(target_p
->from
, cap
))
1121 if(nocap
&& !NotCapable(target_p
->from
, nocap
))
1124 _send_linebuf(target_p
->from
, &rb_linebuf_id
);
1128 rb_linebuf_donebuf(&rb_linebuf_id
);
1131 /* sendto_local_clients_with_capability()
1133 * inputs - caps needed, pattern, va_args
1135 * side effects - message is sent to matching local clients with caps.
1138 sendto_local_clients_with_capability(int cap
, const char *pattern
, ...)
1142 struct Client
*target_p
;
1143 struct MsgBuf msgbuf
;
1144 struct MsgBuf_cache msgbuf_cache
;
1145 rb_strf_t strings
= { .format
= pattern
, .format_args
= &args
, .next
= NULL
};
1147 build_msgbuf_tags(&msgbuf
, &me
);
1149 va_start(args
, pattern
);
1150 msgbuf_cache_init(&msgbuf_cache
, &msgbuf
, &strings
);
1153 RB_DLINK_FOREACH(ptr
, lclient_list
.head
)
1155 target_p
= ptr
->data
;
1157 if(IsIOError(target_p
) || !IsCapable(target_p
, cap
))
1160 send_linebuf(target_p
, msgbuf_cache_get(&msgbuf_cache
, CLIENT_CAPS_ONLY(target_p
)));
1163 msgbuf_cache_free(&msgbuf_cache
);
1168 * inputs - monitor nick to send to, format, va_args
1169 * outputs - message to local users monitoring the given nick
1173 sendto_monitor(struct Client
*source_p
, struct monitor
*monptr
, const char *pattern
, ...)
1176 struct Client
*target_p
;
1178 rb_dlink_node
*next_ptr
;
1179 struct MsgBuf msgbuf
;
1180 struct MsgBuf_cache msgbuf_cache
;
1181 rb_strf_t strings
= { .format
= pattern
, .format_args
= &args
, .next
= NULL
};
1183 build_msgbuf_tags(&msgbuf
, source_p
);
1185 va_start(args
, pattern
);
1186 msgbuf_cache_init(&msgbuf_cache
, &msgbuf
, &strings
);
1189 RB_DLINK_FOREACH_SAFE(ptr
, next_ptr
, monptr
->users
.head
)
1191 target_p
= ptr
->data
;
1193 if(IsIOError(target_p
))
1196 _send_linebuf(target_p
, msgbuf_cache_get(&msgbuf_cache
, CLIENT_CAPS_ONLY(target_p
)));
1199 msgbuf_cache_free(&msgbuf_cache
);
1202 /* _sendto_anywhere()
1204 * inputs - real_target, target, source, va_args
1206 * side effects - client is sent message/own message with correct prefix.
1209 _sendto_anywhere(struct Client
*dest_p
, struct Client
*target_p
,
1210 struct Client
*source_p
, const char *command
,
1211 const char *pattern
, va_list *args
)
1214 rb_strf_t strings
= { .format
= pattern
, .format_args
= args
, .next
= NULL
};
1216 rb_linebuf_newbuf(&linebuf
);
1218 if (MyClient(dest_p
)) {
1219 if (IsServer(source_p
)) {
1220 linebuf_put_msgf(&linebuf
, &strings
, ":%s %s %s ",
1221 source_p
->name
, command
,
1224 struct MsgBuf msgbuf
;
1226 build_msgbuf_tags(&msgbuf
, source_p
);
1228 linebuf_put_tagsf(&linebuf
, &msgbuf
, dest_p
, &strings
,
1229 IsPerson(source_p
) ? ":%1$s!%4$s@%5$s %2$s %3$s " : ":%1$s %2$s %3$s ",
1230 source_p
->name
, command
, target_p
->name
,
1231 source_p
->username
, source_p
->host
);
1234 _send_linebuf(dest_p
, &linebuf
);
1236 linebuf_put_msgf(&linebuf
, &strings
, ":%s %s %s ",
1237 get_id(source_p
, target_p
), command
,
1238 get_id(target_p
, target_p
));
1240 send_linebuf_remote(dest_p
, source_p
, &linebuf
);
1243 rb_linebuf_donebuf(&linebuf
);
1246 /* sendto_anywhere()
1248 * inputs - target, source, va_args
1250 * side effects - client is sent message with correct prefix.
1253 sendto_anywhere(struct Client
*target_p
, struct Client
*source_p
,
1254 const char *command
, const char *pattern
, ...)
1258 va_start(args
, pattern
);
1259 _sendto_anywhere(target_p
, target_p
, source_p
, command
, pattern
, &args
);
1263 /* sendto_anywhere_echo()
1265 * inputs - target, source, va_args
1267 * side effects - client is sent own message with correct prefix.
1270 sendto_anywhere_echo(struct Client
*target_p
, struct Client
*source_p
,
1271 const char *command
, const char *pattern
, ...)
1275 s_assert(MyClient(source_p
));
1276 s_assert(!IsServer(source_p
));
1278 va_start(args
, pattern
);
1279 _sendto_anywhere(source_p
, target_p
, source_p
, command
, pattern
, &args
);
1283 /* sendto_realops_snomask()
1285 * inputs - snomask needed, level (opers/admin), va_args
1287 * side effects - message is sent to opers with matching snomasks
1290 sendto_realops_snomask(int flags
, int level
, const char *pattern
, ...)
1292 static char buf
[BUFSIZE
];
1294 struct Client
*client_p
;
1296 rb_dlink_node
*next_ptr
;
1298 struct MsgBuf msgbuf
;
1299 struct MsgBuf_cache msgbuf_cache
;
1301 build_msgbuf_tags(&msgbuf
, &me
);
1303 /* rather a lot of copying around, oh well -- jilles */
1304 va_start(args
, pattern
);
1305 vsnprintf(buf
, sizeof(buf
), pattern
, args
);
1308 msgbuf_cache_initf(&msgbuf_cache
, &msgbuf
, NULL
,
1309 ":%s NOTICE * :*** Notice -- %s", me
.name
, buf
);
1311 /* Be very sure not to do things like "Trying to send to myself"
1312 * L_NETWIDE, otherwise infinite recursion may result! -- jilles */
1313 if (level
& L_NETWIDE
&& ConfigFileEntry
.global_snotices
)
1315 snobuf
= construct_snobuf(flags
);
1316 if (snobuf
[1] != '\0')
1317 sendto_server(NULL
, NULL
, CAP_ENCAP
|CAP_TS6
, NOCAPS
,
1318 ":%s ENCAP * SNOTE %c :%s",
1319 me
.id
, snobuf
[1], buf
);
1321 else if (remote_rehash_oper_p
!= NULL
)
1323 sendto_one_notice(remote_rehash_oper_p
, ":*** Notice -- %s", buf
);
1325 level
&= ~L_NETWIDE
;
1327 RB_DLINK_FOREACH_SAFE(ptr
, next_ptr
, local_oper_list
.head
)
1329 client_p
= ptr
->data
;
1331 /* If we're sending it to opers and theyre an admin, skip.
1332 * If we're sending it to admins, and theyre not, skip.
1334 if(((level
== L_ADMIN
) && !IsOperAdmin(client_p
)) ||
1335 ((level
== L_OPER
) && IsOperAdmin(client_p
)))
1338 if (client_p
->snomask
& flags
) {
1339 _send_linebuf(client_p
, msgbuf_cache_get(&msgbuf_cache
, CLIENT_CAPS_ONLY(client_p
)));
1343 msgbuf_cache_free(&msgbuf_cache
);
1345 /* sendto_realops_snomask_from()
1347 * inputs - snomask needed, level (opers/admin), source server, va_args
1349 * side effects - message is sent to opers with matching snomask
1352 sendto_realops_snomask_from(int flags
, int level
, struct Client
*source_p
,
1353 const char *pattern
, ...)
1355 struct Client
*client_p
;
1357 rb_dlink_node
*next_ptr
;
1359 struct MsgBuf msgbuf
;
1360 struct MsgBuf_cache msgbuf_cache
;
1361 rb_strf_t strings
= { .format
= pattern
, .format_args
= &args
, .next
= NULL
};
1363 build_msgbuf_tags(&msgbuf
, &me
);
1365 va_start(args
, pattern
);
1366 msgbuf_cache_initf(&msgbuf_cache
, &msgbuf
, &strings
,
1367 ":%s NOTICE * :*** Notice -- ", source_p
->name
);
1370 RB_DLINK_FOREACH_SAFE(ptr
, next_ptr
, local_oper_list
.head
)
1372 client_p
= ptr
->data
;
1374 /* If we're sending it to opers and theyre an admin, skip.
1375 * If we're sending it to admins, and theyre not, skip.
1377 if(((level
== L_ADMIN
) && !IsOperAdmin(client_p
)) ||
1378 ((level
== L_OPER
) && IsOperAdmin(client_p
)))
1381 if (client_p
->snomask
& flags
) {
1382 _send_linebuf(client_p
, msgbuf_cache_get(&msgbuf_cache
, CLIENT_CAPS_ONLY(client_p
)));
1386 msgbuf_cache_free(&msgbuf_cache
);
1390 * sendto_wallops_flags
1392 * inputs - flag types of messages to show to real opers
1393 * - client sending request
1394 * - var args input message
1396 * side effects - Send a wallops to local opers
1399 sendto_wallops_flags(int flags
, struct Client
*source_p
, const char *pattern
, ...)
1401 struct Client
*client_p
;
1403 rb_dlink_node
*next_ptr
;
1405 struct MsgBuf msgbuf
;
1406 struct MsgBuf_cache msgbuf_cache
;
1407 rb_strf_t strings
= { .format
= pattern
, .format_args
= &args
, .next
= NULL
};
1409 build_msgbuf_tags(&msgbuf
, source_p
);
1411 va_start(args
, pattern
);
1412 if (IsPerson(source_p
)) {
1413 msgbuf_cache_initf(&msgbuf_cache
, &msgbuf
, &strings
,
1414 ":%s!%s@%s WALLOPS :", source_p
->name
,
1415 source_p
->username
, source_p
->host
);
1417 msgbuf_cache_initf(&msgbuf_cache
, &msgbuf
, &strings
,
1418 ":%s WALLOPS :", source_p
->name
);
1422 RB_DLINK_FOREACH_SAFE(ptr
, next_ptr
, IsPerson(source_p
) && flags
== UMODE_WALLOP
? lclient_list
.head
: local_oper_list
.head
)
1424 client_p
= ptr
->data
;
1426 if (client_p
->umodes
& flags
) {
1427 _send_linebuf(client_p
, msgbuf_cache_get(&msgbuf_cache
, CLIENT_CAPS_ONLY(client_p
)));
1431 msgbuf_cache_free(&msgbuf_cache
);
1436 * input - client to send kill to, client to kill, va_args
1438 * side effects - we issue a kill for the client
1441 kill_client(struct Client
*target_p
, struct Client
*diedie
, const char *pattern
, ...)
1445 struct MsgBuf msgbuf
;
1446 rb_strf_t strings
= { .format
= pattern
, .format_args
= &args
, .next
= NULL
};
1448 build_msgbuf_tags(&msgbuf
, &me
);
1450 rb_linebuf_newbuf(&linebuf
);
1452 va_start(args
, pattern
);
1453 linebuf_put_tagsf(&linebuf
, &msgbuf
, target_p
, &strings
,
1454 ":%s KILL %s :", get_id(&me
, target_p
), get_id(diedie
, target_p
));
1457 send_linebuf(target_p
, &linebuf
);
1458 rb_linebuf_donebuf(&linebuf
);
1463 * kill_client_serv_butone
1465 * inputs - pointer to client to not send to
1466 * - pointer to client to kill
1468 * side effects - Send a KILL for the given client
1469 * message to all connected servers
1470 * except the client 'one'. Also deal with
1471 * client being unknown to leaf, as in lazylink...
1474 kill_client_serv_butone(struct Client
*one
, struct Client
*target_p
, const char *pattern
, ...)
1476 static char buf
[BUFSIZE
];
1478 struct Client
*client_p
;
1480 rb_dlink_node
*next_ptr
;
1481 buf_head_t rb_linebuf_id
;
1482 rb_strf_t strings
= { .format
= pattern
, .format_args
= &args
, .next
= NULL
};
1484 rb_linebuf_newbuf(&rb_linebuf_id
);
1486 va_start(args
, pattern
);
1487 linebuf_put_msgf(&rb_linebuf_id
, &strings
, ":%s KILL %s :%s",
1488 use_id(&me
), use_id(target_p
), buf
);
1491 RB_DLINK_FOREACH_SAFE(ptr
, next_ptr
, serv_list
.head
)
1493 client_p
= ptr
->data
;
1495 /* ok, if the client we're supposed to not send to has an
1496 * ID, then we still want to issue the kill there..
1498 if(one
!= NULL
&& (client_p
== one
->from
) &&
1499 (!has_id(client_p
) || !has_id(target_p
)))
1502 _send_linebuf(client_p
, &rb_linebuf_id
);
1505 rb_linebuf_donebuf(&rb_linebuf_id
);
1508 static struct Client
*multiline_stashed_target_p
;
1509 static char multiline_prefix
[DATALEN
+1]; /* allow for null termination */
1510 static int multiline_prefix_len
;
1511 static char multiline_separator
[2];
1512 static int multiline_separator_len
;
1513 static char *multiline_item_start
;
1514 static char *multiline_cur
;
1515 static int multiline_cur_len
;
1516 static int multiline_remote_pad
;
1519 send_multiline_init(struct Client
*target_p
, const char *separator
, const char *format
, ...)
1523 s_assert(multiline_stashed_target_p
== NULL
&& "Multiline: didn't cleanup after last usage!");
1525 va_start(args
, format
);
1526 multiline_prefix_len
= vsnprintf(multiline_prefix
, sizeof multiline_prefix
, format
, args
);
1529 if (multiline_prefix_len
<= 0 || multiline_prefix_len
>= DATALEN
)
1531 s_assert(false && "Multiline: failure preparing prefix!");
1535 multiline_separator_len
= rb_strlcpy(multiline_separator
, separator
, sizeof multiline_separator
);
1536 if (multiline_separator_len
>= sizeof multiline_separator
)
1538 s_assert(false && "Multiline: separator too long");
1542 multiline_stashed_target_p
= target_p
;
1543 multiline_item_start
= multiline_prefix
+ multiline_prefix_len
;
1544 multiline_cur
= multiline_item_start
;
1545 multiline_cur_len
= multiline_prefix_len
;
1546 multiline_remote_pad
= 0;
1551 send_multiline_remote_pad(struct Client
*target_p
, struct Client
*client_p
)
1555 if (target_p
!= multiline_stashed_target_p
)
1557 s_assert(false && "Multiline: missed init call!");
1558 multiline_stashed_target_p
= NULL
;
1562 if (MyConnect(target_p
))
1565 remote_pad
= strlen(client_p
->name
) - strlen(client_p
->id
);
1569 multiline_remote_pad
+= remote_pad
;
1575 enum multiline_item_result
1576 send_multiline_item(struct Client
*target_p
, const char *format
, ...)
1581 enum multiline_item_result ret
= MULTILINE_SUCCESS
;
1583 if (target_p
!= multiline_stashed_target_p
)
1585 s_assert(false && "Multiline: missed init call!");
1586 multiline_stashed_target_p
= NULL
;
1587 return MULTILINE_FAILURE
;
1590 va_start(args
, format
);
1591 item_len
= vsnprintf(item
, sizeof item
, format
, args
);
1594 if (item_len
< 0 || multiline_prefix_len
+ multiline_remote_pad
+ item_len
> DATALEN
)
1596 s_assert(false && "Multiline: failure preparing item!");
1597 multiline_stashed_target_p
= NULL
;
1598 return MULTILINE_FAILURE
;
1601 if (multiline_cur_len
+ ((*multiline_item_start
!= '\0') ? multiline_separator_len
: 0) + item_len
> DATALEN
- multiline_remote_pad
)
1603 sendto_one(target_p
, "%s", multiline_prefix
);
1604 *multiline_item_start
= '\0';
1605 multiline_cur_len
= multiline_prefix_len
;
1606 multiline_cur
= multiline_item_start
;
1607 ret
= MULTILINE_WRAPPED
;
1610 res
= snprintf(multiline_cur
, sizeof multiline_prefix
- multiline_cur_len
, "%s%s",
1611 (*multiline_item_start
!= '\0') ? multiline_separator
: "",
1616 s_assert(false && "Multiline: failure appending item!");
1617 multiline_stashed_target_p
= NULL
;
1618 return MULTILINE_FAILURE
;
1621 multiline_cur_len
+= res
;
1622 multiline_cur
+= res
;
1627 send_multiline_fini(struct Client
*target_p
, const char *format
, ...)
1630 char final
[DATALEN
];
1633 if (target_p
!= multiline_stashed_target_p
)
1635 s_assert(false && "Multiline: missed init call!");
1636 multiline_stashed_target_p
= NULL
;
1640 if (multiline_cur_len
== multiline_prefix_len
)
1642 multiline_stashed_target_p
= NULL
;
1648 va_start(args
, format
);
1649 final_len
= vsnprintf(final
, sizeof final
, format
, args
);
1652 if (final_len
<= 0 || final_len
> multiline_prefix_len
)
1654 s_assert(false && "Multiline: failure preparing final prefix!");
1655 multiline_stashed_target_p
= NULL
;
1661 rb_strlcpy(final
, multiline_prefix
, multiline_prefix_len
+ 1);
1664 sendto_one(target_p
, "%s%s", final
, multiline_item_start
);
1666 multiline_stashed_target_p
= NULL
;
1671 send_multiline_reset(void)
1673 multiline_stashed_target_p
= NULL
;