]>
jfr.im git - solanum.git/blob - ircd/msgbuf.c
2 * charybdis - an advanced ircd.
3 * Copyright (c) 2016 William Pitcock <nenolod@dereferenced.org>.
5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice is present in all copies.
9 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
10 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
11 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
12 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
13 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
14 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
15 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
16 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
17 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
18 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
19 * POSSIBILITY OF SUCH DAMAGE.
23 #include "ircd_defs.h"
29 * parse a message into a MsgBuf.
30 * returns 0 on success, 1 on error.
33 msgbuf_parse(struct MsgBuf
*msgbuf
, char *line
)
40 /* skip any leading spaces */
41 for (ch
= line
; *ch
&& *ch
== ' '; ch
++)
55 char *next
= strchr(t
, ';');
56 char *eq
= strchr(t
, '=');
70 msgbuf_append_tag(msgbuf
, t
, eq
, 0);
84 /* skip any whitespace between tags and origin */
85 for (; *ch
&& *ch
== ' '; ch
++)
93 char *end
= strchr(ch
, ' ');
99 for (ch
= end
+ 1; *ch
&& *ch
== ' '; ch
++)
106 n_para
= rb_string_to_array(ch
, parv
, MAXPARA
);
110 msgbuf
->cmd
= parv
[0];
111 for (i
= 0; i
< n_para
; i
++)
112 msgbuf_append_para(msgbuf
, parv
[i
]);
118 msgbuf_unparse_tags(char *buf
, size_t buflen
, struct MsgBuf
*msgbuf
, unsigned int capmask
)
124 for (i
= 0; i
< msgbuf
->n_tags
; i
++)
126 if ((msgbuf
->tags
[i
].capmask
& capmask
) == 0)
130 rb_strlcat(buf
, ";", buflen
);
132 rb_strlcat(buf
, msgbuf
->tags
[i
].key
, buflen
);
134 /* XXX properly handle escaping */
135 if (msgbuf
->tags
[i
].value
)
137 rb_strlcat(buf
, "=", buflen
);
138 rb_strlcat(buf
, msgbuf
->tags
[i
].value
, buflen
);
142 rb_strlcat(buf
, " ", buflen
);
146 msgbuf_unparse_prefix(char *buf
, size_t buflen
, struct MsgBuf
*msgbuf
, unsigned int capmask
)
150 memset(buf
, 0, buflen
);
152 if (msgbuf
->n_tags
> 0)
153 msgbuf_unparse_tags(buf
, buflen
, msgbuf
, capmask
);
155 rb_snprintf_append(buf
, buflen
, ":%s ", msgbuf
->origin
!= NULL
? msgbuf
->origin
: me
.name
);
157 if (msgbuf
->cmd
!= NULL
)
158 rb_snprintf_append(buf
, buflen
, "%s ", msgbuf
->cmd
);
160 if (msgbuf
->target
!= NULL
)
161 rb_snprintf_append(buf
, buflen
, "%s ", msgbuf
->target
);
165 * unparse a pure MsgBuf into a buffer.
166 * if origin is NULL, me.name will be used.
167 * cmd may not be NULL.
168 * returns 0 on success, 1 on error.
171 msgbuf_unparse(char *buf
, size_t buflen
, struct MsgBuf
*msgbuf
, unsigned int capmask
)
175 msgbuf_unparse_prefix(buf
, buflen
, msgbuf
, capmask
);
177 for (i
= msgbuf
->cmd
!= NULL
? 0 : 1; i
< msgbuf
->n_para
; i
++)
179 if (i
== (msgbuf
->n_para
- 1))
181 if (strchr(msgbuf
->para
[i
], ' ') != NULL
)
182 rb_snprintf_append(buf
, buflen
, ":%s", msgbuf
->para
[i
]);
184 rb_strlcat(buf
, msgbuf
->para
[i
], buflen
);
187 rb_strlcat(buf
, msgbuf
->para
[i
], buflen
);
194 * unparse a MsgBuf stem + format string into a buffer
195 * if origin is NULL, me.name will be used.
196 * cmd may not be NULL.
197 * returns 0 on success, 1 on error.
200 msgbuf_vunparse_fmt(char *buf
, size_t buflen
, struct MsgBuf
*head
, unsigned int capmask
, const char *fmt
, va_list va
)
205 msgbuf_unparse_prefix(buf
, buflen
, head
, capmask
);
206 prefixlen
= strlen(buf
);
208 ws
= buf
+ prefixlen
;
209 vsnprintf(ws
, buflen
- prefixlen
, fmt
, va
);
215 * unparse a MsgBuf stem + format string into a buffer (with va_list handling)
216 * if origin is NULL, me.name will be used.
217 * cmd may not be NULL.
218 * returns 0 on success, 1 on error.
221 msgbuf_unparse_fmt(char *buf
, size_t buflen
, struct MsgBuf
*head
, unsigned int capmask
, const char *fmt
, ...)
227 res
= msgbuf_vunparse_fmt(buf
, buflen
, head
, capmask
, fmt
, va
);