ircd: send tags on every message

Simplify linebuf by introducing fsnprint to manage a list of printfs.
Add a msgbuf unparse cache for send functions that loop.
This commit is contained in:
Simon Arlott 2017-08-06 12:05:24 +01:00
parent 8f43ad3f72
commit 4b1cce65ed
No known key found for this signature in database
GPG key ID: C8975F2043CA5D24
32 changed files with 587 additions and 1308 deletions

1
.gitignore vendored
View file

@ -59,7 +59,6 @@ wsockd/wsockd
tests/core tests/core
tests/msgbuf_parse1 tests/msgbuf_parse1
tests/msgbuf_unparse1 tests/msgbuf_unparse1
tests/rb_linebuf_put1
tests/rb_snprintf_append1 tests/rb_snprintf_append1
tests/rb_snprintf_try_append1 tests/rb_snprintf_try_append1
tests/send1 tests/send1

View file

@ -105,7 +105,7 @@ mo_ojoin(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source
":%s SJOIN %ld %s + :@%s", ":%s SJOIN %ld %s + :@%s",
me.id, (long) chptr->channelts, chptr->chname, source_p->id); me.id, (long) chptr->channelts, chptr->chname, source_p->id);
send_channel_join(chptr, source_p); send_channel_join(chptr, source_p);
sendto_channel_local(ALL_MEMBERS, chptr, ":%s MODE %s +o %s", sendto_channel_local(&me, ALL_MEMBERS, chptr, ":%s MODE %s +o %s",
me.name, chptr->chname, source_p->name); me.name, chptr->chname, source_p->name);
} }
@ -116,7 +116,7 @@ mo_ojoin(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source
":%s SJOIN %ld %s + :+%s", ":%s SJOIN %ld %s + :+%s",
me.id, (long) chptr->channelts, chptr->chname, source_p->id); me.id, (long) chptr->channelts, chptr->chname, source_p->id);
send_channel_join(chptr, source_p); send_channel_join(chptr, source_p);
sendto_channel_local(ALL_MEMBERS, chptr, ":%s MODE %s +v %s", sendto_channel_local(&me, ALL_MEMBERS, chptr, ":%s MODE %s +v %s",
me.name, chptr->chname, source_p->name); me.name, chptr->chname, source_p->name);
} }
else else

View file

@ -131,7 +131,7 @@ mo_okick(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source
me.name, chptr->chname, target_p->name, me.name, chptr->chname, target_p->name,
source_p->name, source_p->username, source_p->host); source_p->name, source_p->username, source_p->host);
sendto_channel_local(ALL_MEMBERS, chptr, ":%s KICK %s %s :%s", sendto_channel_local(&me, ALL_MEMBERS, chptr, ":%s KICK %s %s :%s",
me.name, chptr->chname, who->name, comment); me.name, chptr->chname, who->name, comment);
sendto_server(&me, chptr, CAP_TS6, NOCAPS, sendto_server(&me, chptr, CAP_TS6, NOCAPS,
":%s KICK %s %s :%s", me.id, chptr->chname, who->id, comment); ":%s KICK %s %s :%s", me.id, chptr->chname, who->id, comment);

View file

@ -135,7 +135,7 @@ mo_omode(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source
form_str(ERR_USERNOTINCHANNEL), parv[3], chptr->chname); form_str(ERR_USERNOTINCHANNEL), parv[3], chptr->chname);
return; return;
} }
sendto_channel_local(ALL_MEMBERS, chptr, ":%s MODE %s +o %s", sendto_channel_local(&me, ALL_MEMBERS, chptr, ":%s MODE %s +o %s",
me.name, parv[1], source_p->name); me.name, parv[1], source_p->name);
sendto_server(NULL, chptr, CAP_TS6, NOCAPS, sendto_server(NULL, chptr, CAP_TS6, NOCAPS,
":%s TMODE %ld %s +o %s", ":%s TMODE %ld %s +o %s",

View file

@ -108,6 +108,6 @@ mo_opme(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_
me.id, (long) chptr->channelts, parv[1], source_p->id); me.id, (long) chptr->channelts, parv[1], source_p->id);
} }
sendto_channel_local(ALL_MEMBERS, chptr, sendto_channel_local(&me, ALL_MEMBERS, chptr,
":%s MODE %s +o %s", me.name, parv[1], source_p->name); ":%s MODE %s +o %s", me.name, parv[1], source_p->name);
} }

View file

@ -193,7 +193,7 @@ m_remove(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source
* - Personally, flame and I believe that server kicks shouldn't * - Personally, flame and I believe that server kicks shouldn't
* be sent anyways. Just waiting for some oper to abuse it... * be sent anyways. Just waiting for some oper to abuse it...
*/ */
sendto_channel_local(ALL_MEMBERS, chptr, sendto_channel_local(who, ALL_MEMBERS, chptr,
":%s!%s@%s PART %s :requested by %s (%s)", ":%s!%s@%s PART %s :requested by %s (%s)",
who->name, who->username, who->name, who->username,
who->host, name, source_p->name, comment); who->host, name, source_p->name, comment);

View file

@ -203,7 +203,7 @@ m_displaymsg(struct MsgBuf *msgbuf_p, struct Client *source_p, const char *chann
else else
snprintf(text2, sizeof(text2), "%s", text3); snprintf(text2, sizeof(text2), "%s", text3);
sendto_channel_local(ALL_MEMBERS, chptr, ":%s!%s@npc.fakeuser.invalid PRIVMSG %s :%s", nick2, source_p->name, channel, text2); sendto_channel_local(source_p, ALL_MEMBERS, chptr, ":%s!%s@npc.fakeuser.invalid PRIVMSG %s :%s", nick2, source_p->name, channel, text2);
sendto_match_servs(source_p, "*", CAP_ENCAP, NOCAPS, "ENCAP * ROLEPLAY %s %s :%s", sendto_match_servs(source_p, "*", CAP_ENCAP, NOCAPS, "ENCAP * ROLEPLAY %s %s :%s",
channel, nick2, text2); channel, nick2, text2);
} }
@ -218,5 +218,5 @@ me_roleplay(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *sou
if((chptr = find_channel(parv[1])) == NULL) if((chptr = find_channel(parv[1])) == NULL)
return; return;
sendto_channel_local(ALL_MEMBERS, chptr, ":%s!%s@npc.fakeuser.invalid PRIVMSG %s :%s", parv[2], source_p->name, parv[1], parv[3]); sendto_channel_local(source_p, ALL_MEMBERS, chptr, ":%s!%s@npc.fakeuser.invalid PRIVMSG %s :%s", parv[2], source_p->name, parv[1], parv[3]);
} }

View file

@ -43,6 +43,33 @@ struct MsgBuf {
const char *para[MAXPARA]; /* parameters vector (starting with cmd as para[0]) */ const char *para[MAXPARA]; /* parameters vector (starting with cmd as para[0]) */
}; };
struct MsgBuf_str_data {
const struct MsgBuf *msgbuf;
unsigned int caps;
};
#define MSGBUF_CACHE_SIZE 32
struct MsgBuf_cache_entry {
unsigned int caps;
buf_head_t linebuf;
struct MsgBuf_cache_entry *next;
};
struct MsgBuf_cache {
const struct MsgBuf *msgbuf;
char message[DATALEN + 1];
unsigned int overall_capmask;
/* Fixed maximum size linked list, new entries are allocated at the end
* of the array but are accessed through the "next" pointers.
*
* This does not use rb dlink to avoid unnecessary individual allocations.
*/
struct MsgBuf_cache_entry entry[MSGBUF_CACHE_SIZE];
struct MsgBuf_cache_entry *head; /* LRU cache head */
};
/* /*
* parse a message into a MsgBuf. * parse a message into a MsgBuf.
* returns 0 on success, 1 on error. * returns 0 on success, 1 on error.
@ -66,7 +93,13 @@ int msgbuf_unparse(char *buf, size_t buflen, const struct MsgBuf *msgbuf, unsign
int msgbuf_unparse_fmt(char *buf, size_t buflen, const struct MsgBuf *head, unsigned int capmask, const char *fmt, ...) AFP(5, 6); int msgbuf_unparse_fmt(char *buf, size_t buflen, const struct MsgBuf *head, unsigned int capmask, const char *fmt, ...) AFP(5, 6);
int msgbuf_vunparse_fmt(char *buf, size_t buflen, const struct MsgBuf *head, unsigned int capmask, const char *fmt, va_list va); int msgbuf_vunparse_fmt(char *buf, size_t buflen, const struct MsgBuf *head, unsigned int capmask, const char *fmt, va_list va);
void msgbuf_unparse_prefix(char *buf, size_t *buflen, const struct MsgBuf *msgbuf, unsigned int capmask); int msgbuf_unparse_linebuf_tags(char *buf, size_t buflen, void *data);
int msgbuf_unparse_prefix(char *buf, size_t *buflen, const struct MsgBuf *msgbuf, unsigned int capmask);
void msgbuf_cache_init(struct MsgBuf_cache *cache, const struct MsgBuf *msgbuf, const rb_strf_t *message);
void msgbuf_cache_initf(struct MsgBuf_cache *cache, const struct MsgBuf *msgbuf, const rb_strf_t *message, const char *format, ...) AFP(4, 5);
buf_head_t *msgbuf_cache_get(struct MsgBuf_cache *cache, unsigned int caps);
void msgbuf_cache_free(struct MsgBuf_cache *cache);
static inline void static inline void
msgbuf_init(struct MsgBuf *msgbuf) msgbuf_init(struct MsgBuf *msgbuf)

View file

@ -58,10 +58,10 @@ extern void sendto_channel_opmod(struct Client *one, struct Client *source_p,
struct Channel *chptr, const char *command, struct Channel *chptr, const char *command,
const char *text); const char *text);
extern void sendto_channel_local(int type, struct Channel *, const char *, ...) AFP(3, 4); extern void sendto_channel_local(struct Client *, int type, struct Channel *, const char *, ...) AFP(4, 5);
extern void sendto_channel_local_butone(struct Client *, int type, struct Channel *, const char *, ...) AFP(4, 5); extern void sendto_channel_local_butone(struct Client *, int type, struct Channel *, const char *, ...) AFP(4, 5);
extern void sendto_channel_local_with_capability(int type, int caps, int negcaps, struct Channel *, const char *, ...) AFP(5, 6); extern void sendto_channel_local_with_capability(struct Client *, int type, int caps, int negcaps, struct Channel *, const char *, ...) AFP(6, 7);
extern void sendto_channel_local_with_capability_butone(struct Client *, int type, int caps, int negcaps, struct Channel *, extern void sendto_channel_local_with_capability_butone(struct Client *, int type, int caps, int negcaps, struct Channel *,
const char *, ...) AFP(6, 7); const char *, ...) AFP(6, 7);
@ -74,7 +74,7 @@ extern void sendto_match_butone(struct Client *, struct Client *,
extern void sendto_match_servs(struct Client *source_p, const char *mask, extern void sendto_match_servs(struct Client *source_p, const char *mask,
int capab, int, const char *, ...) AFP(5, 6); int capab, int, const char *, ...) AFP(5, 6);
extern void sendto_monitor(struct monitor *monptr, const char *, ...) AFP(2, 3); extern void sendto_monitor(struct Client *, struct monitor *monptr, const char *, ...) AFP(3, 4);
extern void sendto_anywhere(struct Client *, struct Client *, const char *, extern void sendto_anywhere(struct Client *, struct Client *, const char *,
const char *, ...) AFP(4, 5); const char *, ...) AFP(4, 5);

View file

@ -126,10 +126,10 @@ send_channel_join(struct Channel *chptr, struct Client *client_p)
if (!IsClient(client_p)) if (!IsClient(client_p))
return; return;
sendto_channel_local_with_capability(ALL_MEMBERS, NOCAPS, CLICAP_EXTENDED_JOIN, chptr, ":%s!%s@%s JOIN %s", sendto_channel_local_with_capability(client_p, ALL_MEMBERS, NOCAPS, CLICAP_EXTENDED_JOIN, chptr, ":%s!%s@%s JOIN %s",
client_p->name, client_p->username, client_p->host, chptr->chname); client_p->name, client_p->username, client_p->host, chptr->chname);
sendto_channel_local_with_capability(ALL_MEMBERS, CLICAP_EXTENDED_JOIN, NOCAPS, chptr, ":%s!%s@%s JOIN %s %s :%s", sendto_channel_local_with_capability(client_p, ALL_MEMBERS, CLICAP_EXTENDED_JOIN, NOCAPS, chptr, ":%s!%s@%s JOIN %s %s :%s",
client_p->name, client_p->username, client_p->host, chptr->chname, client_p->name, client_p->username, client_p->host, chptr->chname,
EmptyString(client_p->user->suser) ? "*" : client_p->user->suser, EmptyString(client_p->user->suser) ? "*" : client_p->user->suser,
client_p->info); client_p->info);
@ -1383,7 +1383,7 @@ resv_chan_forcepart(const char *name, const char *reason, int temp_time)
sendto_server(target_p, chptr, CAP_TS6, NOCAPS, sendto_server(target_p, chptr, CAP_TS6, NOCAPS,
":%s PART %s", target_p->id, chptr->chname); ":%s PART %s", target_p->id, chptr->chname);
sendto_channel_local(ALL_MEMBERS, chptr, ":%s!%s@%s PART %s :%s", sendto_channel_local(target_p, ALL_MEMBERS, chptr, ":%s!%s@%s PART %s :%s",
target_p->name, target_p->username, target_p->name, target_p->username,
target_p->host, chptr->chname, target_p->name); target_p->host, chptr->chname, target_p->name);

View file

@ -1778,8 +1778,8 @@ set_channel_mode(struct Client *client_p, struct Client *source_p,
*mbuf = '\0'; *mbuf = '\0';
if(cur_len > mlen) if(cur_len > mlen)
sendto_channel_local(flags, chptr, "%s %s", modebuf, sendto_channel_local(IsServer(source_p) ? fakesource_p : source_p,
parabuf); flags, chptr, "%s %s", modebuf, parabuf);
else else
continue; continue;
@ -1815,7 +1815,8 @@ set_channel_mode(struct Client *client_p, struct Client *source_p,
*mbuf = '\0'; *mbuf = '\0';
if(cur_len > mlen) if(cur_len > mlen)
sendto_channel_local(flags, chptr, "%s %s", modebuf, parabuf); sendto_channel_local(IsServer(source_p) ? fakesource_p : source_p,
flags, chptr, "%s %s", modebuf, parabuf);
} }
/* only propagate modes originating locally, or if we're hubbing */ /* only propagate modes originating locally, or if we're hubbing */

View file

@ -95,7 +95,7 @@ monitor_signon(struct Client *client_p)
snprintf(buf, sizeof(buf), "%s!%s@%s", client_p->name, client_p->username, client_p->host); snprintf(buf, sizeof(buf), "%s!%s@%s", client_p->name, client_p->username, client_p->host);
sendto_monitor(monptr, form_str(RPL_MONONLINE), me.name, "*", buf); sendto_monitor(client_p, monptr, form_str(RPL_MONONLINE), me.name, "*", buf);
} }
/* monitor_signoff() /* monitor_signoff()
@ -114,7 +114,7 @@ monitor_signoff(struct Client *client_p)
if(monptr == NULL) if(monptr == NULL)
return; return;
sendto_monitor(monptr, form_str(RPL_MONOFFLINE), me.name, "*", sendto_monitor(client_p, monptr, form_str(RPL_MONOFFLINE), me.name, "*",
client_p->name); client_p->name);
} }

View file

@ -244,17 +244,26 @@ msgbuf_unparse_tags(char *buf, size_t buflen, const struct MsgBuf *msgbuf, unsig
return commit - buf; return commit - buf;
} }
int
msgbuf_unparse_linebuf_tags(char *buf, size_t buflen, void *data)
{
struct MsgBuf_str_data *str_data = data;
return msgbuf_unparse_tags(buf, buflen, str_data->msgbuf, str_data->caps);
}
/* /*
* unparse a MsgBuf and message prefix into a buffer * unparse a MsgBuf and message prefix into a buffer
* if origin is NULL, me.name will be used. * if origin is NULL, me.name will be used.
* cmd should not be NULL. * cmd should not be NULL.
* updates buflen to correctly allow remaining message data to be added * updates buflen to correctly allow remaining message data to be added
*/ */
void int
msgbuf_unparse_prefix(char *buf, size_t *buflen, const struct MsgBuf *msgbuf, unsigned int capmask) msgbuf_unparse_prefix(char *buf, size_t *buflen, const struct MsgBuf *msgbuf, unsigned int capmask)
{ {
size_t tags_buflen; size_t tags_buflen;
size_t tags_used = 0; size_t used = 0;
int ret;
memset(buf, 0, *buflen); memset(buf, 0, *buflen);
@ -263,19 +272,32 @@ msgbuf_unparse_prefix(char *buf, size_t *buflen, const struct MsgBuf *msgbuf, un
tags_buflen = TAGSLEN + 1; tags_buflen = TAGSLEN + 1;
if (msgbuf->n_tags > 0) if (msgbuf->n_tags > 0)
tags_used = msgbuf_unparse_tags(buf, tags_buflen, msgbuf, capmask); used = msgbuf_unparse_tags(buf, tags_buflen, msgbuf, capmask);
const size_t data_bufmax = (tags_used + DATALEN + 1); const size_t data_bufmax = (used + DATALEN + 1);
if (*buflen > data_bufmax) if (*buflen > data_bufmax)
*buflen = data_bufmax; *buflen = data_bufmax;
rb_snprintf_append(buf, *buflen, ":%s ", msgbuf->origin != NULL ? msgbuf->origin : me.name); ret = rb_snprintf_append(buf, *buflen, ":%s ", msgbuf->origin != NULL ? msgbuf->origin : me.name);
if (ret > 0)
used += ret;
if (msgbuf->cmd != NULL) if (msgbuf->cmd != NULL) {
rb_snprintf_append(buf, *buflen, "%s ", msgbuf->cmd); ret = rb_snprintf_append(buf, *buflen, "%s ", msgbuf->cmd);
if (ret > 0)
used += ret;
}
if (msgbuf->target != NULL) if (msgbuf->target != NULL) {
rb_snprintf_append(buf, *buflen, "%s ", msgbuf->target); ret = rb_snprintf_append(buf, *buflen, "%s ", msgbuf->target);
if (ret > 0)
used += ret;
}
if (used > data_bufmax - 1)
used = data_bufmax - 1;
return used;
} }
/* /*
@ -346,3 +368,103 @@ msgbuf_unparse_fmt(char *buf, size_t buflen, const struct MsgBuf *head, unsigned
return res; return res;
} }
void
msgbuf_cache_init(struct MsgBuf_cache *cache, const struct MsgBuf *msgbuf, const rb_strf_t *message)
{
cache->msgbuf = msgbuf;
cache->head = NULL;
cache->overall_capmask = 0;
for (size_t i = 0; i < msgbuf->n_tags; i++) {
cache->overall_capmask |= msgbuf->tags[i].capmask;
}
for (int i = 0; i < MSGBUF_CACHE_SIZE; i++) {
cache->entry[i].caps = 0;
cache->entry[i].next = NULL;
}
rb_fsnprint(cache->message, sizeof(cache->message), message);
}
void
msgbuf_cache_initf(struct MsgBuf_cache *cache, const struct MsgBuf *msgbuf, 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);
msgbuf_cache_init(cache, msgbuf, &strings);
va_end(va);
}
buf_head_t*
msgbuf_cache_get(struct MsgBuf_cache *cache, unsigned int caps)
{
struct MsgBuf_cache_entry *entry = cache->head;
struct MsgBuf_cache_entry *prev = NULL;
struct MsgBuf_cache_entry *result = NULL;
int n = 0;
while (entry != NULL) {
if (entry->caps == caps) {
/* Cache hit */
result = entry;
break;
}
prev = entry;
entry = entry->next;
n++;
}
if (result == NULL) {
if (n < MSGBUF_CACHE_SIZE) {
/* Cache miss, allocate a new entry */
result = &cache->entry[n];
prev = NULL;
} else {
/* Cache full, replace the last entry */
result = prev;
prev = NULL;
rb_linebuf_donebuf(&result->linebuf);
}
/* Construct the line using the tags followed by the no tags line */
struct MsgBuf_str_data msgbuf_str_data = { .msgbuf = cache->msgbuf, .caps = caps };
rb_strf_t strings[2] = {
{ .func = msgbuf_unparse_linebuf_tags, .func_args = &msgbuf_str_data, .length = TAGSLEN + 1, .next = &strings[1] },
{ .format = cache->message, .length = DATALEN + 1, .next = NULL }
};
result->caps = caps;
rb_linebuf_newbuf(&result->linebuf);
rb_linebuf_put(&result->linebuf, &strings[0]);
}
/* Move it to the top */
if (cache->head != result) {
if (prev != NULL) {
prev->next = result->next;
}
result->next = cache->head;
cache->head = result;
}
return &result->linebuf;
}
void
msgbuf_cache_free(struct MsgBuf_cache *cache)
{
struct MsgBuf_cache_entry *entry = cache->head;
while (entry != NULL) {
rb_linebuf_donebuf(&entry->linebuf);
entry = entry->next;
}
cache->head = NULL;
}

View file

@ -42,6 +42,8 @@
/* send the message to the link the target is attached to */ /* 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 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); static void send_queued_write(rb_fde_t *F, void *data);
unsigned long current_serial = 0L; unsigned long current_serial = 0L;
@ -209,40 +211,52 @@ send_queued_write(rb_fde_t *F, void *data)
} }
/* /*
* linebuf_put_tags_prefix * linebuf_put_*
* *
* inputs - msgbuf header, linebuf object, capability mask, pattern, arguments * inputs - msgbuf header, linebuf object, capability mask, pattern, arguments
* outputs - none * outputs - none
* side effects - the linebuf object is cleared, then populated using rb_linebuf_putprefix(). * side effects - the linebuf object is cleared, then populated
*/ */
static void static void
linebuf_put_tags_vprefix(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)
{ {
static char buf[EXT_BUFSIZE]; struct MsgBuf_str_data msgbuf_str_data = { .msgbuf = msgbuf, .caps = CLIENT_CAPS_ONLY(target_p) };
size_t buflen = sizeof(buf); rb_strf_t strings = { .func = msgbuf_unparse_linebuf_tags, .func_args = &msgbuf_str_data, .length = TAGSLEN + 1, .next = message };
rb_linebuf_newbuf(linebuf); message->length = DATALEN + 1;
msgbuf_unparse_prefix(buf, &buflen, msgbuf, capmask); rb_linebuf_put(linebuf, &strings);
rb_linebuf_put_vtags_prefix(linebuf, pattern, va, buflen, buf);
} }
/* linebuf_put_tags_prefixf
*
* inputs - msgbuf header, linebuf object, capability mask, pattern, arguments
* outputs - none
* side effects - the linebuf object is cleared, then populated using rb_linebuf_putprefix().
*/
static void static void
linebuf_put_tags_prefixf(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; va_list va;
rb_strf_t strings = { .format = format, .format_args = &va, .next = message };
va_start(va, pattern); va_start(va, format);
linebuf_put_tags_vprefix(msgbuf, linebuf, capmask, pattern, &va); linebuf_put_tags(linebuf, msgbuf, target_p, &strings);
va_end(va); 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 * inputs - msgbuf object, client the message is from
* outputs - none * outputs - none
@ -250,23 +264,12 @@ linebuf_put_tags_prefixf(struct MsgBuf *msgbuf, buf_head_t *linebuf, unsigned in
* notes - to make this reentrant, find a solution for `buf` below * notes - to make this reentrant, find a solution for `buf` below
*/ */
static void 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; hook_data hdata;
msgbuf_init(msgbuf); 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.client = from;
hdata.arg1 = msgbuf; hdata.arg1 = msgbuf;
@ -283,7 +286,9 @@ void
sendto_one(struct Client *target_p, const char *pattern, ...) sendto_one(struct Client *target_p, const char *pattern, ...)
{ {
va_list args; va_list args;
struct MsgBuf msgbuf;
buf_head_t linebuf; buf_head_t linebuf;
rb_strf_t strings = { .format = pattern, .format_args = &args, .next = NULL };
/* send remote if to->from non NULL */ /* send remote if to->from non NULL */
if(target_p->from != NULL) if(target_p->from != NULL)
@ -294,8 +299,9 @@ sendto_one(struct Client *target_p, const char *pattern, ...)
rb_linebuf_newbuf(&linebuf); rb_linebuf_newbuf(&linebuf);
build_msgbuf_tags(&msgbuf, &me);
va_start(args, pattern); va_start(args, pattern);
rb_linebuf_put_vmsg(&linebuf, pattern, &args); linebuf_put_tags(&linebuf, &msgbuf, target_p, &strings);
va_end(args); va_end(args);
_send_linebuf(target_p, &linebuf); _send_linebuf(target_p, &linebuf);
@ -315,7 +321,9 @@ sendto_one_prefix(struct Client *target_p, struct Client *source_p,
{ {
struct Client *dest_p = target_p->from; struct Client *dest_p = target_p->from;
va_list args; va_list args;
struct MsgBuf msgbuf;
buf_head_t linebuf; buf_head_t linebuf;
rb_strf_t strings = { .format = pattern, .format_args = &args, .next = NULL };
if(IsIOError(dest_p)) if(IsIOError(dest_p))
return; return;
@ -326,12 +334,13 @@ sendto_one_prefix(struct Client *target_p, struct Client *source_p,
return; return;
} }
build_msgbuf_tags(&msgbuf, source_p);
rb_linebuf_newbuf(&linebuf); rb_linebuf_newbuf(&linebuf);
va_start(args, pattern); va_start(args, pattern);
rb_linebuf_put_vmsg_prefixf(&linebuf, pattern, &args, linebuf_put_tagsf(&linebuf, &msgbuf, target_p, &strings,
":%s %s %s ", ":%s %s %s ", get_id(source_p, target_p),
get_id(source_p, target_p), command, get_id(target_p, target_p));
command, get_id(target_p, target_p));
va_end(args); va_end(args);
_send_linebuf(dest_p, &linebuf); _send_linebuf(dest_p, &linebuf);
@ -349,7 +358,9 @@ sendto_one_notice(struct Client *target_p, const char *pattern, ...)
{ {
struct Client *dest_p = target_p->from; struct Client *dest_p = target_p->from;
va_list args; va_list args;
struct MsgBuf msgbuf;
buf_head_t linebuf; buf_head_t linebuf;
rb_strf_t strings = { .format = pattern, .format_args = &args, .next = NULL };
char *to; char *to;
if(IsIOError(dest_p)) if(IsIOError(dest_p))
@ -361,11 +372,13 @@ sendto_one_notice(struct Client *target_p, const char *pattern, ...)
return; return;
} }
build_msgbuf_tags(&msgbuf, &me);
rb_linebuf_newbuf(&linebuf); rb_linebuf_newbuf(&linebuf);
va_start(args, pattern); va_start(args, pattern);
rb_linebuf_put_vmsg_prefixf(&linebuf, pattern, &args, linebuf_put_tagsf(&linebuf, &msgbuf, target_p, &strings,
":%s NOTICE %s ", ":%s NOTICE %s ", get_id(&me, target_p),
get_id(&me, target_p), *(to = get_id(target_p, target_p)) != '\0' ? to : "*"); *(to = get_id(target_p, target_p)) != '\0' ? to : "*");
va_end(args); va_end(args);
_send_linebuf(dest_p, &linebuf); _send_linebuf(dest_p, &linebuf);
@ -384,7 +397,9 @@ sendto_one_numeric(struct Client *target_p, int numeric, const char *pattern, ..
{ {
struct Client *dest_p = target_p->from; struct Client *dest_p = target_p->from;
va_list args; va_list args;
struct MsgBuf msgbuf;
buf_head_t linebuf; buf_head_t linebuf;
rb_strf_t strings = { .format = pattern, .format_args = &args, .next = NULL };
char *to; char *to;
if(IsIOError(dest_p)) if(IsIOError(dest_p))
@ -396,12 +411,13 @@ sendto_one_numeric(struct Client *target_p, int numeric, const char *pattern, ..
return; return;
} }
build_msgbuf_tags(&msgbuf, &me);
rb_linebuf_newbuf(&linebuf); rb_linebuf_newbuf(&linebuf);
va_start(args, pattern); va_start(args, pattern);
rb_linebuf_put_vmsg_prefixf(&linebuf, pattern, &args, linebuf_put_tagsf(&linebuf, &msgbuf, target_p, &strings,
":%s %03d %s ", ":%s %03d %s ", get_id(&me, target_p), numeric,
get_id(&me, target_p), *(to = get_id(target_p, target_p)) != '\0' ? to : "*");
numeric, *(to = get_id(target_p, target_p)) != '\0' ? to : "*");
va_end(args); va_end(args);
_send_linebuf(dest_p, &linebuf); _send_linebuf(dest_p, &linebuf);
@ -434,6 +450,7 @@ sendto_server(struct Client *one, struct Channel *chptr, unsigned long caps,
rb_dlink_node *ptr; rb_dlink_node *ptr;
rb_dlink_node *next_ptr; rb_dlink_node *next_ptr;
buf_head_t linebuf; buf_head_t linebuf;
rb_strf_t strings = { .format = format, .format_args = &args, .next = NULL };
/* noone to send to.. */ /* noone to send to.. */
if(rb_dlink_list_length(&serv_list) == 0) if(rb_dlink_list_length(&serv_list) == 0)
@ -444,7 +461,7 @@ sendto_server(struct Client *one, struct Channel *chptr, unsigned long caps,
rb_linebuf_newbuf(&linebuf); rb_linebuf_newbuf(&linebuf);
va_start(args, format); va_start(args, format);
rb_linebuf_put_vmsg(&linebuf, format, &args); linebuf_put_msg(&linebuf, &strings);
va_end(args); va_end(args);
RB_DLINK_FOREACH_SAFE(ptr, next_ptr, serv_list.head) RB_DLINK_FOREACH_SAFE(ptr, next_ptr, serv_list.head)
@ -481,28 +498,29 @@ sendto_channel_flags(struct Client *one, int type, struct Client *source_p,
{ {
static char buf[BUFSIZE]; static char buf[BUFSIZE];
va_list args; va_list args;
buf_head_t rb_linebuf_local;
buf_head_t rb_linebuf_remote; buf_head_t rb_linebuf_remote;
struct Client *target_p; struct Client *target_p;
struct membership *msptr; struct membership *msptr;
rb_dlink_node *ptr; rb_dlink_node *ptr;
rb_dlink_node *next_ptr; rb_dlink_node *next_ptr;
int current_capmask = NOCAPS;
struct MsgBuf msgbuf; 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_remote); rb_linebuf_newbuf(&rb_linebuf_remote);
current_serial++; current_serial++;
build_msgbuf_from(&msgbuf, source_p, NULL); build_msgbuf_tags(&msgbuf, source_p);
va_start(args, pattern); va_start(args, pattern);
vsnprintf(buf, sizeof buf, pattern, args); vsnprintf(buf, sizeof buf, pattern, args);
va_end(args); va_end(args);
linebuf_put_tags_prefixf(&msgbuf, &rb_linebuf_local, current_capmask, "%s", buf); linebuf_put_msgf(&rb_linebuf_remote, NULL, ":%s %s", use_id(source_p), buf);
rb_linebuf_put_msgf(&rb_linebuf_remote, ":%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) RB_DLINK_FOREACH_SAFE(ptr, next_ptr, chptr->members.head)
{ {
@ -537,18 +555,7 @@ sendto_channel_flags(struct Client *one, int type, struct Client *source_p,
} }
else else
{ {
if (target_p->localClient->caps != current_capmask) _send_linebuf(target_p, msgbuf_cache_get(&msgbuf_cache, CLIENT_CAPS_ONLY(target_p)));
{
/* 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_tags_prefixf(&msgbuf, &rb_linebuf_local, current_capmask, "%s", buf);
}
_send_linebuf(target_p, &rb_linebuf_local);
} }
} }
@ -557,22 +564,11 @@ sendto_channel_flags(struct Client *one, int type, struct Client *source_p,
{ {
target_p = one; target_p = one;
if (target_p->localClient->caps != current_capmask) _send_linebuf(target_p, msgbuf_cache_get(&msgbuf_cache, CLIENT_CAPS_ONLY(target_p)));
{
/* 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_tags_prefixf(&msgbuf, &rb_linebuf_local, current_capmask, "%s", buf);
}
_send_linebuf(target_p, &rb_linebuf_local);
} }
rb_linebuf_donebuf(&rb_linebuf_local);
rb_linebuf_donebuf(&rb_linebuf_remote); rb_linebuf_donebuf(&rb_linebuf_remote);
msgbuf_cache_free(&msgbuf_cache);
} }
/* sendto_channel_flags() /* sendto_channel_flags()
@ -586,42 +582,47 @@ sendto_channel_opmod(struct Client *one, struct Client *source_p,
struct Channel *chptr, const char *command, struct Channel *chptr, const char *command,
const char *text) const char *text)
{ {
buf_head_t rb_linebuf_local;
buf_head_t rb_linebuf_old; buf_head_t rb_linebuf_old;
buf_head_t rb_linebuf_new; buf_head_t rb_linebuf_new;
struct Client *target_p; struct Client *target_p;
struct membership *msptr; struct membership *msptr;
rb_dlink_node *ptr; rb_dlink_node *ptr;
rb_dlink_node *next_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_old);
rb_linebuf_newbuf(&rb_linebuf_new); rb_linebuf_newbuf(&rb_linebuf_new);
build_msgbuf_tags(&msgbuf, source_p);
current_serial++; current_serial++;
if(IsServer(source_p)) if(IsServer(source_p)) {
rb_linebuf_put_msgf(&rb_linebuf_local, msgbuf_cache_initf(&msgbuf_cache, &msgbuf, &strings,
":%s %s %s :%s", ":%s %s %s :",
source_p->name, command, chptr->chname, text); source_p->name, command, chptr->chname);
else } else {
rb_linebuf_put_msgf(&rb_linebuf_local, msgbuf_cache_initf(&msgbuf_cache, &msgbuf, &strings,
":%s!%s@%s %s %s :%s", ":%s!%s@%s %s %s :",
source_p->name, source_p->username, source_p->name, source_p->username,
source_p->host, command, chptr->chname, text); source_p->host, command, chptr->chname);
}
if (chptr->mode.mode & MODE_MODERATED) if (chptr->mode.mode & MODE_MODERATED) {
rb_linebuf_put_msgf(&rb_linebuf_old, linebuf_put_msgf(&rb_linebuf_old, &strings,
":%s %s %s :%s", ":%s %s %s :",
use_id(source_p), command, chptr->chname, text); use_id(source_p), command, chptr->chname, text);
else } else {
rb_linebuf_put_msgf(&rb_linebuf_old, linebuf_put_msgf(&rb_linebuf_old, &strings,
":%s NOTICE @%s :<%s:%s> %s", ":%s NOTICE @%s :<%s:%s> ",
use_id(source_p->servptr), chptr->chname, use_id(source_p->servptr), chptr->chname,
source_p->name, chptr->chname, text); source_p->name, chptr->chname);
rb_linebuf_put_msgf(&rb_linebuf_new, }
":%s %s =%s :%s", linebuf_put_msgf(&rb_linebuf_new, &strings,
use_id(source_p), command, chptr->chname, text); ":%s %s =%s :",
use_id(source_p), command, chptr->chname);
RB_DLINK_FOREACH_SAFE(ptr, next_ptr, chptr->members.head) RB_DLINK_FOREACH_SAFE(ptr, next_ptr, chptr->members.head)
{ {
@ -656,9 +657,9 @@ sendto_channel_opmod(struct Client *one, struct Client *source_p,
send_linebuf_remote(target_p, source_p, &rb_linebuf_old); send_linebuf_remote(target_p, source_p, &rb_linebuf_old);
target_p->from->serial = current_serial; 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 */ /* source client may not be on the channel, send echo separately */
@ -666,34 +667,36 @@ sendto_channel_opmod(struct Client *one, struct Client *source_p,
{ {
target_p = one; 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_old);
rb_linebuf_donebuf(&rb_linebuf_new); rb_linebuf_donebuf(&rb_linebuf_new);
msgbuf_cache_free(&msgbuf_cache);
} }
/* sendto_channel_local() /* 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 * outputs - message to local channel members
* side effects - * side effects -
*/ */
void 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; va_list args;
buf_head_t linebuf;
struct membership *msptr; struct membership *msptr;
struct Client *target_p; struct Client *target_p;
rb_dlink_node *ptr; rb_dlink_node *ptr;
rb_dlink_node *next_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); va_start(args, pattern);
rb_linebuf_put_vmsg(&linebuf, pattern, &args); msgbuf_cache_init(&msgbuf_cache, &msgbuf, &strings);
va_end(args); va_end(args);
RB_DLINK_FOREACH_SAFE(ptr, next_ptr, chptr->locmembers.head) RB_DLINK_FOREACH_SAFE(ptr, next_ptr, chptr->locmembers.head)
@ -712,10 +715,10 @@ sendto_channel_local(int type, struct Channel *chptr, const char *pattern, ...)
else if(type && ((msptr->flags & type) == 0)) else if(type && ((msptr->flags & type) == 0))
continue; 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);
} }
/* /*
@ -724,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 * Shared implementation of sendto_channel_local_with_capability and sendto_channel_local_with_capability_butone
*/ */
static void static void
_sendto_channel_local_with_capability_butone(struct Client *one, int type, int caps, int negcaps, struct Channel *chptr, _sendto_channel_local_with_capability_butone(struct Client *source_p, struct Client *one, int type,
const char *pattern, va_list * args) int caps, int negcaps, struct Channel *chptr, const char *pattern, va_list * args)
{ {
buf_head_t linebuf;
struct membership *msptr; struct membership *msptr;
struct Client *target_p; struct Client *target_p;
rb_dlink_node *ptr; rb_dlink_node *ptr;
rb_dlink_node *next_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);
rb_linebuf_put_vmsg(&linebuf, pattern, args); msgbuf_cache_init(&msgbuf_cache, &msgbuf, &strings);
RB_DLINK_FOREACH_SAFE(ptr, next_ptr, chptr->locmembers.head) RB_DLINK_FOREACH_SAFE(ptr, next_ptr, chptr->locmembers.head)
{ {
@ -752,43 +757,43 @@ _sendto_channel_local_with_capability_butone(struct Client *one, int type, int c
if(type && ((msptr->flags & type) == 0)) if(type && ((msptr->flags & type) == 0))
continue; 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() /* 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 * outputs - message to local channel members
* side effects - * side effects -
*/ */
void 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_list args;
va_start(args, pattern); 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); va_end(args);
} }
/* sendto_channel_local_with_capability() /* 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 * outputs - message to local channel members
* side effects - * side effects -
*/ */
void void
sendto_channel_local_with_capability_butone(struct Client *one, int type, int caps, int negcaps, struct Channel *chptr, sendto_channel_local_with_capability_butone(struct Client *one, int type,
const char *pattern, ...) int caps, int negcaps, struct Channel *chptr, const char *pattern, ...)
{ {
va_list args; va_list args;
va_start(args, pattern); 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); va_end(args);
} }
@ -804,19 +809,18 @@ void
sendto_channel_local_butone(struct Client *one, int type, struct Channel *chptr, const char *pattern, ...) sendto_channel_local_butone(struct Client *one, int type, struct Channel *chptr, const char *pattern, ...)
{ {
va_list args; va_list args;
buf_head_t linebuf;
struct membership *msptr; struct membership *msptr;
struct Client *target_p; struct Client *target_p;
struct MsgBuf msgbuf; struct MsgBuf msgbuf;
rb_dlink_node *ptr; rb_dlink_node *ptr;
rb_dlink_node *next_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_tags(&msgbuf, one);
build_msgbuf_from(&msgbuf, one, NULL);
va_start(args, pattern); va_start(args, pattern);
rb_linebuf_put_vmsg(&linebuf, pattern, &args); msgbuf_cache_init(&msgbuf_cache, &msgbuf, &strings);
va_end(args); va_end(args);
RB_DLINK_FOREACH_SAFE(ptr, next_ptr, chptr->locmembers.head) RB_DLINK_FOREACH_SAFE(ptr, next_ptr, chptr->locmembers.head)
@ -834,18 +838,18 @@ sendto_channel_local_butone(struct Client *one, int type, struct Channel *chptr,
continue; continue;
/* attach the present linebuf to the target */ /* 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() * sendto_common_channels_local()
* *
* inputs - pointer to client * inputs - pointer to client
* - capability mask * - capability mask
* - negated capability mask * - negated capability mask
* - pattern to send * - pattern to send
* output - NONE * output - NONE
* side effects - Sends a message to all people on local server who are * side effects - Sends a message to all people on local server who are
@ -864,11 +868,14 @@ sendto_common_channels_local(struct Client *user, int cap, int negcap, const cha
struct Client *target_p; struct Client *target_p;
struct membership *msptr; struct membership *msptr;
struct membership *mscptr; 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); va_start(args, pattern);
rb_linebuf_put_vmsg(&linebuf, pattern, &args); msgbuf_cache_init(&msgbuf_cache, &msgbuf, &strings);
va_end(args); va_end(args);
++current_serial; ++current_serial;
@ -890,7 +897,7 @@ sendto_common_channels_local(struct Client *user, int cap, int negcap, const cha
continue; continue;
target_p->serial = current_serial; target_p->serial = current_serial;
send_linebuf(target_p, &linebuf); send_linebuf(target_p, msgbuf_cache_get(&msgbuf_cache, CLIENT_CAPS_ONLY(target_p)));
} }
} }
@ -898,18 +905,19 @@ sendto_common_channels_local(struct Client *user, int cap, int negcap, const cha
* need to send them the data, ie a nick change * need to send them the data, ie a nick change
*/ */
if(MyConnect(user) && (user->serial != current_serial) if(MyConnect(user) && (user->serial != current_serial)
&& IsCapable(user, cap) && NotCapable(user, negcap)) && IsCapable(user, cap) && NotCapable(user, negcap)) {
send_linebuf(user, &linebuf); 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() * sendto_common_channels_local_butone()
* *
* inputs - pointer to client * inputs - pointer to client
* - capability mask * - capability mask
* - negated capability mask * - negated capability mask
* - pattern to send * - pattern to send
* output - NONE * output - NONE
* side effects - Sends a message to all people on local server who are * side effects - Sends a message to all people on local server who are
@ -927,12 +935,14 @@ sendto_common_channels_local_butone(struct Client *user, int cap, int negcap, co
struct Client *target_p; struct Client *target_p;
struct membership *msptr; struct membership *msptr;
struct membership *mscptr; 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); va_start(args, pattern);
rb_linebuf_put_vmsg(&linebuf, pattern, &args); msgbuf_cache_init(&msgbuf_cache, &msgbuf, &strings);
va_end(args); va_end(args);
++current_serial; ++current_serial;
@ -956,11 +966,11 @@ sendto_common_channels_local_butone(struct Client *user, int cap, int negcap, co
continue; continue;
target_p->serial = current_serial; 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() /* sendto_match_butone()
@ -978,26 +988,24 @@ sendto_match_butone(struct Client *one, struct Client *source_p,
struct Client *target_p; struct Client *target_p;
rb_dlink_node *ptr; rb_dlink_node *ptr;
rb_dlink_node *next_ptr; rb_dlink_node *next_ptr;
buf_head_t rb_linebuf_local;
buf_head_t rb_linebuf_remote; 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_remote); rb_linebuf_newbuf(&rb_linebuf_remote);
build_msgbuf_tags(&msgbuf, source_p);
va_start(args, pattern); va_start(args, pattern);
vsnprintf(buf, sizeof(buf), pattern, args); vsnprintf(buf, sizeof(buf), pattern, args);
va_end(args); va_end(args);
if(IsServer(source_p)) msgbuf_cache_initf(&msgbuf_cache, &msgbuf, &strings,
rb_linebuf_put_msgf(&rb_linebuf_local, IsServer(source_p) ? ":%s " : ":%s!%s@%s ",
":%s %s", source_p->name, buf); source_p->name, source_p->username, source_p->host);
else
rb_linebuf_put_msgf(&rb_linebuf_local,
":%s!%s@%s %s",
source_p->name, source_p->username,
source_p->host, buf);
rb_linebuf_put_msgf(&rb_linebuf_remote, ":%s %s", use_id(source_p), buf); linebuf_put_msgf(&rb_linebuf_remote, &strings, ":%s ", use_id(source_p));
if(what == MATCH_HOST) if(what == MATCH_HOST)
{ {
@ -1006,7 +1014,7 @@ sendto_match_butone(struct Client *one, struct Client *source_p,
target_p = ptr->data; target_p = ptr->data;
if(match(mask, target_p->host)) 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 */ /* what = MATCH_SERVER, if it doesnt match us, just send remote */
@ -1015,7 +1023,7 @@ sendto_match_butone(struct Client *one, struct Client *source_p,
RB_DLINK_FOREACH_SAFE(ptr, next_ptr, lclient_list.head) RB_DLINK_FOREACH_SAFE(ptr, next_ptr, lclient_list.head)
{ {
target_p = ptr->data; 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)));
} }
} }
@ -1029,7 +1037,7 @@ sendto_match_butone(struct Client *one, struct Client *source_p,
send_linebuf_remote(target_p, source_p, &rb_linebuf_remote); send_linebuf_remote(target_p, source_p, &rb_linebuf_remote);
} }
rb_linebuf_donebuf(&rb_linebuf_local); msgbuf_cache_free(&msgbuf_cache);
rb_linebuf_donebuf(&rb_linebuf_remote); rb_linebuf_donebuf(&rb_linebuf_remote);
} }
@ -1048,6 +1056,7 @@ sendto_match_servs(struct Client *source_p, const char *mask, int cap,
rb_dlink_node *ptr; rb_dlink_node *ptr;
struct Client *target_p; struct Client *target_p;
buf_head_t rb_linebuf_id; buf_head_t rb_linebuf_id;
rb_strf_t strings = { .format = buf, .format_args = NULL, .next = NULL };
if(EmptyString(mask)) if(EmptyString(mask))
return; return;
@ -1058,7 +1067,7 @@ sendto_match_servs(struct Client *source_p, const char *mask, int cap,
vsnprintf(buf, sizeof(buf), pattern, args); vsnprintf(buf, sizeof(buf), pattern, args);
va_end(args); va_end(args);
rb_linebuf_put_msgf(&rb_linebuf_id, ":%s %s", use_id(source_p), buf); linebuf_put_msgf(&rb_linebuf_id, &strings, ":%s ", use_id(source_p));
current_serial++; current_serial++;
@ -1105,12 +1114,14 @@ sendto_local_clients_with_capability(int cap, const char *pattern, ...)
va_list args; va_list args;
rb_dlink_node *ptr; rb_dlink_node *ptr;
struct Client *target_p; 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); va_start(args, pattern);
rb_linebuf_put_vmsg(&linebuf, pattern, &args); msgbuf_cache_init(&msgbuf_cache, &msgbuf, &strings);
va_end(args); va_end(args);
RB_DLINK_FOREACH(ptr, lclient_list.head) RB_DLINK_FOREACH(ptr, lclient_list.head)
@ -1120,10 +1131,10 @@ sendto_local_clients_with_capability(int cap, const char *pattern, ...)
if(IsIOError(target_p) || !IsCapable(target_p, cap)) if(IsIOError(target_p) || !IsCapable(target_p, cap))
continue; 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() /* sendto_monitor()
@ -1133,18 +1144,20 @@ sendto_local_clients_with_capability(int cap, const char *pattern, ...)
* side effects - * side effects -
*/ */
void void
sendto_monitor(struct monitor *monptr, const char *pattern, ...) sendto_monitor(struct Client *source_p, struct monitor *monptr, const char *pattern, ...)
{ {
va_list args; va_list args;
buf_head_t linebuf;
struct Client *target_p; struct Client *target_p;
rb_dlink_node *ptr; rb_dlink_node *ptr;
rb_dlink_node *next_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); va_start(args, pattern);
rb_linebuf_put_vmsg(&linebuf, pattern, &args); msgbuf_cache_init(&msgbuf_cache, &msgbuf, &strings);
va_end(args); va_end(args);
RB_DLINK_FOREACH_SAFE(ptr, next_ptr, monptr->users.head) RB_DLINK_FOREACH_SAFE(ptr, next_ptr, monptr->users.head)
@ -1154,10 +1167,10 @@ sendto_monitor(struct monitor *monptr, const char *pattern, ...)
if(IsIOError(target_p)) if(IsIOError(target_p))
continue; 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() /* _sendto_anywhere()
@ -1172,34 +1185,34 @@ _sendto_anywhere(struct Client *dest_p, struct Client *target_p,
const char *pattern, va_list *args) const char *pattern, va_list *args)
{ {
buf_head_t linebuf; buf_head_t linebuf;
rb_strf_t strings = { .format = pattern, .format_args = args, .next = NULL };
rb_linebuf_newbuf(&linebuf); rb_linebuf_newbuf(&linebuf);
if(MyClient(dest_p)) if (MyClient(dest_p)) {
{ if (IsServer(source_p)) {
if(IsServer(source_p)) linebuf_put_msgf(&linebuf, &strings, ":%s %s %s ",
rb_linebuf_put_vmsg_prefixf(&linebuf, pattern, args, ":%s %s %s ",
source_p->name, command, source_p->name, command,
target_p->name); target_p->name);
else } else {
{
struct MsgBuf msgbuf; struct MsgBuf msgbuf;
build_msgbuf_from(&msgbuf, source_p, command); build_msgbuf_tags(&msgbuf, source_p);
msgbuf.target = target_p->name;
linebuf_put_tags_vprefix(&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 _send_linebuf(dest_p, &linebuf);
rb_linebuf_put_vmsg_prefixf(&linebuf, pattern, args, ":%s %s %s ", } else {
linebuf_put_msgf(&linebuf, &strings, ":%s %s %s ",
get_id(source_p, target_p), command, get_id(source_p, target_p), command,
get_id(target_p, target_p)); get_id(target_p, target_p));
if(MyClient(dest_p))
_send_linebuf(dest_p, &linebuf);
else
send_linebuf_remote(dest_p, source_p, &linebuf); send_linebuf_remote(dest_p, source_p, &linebuf);
}
rb_linebuf_donebuf(&linebuf); rb_linebuf_donebuf(&linebuf);
} }
@ -1256,21 +1269,23 @@ sendto_realops_snomask(int flags, int level, const char *pattern, ...)
rb_dlink_node *ptr; rb_dlink_node *ptr;
rb_dlink_node *next_ptr; rb_dlink_node *next_ptr;
va_list args; 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" /* Be very sure not to do things like "Trying to send to myself"
* L_NETWIDE, otherwise infinite recursion may result! -- jilles */ * L_NETWIDE, otherwise infinite recursion may result! -- jilles */
if (level & L_NETWIDE && ConfigFileEntry.global_snotices) 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_put_msgf(&linebuf,
":%s NOTICE * :*** Notice -- %s", me.name, buf);
snobuf = construct_snobuf(flags); snobuf = construct_snobuf(flags);
if (snobuf[1] != '\0') if (snobuf[1] != '\0')
sendto_server(NULL, NULL, CAP_ENCAP|CAP_TS6, NOCAPS, sendto_server(NULL, NULL, CAP_ENCAP|CAP_TS6, NOCAPS,
@ -1279,22 +1294,8 @@ sendto_realops_snomask(int flags, int level, const char *pattern, ...)
} }
else if (remote_rehash_oper_p != NULL) 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_put_msgf(&linebuf,
":%s NOTICE * :*** Notice -- %s", me.name, buf);
sendto_one_notice(remote_rehash_oper_p, ":*** Notice -- %s", buf); sendto_one_notice(remote_rehash_oper_p, ":*** Notice -- %s", buf);
} }
else
{
va_start(args, pattern);
rb_linebuf_put_vmsg_prefixf(&linebuf, pattern, &args,
":%s NOTICE * :*** Notice -- ", me.name);
va_end(args);
}
level &= ~L_NETWIDE; level &= ~L_NETWIDE;
RB_DLINK_FOREACH_SAFE(ptr, next_ptr, local_oper_list.head) RB_DLINK_FOREACH_SAFE(ptr, next_ptr, local_oper_list.head)
@ -1308,11 +1309,12 @@ sendto_realops_snomask(int flags, int level, const char *pattern, ...)
((level == L_OPER) && IsOperAdmin(client_p))) ((level == L_OPER) && IsOperAdmin(client_p)))
continue; continue;
if(client_p->snomask & flags) if (client_p->snomask & flags) {
_send_linebuf(client_p, &linebuf); _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() /* sendto_realops_snomask_from()
* *
@ -1328,12 +1330,14 @@ sendto_realops_snomask_from(int flags, int level, struct Client *source_p,
rb_dlink_node *ptr; rb_dlink_node *ptr;
rb_dlink_node *next_ptr; rb_dlink_node *next_ptr;
va_list args; 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); va_start(args, pattern);
rb_linebuf_put_vmsg_prefixf(&linebuf, pattern, &args, msgbuf_cache_initf(&msgbuf_cache, &msgbuf, &strings,
":%s NOTICE * :*** Notice -- ", source_p->name); ":%s NOTICE * :*** Notice -- ", source_p->name);
va_end(args); va_end(args);
@ -1348,11 +1352,12 @@ sendto_realops_snomask_from(int flags, int level, struct Client *source_p,
((level == L_OPER) && IsOperAdmin(client_p))) ((level == L_OPER) && IsOperAdmin(client_p)))
continue; continue;
if(client_p->snomask & flags) if (client_p->snomask & flags) {
_send_linebuf(client_p, &linebuf); _send_linebuf(client_p, msgbuf_cache_get(&msgbuf_cache, CLIENT_CAPS_ONLY(client_p)));
}
} }
rb_linebuf_donebuf(&linebuf); msgbuf_cache_free(&msgbuf_cache);
} }
/* /*
@ -1371,30 +1376,33 @@ sendto_wallops_flags(int flags, struct Client *source_p, const char *pattern, ..
rb_dlink_node *ptr; rb_dlink_node *ptr;
rb_dlink_node *next_ptr; rb_dlink_node *next_ptr;
va_list args; 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); va_start(args, pattern);
if (IsPerson(source_p)) {
if(IsPerson(source_p)) msgbuf_cache_initf(&msgbuf_cache, &msgbuf, &strings,
rb_linebuf_put_vmsg_prefixf(&linebuf, pattern, &args,
":%s!%s@%s WALLOPS :", source_p->name, ":%s!%s@%s WALLOPS :", source_p->name,
source_p->username, source_p->host); source_p->username, source_p->host);
else } else {
rb_linebuf_put_vmsg_prefixf(&linebuf, pattern, &args, ":%s WALLOPS :", source_p->name); msgbuf_cache_initf(&msgbuf_cache, &msgbuf, &strings,
":%s WALLOPS :", source_p->name);
}
va_end(args); va_end(args);
RB_DLINK_FOREACH_SAFE(ptr, next_ptr, IsPerson(source_p) && flags == UMODE_WALLOP ? lclient_list.head : local_oper_list.head) RB_DLINK_FOREACH_SAFE(ptr, next_ptr, IsPerson(source_p) && flags == UMODE_WALLOP ? lclient_list.head : local_oper_list.head)
{ {
client_p = ptr->data; client_p = ptr->data;
if(client_p->umodes & flags) if (client_p->umodes & flags) {
_send_linebuf(client_p, &linebuf); _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() /* kill_client()
@ -1408,12 +1416,16 @@ kill_client(struct Client *target_p, struct Client *diedie, const char *pattern,
{ {
va_list args; va_list args;
buf_head_t linebuf; 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); rb_linebuf_newbuf(&linebuf);
va_start(args, pattern); va_start(args, pattern);
rb_linebuf_put_vmsg_prefixf(&linebuf, pattern, &args, ":%s KILL %s :", linebuf_put_tagsf(&linebuf, &msgbuf, target_p, &strings,
get_id(&me, target_p), get_id(diedie, target_p)); ":%s KILL %s :", get_id(&me, target_p), get_id(diedie, target_p));
va_end(args); va_end(args);
send_linebuf(target_p, &linebuf); send_linebuf(target_p, &linebuf);
@ -1441,15 +1453,14 @@ kill_client_serv_butone(struct Client *one, struct Client *target_p, const char
rb_dlink_node *ptr; rb_dlink_node *ptr;
rb_dlink_node *next_ptr; rb_dlink_node *next_ptr;
buf_head_t rb_linebuf_id; buf_head_t rb_linebuf_id;
rb_strf_t strings = { .format = pattern, .format_args = &args, .next = NULL };
rb_linebuf_newbuf(&rb_linebuf_id); rb_linebuf_newbuf(&rb_linebuf_id);
va_start(args, pattern); va_start(args, pattern);
vsnprintf(buf, sizeof(buf), pattern, args); linebuf_put_msgf(&rb_linebuf_id, &strings, ":%s KILL %s :%s",
va_end(args);
rb_linebuf_put_msgf(&rb_linebuf_id, ":%s KILL %s :%s",
use_id(&me), use_id(target_p), buf); use_id(&me), use_id(target_p), buf);
va_end(args);
RB_DLINK_FOREACH_SAFE(ptr, next_ptr, serv_list.head) RB_DLINK_FOREACH_SAFE(ptr, next_ptr, serv_list.head)
{ {

View file

@ -62,8 +62,6 @@ typedef struct _buf_head
int numlines; /* number of lines */ int numlines; /* number of lines */
} buf_head_t; } buf_head_t;
/* they should be functions, but .. */ /* they should be functions, but .. */
#define rb_linebuf_len(x) ((x)->len) #define rb_linebuf_len(x) ((x)->len)
#define rb_linebuf_alloclen(x) ((x)->alloclen) #define rb_linebuf_alloclen(x) ((x)->alloclen)
@ -74,15 +72,7 @@ void rb_linebuf_newbuf(buf_head_t *);
void rb_linebuf_donebuf(buf_head_t *); void rb_linebuf_donebuf(buf_head_t *);
int rb_linebuf_parse(buf_head_t *, char *, int, int); int rb_linebuf_parse(buf_head_t *, char *, int, int);
int rb_linebuf_get(buf_head_t *, char *, int, int, int); int rb_linebuf_get(buf_head_t *, char *, int, int, int);
/* "msg" is limited to RFC1459 message size */ void rb_linebuf_put(buf_head_t *, const rb_strf_t *);
void rb_linebuf_put_msgf(buf_head_t *, const char *, ...) AFP(2,3);
void rb_linebuf_put_vmsg(buf_head_t *, const char *, va_list *);
void rb_linebuf_put_vmsg_prefixf(buf_head_t *, const char *, va_list *, const char *, ...) AFP(4,5);
/* "tags" has a prefix that contains tags AND messages, it must
* specify the correct total buffer length to enforce the limit
* of the RFC1459 message size */
void rb_linebuf_put_vtags_prefix(buf_head_t *, const char *, va_list *, size_t, const char *);
void rb_linebuf_put_vtags_prefixf(buf_head_t *, const char *, va_list *, size_t, const char *, ...) AFP(5,6);
void rb_linebuf_attach(buf_head_t *, buf_head_t *); void rb_linebuf_attach(buf_head_t *, buf_head_t *);
void rb_count_rb_linebuf_memory(size_t *, size_t *); void rb_count_rb_linebuf_memory(size_t *, size_t *);
int rb_linebuf_flush(rb_fde_t *F, buf_head_t *); int rb_linebuf_flush(rb_fde_t *F, buf_head_t *);

View file

@ -368,6 +368,26 @@ void rb_zstring_append_from_c(rb_zstring_t *zs, const char *buf, size_t len);
char *rb_zstring_to_c(rb_zstring_t *zs, char *buf, size_t len); char *rb_zstring_to_c(rb_zstring_t *zs, char *buf, size_t len);
char *rb_zstring_to_c_alloc(rb_zstring_t *zs); char *rb_zstring_to_c_alloc(rb_zstring_t *zs);
size_t rb_zstring_to_ptr(rb_zstring_t *zs, void **ptr); size_t rb_zstring_to_ptr(rb_zstring_t *zs, void **ptr);
typedef int (*rb_strf_func_t)(char *buf, size_t len, void *args);
typedef struct _rb_strf {
size_t length; /* length limit to apply to this string (and following strings if their length is 0) */
const char *format; /* string or format string */
rb_strf_func_t func; /* function to print to string */
union {
va_list *format_args; /* non-NULL if this is a format string */
void *func_args; /* args for a function */
};
const struct _rb_strf *next; /* next string to append */
} rb_strf_t;
int rb_fsnprint(char *buf, size_t len, const rb_strf_t *strings);
int rb_fsnprintf(char *buf, size_t len, const rb_strf_t *strings, const char *format, ...) AFP(4, 5);
const char *rb_path_to_self(void); const char *rb_path_to_self(void);
#endif /* __TOOLS_H__ */ #endif /* __TOOLS_H__ */

View file

@ -65,6 +65,8 @@ rb_get_type
rb_getmaxconnect rb_getmaxconnect
rb_getpid rb_getpid
rb_gettimeofday rb_gettimeofday
rb_fsnprint
rb_fsnprintf
rb_helper_child rb_helper_child
rb_helper_close rb_helper_close
rb_helper_loop rb_helper_loop
@ -100,11 +102,7 @@ rb_linebuf_get
rb_linebuf_init rb_linebuf_init
rb_linebuf_newbuf rb_linebuf_newbuf
rb_linebuf_parse rb_linebuf_parse
rb_linebuf_put_msgf rb_linebuf_put
rb_linebuf_put_vmsg
rb_linebuf_put_vmsg_prefixf
rb_linebuf_put_vtags_prefix
rb_linebuf_put_vtags_prefixf
rb_listen rb_listen
rb_make_rb_dlink_node rb_make_rb_dlink_node
rb_match_exact_string rb_match_exact_string

View file

@ -214,8 +214,10 @@ void
rb_helper_write_queue(rb_helper *helper, const char *format, ...) rb_helper_write_queue(rb_helper *helper, const char *format, ...)
{ {
va_list ap; va_list ap;
rb_strf_t strings = { .format = format, .format_args = &ap, .next = NULL };
va_start(ap, format); va_start(ap, format);
rb_linebuf_put_vmsg(&helper->sendq, format, &ap); rb_linebuf_put(&helper->sendq, &strings);
va_end(ap); va_end(ap);
} }
@ -230,9 +232,12 @@ void
rb_helper_write(rb_helper *helper, const char *format, ...) rb_helper_write(rb_helper *helper, const char *format, ...)
{ {
va_list ap; va_list ap;
rb_strf_t strings = { .format = format, .format_args = &ap, .next = NULL };
va_start(ap, format); va_start(ap, format);
rb_linebuf_put_vmsg(&helper->sendq, format, &ap); rb_linebuf_put(&helper->sendq, &strings);
va_end(ap); va_end(ap);
rb_helper_write_flush(helper); rb_helper_write_flush(helper);
} }

View file

@ -485,20 +485,16 @@ rb_linebuf_attach(buf_head_t * bufhead, buf_head_t * new)
} }
/* /*
* rb_linebuf_put_vstr_vprefix * rb_linebuf_put
* *
* prefix (with/without prefix_args) is inserted first, then format/va_args is * linked list of strings are appended in order.
* appended to the buffer.
*
* max_buflen is the maximum size of the buffer that can be used
* (including the NULL terminator) so that the RFC1459 message is not too long
*/ */
static void void
rb_linebuf_put_vstr_vprefix(buf_head_t *bufhead, const char *format, va_list *format_args, rb_linebuf_put(buf_head_t *bufhead, const rb_strf_t *strings)
size_t max_buflen, const char *prefix, va_list *prefix_args)
{ {
buf_line_t *bufline; buf_line_t *bufline;
ssize_t len = 0; size_t len = 0;
int ret;
/* make sure the previous line is terminated */ /* make sure the previous line is terminated */
if (bufhead->list.tail) { if (bufhead->list.tail) {
@ -509,25 +505,12 @@ rb_linebuf_put_vstr_vprefix(buf_head_t *bufhead, const char *format, va_list *fo
/* create a new line */ /* create a new line */
bufline = rb_linebuf_new_line(bufhead); bufline = rb_linebuf_new_line(bufhead);
if (max_buflen > LINEBUF_SIZE + 1) ret = rb_fsnprint(bufline->buf, LINEBUF_SIZE + 1, strings);
max_buflen = LINEBUF_SIZE + 1; if (ret > 0)
len += ret;
if (prefix != NULL) { if (len > LINEBUF_SIZE)
if (prefix_args != NULL) { len = LINEBUF_SIZE;
len = vsnprintf(bufline->buf, max_buflen, prefix, *prefix_args);
} else {
len = rb_strlcpy(bufline->buf, prefix, max_buflen);
}
if (len > max_buflen - 1)
len = max_buflen - 1;
}
if (format != NULL) {
len += vsnprintf(bufline->buf + len, max_buflen - len, format, *format_args);
if (len > max_buflen - 1)
len = max_buflen - 1;
}
/* add trailing CRLF */ /* add trailing CRLF */
bufline->buf[len++] = '\r'; bufline->buf[len++] = '\r';
@ -540,89 +523,6 @@ rb_linebuf_put_vstr_vprefix(buf_head_t *bufhead, const char *format, va_list *fo
bufhead->len += len; bufhead->len += len;
} }
/*
* rb_linebuf_put_vtags_prefix
*
* prefix is inserted first, then format/va_args is
* appended to the buffer.
*
* prefix_buflen is the maximum size of the buffer that can be used
* (including the NULL terminator) so that the RFC1459 message is not too long
*/
void
rb_linebuf_put_vtags_prefix(buf_head_t *bufhead, const char *format, va_list *va_args,
size_t prefix_buflen, const char *prefix)
{
rb_linebuf_put_vstr_vprefix(bufhead, format, va_args, prefix_buflen, prefix, NULL);
}
/*
* rb_linebuf_put_vtags_prefixf
*
* prefixfmt is inserted first, then format/va_args is
* appended to the buffer.
*
* prefix_buflen is the maximum size of the buffer that can be used
* (including the NULL terminator) so that the RFC1459 message is not too long
*/
void
rb_linebuf_put_vtags_prefixf(buf_head_t *bufhead, const char *format, va_list *va_args,
size_t prefix_buflen, const char *prefixfmt, ...)
{
va_list prefix_args;
va_start(prefix_args, prefixfmt);
rb_linebuf_put_vstr_vprefix(bufhead, format, va_args, prefix_buflen, prefixfmt, &prefix_args);
va_end(prefix_args);
}
/*
* rb_linebuf_put_msgf
*
* format (with args) is appended to the buffer.
* Messages will be limited to the RFC1459 data length
*/
void
rb_linebuf_put_msgf(buf_head_t *bufhead, const char *format, ...)
{
va_list va_args;
va_start(va_args, format);
rb_linebuf_put_vstr_vprefix(bufhead, format, &va_args, LINEBUF_DATALEN + 1, NULL, NULL);
va_end(va_args);
}
/*
* rb_linebuf_put_vmsg
*
* format/va_args is appended to the buffer.
* Messages will be limited to the RFC1459 data length
*/
void
rb_linebuf_put_vmsg(buf_head_t *bufhead, const char *format, va_list *va_args)
{
rb_linebuf_put_vstr_vprefix(bufhead, format, va_args, LINEBUF_DATALEN + 1, NULL, NULL);
}
/*
* rb_linebuf_put_vmsg_prefixf
*
* prefix is inserted first, then format/va_args is appended to the buffer.
* Messages will be limited to the RFC1459 data length
*/
void
rb_linebuf_put_vmsg_prefixf(buf_head_t *bufhead, const char *format, va_list *va_args,
const char *prefixfmt, ...)
{
va_list prefix_args;
va_start(prefix_args, prefixfmt);
rb_linebuf_put_vstr_vprefix(bufhead, format, va_args, LINEBUF_DATALEN + 1, prefixfmt, &prefix_args);
va_end(prefix_args);
}
/* /*
* rb_linebuf_flush * rb_linebuf_flush
* *

View file

@ -523,3 +523,69 @@ size_t rb_zstring_to_ptr(rb_zstring_t *zs, void **ptr)
*ptr = (void *)zs->data; *ptr = (void *)zs->data;
return zs->len; return zs->len;
} }
int rb_fsnprint(char *buf, size_t len, const rb_strf_t *strings)
{
size_t used = 0;
size_t remaining = len;
while (strings != NULL) {
int ret = 0;
if (strings->length != 0) {
remaining = strings->length;
if (remaining > len - used)
remaining = len - used;
}
if (remaining == 0)
break;
if (strings->format != NULL) {
if (strings->format_args != NULL) {
ret = vsnprintf(buf + used, remaining,
strings->format, *strings->format_args);
} else {
ret = rb_strlcpy(buf + used,
strings->format, remaining);
}
} else if (strings->func != NULL) {
ret = strings->func(buf + used, remaining,
strings->func_args);
}
if (ret < 0) {
return ret;
} else if ((size_t)ret > remaining - 1) {
used += remaining - 1;
} else {
used += ret;
}
if (used >= len - 1) {
used = len - 1;
break;
}
remaining -= ret;
strings = strings->next;
}
return used;
}
int rb_fsnprintf(char *buf, size_t len, const rb_strf_t *strings, const char *format, ...)
{
va_list args;
rb_strf_t prepend_string = { .format = format, .format_args = &args, .next = strings };
int ret;
va_start(args, format);
ret = rb_fsnprint(buf, len, &prepend_string);
va_end(args);
return ret;
}

View file

@ -345,7 +345,7 @@ m_join(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p
chptr->mode.mode |= ConfigChannel.autochanmodes; chptr->mode.mode |= ConfigChannel.autochanmodes;
modes = channel_modes(chptr, &me); modes = channel_modes(chptr, &me);
sendto_channel_local(ONLY_CHANOPS, chptr, ":%s MODE %s %s", sendto_channel_local(&me, ONLY_CHANOPS, chptr, ":%s MODE %s %s",
me.name, chptr->chname, modes); me.name, chptr->chname, modes);
sendto_server(client_p, chptr, CAP_TS6, NOCAPS, sendto_server(client_p, chptr, CAP_TS6, NOCAPS,
@ -434,7 +434,7 @@ ms_join(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_
/* making a channel TS0 */ /* making a channel TS0 */
if(!isnew && !newts && oldts) if(!isnew && !newts && oldts)
{ {
sendto_channel_local(ALL_MEMBERS, chptr, sendto_channel_local(&me, ALL_MEMBERS, chptr,
":%s NOTICE %s :*** Notice -- TS for %s changed from %ld to 0", ":%s NOTICE %s :*** Notice -- TS for %s changed from %ld to 0",
me.name, chptr->chname, chptr->chname, (long) oldts); me.name, chptr->chname, chptr->chname, (long) oldts);
sendto_realops_snomask(SNO_GENERAL, L_ALL, sendto_realops_snomask(SNO_GENERAL, L_ALL,
@ -466,7 +466,7 @@ ms_join(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_
} }
/* If setting -j, clear join throttle state -- jilles */ /* If setting -j, clear join throttle state -- jilles */
chptr->join_count = chptr->join_delta = 0; chptr->join_count = chptr->join_delta = 0;
sendto_channel_local(ALL_MEMBERS, chptr, sendto_channel_local(&me, ALL_MEMBERS, chptr,
":%s NOTICE %s :*** Notice -- TS for %s changed from %ld to %ld", ":%s NOTICE %s :*** Notice -- TS for %s changed from %ld to %ld",
me.name, chptr->chname, chptr->chname, me.name, chptr->chname, chptr->chname,
(long) oldts, (long) newts); (long) oldts, (long) newts);
@ -474,7 +474,7 @@ ms_join(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_
* capitalization timestamped like modes are -- jilles */ * capitalization timestamped like modes are -- jilles */
strcpy(chptr->chname, parv[2]); strcpy(chptr->chname, parv[2]);
if(*modebuf != '\0') if(*modebuf != '\0')
sendto_channel_local(ALL_MEMBERS, chptr, sendto_channel_local(source_p->servptr, ALL_MEMBERS, chptr,
":%s MODE %s %s %s", ":%s MODE %s %s %s",
source_p->servptr->name, source_p->servptr->name,
chptr->chname, modebuf, parabuf); chptr->chname, modebuf, parabuf);
@ -615,7 +615,7 @@ ms_sjoin(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source
if(!isnew && !newts && oldts) if(!isnew && !newts && oldts)
{ {
sendto_channel_local(ALL_MEMBERS, chptr, sendto_channel_local(&me, ALL_MEMBERS, chptr,
":%s NOTICE %s :*** Notice -- TS for %s " ":%s NOTICE %s :*** Notice -- TS for %s "
"changed from %ld to 0", "changed from %ld to 0",
me.name, chptr->chname, chptr->chname, (long) oldts); me.name, chptr->chname, chptr->chname, (long) oldts);
@ -731,7 +731,7 @@ ms_sjoin(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source
'q', ALL_MEMBERS); 'q', ALL_MEMBERS);
chptr->bants++; chptr->bants++;
sendto_channel_local(ALL_MEMBERS, chptr, sendto_channel_local(&me, ALL_MEMBERS, chptr,
":%s NOTICE %s :*** Notice -- TS for %s changed from %ld to %ld", ":%s NOTICE %s :*** Notice -- TS for %s changed from %ld to %ld",
me.name, chptr->chname, chptr->chname, me.name, chptr->chname, chptr->chname,
(long) oldts, (long) newts); (long) oldts, (long) newts);
@ -744,7 +744,7 @@ ms_sjoin(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source
} }
if(*modebuf != '\0') if(*modebuf != '\0')
sendto_channel_local(ALL_MEMBERS, chptr, ":%s MODE %s %s %s", sendto_channel_local(fakesource_p, ALL_MEMBERS, chptr, ":%s MODE %s %s %s",
fakesource_p->name, chptr->chname, modebuf, parabuf); fakesource_p->name, chptr->chname, modebuf, parabuf);
*modebuf = *parabuf = '\0'; *modebuf = *parabuf = '\0';
@ -851,7 +851,7 @@ ms_sjoin(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source
if(pargs >= MAXMODEPARAMS) if(pargs >= MAXMODEPARAMS)
{ {
*mbuf = '\0'; *mbuf = '\0';
sendto_channel_local(ALL_MEMBERS, chptr, sendto_channel_local(fakesource_p, ALL_MEMBERS, chptr,
":%s MODE %s %s %s %s %s %s", ":%s MODE %s %s %s %s %s %s",
fakesource_p->name, chptr->chname, fakesource_p->name, chptr->chname,
modebuf, modebuf,
@ -875,7 +875,7 @@ ms_sjoin(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source
if(pargs >= MAXMODEPARAMS) if(pargs >= MAXMODEPARAMS)
{ {
*mbuf = '\0'; *mbuf = '\0';
sendto_channel_local(ALL_MEMBERS, chptr, sendto_channel_local(fakesource_p, ALL_MEMBERS, chptr,
":%s MODE %s %s %s %s %s %s", ":%s MODE %s %s %s %s %s %s",
fakesource_p->name, fakesource_p->name,
chptr->chname, chptr->chname,
@ -910,7 +910,7 @@ ms_sjoin(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source
*mbuf = '\0'; *mbuf = '\0';
if(pargs) if(pargs)
{ {
sendto_channel_local(ALL_MEMBERS, chptr, sendto_channel_local(fakesource_p, ALL_MEMBERS, chptr,
":%s MODE %s %s %s %s %s %s", ":%s MODE %s %s %s %s %s %s",
fakesource_p->name, chptr->chname, modebuf, fakesource_p->name, chptr->chname, modebuf,
para[0], CheckEmpty(para[1]), para[0], CheckEmpty(para[1]),
@ -962,7 +962,7 @@ do_join_0(struct Client *client_p, struct Client *source_p)
msptr = ptr->data; msptr = ptr->data;
chptr = msptr->chptr; chptr = msptr->chptr;
sendto_channel_local(ALL_MEMBERS, chptr, ":%s!%s@%s PART %s", sendto_channel_local(source_p, ALL_MEMBERS, chptr, ":%s!%s@%s PART %s",
source_p->name, source_p->name,
source_p->username, source_p->host, chptr->chname); source_p->username, source_p->host, chptr->chname);
remove_user_from_channel(msptr); remove_user_from_channel(msptr);
@ -1202,7 +1202,7 @@ remove_our_modes(struct Channel *chptr, struct Client *source_p)
if(count >= MAXMODEPARAMS) if(count >= MAXMODEPARAMS)
{ {
*mbuf = '\0'; *mbuf = '\0';
sendto_channel_local(ALL_MEMBERS, chptr, sendto_channel_local(source_p, ALL_MEMBERS, chptr,
":%s MODE %s %s %s %s %s %s", ":%s MODE %s %s %s %s %s %s",
source_p->name, chptr->chname, source_p->name, chptr->chname,
lmodebuf, lpara[0], lpara[1], lmodebuf, lpara[0], lpara[1],
@ -1234,7 +1234,7 @@ remove_our_modes(struct Channel *chptr, struct Client *source_p)
if(count >= MAXMODEPARAMS) if(count >= MAXMODEPARAMS)
{ {
*mbuf = '\0'; *mbuf = '\0';
sendto_channel_local(ALL_MEMBERS, chptr, sendto_channel_local(source_p, ALL_MEMBERS, chptr,
":%s MODE %s %s %s %s %s %s", ":%s MODE %s %s %s %s %s %s",
source_p->name, chptr->chname, lmodebuf, source_p->name, chptr->chname, lmodebuf,
lpara[0], lpara[1], lpara[2], lpara[3]); lpara[0], lpara[1], lpara[2], lpara[3]);
@ -1250,7 +1250,7 @@ remove_our_modes(struct Channel *chptr, struct Client *source_p)
if(count != 0) if(count != 0)
{ {
*mbuf = '\0'; *mbuf = '\0';
sendto_channel_local(ALL_MEMBERS, chptr, sendto_channel_local(source_p, ALL_MEMBERS, chptr,
":%s MODE %s %s %s %s %s %s", ":%s MODE %s %s %s %s %s %s",
source_p->name, chptr->chname, lmodebuf, source_p->name, chptr->chname, lmodebuf,
EmptyString(lpara[0]) ? "" : lpara[0], EmptyString(lpara[0]) ? "" : lpara[0],
@ -1300,7 +1300,7 @@ remove_ban_list(struct Channel *chptr, struct Client *source_p,
*mbuf = '\0'; *mbuf = '\0';
*(pbuf - 1) = '\0'; *(pbuf - 1) = '\0';
sendto_channel_local(mems, chptr, "%s %s", lmodebuf, lparabuf); sendto_channel_local(source_p, mems, chptr, "%s %s", lmodebuf, lparabuf);
cur_len = mlen; cur_len = mlen;
mbuf = lmodebuf + mlen; mbuf = lmodebuf + mlen;
@ -1321,7 +1321,7 @@ remove_ban_list(struct Channel *chptr, struct Client *source_p,
*mbuf = '\0'; *mbuf = '\0';
*(pbuf - 1) = '\0'; *(pbuf - 1) = '\0';
sendto_channel_local(mems, chptr, "%s %s", lmodebuf, lparabuf); sendto_channel_local(source_p, mems, chptr, "%s %s", lmodebuf, lparabuf);
list->head = list->tail = NULL; list->head = list->tail = NULL;
list->length = 0; list->length = 0;

View file

@ -167,10 +167,10 @@ m_kick(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p
* be sent anyways. Just waiting for some oper to abuse it... * be sent anyways. Just waiting for some oper to abuse it...
*/ */
if(IsServer(source_p)) if(IsServer(source_p))
sendto_channel_local(ALL_MEMBERS, chptr, ":%s KICK %s %s :%s", sendto_channel_local(source_p, ALL_MEMBERS, chptr, ":%s KICK %s %s :%s",
source_p->name, name, who->name, comment); source_p->name, name, who->name, comment);
else else
sendto_channel_local(ALL_MEMBERS, chptr, sendto_channel_local(source_p, ALL_MEMBERS, chptr,
":%s!%s@%s KICK %s %s :%s", ":%s!%s@%s KICK %s %s :%s",
source_p->name, source_p->username, source_p->name, source_p->username,
source_p->host, name, who->name, comment); source_p->host, name, who->name, comment);

View file

@ -248,7 +248,7 @@ possibly_remove_lower_forward(struct Client *fakesource_p, int mems,
(actualBan->forward == NULL || (actualBan->forward == NULL ||
irccmp(actualBan->forward, forward) < 0)) irccmp(actualBan->forward, forward) < 0))
{ {
sendto_channel_local(mems, chptr, ":%s MODE %s -%c %s%s%s", sendto_channel_local(fakesource_p, mems, chptr, ":%s MODE %s -%c %s%s%s",
fakesource_p->name, fakesource_p->name,
chptr->chname, chptr->chname,
mchar, mchar,
@ -383,7 +383,7 @@ ms_bmask(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source
{ {
*mbuf = '\0'; *mbuf = '\0';
*(pbuf - 1) = '\0'; *(pbuf - 1) = '\0';
sendto_channel_local(mems, chptr, "%s %s", modebuf, parabuf); sendto_channel_local(fakesource_p, mems, chptr, "%s %s", modebuf, parabuf);
mbuf = modebuf + mlen; mbuf = modebuf + mlen;
pbuf = parabuf; pbuf = parabuf;
@ -419,7 +419,7 @@ ms_bmask(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source
{ {
*mbuf = '\0'; *mbuf = '\0';
*(pbuf - 1) = '\0'; *(pbuf - 1) = '\0';
sendto_channel_local(mems, chptr, "%s %s", modebuf, parabuf); sendto_channel_local(fakesource_p, mems, chptr, "%s %s", modebuf, parabuf);
} }
sendto_server(client_p, chptr, CAP_TS6 | needcap, NOCAPS, ":%s BMASK %ld %s %s :%s", sendto_server(client_p, chptr, CAP_TS6 | needcap, NOCAPS, ":%s BMASK %ld %s %s :%s",

View file

@ -133,7 +133,7 @@ part_one_client(struct Client *client_p, struct Client *source_p, char *name, co
sendto_server(client_p, chptr, CAP_TS6, NOCAPS, sendto_server(client_p, chptr, CAP_TS6, NOCAPS,
":%s PART %s :%s", use_id(source_p), chptr->chname, reason); ":%s PART %s :%s", use_id(source_p), chptr->chname, reason);
sendto_channel_local(ALL_MEMBERS, chptr, ":%s!%s@%s PART %s :%s", sendto_channel_local(source_p, ALL_MEMBERS, chptr, ":%s!%s@%s PART %s :%s",
source_p->name, source_p->username, source_p->name, source_p->username,
source_p->host, chptr->chname, reason); source_p->host, chptr->chname, reason);
} }
@ -141,7 +141,7 @@ part_one_client(struct Client *client_p, struct Client *source_p, char *name, co
{ {
sendto_server(client_p, chptr, CAP_TS6, NOCAPS, sendto_server(client_p, chptr, CAP_TS6, NOCAPS,
":%s PART %s", use_id(source_p), chptr->chname); ":%s PART %s", use_id(source_p), chptr->chname);
sendto_channel_local(ALL_MEMBERS, chptr, ":%s!%s@%s PART %s", sendto_channel_local(source_p, ALL_MEMBERS, chptr, ":%s!%s@%s PART %s",
source_p->name, source_p->username, source_p->name, source_p->username,
source_p->host, chptr->chname); source_p->host, chptr->chname);
} }

View file

@ -224,10 +224,10 @@ m_invite(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source
if (!add_invite(chptr, target_p)) if (!add_invite(chptr, target_p))
return; return;
sendto_channel_local_with_capability(CHFL_CHANOP, 0, CAP_INVITE_NOTIFY, chptr, sendto_channel_local_with_capability(source_p, CHFL_CHANOP, 0, CAP_INVITE_NOTIFY, chptr,
":%s NOTICE %s :%s is inviting %s to %s.", ":%s NOTICE %s :%s is inviting %s to %s.",
me.name, chptr->chname, source_p->name, target_p->name, chptr->chname); me.name, chptr->chname, source_p->name, target_p->name, chptr->chname);
sendto_channel_local_with_capability(CHFL_CHANOP, CAP_INVITE_NOTIFY, 0, chptr, sendto_channel_local_with_capability(source_p, CHFL_CHANOP, CAP_INVITE_NOTIFY, 0, chptr,
":%s!%s@%s INVITE %s %s", source_p->name, source_p->username, ":%s!%s@%s INVITE %s %s", source_p->name, source_p->username,
source_p->host, target_p->name, chptr->chname); source_p->host, target_p->name, chptr->chname);
} }

View file

@ -166,7 +166,7 @@ m_knock(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_
chptr->last_knock = rb_current_time(); chptr->last_knock = rb_current_time();
if(ConfigChannel.use_knock) if(ConfigChannel.use_knock)
sendto_channel_local((chptr->mode.mode & MODE_FREEINVITE) ? ALL_MEMBERS : ONLY_CHANOPS, sendto_channel_local(source_p, (chptr->mode.mode & MODE_FREEINVITE) ? ALL_MEMBERS : ONLY_CHANOPS,
chptr, form_str(RPL_KNOCK), chptr, form_str(RPL_KNOCK),
me.name, name, name, source_p->name, me.name, name, name, source_p->name,
source_p->username, source_p->host); source_p->username, source_p->host);

View file

@ -113,7 +113,7 @@ ms_tb(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p,
return; return;
set_channel_topic(chptr, newtopic, newtopicwho, newtopicts); set_channel_topic(chptr, newtopic, newtopicwho, newtopicts);
sendto_channel_local(ALL_MEMBERS, chptr, ":%s TOPIC %s :%s", sendto_channel_local(fakesource_p, ALL_MEMBERS, chptr, ":%s TOPIC %s :%s",
fakesource_p->name, chptr->chname, newtopic); fakesource_p->name, chptr->chname, newtopic);
sendto_server(client_p, chptr, CAP_TB|CAP_TS6, NOCAPS, sendto_server(client_p, chptr, CAP_TB|CAP_TS6, NOCAPS,
":%s TB %s %ld %s%s:%s", ":%s TB %s %ld %s%s:%s",
@ -177,7 +177,7 @@ ms_etb(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p
if(textchange) if(textchange)
{ {
if (IsPerson(fakesource_p)) if (IsPerson(fakesource_p))
sendto_channel_local(ALL_MEMBERS, chptr, sendto_channel_local(fakesource_p, ALL_MEMBERS, chptr,
":%s!%s@%s TOPIC %s :%s", ":%s!%s@%s TOPIC %s :%s",
fakesource_p->name, fakesource_p->name,
fakesource_p->username, fakesource_p->username,
@ -185,7 +185,7 @@ ms_etb(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p
chptr->chname, chptr->chname,
newtopic); newtopic);
else else
sendto_channel_local(ALL_MEMBERS, chptr, sendto_channel_local(fakesource_p, ALL_MEMBERS, chptr,
":%s TOPIC %s :%s", ":%s TOPIC %s :%s",
fakesource_p->name, fakesource_p->name,
chptr->chname, newtopic); chptr->chname, newtopic);

View file

@ -140,7 +140,7 @@ m_topic(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_
":%s TOPIC %s :%s", ":%s TOPIC %s :%s",
use_id(source_p), chptr->chname, use_id(source_p), chptr->chname,
chptr->topic == NULL ? "" : chptr->topic); chptr->topic == NULL ? "" : chptr->topic);
sendto_channel_local(ALL_MEMBERS, sendto_channel_local(source_p, ALL_MEMBERS,
chptr, ":%s!%s@%s TOPIC %s :%s", chptr, ":%s!%s@%s TOPIC %s :%s",
source_p->name, source_p->username, source_p->name, source_p->username,
source_p->host, chptr->chname, source_p->host, chptr->chname,
@ -197,7 +197,7 @@ ms_topic(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source
set_channel_topic(chptr, parv[4], parv[2], atoi(parv[3])); set_channel_topic(chptr, parv[4], parv[2], atoi(parv[3]));
sendto_channel_local(ALL_MEMBERS, chptr, ":%s TOPIC %s :%s", sendto_channel_local(source_p, ALL_MEMBERS, chptr, ":%s TOPIC %s :%s",
source_p->name, parv[1], source_p->name, parv[1],
chptr->topic == NULL ? "" : chptr->topic); chptr->topic == NULL ? "" : chptr->topic);
} }

View file

@ -1,7 +1,6 @@
check_PROGRAMS = runtests \ check_PROGRAMS = runtests \
msgbuf_parse1 \ msgbuf_parse1 \
msgbuf_unparse1 \ msgbuf_unparse1 \
rb_linebuf_put1 \
rb_snprintf_append1 \ rb_snprintf_append1 \
rb_snprintf_try_append1 \ rb_snprintf_try_append1 \
send1 \ send1 \
@ -22,7 +21,6 @@ tap_libtap_a_SOURCES = tap/basic.c tap/basic.h \
msgbuf_parse1_SOURCES = msgbuf_parse1.c msgbuf_parse1_SOURCES = msgbuf_parse1.c
msgbuf_unparse1_SOURCES = msgbuf_unparse1.c msgbuf_unparse1_SOURCES = msgbuf_unparse1.c
rb_linebuf_put1_SOURCES = rb_linebuf_put1.c
rb_snprintf_append1_SOURCES = rb_snprintf_append1.c rb_snprintf_append1_SOURCES = rb_snprintf_append1.c
rb_snprintf_try_append1_SOURCES = rb_snprintf_try_append1.c rb_snprintf_try_append1_SOURCES = rb_snprintf_try_append1.c
send1_SOURCES = send1.c ircd_util.c client_util.c send1_SOURCES = send1.c ircd_util.c client_util.c

View file

@ -1,6 +1,5 @@
msgbuf_parse1 msgbuf_parse1
msgbuf_unparse1 msgbuf_unparse1
rb_linebuf_put1
rb_snprintf_append1 rb_snprintf_append1
rb_snprintf_try_append1 rb_snprintf_try_append1
send1 send1

View file

@ -1,863 +0,0 @@
/*
* rb_linebuf_put1.c: Test rb_linebuf_put* under various conditions
* Copyright 2017 Simon Arlott
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include "tap/basic.h"
#include "stdinc.h"
#include "ircd_defs.h"
#include "client.h"
#include "rb_lib.h"
#define MSG "%s:%d (%s)", __FILE__, __LINE__, __FUNCTION__
struct Client me;
static const char text[] =
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba"
"ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba"
"ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba"
"ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba"
"ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba"
"ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
;
char long_tags[TAGSLEN + 1];
char long_prefix[TAGSLEN + DATALEN + 1];
char long_prefixf[TAGSLEN + DATALEN + 1];
#define MKTEXT(n) &text[sizeof(text) - ((n) + 1)]
static void _rb_linebuf_put_vtags_prefix(buf_head_t *bufhead, size_t prefix_buflen, const char *prefix, const char *format, ...)
{
va_list args;
va_start(args, format);
rb_linebuf_put_vtags_prefix(bufhead, format, &args, prefix_buflen, prefix);
va_end(args);
}
static void _rb_linebuf_put_vtags_prefixf(buf_head_t *bufhead, size_t prefix_buflen, const char *prefix, const char *format, ...)
{
va_list args;
va_start(args, format);
rb_linebuf_put_vtags_prefixf(bufhead, format, &args, prefix_buflen, prefix, 300);
va_end(args);
}
static void _rb_linebuf_put_vmsg(buf_head_t *bufhead, const char *format, ...)
{
va_list args;
va_start(args, format);
rb_linebuf_put_vmsg(bufhead, format, &args);
va_end(args);
}
static void _rb_linebuf_put_vmsg_prefixf(buf_head_t *bufhead, const char *prefix, const char *format, ...)
{
va_list args;
va_start(args, format);
rb_linebuf_put_vmsg_prefixf(bufhead, format, &args, prefix, 300);
va_end(args);
}
#define CRLF "\r\n"
#define SOME_TAGS "@tag1=value1;tag2=value2 "
static void basic_vtags_prefix1(void)
{
buf_head_t linebuf;
char output[2048] = { 0 };
int len;
rb_linebuf_newbuf(&linebuf);
_rb_linebuf_put_vtags_prefix(&linebuf, strlen(SOME_TAGS) + DATALEN + 1, SOME_TAGS ":prefix ", "test %s %d", "TEST", 42);
len = rb_linebuf_get(&linebuf, output, sizeof(output), 0, 1);
rb_linebuf_donebuf(&linebuf);
is_int(strlen(output), len, MSG);
is_string(SOME_TAGS ":prefix test TEST 42" CRLF, output, MSG);
}
static void long_vtags_prefix1(void)
{
buf_head_t linebuf;
char output[2048] = { 0 };
int len;
rb_linebuf_newbuf(&linebuf);
_rb_linebuf_put_vtags_prefix(&linebuf, strlen(SOME_TAGS) + DATALEN + 1, SOME_TAGS ":prefix ", "%s", MKTEXT(502));
len = rb_linebuf_get(&linebuf, output, sizeof(output), 0, 1);
rb_linebuf_donebuf(&linebuf);
is_int(strlen(output), len, MSG);
char tmp[2048];
strcpy(tmp, SOME_TAGS ":prefix ");
strcat(tmp, MKTEXT(502));
strcat(tmp, CRLF);
is_string(tmp, output, MSG);
is_int(strlen(SOME_TAGS) + DATALEN + strlen(CRLF), strlen(output), MSG);
}
static void too_long_vtags_prefix1(void)
{
buf_head_t linebuf;
char output[2048] = { 0 };
int len;
rb_linebuf_newbuf(&linebuf);
_rb_linebuf_put_vtags_prefix(&linebuf, strlen(SOME_TAGS) + DATALEN + 1, SOME_TAGS ":prefix ", "%s", MKTEXT(503));
len = rb_linebuf_get(&linebuf, output, sizeof(output), 0, 1);
rb_linebuf_donebuf(&linebuf);
is_int(strlen(output), len, MSG);
char tmp[2048];
strcpy(tmp, SOME_TAGS ":prefix ");
strcat(tmp, MKTEXT(503));
tmp[strlen(tmp) - 1] = 0; /* truncated message */
strcat(tmp, CRLF);
is_string(tmp, output, MSG);
is_int(strlen(SOME_TAGS) + DATALEN + strlen(CRLF), strlen(output), MSG);
}
static void long_vtags_prefix2(void)
{
buf_head_t linebuf;
char output[2048] = { 0 };
char prefix[2048] = { 0 };
int len;
strcpy(prefix, long_tags);
strcat(prefix, ":prefix ");
rb_linebuf_newbuf(&linebuf);
_rb_linebuf_put_vtags_prefix(&linebuf, strlen(long_tags) + DATALEN + 1, prefix, "%s", MKTEXT(502));
len = rb_linebuf_get(&linebuf, output, sizeof(output), 0, 1);
rb_linebuf_donebuf(&linebuf);
is_int(strlen(output), len, MSG);
char tmp[2048];
strcpy(tmp, long_tags);
strcat(tmp, ":prefix ");
strcat(tmp, MKTEXT(502));
strcat(tmp, CRLF);
is_string(tmp, output, MSG);
is_int(strlen(long_tags) + DATALEN + strlen(CRLF), strlen(output), MSG);
}
static void too_long_vtags_prefix2(void)
{
buf_head_t linebuf;
char output[2048] = { 0 };
char prefix[2048] = { 0 };
int len;
strcpy(prefix, long_tags);
strcat(prefix, ":prefix ");
rb_linebuf_newbuf(&linebuf);
_rb_linebuf_put_vtags_prefix(&linebuf, strlen(prefix) + DATALEN + 1, prefix, "%s", MKTEXT(503));
len = rb_linebuf_get(&linebuf, output, sizeof(output), 0, 1);
rb_linebuf_donebuf(&linebuf);
is_int(strlen(output), len, MSG);
char tmp[2048];
strcpy(tmp, long_tags);
strcat(tmp, ":prefix ");
strcat(tmp, MKTEXT(503));
tmp[strlen(tmp) - 1] = 0; /* truncated message */
strcat(tmp, CRLF);
is_string(tmp, output, MSG);
is_int(strlen(long_tags) + DATALEN + strlen(CRLF), strlen(output), MSG);
}
static void long_vtags_prefix3(void)
{
buf_head_t linebuf;
char output[2048] = { 0 };
char prefix[2048] = { 0 };
int len;
strcpy(prefix, long_prefix);
rb_linebuf_newbuf(&linebuf);
_rb_linebuf_put_vtags_prefix(&linebuf, strlen(long_prefix) + DATALEN + 1, prefix, "%s", MKTEXT(500));
len = rb_linebuf_get(&linebuf, output, sizeof(output), 0, 1);
rb_linebuf_donebuf(&linebuf);
is_int(strlen(output), len, MSG);
char tmp[2048];
strcpy(tmp, long_prefix);
strcat(tmp, CRLF);
is_string(tmp, output, MSG);
is_int(strlen(long_prefix) + strlen(CRLF), strlen(output), MSG);
}
static void too_long_vtags_prefix3(void)
{
buf_head_t linebuf;
char output[2048] = { 0 };
char prefix[2048] = { 0 };
int len;
strcpy(prefix, long_prefix);
strcat(prefix, ":");
rb_linebuf_newbuf(&linebuf);
_rb_linebuf_put_vtags_prefix(&linebuf, strlen(long_prefix) + DATALEN + 1, prefix, "%s", MKTEXT(500));
len = rb_linebuf_get(&linebuf, output, sizeof(output), 0, 1);
rb_linebuf_donebuf(&linebuf);
is_int(strlen(output), len, MSG);
char tmp[2048];
strcpy(tmp, long_prefix);
strcat(tmp, CRLF);
is_string(tmp, output, MSG);
is_int(strlen(long_prefix) + strlen(CRLF), strlen(output), MSG);
}
static void basic_vtags_prefixf1(void)
{
buf_head_t linebuf;
char output[2048] = { 0 };
int len;
rb_linebuf_newbuf(&linebuf);
_rb_linebuf_put_vtags_prefixf(&linebuf, strlen(SOME_TAGS) + DATALEN + 1, SOME_TAGS ":pre%d ", "test %s %d", "TEST", 42);
len = rb_linebuf_get(&linebuf, output, sizeof(output), 0, 1);
rb_linebuf_donebuf(&linebuf);
is_int(strlen(output), len, MSG);
is_string(SOME_TAGS ":pre300 test TEST 42" CRLF, output, MSG);
}
static void long_vtags_prefixf1(void)
{
buf_head_t linebuf;
char output[2048] = { 0 };
int len;
rb_linebuf_newbuf(&linebuf);
_rb_linebuf_put_vtags_prefixf(&linebuf, strlen(SOME_TAGS) + DATALEN + 1, SOME_TAGS ":pre%d ", "%s", MKTEXT(502));
len = rb_linebuf_get(&linebuf, output, sizeof(output), 0, 1);
rb_linebuf_donebuf(&linebuf);
is_int(strlen(output), len, MSG);
char tmp[2048];
strcpy(tmp, SOME_TAGS ":pre300 ");
strcat(tmp, MKTEXT(502));
strcat(tmp, CRLF);
is_string(tmp, output, MSG);
is_int(strlen(SOME_TAGS) + DATALEN + strlen(CRLF), strlen(output), MSG);
}
static void too_long_vtags_prefixf1(void)
{
buf_head_t linebuf;
char output[2048] = { 0 };
int len;
rb_linebuf_newbuf(&linebuf);
_rb_linebuf_put_vtags_prefixf(&linebuf, strlen(SOME_TAGS) + DATALEN + 1, SOME_TAGS ":pre%d ", "%s", MKTEXT(503));
len = rb_linebuf_get(&linebuf, output, sizeof(output), 0, 1);
rb_linebuf_donebuf(&linebuf);
is_int(strlen(output), len, MSG);
char tmp[2048];
strcpy(tmp, SOME_TAGS ":pre300 ");
strcat(tmp, MKTEXT(503));
tmp[strlen(tmp) - 1] = 0; /* truncated message */
strcat(tmp, CRLF);
is_string(tmp, output, MSG);
is_int(strlen(SOME_TAGS) + DATALEN + strlen(CRLF), strlen(output), MSG);
}
static void long_vtags_prefixf2(void)
{
buf_head_t linebuf;
char output[2048] = { 0 };
char prefix[2048] = { 0 };
int len;
strcpy(prefix, long_tags);
strcat(prefix, ":pre%d ");
rb_linebuf_newbuf(&linebuf);
_rb_linebuf_put_vtags_prefixf(&linebuf, strlen(long_tags) + DATALEN + 1, prefix, "%s", MKTEXT(502));
len = rb_linebuf_get(&linebuf, output, sizeof(output), 0, 1);
rb_linebuf_donebuf(&linebuf);
is_int(strlen(output), len, MSG);
char tmp[2048];
strcpy(tmp, long_tags);
strcat(tmp, ":pre300 ");
strcat(tmp, MKTEXT(502));
strcat(tmp, CRLF);
is_string(tmp, output, MSG);
is_int(strlen(long_tags) + DATALEN + strlen(CRLF), strlen(output), MSG);
}
static void too_long_vtags_prefixf2(void)
{
buf_head_t linebuf;
char output[2048] = { 0 };
char prefix[2048] = { 0 };
int len;
strcpy(prefix, long_tags);
strcat(prefix, ":pre%d ");
rb_linebuf_newbuf(&linebuf);
_rb_linebuf_put_vtags_prefixf(&linebuf, strlen(long_tags) + DATALEN + 1, prefix, "%s", MKTEXT(503));
len = rb_linebuf_get(&linebuf, output, sizeof(output), 0, 1);
rb_linebuf_donebuf(&linebuf);
is_int(strlen(output), len, MSG);
char tmp[2048];
strcpy(tmp, long_tags);
strcat(tmp, ":pre300 ");
strcat(tmp, MKTEXT(503));
tmp[strlen(tmp) - 1] = 0; /* truncated message */
strcat(tmp, CRLF);
is_string(tmp, output, MSG);
is_int(strlen(long_tags) + DATALEN + strlen(CRLF), strlen(output), MSG);
}
static void long_vtags_prefixf3(void)
{
buf_head_t linebuf;
char output[2048] = { 0 };
char prefix[2048] = { 0 };
int len;
strcpy(prefix, long_prefixf);
rb_linebuf_newbuf(&linebuf);
_rb_linebuf_put_vtags_prefixf(&linebuf, strlen(prefix) + 1 + DATALEN + 1, prefix, "%s", MKTEXT(500));
len = rb_linebuf_get(&linebuf, output, sizeof(output), 0, 1);
rb_linebuf_donebuf(&linebuf);
is_int(strlen(output), len, MSG);
char tmp[2048];
strcpy(tmp, long_prefixf);
tmp[strlen(tmp) - 2] = 0;
strcat(tmp, "300");
strcat(tmp, CRLF);
is_string(tmp, output, MSG);
is_int(strlen(long_prefixf) + 1 + strlen(CRLF), strlen(output), MSG);
}
static void too_long_vtags_prefixf3(void)
{
buf_head_t linebuf;
char output[2048] = { 0 };
char prefix[2048] = { 0 };
int len;
strcpy(prefix, long_prefixf);
strcat(prefix, ":");
rb_linebuf_newbuf(&linebuf);
_rb_linebuf_put_vtags_prefixf(&linebuf, strlen(prefix) + 1 + 1 + DATALEN + 1, prefix, "%s", MKTEXT(500));
len = rb_linebuf_get(&linebuf, output, sizeof(output), 0, 1);
rb_linebuf_donebuf(&linebuf);
is_int(strlen(output), len, MSG);
char tmp[2048];
strcpy(tmp, long_prefixf);
tmp[strlen(tmp) - 2] = 0;
strcat(tmp, "300");
strcat(tmp, CRLF);
is_string(tmp, output, MSG);
is_int(strlen(long_prefixf) + 1 + strlen(CRLF), strlen(output), MSG);
}
static void basic_msgf1(void)
{
buf_head_t linebuf;
char output[2048] = { 0 };
int len;
rb_linebuf_newbuf(&linebuf);
rb_linebuf_put_msgf(&linebuf, ":prefix test %s %d", "TEST", 42);
len = rb_linebuf_get(&linebuf, output, sizeof(output), 0, 1);
rb_linebuf_donebuf(&linebuf);
is_int(strlen(output), len, MSG);
is_string(":prefix test TEST 42" CRLF, output, MSG);
}
static void long_msgf1(void)
{
buf_head_t linebuf;
char output[2048] = { 0 };
int len;
rb_linebuf_newbuf(&linebuf);
rb_linebuf_put_msgf(&linebuf, ":prefix %s", MKTEXT(502));
len = rb_linebuf_get(&linebuf, output, sizeof(output), 0, 1);
rb_linebuf_donebuf(&linebuf);
is_int(strlen(output), len, MSG);
char tmp[2048];
strcpy(tmp, ":prefix ");
strcat(tmp, MKTEXT(502));
strcat(tmp, CRLF);
is_string(tmp, output, MSG);
is_int(DATALEN + strlen(CRLF), strlen(output), MSG);
}
static void too_long_msgf1(void)
{
buf_head_t linebuf;
char output[2048] = { 0 };
int len;
rb_linebuf_newbuf(&linebuf);
rb_linebuf_put_msgf(&linebuf, ":prefix %s", MKTEXT(503));
len = rb_linebuf_get(&linebuf, output, sizeof(output), 0, 1);
rb_linebuf_donebuf(&linebuf);
is_int(strlen(output), len, MSG);
char tmp[2048];
strcpy(tmp, ":prefix ");
strcat(tmp, MKTEXT(503));
tmp[strlen(tmp) - 1] = 0; /* truncated message */
strcat(tmp, CRLF);
is_string(tmp, output, MSG);
is_int(DATALEN + strlen(CRLF), strlen(output), MSG);
}
static void long_msgf2(void)
{
buf_head_t linebuf;
char output[2048] = { 0 };
int len;
rb_linebuf_newbuf(&linebuf);
rb_linebuf_put_msgf(&linebuf, ":prefix %s", MKTEXT(502));
len = rb_linebuf_get(&linebuf, output, sizeof(output), 0, 1);
rb_linebuf_donebuf(&linebuf);
is_int(strlen(output), len, MSG);
char tmp[2048];
strcpy(tmp, ":prefix ");
strcat(tmp, MKTEXT(502));
strcat(tmp, CRLF);
is_string(tmp, output, MSG);
is_int(DATALEN + strlen(CRLF), strlen(output), MSG);
}
static void too_long_msgf2(void)
{
buf_head_t linebuf;
char output[2048] = { 0 };
int len;
rb_linebuf_newbuf(&linebuf);
rb_linebuf_put_msgf(&linebuf, ":prefix %s", MKTEXT(503));
len = rb_linebuf_get(&linebuf, output, sizeof(output), 0, 1);
rb_linebuf_donebuf(&linebuf);
is_int(strlen(output), len, MSG);
char tmp[2048];
strcpy(tmp, ":prefix ");
strcat(tmp, MKTEXT(503));
tmp[strlen(tmp) - 1] = 0; /* truncated message */
strcat(tmp, CRLF);
is_string(tmp, output, MSG);
is_int(DATALEN + strlen(CRLF), strlen(output), MSG);
}
static void basic_vmsg1(void)
{
buf_head_t linebuf;
char output[2048] = { 0 };
int len;
rb_linebuf_newbuf(&linebuf);
_rb_linebuf_put_vmsg(&linebuf, ":prefix test %s %d", "TEST", 42);
len = rb_linebuf_get(&linebuf, output, sizeof(output), 0, 1);
rb_linebuf_donebuf(&linebuf);
is_int(strlen(output), len, MSG);
is_string(":prefix test TEST 42" CRLF, output, MSG);
}
static void long_vmsg1(void)
{
buf_head_t linebuf;
char output[2048] = { 0 };
int len;
rb_linebuf_newbuf(&linebuf);
_rb_linebuf_put_vmsg(&linebuf, ":prefix %s", MKTEXT(502));
len = rb_linebuf_get(&linebuf, output, sizeof(output), 0, 1);
rb_linebuf_donebuf(&linebuf);
is_int(strlen(output), len, MSG);
char tmp[2048];
strcpy(tmp, ":prefix ");
strcat(tmp, MKTEXT(502));
strcat(tmp, CRLF);
is_string(tmp, output, MSG);
is_int(DATALEN + strlen(CRLF), strlen(output), MSG);
}
static void too_long_vmsg1(void)
{
buf_head_t linebuf;
char output[2048] = { 0 };
int len;
rb_linebuf_newbuf(&linebuf);
_rb_linebuf_put_vmsg(&linebuf, ":prefix %s", MKTEXT(503));
len = rb_linebuf_get(&linebuf, output, sizeof(output), 0, 1);
rb_linebuf_donebuf(&linebuf);
is_int(strlen(output), len, MSG);
char tmp[2048];
strcpy(tmp, ":prefix ");
strcat(tmp, MKTEXT(503));
tmp[strlen(tmp) - 1] = 0; /* truncated message */
strcat(tmp, CRLF);
is_string(tmp, output, MSG);
is_int(DATALEN + strlen(CRLF), strlen(output), MSG);
}
static void long_vmsg2(void)
{
buf_head_t linebuf;
char output[2048] = { 0 };
int len;
rb_linebuf_newbuf(&linebuf);
_rb_linebuf_put_vmsg(&linebuf, ":prefix %s", MKTEXT(502));
len = rb_linebuf_get(&linebuf, output, sizeof(output), 0, 1);
rb_linebuf_donebuf(&linebuf);
is_int(strlen(output), len, MSG);
char tmp[2048];
strcpy(tmp, ":prefix ");
strcat(tmp, MKTEXT(502));
strcat(tmp, CRLF);
is_string(tmp, output, MSG);
is_int(DATALEN + strlen(CRLF), strlen(output), MSG);
}
static void too_long_vmsg2(void)
{
buf_head_t linebuf;
char output[2048] = { 0 };
int len;
rb_linebuf_newbuf(&linebuf);
_rb_linebuf_put_vmsg(&linebuf, ":prefix %s", MKTEXT(503));
len = rb_linebuf_get(&linebuf, output, sizeof(output), 0, 1);
rb_linebuf_donebuf(&linebuf);
is_int(strlen(output), len, MSG);
char tmp[2048];
strcpy(tmp, ":prefix ");
strcat(tmp, MKTEXT(503));
tmp[strlen(tmp) - 1] = 0; /* truncated message */
strcat(tmp, CRLF);
is_string(tmp, output, MSG);
is_int(DATALEN + strlen(CRLF), strlen(output), MSG);
}
static void basic_vmsg_prefixf1(void)
{
buf_head_t linebuf;
char output[2048] = { 0 };
int len;
rb_linebuf_newbuf(&linebuf);
_rb_linebuf_put_vmsg_prefixf(&linebuf, ":pre%d ", "test %s %d", "TEST", 42);
len = rb_linebuf_get(&linebuf, output, sizeof(output), 0, 1);
rb_linebuf_donebuf(&linebuf);
is_int(strlen(output), len, MSG);
is_string(":pre300 test TEST 42" CRLF, output, MSG);
}
static void long_vmsg_prefixf1(void)
{
buf_head_t linebuf;
char output[2048] = { 0 };
int len;
rb_linebuf_newbuf(&linebuf);
_rb_linebuf_put_vmsg_prefixf(&linebuf, ":pre%d ", "%s", MKTEXT(502));
len = rb_linebuf_get(&linebuf, output, sizeof(output), 0, 1);
rb_linebuf_donebuf(&linebuf);
is_int(strlen(output), len, MSG);
char tmp[2048];
strcpy(tmp, ":pre300 ");
strcat(tmp, MKTEXT(502));
strcat(tmp, CRLF);
is_string(tmp, output, MSG);
is_int(DATALEN + strlen(CRLF), strlen(output), MSG);
}
static void too_long_vmsg_prefixf1(void)
{
buf_head_t linebuf;
char output[2048] = { 0 };
int len;
rb_linebuf_newbuf(&linebuf);
_rb_linebuf_put_vmsg_prefixf(&linebuf, ":pre%d ", "%s", MKTEXT(503));
len = rb_linebuf_get(&linebuf, output, sizeof(output), 0, 1);
rb_linebuf_donebuf(&linebuf);
is_int(strlen(output), len, MSG);
char tmp[2048];
strcpy(tmp, ":pre300 ");
strcat(tmp, MKTEXT(503));
tmp[strlen(tmp) - 1] = 0; /* truncated message */
strcat(tmp, CRLF);
is_string(tmp, output, MSG);
is_int(DATALEN + strlen(CRLF), strlen(output), MSG);
}
static void long_vmsg_prefixf2(void)
{
buf_head_t linebuf;
char output[2048] = { 0 };
int len;
rb_linebuf_newbuf(&linebuf);
_rb_linebuf_put_vmsg_prefixf(&linebuf, ":pre%d ", "%s", MKTEXT(502));
len = rb_linebuf_get(&linebuf, output, sizeof(output), 0, 1);
rb_linebuf_donebuf(&linebuf);
is_int(strlen(output), len, MSG);
char tmp[2048];
strcpy(tmp, ":pre300 ");
strcat(tmp, MKTEXT(502));
strcat(tmp, CRLF);
is_string(tmp, output, MSG);
is_int(DATALEN + strlen(CRLF), strlen(output), MSG);
}
static void too_long_vmsg_prefixf2(void)
{
buf_head_t linebuf;
char output[2048] = { 0 };
int len;
rb_linebuf_newbuf(&linebuf);
_rb_linebuf_put_vmsg_prefixf(&linebuf, ":pre%d ", "%s", MKTEXT(503));
len = rb_linebuf_get(&linebuf, output, sizeof(output), 0, 1);
rb_linebuf_donebuf(&linebuf);
is_int(strlen(output), len, MSG);
char tmp[2048];
strcpy(tmp, ":pre300 ");
strcat(tmp, MKTEXT(503));
tmp[strlen(tmp) - 1] = 0; /* truncated message */
strcat(tmp, CRLF);
is_string(tmp, output, MSG);
is_int(DATALEN + strlen(CRLF), strlen(output), MSG);
}
static void long_vmsg_prefixf3(void)
{
buf_head_t linebuf;
char output[2048] = { 0 };
char prefix[2048] = { 0 };
int len;
strcpy(prefix, MKTEXT(507));
strcat(prefix, "%d");
rb_linebuf_newbuf(&linebuf);
_rb_linebuf_put_vmsg_prefixf(&linebuf, prefix, "%s", MKTEXT(500));
len = rb_linebuf_get(&linebuf, output, sizeof(output), 0, 1);
rb_linebuf_donebuf(&linebuf);
is_int(strlen(output), len, MSG);
char tmp[2048];
strcpy(tmp, MKTEXT(507));
strcat(tmp, "300");
strcat(tmp, CRLF);
is_string(tmp, output, MSG);
is_int(DATALEN + strlen(CRLF), strlen(output), MSG);
}
static void too_long_vmsg_prefixf3(void)
{
buf_head_t linebuf;
char output[2048] = { 0 };
char prefix[2048] = { 0 };
int len;
strcpy(prefix, MKTEXT(508));
strcat(prefix, "%d");
rb_linebuf_newbuf(&linebuf);
_rb_linebuf_put_vmsg_prefixf(&linebuf, prefix, "%s", MKTEXT(500));
len = rb_linebuf_get(&linebuf, output, sizeof(output), 0, 1);
rb_linebuf_donebuf(&linebuf);
is_int(strlen(output), len, MSG);
char tmp[2048];
strcpy(tmp, MKTEXT(508));
strcat(tmp, "300");
tmp[strlen(tmp) - 1] = 0; /* truncated message */
strcat(tmp, CRLF);
is_string(tmp, output, MSG);
is_int(DATALEN + strlen(CRLF), strlen(output), MSG);
}
int main(int argc, char *argv[])
{
memset(&me, 0, sizeof(me));
strcpy(me.name, "me.name.");
strcpy(long_tags, "@");
strcat(long_tags, MKTEXT(510));
strcat(long_tags, " ");
/* no space for any additional message */
strcpy(long_prefix, "@");
strcat(long_prefix, MKTEXT(510));
strcat(long_prefix, " ");
strcat(long_prefix, MKTEXT(510));
strcpy(long_prefixf, "@");
strcat(long_prefixf, MKTEXT(510));
strcat(long_prefixf, " ");
strcat(long_prefixf, MKTEXT(507));
strcat(long_prefixf, "%d");
rb_lib_init(NULL, NULL, NULL, 0, 1024, DNODE_HEAP_SIZE, FD_HEAP_SIZE);
rb_linebuf_init(LINEBUF_HEAP_SIZE);
plan_lazy();
is_int(512, TAGSLEN, MSG);
is_int(510, DATALEN, MSG);
is_int(TAGSLEN, strlen(long_tags), MSG);
is_int(TAGSLEN + DATALEN, strlen(long_prefix), MSG);
/* this is a format string, "%d" -> "300", so 1 char short */
is_int(TAGSLEN + DATALEN - 1, strlen(long_prefixf), MSG);
basic_vtags_prefix1();
long_vtags_prefix1();
too_long_vtags_prefix1();
long_vtags_prefix2();
too_long_vtags_prefix2();
long_vtags_prefix3();
too_long_vtags_prefix3();
basic_vtags_prefixf1();
long_vtags_prefixf1();
too_long_vtags_prefixf1();
long_vtags_prefixf2();
too_long_vtags_prefixf2();
long_vtags_prefixf3();
too_long_vtags_prefixf3();
basic_msgf1();
long_msgf1();
too_long_msgf1();
long_msgf2();
too_long_msgf2();
basic_vmsg1();
long_vmsg1();
too_long_vmsg1();
long_vmsg2();
too_long_vmsg2();
basic_vmsg_prefixf1();
long_vmsg_prefixf1();
too_long_vmsg_prefixf1();
long_vmsg_prefixf2();
too_long_vmsg_prefixf2();
long_vmsg_prefixf3();
too_long_vmsg_prefixf3();
return 0;
}

View file

@ -1009,7 +1009,7 @@ static void sendto_channel_local1(void)
{ {
standard_init(); standard_init();
sendto_channel_local(ALL_MEMBERS, channel, "Hello %s!", "World"); sendto_channel_local(user, ALL_MEMBERS, channel, "Hello %s!", "World");
is_client_sendq_empty(user, "Not on channel; " MSG); is_client_sendq_empty(user, "Not on channel; " MSG);
is_client_sendq("Hello World!" CRLF, local_chan_o, "On channel; " MSG); is_client_sendq("Hello World!" CRLF, local_chan_o, "On channel; " MSG);
is_client_sendq("Hello World!" CRLF, local_chan_ov, "On channel; " MSG); is_client_sendq("Hello World!" CRLF, local_chan_ov, "On channel; " MSG);
@ -1019,7 +1019,7 @@ static void sendto_channel_local1(void)
is_client_sendq_empty(server, MSG); is_client_sendq_empty(server, MSG);
is_client_sendq_empty(server2, MSG); is_client_sendq_empty(server2, MSG);
sendto_channel_local(CHFL_VOICE, channel, "Hello %s!", "World"); sendto_channel_local(user, CHFL_VOICE, channel, "Hello %s!", "World");
is_client_sendq_empty(user, "Not on channel; " MSG); is_client_sendq_empty(user, "Not on channel; " MSG);
is_client_sendq_empty(local_chan_o, "Not +v; " MSG); is_client_sendq_empty(local_chan_o, "Not +v; " MSG);
is_client_sendq("Hello World!" CRLF, local_chan_ov, "Has +v; " MSG); is_client_sendq("Hello World!" CRLF, local_chan_ov, "Has +v; " MSG);
@ -1029,7 +1029,7 @@ static void sendto_channel_local1(void)
is_client_sendq_empty(server, MSG); is_client_sendq_empty(server, MSG);
is_client_sendq_empty(server2, MSG); is_client_sendq_empty(server2, MSG);
sendto_channel_local(CHFL_CHANOP, channel, "Hello %s!", "World"); sendto_channel_local(user, CHFL_CHANOP, channel, "Hello %s!", "World");
is_client_sendq_empty(user, "Not on channel; " MSG); is_client_sendq_empty(user, "Not on channel; " MSG);
is_client_sendq("Hello World!" CRLF, local_chan_o, "Has +o; " MSG); is_client_sendq("Hello World!" CRLF, local_chan_o, "Has +o; " MSG);
is_client_sendq("Hello World!" CRLF, local_chan_ov, "Has +o; " MSG); is_client_sendq("Hello World!" CRLF, local_chan_ov, "Has +o; " MSG);
@ -1039,7 +1039,7 @@ static void sendto_channel_local1(void)
is_client_sendq_empty(server, MSG); is_client_sendq_empty(server, MSG);
is_client_sendq_empty(server2, MSG); is_client_sendq_empty(server2, MSG);
sendto_channel_local(CHFL_CHANOP | CHFL_VOICE, channel, "Hello %s!", "World"); sendto_channel_local(user, CHFL_CHANOP | CHFL_VOICE, channel, "Hello %s!", "World");
is_client_sendq_empty(user, "Not on channel; " MSG); is_client_sendq_empty(user, "Not on channel; " MSG);
is_client_sendq("Hello World!" CRLF, local_chan_o, "Has +o/+v; " MSG); is_client_sendq("Hello World!" CRLF, local_chan_o, "Has +o/+v; " MSG);
is_client_sendq("Hello World!" CRLF, local_chan_ov, "Has +o/+v; " MSG); is_client_sendq("Hello World!" CRLF, local_chan_ov, "Has +o/+v; " MSG);
@ -1049,7 +1049,7 @@ static void sendto_channel_local1(void)
is_client_sendq_empty(server, MSG); is_client_sendq_empty(server, MSG);
is_client_sendq_empty(server2, MSG); is_client_sendq_empty(server2, MSG);
sendto_channel_local(ONLY_OPERS, channel, "Hello %s!", "World"); sendto_channel_local(user, ONLY_OPERS, channel, "Hello %s!", "World");
is_client_sendq_empty(user, "Not an oper; " MSG); is_client_sendq_empty(user, "Not an oper; " MSG);
is_client_sendq_empty(local_chan_o, "Not an oper; " MSG); is_client_sendq_empty(local_chan_o, "Not an oper; " MSG);
is_client_sendq_empty(local_chan_ov, "Not an oper; " MSG); is_client_sendq_empty(local_chan_ov, "Not an oper; " MSG);
@ -1070,7 +1070,7 @@ static void sendto_channel_local1(void)
add_user_to_channel(lchannel, oper1, CHFL_PEON); add_user_to_channel(lchannel, oper1, CHFL_PEON);
add_user_to_channel(lchannel, oper2, CHFL_PEON); add_user_to_channel(lchannel, oper2, CHFL_PEON);
sendto_channel_local(ALL_MEMBERS, lchannel, "Hello %s!", "World"); sendto_channel_local(user, ALL_MEMBERS, lchannel, "Hello %s!", "World");
is_client_sendq("Hello World!" CRLF, user, "On channel; " MSG); is_client_sendq("Hello World!" CRLF, user, "On channel; " MSG);
is_client_sendq("Hello World!" CRLF, oper1, "On channel; " MSG); is_client_sendq("Hello World!" CRLF, oper1, "On channel; " MSG);
is_client_sendq("Hello World!" CRLF, oper2, "On channel; " MSG); is_client_sendq("Hello World!" CRLF, oper2, "On channel; " MSG);
@ -1078,7 +1078,7 @@ static void sendto_channel_local1(void)
is_client_sendq_empty(server2, MSG); is_client_sendq_empty(server2, MSG);
is_client_sendq_empty(server3, MSG); is_client_sendq_empty(server3, MSG);
sendto_channel_local(ONLY_OPERS, lchannel, "Hello %s!", "World"); sendto_channel_local(user, ONLY_OPERS, lchannel, "Hello %s!", "World");
is_client_sendq_empty(user, "Not an oper; " MSG); is_client_sendq_empty(user, "Not an oper; " MSG);
is_client_sendq("Hello World!" CRLF, oper1, "Is an oper; " MSG); is_client_sendq("Hello World!" CRLF, oper1, "Is an oper; " MSG);
is_client_sendq("Hello World!" CRLF, oper2, "Is an oper; " MSG); is_client_sendq("Hello World!" CRLF, oper2, "Is an oper; " MSG);
@ -1096,7 +1096,7 @@ static void sendto_channel_local_with_capability1(void)
local_chan_o->localClient->caps |= CAP_INVITE_NOTIFY; local_chan_o->localClient->caps |= CAP_INVITE_NOTIFY;
local_chan_v->localClient->caps |= CAP_INVITE_NOTIFY; local_chan_v->localClient->caps |= CAP_INVITE_NOTIFY;
sendto_channel_local_with_capability(ALL_MEMBERS, CAP_INVITE_NOTIFY, 0, channel, "Hello %s!", "World"); sendto_channel_local_with_capability(user, ALL_MEMBERS, CAP_INVITE_NOTIFY, 0, channel, "Hello %s!", "World");
is_client_sendq_empty(user, "Not on channel; " MSG); is_client_sendq_empty(user, "Not on channel; " MSG);
is_client_sendq("Hello World!" CRLF, local_chan_o, "On channel; " MSG); is_client_sendq("Hello World!" CRLF, local_chan_o, "On channel; " MSG);
is_client_sendq_empty(local_chan_ov, "Doesn't have cap; " MSG); is_client_sendq_empty(local_chan_ov, "Doesn't have cap; " MSG);
@ -1106,7 +1106,7 @@ static void sendto_channel_local_with_capability1(void)
is_client_sendq_empty(server, MSG); is_client_sendq_empty(server, MSG);
is_client_sendq_empty(server2, MSG); is_client_sendq_empty(server2, MSG);
sendto_channel_local_with_capability(ALL_MEMBERS, 0, CAP_INVITE_NOTIFY, channel, "Hello %s!", "World"); sendto_channel_local_with_capability(user, ALL_MEMBERS, 0, CAP_INVITE_NOTIFY, channel, "Hello %s!", "World");
is_client_sendq_empty(user, "Not on channel; " MSG); is_client_sendq_empty(user, "Not on channel; " MSG);
is_client_sendq_empty(local_chan_o, "Has cap; " MSG); is_client_sendq_empty(local_chan_o, "Has cap; " MSG);
is_client_sendq("Hello World!" CRLF, local_chan_ov, "On channel; " MSG); is_client_sendq("Hello World!" CRLF, local_chan_ov, "On channel; " MSG);
@ -1116,7 +1116,7 @@ static void sendto_channel_local_with_capability1(void)
is_client_sendq_empty(server, MSG); is_client_sendq_empty(server, MSG);
is_client_sendq_empty(server2, MSG); is_client_sendq_empty(server2, MSG);
sendto_channel_local_with_capability(ALL_MEMBERS, 0, 0, channel, "Hello %s!", "World"); sendto_channel_local_with_capability(user, ALL_MEMBERS, 0, 0, channel, "Hello %s!", "World");
is_client_sendq_empty(user, "Not on channel; " MSG); is_client_sendq_empty(user, "Not on channel; " MSG);
is_client_sendq("Hello World!" CRLF, local_chan_o, "On channel; " MSG); is_client_sendq("Hello World!" CRLF, local_chan_o, "On channel; " MSG);
is_client_sendq("Hello World!" CRLF, local_chan_ov, "On channel; " MSG); is_client_sendq("Hello World!" CRLF, local_chan_ov, "On channel; " MSG);
@ -1126,7 +1126,7 @@ static void sendto_channel_local_with_capability1(void)
is_client_sendq_empty(server, MSG); is_client_sendq_empty(server, MSG);
is_client_sendq_empty(server2, MSG); is_client_sendq_empty(server2, MSG);
sendto_channel_local_with_capability(CHFL_VOICE, CAP_INVITE_NOTIFY, 0, channel, "Hello %s!", "World"); sendto_channel_local_with_capability(user, CHFL_VOICE, CAP_INVITE_NOTIFY, 0, channel, "Hello %s!", "World");
is_client_sendq_empty(user, "Not on channel; " MSG); is_client_sendq_empty(user, "Not on channel; " MSG);
is_client_sendq_empty(local_chan_o, "Not +v; " MSG); is_client_sendq_empty(local_chan_o, "Not +v; " MSG);
is_client_sendq_empty(local_chan_ov, "Doesn't have cap; " MSG); is_client_sendq_empty(local_chan_ov, "Doesn't have cap; " MSG);
@ -1136,7 +1136,7 @@ static void sendto_channel_local_with_capability1(void)
is_client_sendq_empty(server, MSG); is_client_sendq_empty(server, MSG);
is_client_sendq_empty(server2, MSG); is_client_sendq_empty(server2, MSG);
sendto_channel_local_with_capability(CHFL_VOICE, 0, CAP_INVITE_NOTIFY, channel, "Hello %s!", "World"); sendto_channel_local_with_capability(user, CHFL_VOICE, 0, CAP_INVITE_NOTIFY, channel, "Hello %s!", "World");
is_client_sendq_empty(user, "Not on channel; " MSG); is_client_sendq_empty(user, "Not on channel; " MSG);
is_client_sendq_empty(local_chan_o, "Not +v; " MSG); is_client_sendq_empty(local_chan_o, "Not +v; " MSG);
is_client_sendq("Hello World!" CRLF, local_chan_ov, "Has +v; " MSG); is_client_sendq("Hello World!" CRLF, local_chan_ov, "Has +v; " MSG);
@ -1146,7 +1146,7 @@ static void sendto_channel_local_with_capability1(void)
is_client_sendq_empty(server, MSG); is_client_sendq_empty(server, MSG);
is_client_sendq_empty(server2, MSG); is_client_sendq_empty(server2, MSG);
sendto_channel_local_with_capability(CHFL_VOICE, 0, 0, channel, "Hello %s!", "World"); sendto_channel_local_with_capability(user, CHFL_VOICE, 0, 0, channel, "Hello %s!", "World");
is_client_sendq_empty(user, "Not on channel; " MSG); is_client_sendq_empty(user, "Not on channel; " MSG);
is_client_sendq_empty(local_chan_o, "Not +v; " MSG); is_client_sendq_empty(local_chan_o, "Not +v; " MSG);
is_client_sendq("Hello World!" CRLF, local_chan_ov, "Has +v; " MSG); is_client_sendq("Hello World!" CRLF, local_chan_ov, "Has +v; " MSG);
@ -1156,7 +1156,7 @@ static void sendto_channel_local_with_capability1(void)
is_client_sendq_empty(server, MSG); is_client_sendq_empty(server, MSG);
is_client_sendq_empty(server2, MSG); is_client_sendq_empty(server2, MSG);
sendto_channel_local_with_capability(CHFL_CHANOP, CAP_INVITE_NOTIFY, 0, channel, "Hello %s!", "World"); sendto_channel_local_with_capability(user, CHFL_CHANOP, CAP_INVITE_NOTIFY, 0, channel, "Hello %s!", "World");
is_client_sendq_empty(user, "Not on channel; " MSG); is_client_sendq_empty(user, "Not on channel; " MSG);
is_client_sendq("Hello World!" CRLF, local_chan_o, "Has +o; " MSG); is_client_sendq("Hello World!" CRLF, local_chan_o, "Has +o; " MSG);
is_client_sendq_empty(local_chan_ov, "Doesn't have cap; " MSG); is_client_sendq_empty(local_chan_ov, "Doesn't have cap; " MSG);
@ -1166,7 +1166,7 @@ static void sendto_channel_local_with_capability1(void)
is_client_sendq_empty(server, MSG); is_client_sendq_empty(server, MSG);
is_client_sendq_empty(server2, MSG); is_client_sendq_empty(server2, MSG);
sendto_channel_local_with_capability(CHFL_CHANOP, 0, CAP_INVITE_NOTIFY, channel, "Hello %s!", "World"); sendto_channel_local_with_capability(user, CHFL_CHANOP, 0, CAP_INVITE_NOTIFY, channel, "Hello %s!", "World");
is_client_sendq_empty(user, "Not on channel; " MSG); is_client_sendq_empty(user, "Not on channel; " MSG);
is_client_sendq_empty(local_chan_o, "Has cap; " MSG); is_client_sendq_empty(local_chan_o, "Has cap; " MSG);
is_client_sendq("Hello World!" CRLF, local_chan_ov, "Has +o; " MSG); is_client_sendq("Hello World!" CRLF, local_chan_ov, "Has +o; " MSG);
@ -1176,7 +1176,7 @@ static void sendto_channel_local_with_capability1(void)
is_client_sendq_empty(server, MSG); is_client_sendq_empty(server, MSG);
is_client_sendq_empty(server2, MSG); is_client_sendq_empty(server2, MSG);
sendto_channel_local_with_capability(CHFL_CHANOP, 0, 0, channel, "Hello %s!", "World"); sendto_channel_local_with_capability(user, CHFL_CHANOP, 0, 0, channel, "Hello %s!", "World");
is_client_sendq_empty(user, "Not on channel; " MSG); is_client_sendq_empty(user, "Not on channel; " MSG);
is_client_sendq("Hello World!" CRLF, local_chan_o, "Has +o; " MSG); is_client_sendq("Hello World!" CRLF, local_chan_o, "Has +o; " MSG);
is_client_sendq("Hello World!" CRLF, local_chan_ov, "Has +o; " MSG); is_client_sendq("Hello World!" CRLF, local_chan_ov, "Has +o; " MSG);
@ -1186,7 +1186,7 @@ static void sendto_channel_local_with_capability1(void)
is_client_sendq_empty(server, MSG); is_client_sendq_empty(server, MSG);
is_client_sendq_empty(server2, MSG); is_client_sendq_empty(server2, MSG);
sendto_channel_local_with_capability(CHFL_CHANOP | CHFL_VOICE, CAP_INVITE_NOTIFY, 0, channel, "Hello %s!", "World"); sendto_channel_local_with_capability(user, CHFL_CHANOP | CHFL_VOICE, CAP_INVITE_NOTIFY, 0, channel, "Hello %s!", "World");
is_client_sendq_empty(user, "Not on channel; " MSG); is_client_sendq_empty(user, "Not on channel; " MSG);
is_client_sendq("Hello World!" CRLF, local_chan_o, "Has +o/+v; " MSG); is_client_sendq("Hello World!" CRLF, local_chan_o, "Has +o/+v; " MSG);
is_client_sendq_empty(local_chan_ov, "Doesn't have cap; " MSG); is_client_sendq_empty(local_chan_ov, "Doesn't have cap; " MSG);
@ -1196,7 +1196,7 @@ static void sendto_channel_local_with_capability1(void)
is_client_sendq_empty(server, MSG); is_client_sendq_empty(server, MSG);
is_client_sendq_empty(server2, MSG); is_client_sendq_empty(server2, MSG);
sendto_channel_local_with_capability(CHFL_CHANOP | CHFL_VOICE, 0, CAP_INVITE_NOTIFY, channel, "Hello %s!", "World"); sendto_channel_local_with_capability(user, CHFL_CHANOP | CHFL_VOICE, 0, CAP_INVITE_NOTIFY, channel, "Hello %s!", "World");
is_client_sendq_empty(user, "Not on channel; " MSG); is_client_sendq_empty(user, "Not on channel; " MSG);
is_client_sendq_empty(local_chan_o, "Has cap; " MSG); is_client_sendq_empty(local_chan_o, "Has cap; " MSG);
is_client_sendq("Hello World!" CRLF, local_chan_ov, "Has +o/+v; " MSG); is_client_sendq("Hello World!" CRLF, local_chan_ov, "Has +o/+v; " MSG);
@ -1206,7 +1206,7 @@ static void sendto_channel_local_with_capability1(void)
is_client_sendq_empty(server, MSG); is_client_sendq_empty(server, MSG);
is_client_sendq_empty(server2, MSG); is_client_sendq_empty(server2, MSG);
sendto_channel_local_with_capability(CHFL_CHANOP | CHFL_VOICE, 0, 0, channel, "Hello %s!", "World"); sendto_channel_local_with_capability(user, CHFL_CHANOP | CHFL_VOICE, 0, 0, channel, "Hello %s!", "World");
is_client_sendq_empty(user, "Not on channel; " MSG); is_client_sendq_empty(user, "Not on channel; " MSG);
is_client_sendq("Hello World!" CRLF, local_chan_o, "Has +o/+v; " MSG); is_client_sendq("Hello World!" CRLF, local_chan_o, "Has +o/+v; " MSG);
is_client_sendq("Hello World!" CRLF, local_chan_ov, "Has +o/+v; " MSG); is_client_sendq("Hello World!" CRLF, local_chan_ov, "Has +o/+v; " MSG);
@ -1858,7 +1858,7 @@ static void sendto_monitor1(void)
rb_dlinkAddAlloc(local_chan_v, &monptr->users); rb_dlinkAddAlloc(local_chan_v, &monptr->users);
rb_dlinkAddAlloc(monptr, &local_chan_v->localClient->monitor_list); rb_dlinkAddAlloc(monptr, &local_chan_v->localClient->monitor_list);
sendto_monitor(monptr, "Hello %s!", "World"); sendto_monitor(user, monptr, "Hello %s!", "World");
is_client_sendq_empty(user, "Not monitoring; " MSG); is_client_sendq_empty(user, "Not monitoring; " MSG);
is_client_sendq("Hello World!" CRLF, local_chan_o, "Monitoring; " MSG); is_client_sendq("Hello World!" CRLF, local_chan_o, "Monitoring; " MSG);
is_client_sendq_empty(local_chan_ov, "Not monitoring; " MSG); is_client_sendq_empty(local_chan_ov, "Not monitoring; " MSG);