]>
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
)
39 /* skip any leading spaces */
40 for (ch
= line
; *ch
&& *ch
== ' '; ch
++)
54 char *next
= strchr(t
, ';');
55 char *eq
= strchr(t
, '=');
69 msgbuf_append_tag(msgbuf
, t
, eq
, 0);
83 /* skip any whitespace between tags and origin */
84 for (; *ch
&& *ch
== ' '; ch
++)
92 char *end
= strchr(ch
, ' ');
98 for (ch
= end
+ 1; *ch
&& *ch
== ' '; ch
++)
105 n_para
= rb_string_to_array(ch
, parv
, MAXPARA
);
109 msgbuf
->cmd
= parv
[0];
110 for (size_t i
= 0; i
< n_para
; i
++)
111 msgbuf_append_para(msgbuf
, parv
[i
]);
117 msgbuf_has_matching_tags(struct MsgBuf
*msgbuf
, unsigned int capmask
)
119 for (size_t i
= 0; i
< msgbuf
->n_tags
; i
++)
121 if ((msgbuf
->tags
[i
].capmask
& capmask
) != 0)
129 msgbuf_unparse_tags(char *buf
, size_t buflen
, struct MsgBuf
*msgbuf
, unsigned int capmask
)
131 if (!msgbuf_has_matching_tags(msgbuf
, capmask
))
136 for (size_t i
= 0; i
< msgbuf
->n_tags
; i
++)
138 if ((msgbuf
->tags
[i
].capmask
& capmask
) == 0)
142 rb_strlcat(buf
, ";", buflen
);
144 rb_strlcat(buf
, msgbuf
->tags
[i
].key
, buflen
);
146 /* XXX properly handle escaping */
147 if (msgbuf
->tags
[i
].value
)
149 rb_strlcat(buf
, "=", buflen
);
150 rb_strlcat(buf
, msgbuf
->tags
[i
].value
, buflen
);
154 rb_strlcat(buf
, " ", buflen
);
158 msgbuf_unparse_prefix(char *buf
, size_t buflen
, struct MsgBuf
*msgbuf
, unsigned int capmask
)
160 memset(buf
, 0, buflen
);
162 if (msgbuf
->n_tags
> 0)
163 msgbuf_unparse_tags(buf
, buflen
, msgbuf
, capmask
);
165 rb_snprintf_append(buf
, buflen
, ":%s ", msgbuf
->origin
!= NULL
? msgbuf
->origin
: me
.name
);
167 if (msgbuf
->cmd
!= NULL
)
168 rb_snprintf_append(buf
, buflen
, "%s ", msgbuf
->cmd
);
170 if (msgbuf
->target
!= NULL
)
171 rb_snprintf_append(buf
, buflen
, "%s ", msgbuf
->target
);
175 * unparse a pure MsgBuf into a buffer.
176 * if origin is NULL, me.name will be used.
177 * cmd may not be NULL.
178 * returns 0 on success, 1 on error.
181 msgbuf_unparse(char *buf
, size_t buflen
, struct MsgBuf
*msgbuf
, unsigned int capmask
)
183 msgbuf_unparse_prefix(buf
, buflen
, msgbuf
, capmask
);
185 for (size_t i
= msgbuf
->cmd
!= NULL
? 0 : 1; i
< msgbuf
->n_para
; i
++)
187 if (i
== (msgbuf
->n_para
- 1))
189 if (strchr(msgbuf
->para
[i
], ' ') != NULL
)
190 rb_snprintf_append(buf
, buflen
, ":%s", msgbuf
->para
[i
]);
192 rb_strlcat(buf
, msgbuf
->para
[i
], buflen
);
195 rb_strlcat(buf
, msgbuf
->para
[i
], buflen
);
202 * unparse a MsgBuf stem + format string into a buffer
203 * if origin is NULL, me.name will be used.
204 * cmd may not be NULL.
205 * returns 0 on success, 1 on error.
208 msgbuf_vunparse_fmt(char *buf
, size_t buflen
, struct MsgBuf
*head
, unsigned int capmask
, const char *fmt
, va_list va
)
213 msgbuf_unparse_prefix(buf
, buflen
, head
, capmask
);
214 prefixlen
= strlen(buf
);
216 ws
= buf
+ prefixlen
;
217 vsnprintf(ws
, buflen
- prefixlen
, fmt
, va
);
223 * unparse a MsgBuf stem + format string into a buffer (with va_list handling)
224 * if origin is NULL, me.name will be used.
225 * cmd may not be NULL.
226 * returns 0 on success, 1 on error.
229 msgbuf_unparse_fmt(char *buf
, size_t buflen
, struct MsgBuf
*head
, unsigned int capmask
, const char *fmt
, ...)
235 res
= msgbuf_vunparse_fmt(buf
, buflen
, head
, capmask
, fmt
, va
);