]>
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_has_matching_tags(struct MsgBuf
*msgbuf
, unsigned int capmask
)
122 for (i
= 0; i
< msgbuf
->n_tags
; i
++)
124 if ((msgbuf
->tags
[i
].capmask
& capmask
) != 0)
132 msgbuf_unparse_tags(char *buf
, size_t buflen
, struct MsgBuf
*msgbuf
, unsigned int capmask
)
136 if (!msgbuf_has_matching_tags(msgbuf
, capmask
))
141 for (i
= 0; i
< msgbuf
->n_tags
; i
++)
143 if ((msgbuf
->tags
[i
].capmask
& capmask
) == 0)
147 rb_strlcat(buf
, ";", buflen
);
149 rb_strlcat(buf
, msgbuf
->tags
[i
].key
, buflen
);
151 /* XXX properly handle escaping */
152 if (msgbuf
->tags
[i
].value
)
154 rb_strlcat(buf
, "=", buflen
);
155 rb_strlcat(buf
, msgbuf
->tags
[i
].value
, buflen
);
159 rb_strlcat(buf
, " ", buflen
);
163 msgbuf_unparse_prefix(char *buf
, size_t buflen
, struct MsgBuf
*msgbuf
, unsigned int capmask
)
167 memset(buf
, 0, buflen
);
169 if (msgbuf
->n_tags
> 0)
170 msgbuf_unparse_tags(buf
, buflen
, msgbuf
, capmask
);
172 rb_snprintf_append(buf
, buflen
, ":%s ", msgbuf
->origin
!= NULL
? msgbuf
->origin
: me
.name
);
174 if (msgbuf
->cmd
!= NULL
)
175 rb_snprintf_append(buf
, buflen
, "%s ", msgbuf
->cmd
);
177 if (msgbuf
->target
!= NULL
)
178 rb_snprintf_append(buf
, buflen
, "%s ", msgbuf
->target
);
182 * unparse a pure MsgBuf into a buffer.
183 * if origin is NULL, me.name will be used.
184 * cmd may not be NULL.
185 * returns 0 on success, 1 on error.
188 msgbuf_unparse(char *buf
, size_t buflen
, struct MsgBuf
*msgbuf
, unsigned int capmask
)
192 msgbuf_unparse_prefix(buf
, buflen
, msgbuf
, capmask
);
194 for (i
= msgbuf
->cmd
!= NULL
? 0 : 1; i
< msgbuf
->n_para
; i
++)
196 if (i
== (msgbuf
->n_para
- 1))
198 if (strchr(msgbuf
->para
[i
], ' ') != NULL
)
199 rb_snprintf_append(buf
, buflen
, ":%s", msgbuf
->para
[i
]);
201 rb_strlcat(buf
, msgbuf
->para
[i
], buflen
);
204 rb_strlcat(buf
, msgbuf
->para
[i
], buflen
);
211 * unparse a MsgBuf stem + format string into a buffer
212 * if origin is NULL, me.name will be used.
213 * cmd may not be NULL.
214 * returns 0 on success, 1 on error.
217 msgbuf_vunparse_fmt(char *buf
, size_t buflen
, struct MsgBuf
*head
, unsigned int capmask
, const char *fmt
, va_list va
)
222 msgbuf_unparse_prefix(buf
, buflen
, head
, capmask
);
223 prefixlen
= strlen(buf
);
225 ws
= buf
+ prefixlen
;
226 vsnprintf(ws
, buflen
- prefixlen
, fmt
, va
);
232 * unparse a MsgBuf stem + format string into a buffer (with va_list handling)
233 * if origin is NULL, me.name will be used.
234 * cmd may not be NULL.
235 * returns 0 on success, 1 on error.
238 msgbuf_unparse_fmt(char *buf
, size_t buflen
, struct MsgBuf
*head
, unsigned int capmask
, const char *fmt
, ...)
244 res
= msgbuf_vunparse_fmt(buf
, buflen
, head
, capmask
, fmt
, va
);