X-Git-Url: https://jfr.im/git/solanum.git/blobdiff_plain/07807ce8b010fbedfb2237e8f13ce6779d6f85bb..04e5ed6c57154114cca330767e3bfb1006b46ee9:/ircd/send.c diff --git a/ircd/send.c b/ircd/send.c index ee0dabb0..d2a92d16 100644 --- a/ircd/send.c +++ b/ircd/send.c @@ -42,6 +42,8 @@ /* send the message to the link the target is attached to */ #define send_linebuf(a,b) _send_linebuf((a->from ? a->from : a) ,b) +#define CLIENT_CAPS_ONLY(x) ((IsClient((x)) && (x)->localClient) ? (x)->localClient->caps : 0) + static void send_queued_write(rb_fde_t *F, void *data); unsigned long current_serial = 0L; @@ -209,39 +211,52 @@ send_queued_write(rb_fde_t *F, void *data) } /* - * linebuf_put_msgvbuf + * linebuf_put_* * * inputs - msgbuf header, linebuf object, capability mask, pattern, arguments * outputs - none - * side effects - the linebuf object is cleared, then populated using rb_linebuf_putmsg(). + * side effects - the linebuf object is cleared, then populated */ static void -linebuf_put_msgvbuf(struct MsgBuf *msgbuf, buf_head_t *linebuf, unsigned int capmask, const char *pattern, va_list *va) +linebuf_put_tags(buf_head_t *linebuf, const struct MsgBuf *msgbuf, const struct Client *target_p, rb_strf_t *message) { - char buf[BUFSIZE]; + struct MsgBuf_str_data msgbuf_str_data = { .msgbuf = msgbuf, .caps = CLIENT_CAPS_ONLY(target_p) }; + rb_strf_t strings = { .func = msgbuf_unparse_linebuf_tags, .func_args = &msgbuf_str_data, .length = TAGSLEN + 1, .next = message }; - rb_linebuf_newbuf(linebuf); - msgbuf_unparse_prefix(buf, sizeof buf, msgbuf, capmask); - rb_linebuf_putprefix(linebuf, pattern, va, buf); + message->length = DATALEN + 1; + rb_linebuf_put(linebuf, &strings); } -/* linebuf_put_msgbuf - * - * inputs - msgbuf header, linebuf object, capability mask, pattern, arguments - * outputs - none - * side effects - the linebuf object is cleared, then populated using rb_linebuf_putmsg(). - */ static void -linebuf_put_msgbuf(struct MsgBuf *msgbuf, buf_head_t *linebuf, unsigned int capmask, const char *pattern, ...) +linebuf_put_tagsf(buf_head_t *linebuf, const struct MsgBuf *msgbuf, const struct Client *target_p, const rb_strf_t *message, const char *format, ...) { va_list va; + rb_strf_t strings = { .format = format, .format_args = &va, .next = message }; - va_start(va, pattern); - linebuf_put_msgvbuf(msgbuf, linebuf, capmask, pattern, &va); + va_start(va, format); + linebuf_put_tags(linebuf, msgbuf, target_p, &strings); va_end(va); } -/* build_msgbuf_from +static void +linebuf_put_msg(buf_head_t *linebuf, rb_strf_t *message) +{ + message->length = DATALEN + 1; + rb_linebuf_put(linebuf, message); +} + +static void +linebuf_put_msgf(buf_head_t *linebuf, const rb_strf_t *message, const char *format, ...) +{ + va_list va; + rb_strf_t strings = { .format = format, .format_args = &va, .next = message }; + + va_start(va, format); + linebuf_put_msg(linebuf, &strings); + va_end(va); +} + +/* build_msgbuf_tags * * inputs - msgbuf object, client the message is from * outputs - none @@ -249,23 +264,12 @@ linebuf_put_msgbuf(struct MsgBuf *msgbuf, buf_head_t *linebuf, unsigned int capm * notes - to make this reentrant, find a solution for `buf` below */ static void -build_msgbuf_from(struct MsgBuf *msgbuf, struct Client *from, const char *cmd) +build_msgbuf_tags(struct MsgBuf *msgbuf, struct Client *from) { - static char buf[BUFSIZE]; hook_data hdata; msgbuf_init(msgbuf); - msgbuf->origin = buf; - msgbuf->cmd = cmd; - - if (from != NULL && IsPerson(from)) - snprintf(buf, sizeof buf, "%s!%s@%s", from->name, from->username, from->host); - else if (from != NULL) - rb_strlcpy(buf, from->name, sizeof buf); - else - rb_strlcpy(buf, me.name, sizeof buf); - hdata.client = from; hdata.arg1 = msgbuf; @@ -282,7 +286,9 @@ void sendto_one(struct Client *target_p, const char *pattern, ...) { va_list args; + struct MsgBuf msgbuf; buf_head_t linebuf; + rb_strf_t strings = { .format = pattern, .format_args = &args, .next = NULL }; /* send remote if to->from non NULL */ if(target_p->from != NULL) @@ -293,8 +299,9 @@ sendto_one(struct Client *target_p, const char *pattern, ...) rb_linebuf_newbuf(&linebuf); + build_msgbuf_tags(&msgbuf, &me); va_start(args, pattern); - rb_linebuf_putmsg(&linebuf, pattern, &args, NULL); + linebuf_put_tags(&linebuf, &msgbuf, target_p, &strings); va_end(args); _send_linebuf(target_p, &linebuf); @@ -314,7 +321,9 @@ sendto_one_prefix(struct Client *target_p, struct Client *source_p, { struct Client *dest_p = target_p->from; va_list args; + struct MsgBuf msgbuf; buf_head_t linebuf; + rb_strf_t strings = { .format = pattern, .format_args = &args, .next = NULL }; if(IsIOError(dest_p)) return; @@ -325,12 +334,13 @@ sendto_one_prefix(struct Client *target_p, struct Client *source_p, return; } + build_msgbuf_tags(&msgbuf, source_p); + rb_linebuf_newbuf(&linebuf); va_start(args, pattern); - rb_linebuf_putmsg(&linebuf, pattern, &args, - ":%s %s %s ", - get_id(source_p, target_p), - command, get_id(target_p, target_p)); + linebuf_put_tagsf(&linebuf, &msgbuf, target_p, &strings, + ":%s %s %s ", get_id(source_p, target_p), + command, get_id(target_p, target_p)); va_end(args); _send_linebuf(dest_p, &linebuf); @@ -348,7 +358,9 @@ sendto_one_notice(struct Client *target_p, const char *pattern, ...) { struct Client *dest_p = target_p->from; va_list args; + struct MsgBuf msgbuf; buf_head_t linebuf; + rb_strf_t strings = { .format = pattern, .format_args = &args, .next = NULL }; char *to; if(IsIOError(dest_p)) @@ -360,11 +372,13 @@ sendto_one_notice(struct Client *target_p, const char *pattern, ...) return; } + build_msgbuf_tags(&msgbuf, &me); + rb_linebuf_newbuf(&linebuf); va_start(args, pattern); - rb_linebuf_putmsg(&linebuf, pattern, &args, - ":%s NOTICE %s ", - get_id(&me, target_p), *(to = get_id(target_p, target_p)) != '\0' ? to : "*"); + linebuf_put_tagsf(&linebuf, &msgbuf, target_p, &strings, + ":%s NOTICE %s ", get_id(&me, target_p), + *(to = get_id(target_p, target_p)) != '\0' ? to : "*"); va_end(args); _send_linebuf(dest_p, &linebuf); @@ -383,7 +397,9 @@ sendto_one_numeric(struct Client *target_p, int numeric, const char *pattern, .. { struct Client *dest_p = target_p->from; va_list args; + struct MsgBuf msgbuf; buf_head_t linebuf; + rb_strf_t strings = { .format = pattern, .format_args = &args, .next = NULL }; char *to; if(IsIOError(dest_p)) @@ -395,12 +411,13 @@ sendto_one_numeric(struct Client *target_p, int numeric, const char *pattern, .. return; } + build_msgbuf_tags(&msgbuf, &me); + rb_linebuf_newbuf(&linebuf); va_start(args, pattern); - rb_linebuf_putmsg(&linebuf, pattern, &args, - ":%s %03d %s ", - get_id(&me, target_p), - numeric, *(to = get_id(target_p, target_p)) != '\0' ? to : "*"); + linebuf_put_tagsf(&linebuf, &msgbuf, target_p, &strings, + ":%s %03d %s ", get_id(&me, target_p), numeric, + *(to = get_id(target_p, target_p)) != '\0' ? to : "*"); va_end(args); _send_linebuf(dest_p, &linebuf); @@ -433,6 +450,7 @@ sendto_server(struct Client *one, struct Channel *chptr, unsigned long caps, rb_dlink_node *ptr; rb_dlink_node *next_ptr; buf_head_t linebuf; + rb_strf_t strings = { .format = format, .format_args = &args, .next = NULL }; /* noone to send to.. */ if(rb_dlink_list_length(&serv_list) == 0) @@ -443,7 +461,7 @@ sendto_server(struct Client *one, struct Channel *chptr, unsigned long caps, rb_linebuf_newbuf(&linebuf); va_start(args, format); - rb_linebuf_putmsg(&linebuf, format, &args, NULL); + linebuf_put_msg(&linebuf, &strings); va_end(args); RB_DLINK_FOREACH_SAFE(ptr, next_ptr, serv_list.head) @@ -478,30 +496,31 @@ void sendto_channel_flags(struct Client *one, int type, struct Client *source_p, struct Channel *chptr, const char *pattern, ...) { - char buf[BUFSIZE]; + static char buf[BUFSIZE]; va_list args; - buf_head_t rb_linebuf_local; - buf_head_t rb_linebuf_id; + buf_head_t rb_linebuf_remote; struct Client *target_p; struct membership *msptr; rb_dlink_node *ptr; rb_dlink_node *next_ptr; - int current_capmask = 0; struct MsgBuf msgbuf; + struct MsgBuf_cache msgbuf_cache; + rb_strf_t strings = { .format = buf, .format_args = NULL, .next = NULL }; - rb_linebuf_newbuf(&rb_linebuf_local); - rb_linebuf_newbuf(&rb_linebuf_id); + rb_linebuf_newbuf(&rb_linebuf_remote); current_serial++; - build_msgbuf_from(&msgbuf, source_p, NULL); + build_msgbuf_tags(&msgbuf, source_p); va_start(args, pattern); vsnprintf(buf, sizeof buf, pattern, args); va_end(args); - linebuf_put_msgbuf(&msgbuf, &rb_linebuf_local, NOCAPS, "%s", buf); - rb_linebuf_putmsg(&rb_linebuf_id, NULL, NULL, ":%s %s", use_id(source_p), buf); + linebuf_put_msgf(&rb_linebuf_remote, NULL, ":%s %s", use_id(source_p), buf); + msgbuf_cache_initf(&msgbuf_cache, &msgbuf, &strings, + IsPerson(source_p) ? ":%1$s!%2$s@%3$s " : ":%1$s ", + source_p->name, source_p->username, source_p->host); RB_DLINK_FOREACH_SAFE(ptr, next_ptr, chptr->members.head) { @@ -530,24 +549,13 @@ sendto_channel_flags(struct Client *one, int type, struct Client *source_p, if(target_p->from->serial != current_serial) { - send_linebuf_remote(target_p, source_p, &rb_linebuf_id); + send_linebuf_remote(target_p, source_p, &rb_linebuf_remote); target_p->from->serial = current_serial; } } else { - if (target_p->localClient->caps != current_capmask) - { - /* reset the linebuf */ - rb_linebuf_donebuf(&rb_linebuf_local); - rb_linebuf_newbuf(&rb_linebuf_local); - - /* render the new linebuf and attach it */ - current_capmask = target_p->localClient->caps; - linebuf_put_msgbuf(&msgbuf, &rb_linebuf_local, current_capmask, "%s", buf); - } - - _send_linebuf(target_p, &rb_linebuf_local); + _send_linebuf(target_p, msgbuf_cache_get(&msgbuf_cache, CLIENT_CAPS_ONLY(target_p))); } } @@ -556,22 +564,11 @@ sendto_channel_flags(struct Client *one, int type, struct Client *source_p, { target_p = one; - if (target_p->localClient->caps != current_capmask) - { - /* reset the linebuf */ - rb_linebuf_donebuf(&rb_linebuf_local); - rb_linebuf_newbuf(&rb_linebuf_local); - - /* render the new linebuf and attach it */ - current_capmask = target_p->localClient->caps; - linebuf_put_msgbuf(&msgbuf, &rb_linebuf_local, current_capmask, "%s", buf); - } - - _send_linebuf(target_p, &rb_linebuf_local); + _send_linebuf(target_p, msgbuf_cache_get(&msgbuf_cache, CLIENT_CAPS_ONLY(target_p))); } - rb_linebuf_donebuf(&rb_linebuf_local); - rb_linebuf_donebuf(&rb_linebuf_id); + rb_linebuf_donebuf(&rb_linebuf_remote); + msgbuf_cache_free(&msgbuf_cache); } /* sendto_channel_flags() @@ -585,43 +582,48 @@ sendto_channel_opmod(struct Client *one, struct Client *source_p, struct Channel *chptr, const char *command, const char *text) { - buf_head_t rb_linebuf_local; buf_head_t rb_linebuf_old; buf_head_t rb_linebuf_new; struct Client *target_p; struct membership *msptr; rb_dlink_node *ptr; rb_dlink_node *next_ptr; + struct MsgBuf msgbuf; + struct MsgBuf_cache msgbuf_cache; + rb_strf_t strings = { .format = text, .format_args = NULL, .next = NULL }; - rb_linebuf_newbuf(&rb_linebuf_local); rb_linebuf_newbuf(&rb_linebuf_old); rb_linebuf_newbuf(&rb_linebuf_new); - current_serial++; + build_msgbuf_tags(&msgbuf, source_p); - if(IsServer(source_p)) - rb_linebuf_putmsg(&rb_linebuf_local, NULL, NULL, - ":%s %s %s :%s", - source_p->name, command, chptr->chname, text); - else - rb_linebuf_putmsg(&rb_linebuf_local, NULL, NULL, - ":%s!%s@%s %s %s :%s", + current_serial++; + const char *statusmsg_prefix = (ConfigChannel.opmod_send_statusmsg ? "@" : ""); + + if(IsServer(source_p)) { + msgbuf_cache_initf(&msgbuf_cache, &msgbuf, &strings, + ":%s %s %s%s :", + source_p->name, command, statusmsg_prefix, chptr->chname); + } else { + msgbuf_cache_initf(&msgbuf_cache, &msgbuf, &strings, + ":%s!%s@%s %s %s%s :", source_p->name, source_p->username, - source_p->host, command, chptr->chname, text); + source_p->host, command, statusmsg_prefix, chptr->chname); + } - if (chptr->mode.mode & MODE_MODERATED) - rb_linebuf_putmsg(&rb_linebuf_old, NULL, NULL, - ":%s %s %s :%s", - use_id(source_p), command, chptr->chname, text); - else - rb_linebuf_putmsg(&rb_linebuf_old, NULL, NULL, - ":%s NOTICE @%s :<%s:%s> %s", + if (chptr->mode.mode & MODE_MODERATED) { + linebuf_put_msgf(&rb_linebuf_old, &strings, + ":%s %s %s%s :", + use_id(source_p), command, statusmsg_prefix, chptr->chname, text); + } else { + linebuf_put_msgf(&rb_linebuf_old, &strings, + ":%s NOTICE @%s :<%s:%s> ", use_id(source_p->servptr), chptr->chname, - source_p->name, chptr->chname, text); - rb_linebuf_putmsg(&rb_linebuf_new, NULL, NULL, - ":%s %s =%s :%s", - use_id(source_p), command, chptr->chname, text); - + source_p->name, chptr->chname); + } + linebuf_put_msgf(&rb_linebuf_new, &strings, + ":%s %s =%s :", + use_id(source_p), command, chptr->chname); RB_DLINK_FOREACH_SAFE(ptr, next_ptr, chptr->members.head) { msptr = ptr->data; @@ -655,9 +657,9 @@ sendto_channel_opmod(struct Client *one, struct Client *source_p, send_linebuf_remote(target_p, source_p, &rb_linebuf_old); target_p->from->serial = current_serial; } + } else { + _send_linebuf(target_p, msgbuf_cache_get(&msgbuf_cache, CLIENT_CAPS_ONLY(target_p))); } - else - _send_linebuf(target_p, &rb_linebuf_local); } /* source client may not be on the channel, send echo separately */ @@ -665,34 +667,36 @@ sendto_channel_opmod(struct Client *one, struct Client *source_p, { target_p = one; - _send_linebuf(target_p, &rb_linebuf_local); + _send_linebuf(target_p, msgbuf_cache_get(&msgbuf_cache, CLIENT_CAPS_ONLY(target_p))); } - rb_linebuf_donebuf(&rb_linebuf_local); rb_linebuf_donebuf(&rb_linebuf_old); rb_linebuf_donebuf(&rb_linebuf_new); + msgbuf_cache_free(&msgbuf_cache); } /* sendto_channel_local() * - * inputs - flags to send to, channel to send to, va_args + * inputs - source, flags to send to, channel to send to, va_args * outputs - message to local channel members * side effects - */ void -sendto_channel_local(int type, struct Channel *chptr, const char *pattern, ...) +sendto_channel_local(struct Client *source_p, int type, struct Channel *chptr, const char *pattern, ...) { va_list args; - buf_head_t linebuf; struct membership *msptr; struct Client *target_p; rb_dlink_node *ptr; rb_dlink_node *next_ptr; + struct MsgBuf msgbuf; + struct MsgBuf_cache msgbuf_cache; + rb_strf_t strings = { .format = pattern, .format_args = &args, .next = NULL }; - rb_linebuf_newbuf(&linebuf); + build_msgbuf_tags(&msgbuf, source_p); va_start(args, pattern); - rb_linebuf_putmsg(&linebuf, pattern, &args, NULL); + msgbuf_cache_init(&msgbuf_cache, &msgbuf, &strings); va_end(args); RB_DLINK_FOREACH_SAFE(ptr, next_ptr, chptr->locmembers.head) @@ -711,10 +715,10 @@ sendto_channel_local(int type, struct Channel *chptr, const char *pattern, ...) else if(type && ((msptr->flags & type) == 0)) continue; - _send_linebuf(target_p, &linebuf); + _send_linebuf(target_p, msgbuf_cache_get(&msgbuf_cache, CLIENT_CAPS_ONLY(target_p))); } - rb_linebuf_donebuf(&linebuf); + msgbuf_cache_free(&msgbuf_cache); } /* @@ -723,17 +727,19 @@ sendto_channel_local(int type, struct Channel *chptr, const char *pattern, ...) * Shared implementation of sendto_channel_local_with_capability and sendto_channel_local_with_capability_butone */ static void -_sendto_channel_local_with_capability_butone(struct Client *one, int type, int caps, int negcaps, struct Channel *chptr, - const char *pattern, va_list * args) +_sendto_channel_local_with_capability_butone(struct Client *source_p, struct Client *one, int type, + int caps, int negcaps, struct Channel *chptr, const char *pattern, va_list * args) { - buf_head_t linebuf; struct membership *msptr; struct Client *target_p; rb_dlink_node *ptr; rb_dlink_node *next_ptr; + struct MsgBuf msgbuf; + struct MsgBuf_cache msgbuf_cache; + rb_strf_t strings = { .format = pattern, .format_args = args, .next = NULL }; - rb_linebuf_newbuf(&linebuf); - rb_linebuf_putmsg(&linebuf, pattern, args, NULL); + build_msgbuf_tags(&msgbuf, source_p); + msgbuf_cache_init(&msgbuf_cache, &msgbuf, &strings); RB_DLINK_FOREACH_SAFE(ptr, next_ptr, chptr->locmembers.head) { @@ -751,43 +757,43 @@ _sendto_channel_local_with_capability_butone(struct Client *one, int type, int c if(type && ((msptr->flags & type) == 0)) continue; - _send_linebuf(target_p, &linebuf); + _send_linebuf(target_p, msgbuf_cache_get(&msgbuf_cache, CLIENT_CAPS_ONLY(target_p))); } - rb_linebuf_donebuf(&linebuf); + msgbuf_cache_free(&msgbuf_cache); } /* sendto_channel_local_with_capability() * - * inputs - flags to send to, caps, negate caps, channel to send to, va_args + * inputs - source, flags to send to, caps, negate caps, channel to send to, va_args * outputs - message to local channel members * side effects - */ void -sendto_channel_local_with_capability(int type, int caps, int negcaps, struct Channel *chptr, const char *pattern, ...) +sendto_channel_local_with_capability(struct Client *source_p, int type, int caps, int negcaps, struct Channel *chptr, const char *pattern, ...) { va_list args; va_start(args, pattern); - _sendto_channel_local_with_capability_butone(NULL, type, caps, negcaps, chptr, pattern, &args); + _sendto_channel_local_with_capability_butone(source_p, NULL, type, caps, negcaps, chptr, pattern, &args); va_end(args); } /* sendto_channel_local_with_capability() * - * inputs - flags to send to, caps, negate caps, channel to send to, va_args + * inputs - source, flags to send to, caps, negate caps, channel to send to, va_args * outputs - message to local channel members * side effects - */ void -sendto_channel_local_with_capability_butone(struct Client *one, int type, int caps, int negcaps, struct Channel *chptr, - const char *pattern, ...) +sendto_channel_local_with_capability_butone(struct Client *one, int type, + int caps, int negcaps, struct Channel *chptr, const char *pattern, ...) { va_list args; va_start(args, pattern); - _sendto_channel_local_with_capability_butone(one, type, caps, negcaps, chptr, pattern, &args); + _sendto_channel_local_with_capability_butone(one, one, type, caps, negcaps, chptr, pattern, &args); va_end(args); } @@ -803,19 +809,18 @@ void sendto_channel_local_butone(struct Client *one, int type, struct Channel *chptr, const char *pattern, ...) { va_list args; - buf_head_t linebuf; struct membership *msptr; struct Client *target_p; struct MsgBuf msgbuf; rb_dlink_node *ptr; rb_dlink_node *next_ptr; + struct MsgBuf_cache msgbuf_cache; + rb_strf_t strings = { .format = pattern, .format_args = &args, .next = NULL }; - rb_linebuf_newbuf(&linebuf); - - build_msgbuf_from(&msgbuf, one, NULL); + build_msgbuf_tags(&msgbuf, one); va_start(args, pattern); - rb_linebuf_putmsg(&linebuf, pattern, &args, NULL); + msgbuf_cache_init(&msgbuf_cache, &msgbuf, &strings); va_end(args); RB_DLINK_FOREACH_SAFE(ptr, next_ptr, chptr->locmembers.head) @@ -833,18 +838,18 @@ sendto_channel_local_butone(struct Client *one, int type, struct Channel *chptr, continue; /* attach the present linebuf to the target */ - _send_linebuf(target_p, &linebuf); + _send_linebuf(target_p, msgbuf_cache_get(&msgbuf_cache, CLIENT_CAPS_ONLY(target_p))); } - rb_linebuf_donebuf(&linebuf); + msgbuf_cache_free(&msgbuf_cache); } /* * sendto_common_channels_local() * * inputs - pointer to client - * - capability mask - * - negated capability mask + * - capability mask + * - negated capability mask * - pattern to send * output - NONE * side effects - Sends a message to all people on local server who are @@ -863,11 +868,14 @@ sendto_common_channels_local(struct Client *user, int cap, int negcap, const cha struct Client *target_p; struct membership *msptr; struct membership *mscptr; - buf_head_t linebuf; + struct MsgBuf msgbuf; + struct MsgBuf_cache msgbuf_cache; + rb_strf_t strings = { .format = pattern, .format_args = &args, .next = NULL }; + + build_msgbuf_tags(&msgbuf, user); - rb_linebuf_newbuf(&linebuf); va_start(args, pattern); - rb_linebuf_putmsg(&linebuf, pattern, &args, NULL); + msgbuf_cache_init(&msgbuf_cache, &msgbuf, &strings); va_end(args); ++current_serial; @@ -889,25 +897,27 @@ sendto_common_channels_local(struct Client *user, int cap, int negcap, const cha continue; target_p->serial = current_serial; - send_linebuf(target_p, &linebuf); + send_linebuf(target_p, msgbuf_cache_get(&msgbuf_cache, CLIENT_CAPS_ONLY(target_p))); } } /* this can happen when the user isnt in any channels, but we still * need to send them the data, ie a nick change */ - if(MyConnect(user) && (user->serial != current_serial)) - send_linebuf(user, &linebuf); + if(MyConnect(user) && (user->serial != current_serial) + && IsCapable(user, cap) && NotCapable(user, negcap)) { + send_linebuf(user, msgbuf_cache_get(&msgbuf_cache, CLIENT_CAPS_ONLY(user))); + } - rb_linebuf_donebuf(&linebuf); + msgbuf_cache_free(&msgbuf_cache); } /* * sendto_common_channels_local_butone() * * inputs - pointer to client - * - capability mask - * - negated capability mask + * - capability mask + * - negated capability mask * - pattern to send * output - NONE * side effects - Sends a message to all people on local server who are @@ -925,12 +935,14 @@ sendto_common_channels_local_butone(struct Client *user, int cap, int negcap, co struct Client *target_p; struct membership *msptr; struct membership *mscptr; - buf_head_t linebuf; + struct MsgBuf msgbuf; + struct MsgBuf_cache msgbuf_cache; + rb_strf_t strings = { .format = pattern, .format_args = &args, .next = NULL }; - rb_linebuf_newbuf(&linebuf); + build_msgbuf_tags(&msgbuf, user); va_start(args, pattern); - rb_linebuf_putmsg(&linebuf, pattern, &args, NULL); + msgbuf_cache_init(&msgbuf_cache, &msgbuf, &strings); va_end(args); ++current_serial; @@ -954,11 +966,11 @@ sendto_common_channels_local_butone(struct Client *user, int cap, int negcap, co continue; target_p->serial = current_serial; - send_linebuf(target_p, &linebuf); + send_linebuf(target_p, msgbuf_cache_get(&msgbuf_cache, CLIENT_CAPS_ONLY(target_p))); } } - rb_linebuf_donebuf(&linebuf); + msgbuf_cache_free(&msgbuf_cache); } /* sendto_match_butone() @@ -976,26 +988,24 @@ sendto_match_butone(struct Client *one, struct Client *source_p, struct Client *target_p; rb_dlink_node *ptr; rb_dlink_node *next_ptr; - buf_head_t rb_linebuf_local; - buf_head_t rb_linebuf_id; + buf_head_t rb_linebuf_remote; + struct MsgBuf msgbuf; + struct MsgBuf_cache msgbuf_cache; + rb_strf_t strings = { .format = buf, .format_args = NULL, .next = NULL }; - rb_linebuf_newbuf(&rb_linebuf_local); - rb_linebuf_newbuf(&rb_linebuf_id); + rb_linebuf_newbuf(&rb_linebuf_remote); + + build_msgbuf_tags(&msgbuf, source_p); va_start(args, pattern); vsnprintf(buf, sizeof(buf), pattern, args); va_end(args); - if(IsServer(source_p)) - rb_linebuf_putmsg(&rb_linebuf_local, NULL, NULL, - ":%s %s", source_p->name, buf); - else - rb_linebuf_putmsg(&rb_linebuf_local, NULL, NULL, - ":%s!%s@%s %s", - source_p->name, source_p->username, - source_p->host, buf); + msgbuf_cache_initf(&msgbuf_cache, &msgbuf, &strings, + IsServer(source_p) ? ":%s " : ":%s!%s@%s ", + source_p->name, source_p->username, source_p->host); - rb_linebuf_putmsg(&rb_linebuf_id, NULL, NULL, ":%s %s", use_id(source_p), buf); + linebuf_put_msgf(&rb_linebuf_remote, &strings, ":%s ", use_id(source_p)); if(what == MATCH_HOST) { @@ -1004,7 +1014,7 @@ sendto_match_butone(struct Client *one, struct Client *source_p, target_p = ptr->data; if(match(mask, target_p->host)) - _send_linebuf(target_p, &rb_linebuf_local); + _send_linebuf(target_p, msgbuf_cache_get(&msgbuf_cache, CLIENT_CAPS_ONLY(target_p))); } } /* what = MATCH_SERVER, if it doesnt match us, just send remote */ @@ -1013,7 +1023,7 @@ sendto_match_butone(struct Client *one, struct Client *source_p, RB_DLINK_FOREACH_SAFE(ptr, next_ptr, lclient_list.head) { target_p = ptr->data; - _send_linebuf(target_p, &rb_linebuf_local); + _send_linebuf(target_p, msgbuf_cache_get(&msgbuf_cache, CLIENT_CAPS_ONLY(target_p))); } } @@ -1024,11 +1034,11 @@ sendto_match_butone(struct Client *one, struct Client *source_p, if(target_p == one) continue; - send_linebuf_remote(target_p, source_p, &rb_linebuf_id); + send_linebuf_remote(target_p, source_p, &rb_linebuf_remote); } - rb_linebuf_donebuf(&rb_linebuf_local); - rb_linebuf_donebuf(&rb_linebuf_id); + msgbuf_cache_free(&msgbuf_cache); + rb_linebuf_donebuf(&rb_linebuf_remote); } /* sendto_match_servs() @@ -1046,6 +1056,7 @@ sendto_match_servs(struct Client *source_p, const char *mask, int cap, rb_dlink_node *ptr; struct Client *target_p; buf_head_t rb_linebuf_id; + rb_strf_t strings = { .format = buf, .format_args = NULL, .next = NULL }; if(EmptyString(mask)) return; @@ -1056,8 +1067,7 @@ sendto_match_servs(struct Client *source_p, const char *mask, int cap, vsnprintf(buf, sizeof(buf), pattern, args); va_end(args); - rb_linebuf_putmsg(&rb_linebuf_id, NULL, NULL, - ":%s %s", use_id(source_p), buf); + linebuf_put_msgf(&rb_linebuf_id, &strings, ":%s ", use_id(source_p)); current_serial++; @@ -1104,12 +1114,14 @@ sendto_local_clients_with_capability(int cap, const char *pattern, ...) va_list args; rb_dlink_node *ptr; struct Client *target_p; - buf_head_t linebuf; + struct MsgBuf msgbuf; + struct MsgBuf_cache msgbuf_cache; + rb_strf_t strings = { .format = pattern, .format_args = &args, .next = NULL }; - rb_linebuf_newbuf(&linebuf); + build_msgbuf_tags(&msgbuf, &me); va_start(args, pattern); - rb_linebuf_putmsg(&linebuf, pattern, &args, NULL); + msgbuf_cache_init(&msgbuf_cache, &msgbuf, &strings); va_end(args); RB_DLINK_FOREACH(ptr, lclient_list.head) @@ -1119,10 +1131,10 @@ sendto_local_clients_with_capability(int cap, const char *pattern, ...) if(IsIOError(target_p) || !IsCapable(target_p, cap)) continue; - send_linebuf(target_p, &linebuf); + send_linebuf(target_p, msgbuf_cache_get(&msgbuf_cache, CLIENT_CAPS_ONLY(target_p))); } - rb_linebuf_donebuf(&linebuf); + msgbuf_cache_free(&msgbuf_cache); } /* sendto_monitor() @@ -1132,18 +1144,20 @@ sendto_local_clients_with_capability(int cap, const char *pattern, ...) * side effects - */ void -sendto_monitor(struct monitor *monptr, const char *pattern, ...) +sendto_monitor(struct Client *source_p, struct monitor *monptr, const char *pattern, ...) { va_list args; - buf_head_t linebuf; struct Client *target_p; rb_dlink_node *ptr; rb_dlink_node *next_ptr; + struct MsgBuf msgbuf; + struct MsgBuf_cache msgbuf_cache; + rb_strf_t strings = { .format = pattern, .format_args = &args, .next = NULL }; - rb_linebuf_newbuf(&linebuf); + build_msgbuf_tags(&msgbuf, source_p); va_start(args, pattern); - rb_linebuf_putmsg(&linebuf, pattern, &args, NULL); + msgbuf_cache_init(&msgbuf_cache, &msgbuf, &strings); va_end(args); RB_DLINK_FOREACH_SAFE(ptr, next_ptr, monptr->users.head) @@ -1153,10 +1167,10 @@ sendto_monitor(struct monitor *monptr, const char *pattern, ...) if(IsIOError(target_p)) continue; - _send_linebuf(target_p, &linebuf); + _send_linebuf(target_p, msgbuf_cache_get(&msgbuf_cache, CLIENT_CAPS_ONLY(target_p))); } - rb_linebuf_donebuf(&linebuf); + msgbuf_cache_free(&msgbuf_cache); } /* _sendto_anywhere() @@ -1171,34 +1185,34 @@ _sendto_anywhere(struct Client *dest_p, struct Client *target_p, const char *pattern, va_list *args) { buf_head_t linebuf; + rb_strf_t strings = { .format = pattern, .format_args = args, .next = NULL }; rb_linebuf_newbuf(&linebuf); - if(MyClient(dest_p)) - { - if(IsServer(source_p)) - rb_linebuf_putmsg(&linebuf, pattern, args, ":%s %s %s ", + if (MyClient(dest_p)) { + if (IsServer(source_p)) { + linebuf_put_msgf(&linebuf, &strings, ":%s %s %s ", source_p->name, command, target_p->name); - else - { + } else { struct MsgBuf msgbuf; - build_msgbuf_from(&msgbuf, source_p, command); - msgbuf.target = target_p->name; + build_msgbuf_tags(&msgbuf, source_p); - linebuf_put_msgvbuf(&msgbuf, &linebuf, dest_p->localClient->caps, pattern, args); + linebuf_put_tagsf(&linebuf, &msgbuf, dest_p, &strings, + IsPerson(source_p) ? ":%1$s!%4$s@%5$s %2$s %3$s " : ":%1$s %2$s %3$s ", + source_p->name, command, target_p->name, + source_p->username, source_p->host); } - } - else - rb_linebuf_putmsg(&linebuf, pattern, args, ":%s %s %s ", + + _send_linebuf(dest_p, &linebuf); + } else { + linebuf_put_msgf(&linebuf, &strings, ":%s %s %s ", get_id(source_p, target_p), command, get_id(target_p, target_p)); - if(MyClient(dest_p)) - _send_linebuf(dest_p, &linebuf); - else send_linebuf_remote(dest_p, source_p, &linebuf); + } rb_linebuf_donebuf(&linebuf); } @@ -1255,20 +1269,23 @@ sendto_realops_snomask(int flags, int level, const char *pattern, ...) rb_dlink_node *ptr; rb_dlink_node *next_ptr; va_list args; - buf_head_t linebuf; + struct MsgBuf msgbuf; + struct MsgBuf_cache msgbuf_cache; - rb_linebuf_newbuf(&linebuf); + build_msgbuf_tags(&msgbuf, &me); + + /* rather a lot of copying around, oh well -- jilles */ + va_start(args, pattern); + vsnprintf(buf, sizeof(buf), pattern, args); + va_end(args); + + msgbuf_cache_initf(&msgbuf_cache, &msgbuf, NULL, + ":%s NOTICE * :*** Notice -- %s", me.name, buf); /* Be very sure not to do things like "Trying to send to myself" * L_NETWIDE, otherwise infinite recursion may result! -- jilles */ if (level & L_NETWIDE && ConfigFileEntry.global_snotices) { - /* rather a lot of copying around, oh well -- jilles */ - va_start(args, pattern); - vsnprintf(buf, sizeof(buf), pattern, args); - va_end(args); - rb_linebuf_putmsg(&linebuf, pattern, NULL, - ":%s NOTICE * :*** Notice -- %s", me.name, buf); snobuf = construct_snobuf(flags); if (snobuf[1] != '\0') sendto_server(NULL, NULL, CAP_ENCAP|CAP_TS6, NOCAPS, @@ -1277,21 +1294,8 @@ sendto_realops_snomask(int flags, int level, const char *pattern, ...) } else if (remote_rehash_oper_p != NULL) { - /* rather a lot of copying around, oh well -- jilles */ - va_start(args, pattern); - vsnprintf(buf, sizeof(buf), pattern, args); - va_end(args); - rb_linebuf_putmsg(&linebuf, pattern, NULL, - ":%s NOTICE * :*** Notice -- %s", me.name, buf); sendto_one_notice(remote_rehash_oper_p, ":*** Notice -- %s", buf); } - else - { - va_start(args, pattern); - rb_linebuf_putmsg(&linebuf, pattern, &args, - ":%s NOTICE * :*** Notice -- ", me.name); - va_end(args); - } level &= ~L_NETWIDE; RB_DLINK_FOREACH_SAFE(ptr, next_ptr, local_oper_list.head) @@ -1305,11 +1309,12 @@ sendto_realops_snomask(int flags, int level, const char *pattern, ...) ((level == L_OPER) && IsOperAdmin(client_p))) continue; - if(client_p->snomask & flags) - _send_linebuf(client_p, &linebuf); + if (client_p->snomask & flags) { + _send_linebuf(client_p, msgbuf_cache_get(&msgbuf_cache, CLIENT_CAPS_ONLY(client_p))); + } } - rb_linebuf_donebuf(&linebuf); + msgbuf_cache_free(&msgbuf_cache); } /* sendto_realops_snomask_from() * @@ -1325,12 +1330,14 @@ sendto_realops_snomask_from(int flags, int level, struct Client *source_p, rb_dlink_node *ptr; rb_dlink_node *next_ptr; va_list args; - buf_head_t linebuf; + struct MsgBuf msgbuf; + struct MsgBuf_cache msgbuf_cache; + rb_strf_t strings = { .format = pattern, .format_args = &args, .next = NULL }; - rb_linebuf_newbuf(&linebuf); + build_msgbuf_tags(&msgbuf, &me); va_start(args, pattern); - rb_linebuf_putmsg(&linebuf, pattern, &args, + msgbuf_cache_initf(&msgbuf_cache, &msgbuf, &strings, ":%s NOTICE * :*** Notice -- ", source_p->name); va_end(args); @@ -1345,11 +1352,12 @@ sendto_realops_snomask_from(int flags, int level, struct Client *source_p, ((level == L_OPER) && IsOperAdmin(client_p))) continue; - if(client_p->snomask & flags) - _send_linebuf(client_p, &linebuf); + if (client_p->snomask & flags) { + _send_linebuf(client_p, msgbuf_cache_get(&msgbuf_cache, CLIENT_CAPS_ONLY(client_p))); + } } - rb_linebuf_donebuf(&linebuf); + msgbuf_cache_free(&msgbuf_cache); } /* @@ -1368,30 +1376,33 @@ sendto_wallops_flags(int flags, struct Client *source_p, const char *pattern, .. rb_dlink_node *ptr; rb_dlink_node *next_ptr; va_list args; - buf_head_t linebuf; + struct MsgBuf msgbuf; + struct MsgBuf_cache msgbuf_cache; + rb_strf_t strings = { .format = pattern, .format_args = &args, .next = NULL }; - rb_linebuf_newbuf(&linebuf); + build_msgbuf_tags(&msgbuf, source_p); va_start(args, pattern); - - if(IsPerson(source_p)) - rb_linebuf_putmsg(&linebuf, pattern, &args, + if (IsPerson(source_p)) { + msgbuf_cache_initf(&msgbuf_cache, &msgbuf, &strings, ":%s!%s@%s WALLOPS :", source_p->name, source_p->username, source_p->host); - else - rb_linebuf_putmsg(&linebuf, pattern, &args, ":%s WALLOPS :", source_p->name); - + } else { + msgbuf_cache_initf(&msgbuf_cache, &msgbuf, &strings, + ":%s WALLOPS :", source_p->name); + } va_end(args); RB_DLINK_FOREACH_SAFE(ptr, next_ptr, IsPerson(source_p) && flags == UMODE_WALLOP ? lclient_list.head : local_oper_list.head) { client_p = ptr->data; - if(client_p->umodes & flags) - _send_linebuf(client_p, &linebuf); + if (client_p->umodes & flags) { + _send_linebuf(client_p, msgbuf_cache_get(&msgbuf_cache, CLIENT_CAPS_ONLY(client_p))); + } } - rb_linebuf_donebuf(&linebuf); + msgbuf_cache_free(&msgbuf_cache); } /* kill_client() @@ -1405,12 +1416,16 @@ kill_client(struct Client *target_p, struct Client *diedie, const char *pattern, { va_list args; buf_head_t linebuf; + struct MsgBuf msgbuf; + rb_strf_t strings = { .format = pattern, .format_args = &args, .next = NULL }; + + build_msgbuf_tags(&msgbuf, &me); rb_linebuf_newbuf(&linebuf); va_start(args, pattern); - rb_linebuf_putmsg(&linebuf, pattern, &args, ":%s KILL %s :", - get_id(&me, target_p), get_id(diedie, target_p)); + linebuf_put_tagsf(&linebuf, &msgbuf, target_p, &strings, + ":%s KILL %s :", get_id(&me, target_p), get_id(diedie, target_p)); va_end(args); send_linebuf(target_p, &linebuf); @@ -1438,15 +1453,14 @@ kill_client_serv_butone(struct Client *one, struct Client *target_p, const char rb_dlink_node *ptr; rb_dlink_node *next_ptr; buf_head_t rb_linebuf_id; + rb_strf_t strings = { .format = pattern, .format_args = &args, .next = NULL }; rb_linebuf_newbuf(&rb_linebuf_id); va_start(args, pattern); - vsnprintf(buf, sizeof(buf), pattern, args); - va_end(args); - - rb_linebuf_putmsg(&rb_linebuf_id, NULL, NULL, ":%s KILL %s :%s", + linebuf_put_msgf(&rb_linebuf_id, &strings, ":%s KILL %s :%s", use_id(&me), use_id(target_p), buf); + va_end(args); RB_DLINK_FOREACH_SAFE(ptr, next_ptr, serv_list.head) {