From 4a13e3f1da46f196ad63884730611c56aed4f771 Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Sat, 20 Feb 2016 11:21:12 -0600 Subject: [PATCH] msgbuf: add some message building code --- include/msgbuf.h | 6 ++-- ircd/msgbuf.c | 71 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+), 3 deletions(-) diff --git a/include/msgbuf.h b/include/msgbuf.h index b060fafb..7de796a0 100644 --- a/include/msgbuf.h +++ b/include/msgbuf.h @@ -57,7 +57,7 @@ int msgbuf_parse(struct MsgBuf *msgbuf, char *line); * cmd may not be NULL. * returns 0 on success, 1 on error. */ -int msgbuf_unparse(char *buf, struct MsgBuf *msgbuf, unsigned int capmask); +int msgbuf_unparse(char *buf, size_t buflen, struct MsgBuf *msgbuf, unsigned int capmask); /* * unparse a MsgBuf header plus payload into a buffer. @@ -65,8 +65,8 @@ int msgbuf_unparse(char *buf, struct MsgBuf *msgbuf, unsigned int capmask); * cmd may not be NULL. * returns 0 on success, 1 on error. */ -int msgbuf_unparse_fmt(char *buf, struct MsgBuf *head, unsigned int capmask, const char *fmt, ...) AFP(4, 5); -int msgbuf_vunparse_fmt(char *buf, struct MsgBuf *head, unsigned int capmask, const char *fmt, va_list va); +int msgbuf_unparse_fmt(char *buf, size_t buflen, struct MsgBuf *head, unsigned int capmask, const char *fmt, ...) AFP(5, 6); +int msgbuf_vunparse_fmt(char *buf, size_t buflen, struct MsgBuf *head, unsigned int capmask, const char *fmt, va_list va); static inline void msgbuf_init(struct MsgBuf *msgbuf) diff --git a/ircd/msgbuf.c b/ircd/msgbuf.c index a7fe53b2..67581b0c 100644 --- a/ircd/msgbuf.c +++ b/ircd/msgbuf.c @@ -111,3 +111,74 @@ msgbuf_parse(struct MsgBuf *msgbuf, char *line) return 0; } + +static void +msgbuf_unparse_tags(char *buf, size_t buflen, struct MsgBuf *msgbuf, unsigned int capmask) +{ + int i; + + *buf = '@'; + + for (i = 0; i < msgbuf->n_tags; i++) + { + if ((msgbuf->tags[i].capmask & capmask) == 0) + continue; + + if (i != 0) + rb_strlcat(buf, ";", buflen); + + rb_strlcat(buf, msgbuf->tags[i].key, buflen); + + /* XXX properly handle escaping */ + if (msgbuf->tags[i].value) + { + rb_strlcat(buf, "=", buflen); + rb_strlcat(buf, msgbuf->tags[i].value, buflen); + } + } + + rb_strlcat(buf, " ", buflen); +} + +static void +msgbuf_unparse_prefix(char *buf, size_t buflen, struct MsgBuf *msgbuf, unsigned int capmask) +{ + int i; + + memset(buf, 0, buflen); + + if (msgbuf->n_tags > 0) + msgbuf_unparse_tags(buf, buflen, msgbuf, capmask); + + if (msgbuf->origin) + rb_snprintf_append(buf, buflen, ":%s ", msgbuf->origin); +} + +/* + * unparse a pure MsgBuf into a buffer. + * if origin is NULL, me.name will be used. + * cmd may not be NULL. + * returns 0 on success, 1 on error. + */ +int +msgbuf_unparse(char *buf, size_t buflen, struct MsgBuf *msgbuf, unsigned int capmask) +{ + int i; + + msgbuf_unparse_prefix(buf, buflen, msgbuf, capmask); + + for (i = 0; i < msgbuf->n_para; i++) + { + if (i == (msgbuf->n_para - 1)) + { + if (strchr(msgbuf->para[i], ' ') != NULL) + rb_snprintf_append(buf, buflen, ":%s", msgbuf->para[i]); + else + rb_strlcat(buf, msgbuf->para[i], buflen); + } + else + rb_strlcat(buf, msgbuf->para[i], buflen); + } + + return 0; +}