Blame


1 b8a11905 2023-08-31 op /*
2 b8a11905 2023-08-31 op * This is free and unencumbered software released into the public domain.
3 b8a11905 2023-08-31 op *
4 b8a11905 2023-08-31 op * Anyone is free to copy, modify, publish, use, compile, sell, or
5 b8a11905 2023-08-31 op * distribute this software, either in source code form or as a compiled
6 b8a11905 2023-08-31 op * binary, for any purpose, commercial or non-commercial, and by any
7 b8a11905 2023-08-31 op * means.
8 b8a11905 2023-08-31 op *
9 b8a11905 2023-08-31 op * In jurisdictions that recognize copyright laws, the author or authors
10 b8a11905 2023-08-31 op * of this software dedicate any and all copyright interest in the
11 b8a11905 2023-08-31 op * software to the public domain. We make this dedication for the benefit
12 b8a11905 2023-08-31 op * of the public at large and to the detriment of our heirs and
13 b8a11905 2023-08-31 op * successors. We intend this dedication to be an overt act of
14 b8a11905 2023-08-31 op * relinquishment in perpetuity of all present and future rights to this
15 b8a11905 2023-08-31 op * software under copyright law.
16 b8a11905 2023-08-31 op *
17 b8a11905 2023-08-31 op * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 b8a11905 2023-08-31 op * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 b8a11905 2023-08-31 op * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20 b8a11905 2023-08-31 op * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
21 b8a11905 2023-08-31 op * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
22 b8a11905 2023-08-31 op * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23 b8a11905 2023-08-31 op * OTHER DEALINGS IN THE SOFTWARE.
24 b8a11905 2023-08-31 op */
25 b8a11905 2023-08-31 op
26 cc89e101 2023-09-02 op #include "config.h"
27 cc89e101 2023-09-02 op
28 b8a11905 2023-08-31 op #include <assert.h>
29 b8a11905 2023-08-31 op #include <errno.h>
30 b8a11905 2023-08-31 op #include <stdarg.h>
31 cc89e101 2023-09-02 op #include <stdint.h>
32 b8a11905 2023-08-31 op #include <stdio.h>
33 b8a11905 2023-08-31 op #include <stdlib.h>
34 b8a11905 2023-08-31 op #include <string.h>
35 b8a11905 2023-08-31 op #include <unistd.h>
36 b8a11905 2023-08-31 op
37 6be81433 2024-04-14 op #ifndef BUFIO_WITHOUT_TLS
38 6be81433 2024-04-14 op #include <tls.h>
39 6be81433 2024-04-14 op #endif
40 6be81433 2024-04-14 op
41 b8a11905 2023-08-31 op #include "bufio.h"
42 b8a11905 2023-08-31 op
43 b8a11905 2023-08-31 op int
44 6be81433 2024-04-14 op buf_init(struct buf *buf)
45 b8a11905 2023-08-31 op {
46 b8a11905 2023-08-31 op const size_t cap = BIO_CHUNK;
47 b8a11905 2023-08-31 op
48 b8a11905 2023-08-31 op memset(buf, 0, sizeof(*buf));
49 b8a11905 2023-08-31 op if ((buf->buf = malloc(cap)) == NULL)
50 b8a11905 2023-08-31 op return (-1);
51 b8a11905 2023-08-31 op buf->cap = cap;
52 b8a11905 2023-08-31 op return (0);
53 b8a11905 2023-08-31 op }
54 b8a11905 2023-08-31 op
55 b8a11905 2023-08-31 op static int
56 6be81433 2024-04-14 op buf_grow(struct buf *buf)
57 b8a11905 2023-08-31 op {
58 b8a11905 2023-08-31 op size_t newcap;
59 b8a11905 2023-08-31 op void *t;
60 b8a11905 2023-08-31 op
61 b8a11905 2023-08-31 op newcap = buf->cap + BIO_CHUNK;
62 b8a11905 2023-08-31 op t = realloc(buf->buf, newcap);
63 b8a11905 2023-08-31 op if (t == NULL)
64 b8a11905 2023-08-31 op return (-1);
65 b8a11905 2023-08-31 op buf->buf = t;
66 b8a11905 2023-08-31 op buf->cap = newcap;
67 2216d3fb 2023-09-07 op return (0);
68 2216d3fb 2023-09-07 op }
69 2216d3fb 2023-09-07 op
70 2216d3fb 2023-09-07 op int
71 6be81433 2024-04-14 op buf_write(struct buf *buf, const void *d, size_t len)
72 2216d3fb 2023-09-07 op {
73 d20f7b51 2023-09-08 op while (buf->len + len > buf->cap) {
74 2216d3fb 2023-09-07 op if (buf_grow(buf) == -1)
75 2216d3fb 2023-09-07 op return (-1);
76 2216d3fb 2023-09-07 op }
77 2216d3fb 2023-09-07 op memcpy(buf->buf + buf->len, d, len);
78 2216d3fb 2023-09-07 op buf->len += len;
79 b8a11905 2023-08-31 op return (0);
80 b8a11905 2023-08-31 op }
81 b8a11905 2023-08-31 op
82 b8a11905 2023-08-31 op int
83 6be81433 2024-04-14 op buf_has_line(struct buf *buf, const char *nl)
84 b8a11905 2023-08-31 op {
85 b8a11905 2023-08-31 op return (memmem(buf->buf, buf->len, nl, strlen(nl)) != NULL);
86 b8a11905 2023-08-31 op }
87 b8a11905 2023-08-31 op
88 6be81433 2024-04-14 op char *
89 6be81433 2024-04-14 op buf_getdelim(struct buf *buf, const char *nl, size_t *len)
90 6be81433 2024-04-14 op {
91 6be81433 2024-04-14 op uint8_t *endl;
92 6be81433 2024-04-14 op size_t nlen;
93 6be81433 2024-04-14 op
94 6be81433 2024-04-14 op *len = 0;
95 6be81433 2024-04-14 op
96 6be81433 2024-04-14 op nlen = strlen(nl);
97 6be81433 2024-04-14 op if ((endl = memmem(buf->buf, buf->len, nl, nlen)) == NULL)
98 6be81433 2024-04-14 op return (NULL);
99 6be81433 2024-04-14 op *len = endl + nlen - buf->buf;
100 6be81433 2024-04-14 op *endl = '\0';
101 6be81433 2024-04-14 op return (buf->buf);
102 6be81433 2024-04-14 op }
103 6be81433 2024-04-14 op
104 b8a11905 2023-08-31 op void
105 6be81433 2024-04-14 op buf_drain(struct buf *buf, size_t l)
106 b8a11905 2023-08-31 op {
107 6be81433 2024-04-14 op buf->cur = 0;
108 6be81433 2024-04-14 op
109 b8a11905 2023-08-31 op if (l >= buf->len) {
110 b8a11905 2023-08-31 op buf->len = 0;
111 b8a11905 2023-08-31 op return;
112 b8a11905 2023-08-31 op }
113 b8a11905 2023-08-31 op
114 b8a11905 2023-08-31 op memmove(buf->buf, buf->buf + l, buf->len - l);
115 b8a11905 2023-08-31 op buf->len -= l;
116 b8a11905 2023-08-31 op }
117 b8a11905 2023-08-31 op
118 b8a11905 2023-08-31 op void
119 6be81433 2024-04-14 op buf_drain_line(struct buf *buf, const char *nl)
120 b8a11905 2023-08-31 op {
121 b8a11905 2023-08-31 op uint8_t *endln;
122 b8a11905 2023-08-31 op size_t nlen;
123 b8a11905 2023-08-31 op
124 b8a11905 2023-08-31 op nlen = strlen(nl);
125 b8a11905 2023-08-31 op if ((endln = memmem(buf->buf, buf->len, nl, nlen)) == NULL)
126 b8a11905 2023-08-31 op return;
127 b8a11905 2023-08-31 op buf_drain(buf, endln + nlen - buf->buf);
128 b8a11905 2023-08-31 op }
129 b8a11905 2023-08-31 op
130 b8a11905 2023-08-31 op void
131 6be81433 2024-04-14 op buf_free(struct buf *buf)
132 b8a11905 2023-08-31 op {
133 b8a11905 2023-08-31 op free(buf->buf);
134 b8a11905 2023-08-31 op memset(buf, 0, sizeof(*buf));
135 b8a11905 2023-08-31 op }
136 b8a11905 2023-08-31 op
137 b8a11905 2023-08-31 op int
138 b8a11905 2023-08-31 op bufio_init(struct bufio *bio)
139 b8a11905 2023-08-31 op {
140 b8a11905 2023-08-31 op memset(bio, 0, sizeof(*bio));
141 b8a11905 2023-08-31 op bio->fd = -1;
142 b8a11905 2023-08-31 op
143 b8a11905 2023-08-31 op if (buf_init(&bio->wbuf) == -1)
144 b8a11905 2023-08-31 op return (-1);
145 b8a11905 2023-08-31 op if (buf_init(&bio->rbuf) == -1) {
146 b8a11905 2023-08-31 op buf_free(&bio->wbuf);
147 b8a11905 2023-08-31 op return (-1);
148 b8a11905 2023-08-31 op }
149 b8a11905 2023-08-31 op return (0);
150 b8a11905 2023-08-31 op }
151 b8a11905 2023-08-31 op
152 d48ffc66 2023-08-31 op void
153 d48ffc66 2023-08-31 op bufio_free(struct bufio *bio)
154 b8a11905 2023-08-31 op {
155 6be81433 2024-04-14 op #ifndef BUFIO_WITHOUT_TLS
156 6be81433 2024-04-14 op if (bio->ctx)
157 6be81433 2024-04-14 op tls_free(bio->ctx);
158 6be81433 2024-04-14 op bio->ctx = NULL;
159 6be81433 2024-04-14 op #endif
160 6be81433 2024-04-14 op
161 b8a11905 2023-08-31 op if (bio->fd != -1)
162 b8a11905 2023-08-31 op close(bio->fd);
163 6be81433 2024-04-14 op bio->fd = -1;
164 b8a11905 2023-08-31 op
165 b8a11905 2023-08-31 op buf_free(&bio->rbuf);
166 b8a11905 2023-08-31 op buf_free(&bio->wbuf);
167 d48ffc66 2023-08-31 op }
168 d48ffc66 2023-08-31 op
169 d48ffc66 2023-08-31 op int
170 6be81433 2024-04-14 op bufio_close(struct bufio *bio)
171 6be81433 2024-04-14 op {
172 6be81433 2024-04-14 op #ifndef BUFIO_WITHOUT_TLS
173 6be81433 2024-04-14 op if (bio->ctx == NULL)
174 6be81433 2024-04-14 op return (0);
175 6be81433 2024-04-14 op
176 6be81433 2024-04-14 op switch (tls_close(bio->ctx)) {
177 6be81433 2024-04-14 op case 0:
178 6be81433 2024-04-14 op return 0;
179 6be81433 2024-04-14 op case TLS_WANT_POLLIN:
180 6be81433 2024-04-14 op errno = EAGAIN;
181 6be81433 2024-04-14 op bio->wantev = BUFIO_WANT_READ;
182 6be81433 2024-04-14 op return (-1);
183 6be81433 2024-04-14 op case TLS_WANT_POLLOUT:
184 6be81433 2024-04-14 op errno = EAGAIN;
185 6be81433 2024-04-14 op bio->wantev = BUFIO_WANT_WRITE;
186 6be81433 2024-04-14 op return (-1);
187 6be81433 2024-04-14 op default:
188 6be81433 2024-04-14 op return (-1);
189 6be81433 2024-04-14 op }
190 6be81433 2024-04-14 op #else
191 6be81433 2024-04-14 op return (0);
192 6be81433 2024-04-14 op #endif
193 6be81433 2024-04-14 op }
194 6be81433 2024-04-14 op
195 6be81433 2024-04-14 op int
196 d48ffc66 2023-08-31 op bufio_reset(struct bufio *bio)
197 d48ffc66 2023-08-31 op {
198 d48ffc66 2023-08-31 op bufio_free(bio);
199 b8a11905 2023-08-31 op return (bufio_init(bio));
200 b8a11905 2023-08-31 op }
201 b8a11905 2023-08-31 op
202 b8a11905 2023-08-31 op void
203 b8a11905 2023-08-31 op bufio_set_fd(struct bufio *bio, int fd)
204 b8a11905 2023-08-31 op {
205 b8a11905 2023-08-31 op bio->fd = fd;
206 b8a11905 2023-08-31 op }
207 b8a11905 2023-08-31 op
208 d48ffc66 2023-08-31 op void
209 d48ffc66 2023-08-31 op bufio_set_chunked(struct bufio *bio, int chunked)
210 d48ffc66 2023-08-31 op {
211 d48ffc66 2023-08-31 op bio->chunked = chunked;
212 d48ffc66 2023-08-31 op }
213 d48ffc66 2023-08-31 op
214 6be81433 2024-04-14 op int
215 6be81433 2024-04-14 op bufio_starttls(struct bufio *bio, const char *host, int insecure,
216 6be81433 2024-04-14 op const uint8_t *cert, size_t certlen, const uint8_t *key, size_t keylen)
217 b8a11905 2023-08-31 op {
218 6be81433 2024-04-14 op #ifndef BUFIO_WITHOUT_TLS
219 6be81433 2024-04-14 op struct tls_config *conf;
220 b8a11905 2023-08-31 op
221 6be81433 2024-04-14 op if ((conf = tls_config_new()) == NULL)
222 6be81433 2024-04-14 op return (-1);
223 6be81433 2024-04-14 op
224 6be81433 2024-04-14 op if (insecure) {
225 6be81433 2024-04-14 op tls_config_insecure_noverifycert(conf);
226 6be81433 2024-04-14 op tls_config_insecure_noverifyname(conf);
227 6be81433 2024-04-14 op tls_config_insecure_noverifytime(conf);
228 6be81433 2024-04-14 op }
229 6be81433 2024-04-14 op
230 6be81433 2024-04-14 op if (cert && tls_config_set_keypair_mem(conf, cert, certlen,
231 6be81433 2024-04-14 op key, keylen) == -1) {
232 6be81433 2024-04-14 op tls_config_free(conf);
233 6be81433 2024-04-14 op return (-1);
234 6be81433 2024-04-14 op }
235 6be81433 2024-04-14 op
236 6be81433 2024-04-14 op if ((bio->ctx = tls_client()) == NULL) {
237 6be81433 2024-04-14 op tls_config_free(conf);
238 6be81433 2024-04-14 op return (-1);
239 6be81433 2024-04-14 op }
240 6be81433 2024-04-14 op
241 6be81433 2024-04-14 op if (tls_configure(bio->ctx, conf) == -1) {
242 6be81433 2024-04-14 op tls_config_free(conf);
243 6be81433 2024-04-14 op return (-1);
244 6be81433 2024-04-14 op }
245 6be81433 2024-04-14 op
246 6be81433 2024-04-14 op tls_config_free(conf);
247 6be81433 2024-04-14 op
248 6be81433 2024-04-14 op if (tls_connect_socket(bio->ctx, bio->fd, host) == -1)
249 6be81433 2024-04-14 op return (-1);
250 6be81433 2024-04-14 op
251 6be81433 2024-04-14 op return (0);
252 6be81433 2024-04-14 op #else
253 6be81433 2024-04-14 op errno = EINVAL;
254 6be81433 2024-04-14 op return (-1);
255 6be81433 2024-04-14 op #endif
256 6be81433 2024-04-14 op }
257 6be81433 2024-04-14 op
258 6be81433 2024-04-14 op int
259 6be81433 2024-04-14 op bufio_ev(struct bufio *bio)
260 6be81433 2024-04-14 op {
261 6be81433 2024-04-14 op short ev;
262 b8a11905 2023-08-31 op
263 6be81433 2024-04-14 op if (bio->wantev)
264 6be81433 2024-04-14 op return (bio->wantev);
265 6be81433 2024-04-14 op
266 6be81433 2024-04-14 op ev = BUFIO_WANT_READ;
267 6be81433 2024-04-14 op if (bio->wbuf.len != 0)
268 6be81433 2024-04-14 op ev |= BUFIO_WANT_WRITE;
269 6be81433 2024-04-14 op
270 b8a11905 2023-08-31 op return (ev);
271 b8a11905 2023-08-31 op }
272 b8a11905 2023-08-31 op
273 6be81433 2024-04-14 op int
274 6be81433 2024-04-14 op bufio_handshake(struct bufio *bio)
275 6be81433 2024-04-14 op {
276 6be81433 2024-04-14 op #ifndef BUFIO_WITHOUT_TLS
277 6be81433 2024-04-14 op if (bio->ctx == NULL) {
278 6be81433 2024-04-14 op errno = EINVAL;
279 6be81433 2024-04-14 op return (-1);
280 6be81433 2024-04-14 op }
281 6be81433 2024-04-14 op
282 6be81433 2024-04-14 op switch (tls_handshake(bio->ctx)) {
283 6be81433 2024-04-14 op case 0:
284 6be81433 2024-04-14 op return (0);
285 6be81433 2024-04-14 op case TLS_WANT_POLLIN:
286 6be81433 2024-04-14 op errno = EAGAIN;
287 6be81433 2024-04-14 op bio->wantev = BUFIO_WANT_READ;
288 6be81433 2024-04-14 op return (-1);
289 6be81433 2024-04-14 op case TLS_WANT_POLLOUT:
290 6be81433 2024-04-14 op errno = EAGAIN;
291 6be81433 2024-04-14 op bio->wantev = BUFIO_WANT_WRITE;
292 6be81433 2024-04-14 op return (-1);
293 6be81433 2024-04-14 op default:
294 6be81433 2024-04-14 op return (-1);
295 6be81433 2024-04-14 op }
296 6be81433 2024-04-14 op #else
297 6be81433 2024-04-14 op errno = EINVAL;
298 6be81433 2024-04-14 op return (-1);
299 6be81433 2024-04-14 op #endif
300 6be81433 2024-04-14 op }
301 6be81433 2024-04-14 op
302 b8a11905 2023-08-31 op ssize_t
303 b8a11905 2023-08-31 op bufio_read(struct bufio *bio)
304 b8a11905 2023-08-31 op {
305 6be81433 2024-04-14 op struct buf *rbuf = &bio->rbuf;
306 b8a11905 2023-08-31 op ssize_t r;
307 b8a11905 2023-08-31 op
308 b8a11905 2023-08-31 op assert(rbuf->cap >= rbuf->len);
309 b8a11905 2023-08-31 op if (rbuf->cap - rbuf->len < BIO_CHUNK) {
310 b8a11905 2023-08-31 op if (buf_grow(rbuf) == -1)
311 b8a11905 2023-08-31 op return (-1);
312 b8a11905 2023-08-31 op }
313 b8a11905 2023-08-31 op
314 6be81433 2024-04-14 op #ifndef BUFIO_WITHOUT_TLS
315 6be81433 2024-04-14 op if (bio->ctx) {
316 6be81433 2024-04-14 op r = tls_read(bio->ctx, rbuf->buf + rbuf->len,
317 6be81433 2024-04-14 op rbuf->cap - rbuf->len);
318 6be81433 2024-04-14 op switch (r) {
319 6be81433 2024-04-14 op case TLS_WANT_POLLIN:
320 6be81433 2024-04-14 op errno = EAGAIN;
321 6be81433 2024-04-14 op bio->wantev = BUFIO_WANT_READ;
322 6be81433 2024-04-14 op return (-1);
323 6be81433 2024-04-14 op case TLS_WANT_POLLOUT:
324 6be81433 2024-04-14 op errno = EAGAIN;
325 6be81433 2024-04-14 op bio->wantev = BUFIO_WANT_WRITE;
326 6be81433 2024-04-14 op return (-1);
327 6be81433 2024-04-14 op case -1:
328 6be81433 2024-04-14 op return (-1);
329 6be81433 2024-04-14 op default:
330 6be81433 2024-04-14 op bio->wantev = 0;
331 6be81433 2024-04-14 op rbuf->len += r;
332 6be81433 2024-04-14 op return (r);
333 6be81433 2024-04-14 op }
334 6be81433 2024-04-14 op }
335 6be81433 2024-04-14 op #endif
336 6be81433 2024-04-14 op
337 b8a11905 2023-08-31 op r = read(bio->fd, rbuf->buf + rbuf->len, rbuf->cap - rbuf->len);
338 b8a11905 2023-08-31 op if (r == -1)
339 b8a11905 2023-08-31 op return (-1);
340 b8a11905 2023-08-31 op rbuf->len += r;
341 b8a11905 2023-08-31 op return (r);
342 b8a11905 2023-08-31 op }
343 b8a11905 2023-08-31 op
344 d48ffc66 2023-08-31 op size_t
345 d48ffc66 2023-08-31 op bufio_drain(struct bufio *bio, void *d, size_t len)
346 d48ffc66 2023-08-31 op {
347 6be81433 2024-04-14 op struct buf *rbuf = &bio->rbuf;
348 d48ffc66 2023-08-31 op
349 d48ffc66 2023-08-31 op if (len > rbuf->len)
350 d48ffc66 2023-08-31 op len = rbuf->len;
351 d48ffc66 2023-08-31 op memcpy(d, rbuf->buf, len);
352 d48ffc66 2023-08-31 op buf_drain(rbuf, len);
353 d48ffc66 2023-08-31 op return (len);
354 d48ffc66 2023-08-31 op }
355 d48ffc66 2023-08-31 op
356 b8a11905 2023-08-31 op ssize_t
357 b8a11905 2023-08-31 op bufio_write(struct bufio *bio)
358 b8a11905 2023-08-31 op {
359 6be81433 2024-04-14 op struct buf *wbuf = &bio->wbuf;
360 b8a11905 2023-08-31 op ssize_t w;
361 b8a11905 2023-08-31 op
362 6be81433 2024-04-14 op #ifndef BUFIO_WITHOUT_TLS
363 6be81433 2024-04-14 op if (bio->ctx) {
364 6be81433 2024-04-14 op switch (w = tls_write(bio->ctx, wbuf->buf, wbuf->len)) {
365 6be81433 2024-04-14 op case TLS_WANT_POLLIN:
366 6be81433 2024-04-14 op errno = EAGAIN;
367 6be81433 2024-04-14 op bio->wantev = BUFIO_WANT_READ;
368 6be81433 2024-04-14 op return (-1);
369 6be81433 2024-04-14 op case TLS_WANT_POLLOUT:
370 6be81433 2024-04-14 op errno = EAGAIN;
371 6be81433 2024-04-14 op bio->wantev = BUFIO_WANT_WRITE;
372 6be81433 2024-04-14 op return (-1);
373 6be81433 2024-04-14 op case -1:
374 6be81433 2024-04-14 op return (-1);
375 6be81433 2024-04-14 op default:
376 6be81433 2024-04-14 op bio->wantev = 0;
377 6be81433 2024-04-14 op buf_drain(wbuf, w);
378 6be81433 2024-04-14 op return (w);
379 6be81433 2024-04-14 op }
380 6be81433 2024-04-14 op }
381 6be81433 2024-04-14 op #endif
382 6be81433 2024-04-14 op
383 b8a11905 2023-08-31 op w = write(bio->fd, wbuf->buf, wbuf->len);
384 b8a11905 2023-08-31 op if (w == -1)
385 b8a11905 2023-08-31 op return (-1);
386 b8a11905 2023-08-31 op buf_drain(wbuf, w);
387 b8a11905 2023-08-31 op return (w);
388 b8a11905 2023-08-31 op }
389 b8a11905 2023-08-31 op
390 d48ffc66 2023-08-31 op static int
391 d48ffc66 2023-08-31 op bufio_append(struct bufio *bio, const void *d, size_t len)
392 b8a11905 2023-08-31 op {
393 6be81433 2024-04-14 op struct buf *wbuf = &bio->wbuf;
394 b8a11905 2023-08-31 op
395 d48ffc66 2023-08-31 op if (len == 0)
396 d48ffc66 2023-08-31 op return (0);
397 d48ffc66 2023-08-31 op
398 b8a11905 2023-08-31 op while (wbuf->cap - wbuf->len < len) {
399 b8a11905 2023-08-31 op if (buf_grow(wbuf) == -1)
400 b8a11905 2023-08-31 op return (-1);
401 b8a11905 2023-08-31 op }
402 b8a11905 2023-08-31 op
403 b8a11905 2023-08-31 op memcpy(wbuf->buf + wbuf->len, d, len);
404 b8a11905 2023-08-31 op wbuf->len += len;
405 b8a11905 2023-08-31 op return (0);
406 b8a11905 2023-08-31 op }
407 b8a11905 2023-08-31 op
408 b8a11905 2023-08-31 op int
409 d48ffc66 2023-08-31 op bufio_compose(struct bufio *bio, const void *d, size_t len)
410 d48ffc66 2023-08-31 op {
411 d48ffc66 2023-08-31 op char n[16];
412 d48ffc66 2023-08-31 op int r;
413 d48ffc66 2023-08-31 op
414 d48ffc66 2023-08-31 op if (bio->chunked) {
415 d48ffc66 2023-08-31 op r = snprintf(n, sizeof(n), "%zx\r\n", len);
416 d48ffc66 2023-08-31 op if (r < 0 || (size_t)r >= sizeof(n))
417 d48ffc66 2023-08-31 op return (-1);
418 d48ffc66 2023-08-31 op if (bufio_append(bio, n, r) == -1)
419 d48ffc66 2023-08-31 op return (-1);
420 d48ffc66 2023-08-31 op }
421 d48ffc66 2023-08-31 op
422 d48ffc66 2023-08-31 op if (bufio_append(bio, d, len) == -1)
423 d48ffc66 2023-08-31 op return (-1);
424 d48ffc66 2023-08-31 op
425 d48ffc66 2023-08-31 op if (bio->chunked)
426 d48ffc66 2023-08-31 op return bufio_append(bio, "\r\n", 2);
427 d48ffc66 2023-08-31 op
428 d48ffc66 2023-08-31 op return (0);
429 d48ffc66 2023-08-31 op }
430 d48ffc66 2023-08-31 op
431 d48ffc66 2023-08-31 op int
432 b8a11905 2023-08-31 op bufio_compose_str(struct bufio *bio, const char *str)
433 b8a11905 2023-08-31 op {
434 b8a11905 2023-08-31 op return (bufio_compose(bio, str, strlen(str)));
435 b8a11905 2023-08-31 op }
436 b8a11905 2023-08-31 op
437 b8a11905 2023-08-31 op int
438 b8a11905 2023-08-31 op bufio_compose_fmt(struct bufio *bio, const char *fmt, ...)
439 b8a11905 2023-08-31 op {
440 b8a11905 2023-08-31 op va_list ap;
441 b8a11905 2023-08-31 op char *str;
442 b8a11905 2023-08-31 op int r;
443 b8a11905 2023-08-31 op
444 b8a11905 2023-08-31 op va_start(ap, fmt);
445 b8a11905 2023-08-31 op r = vasprintf(&str, fmt, ap);
446 b8a11905 2023-08-31 op va_end(ap);
447 b8a11905 2023-08-31 op
448 b8a11905 2023-08-31 op if (r == -1)
449 b8a11905 2023-08-31 op return (-1);
450 b8a11905 2023-08-31 op r = bufio_compose(bio, str, r);
451 b8a11905 2023-08-31 op free(str);
452 b8a11905 2023-08-31 op return (r);
453 b8a11905 2023-08-31 op }
454 6be81433 2024-04-14 op
455 6be81433 2024-04-14 op void
456 6be81433 2024-04-14 op bufio_rewind_cursor(struct bufio *bio)
457 6be81433 2024-04-14 op {
458 6be81433 2024-04-14 op bio->rbuf.cur = 0;
459 6be81433 2024-04-14 op }
460 6be81433 2024-04-14 op
461 6be81433 2024-04-14 op int
462 6be81433 2024-04-14 op bufio_get_cb(void *d)
463 6be81433 2024-04-14 op {
464 6be81433 2024-04-14 op struct bufio *bio = d;
465 6be81433 2024-04-14 op struct buf *rbuf = &bio->rbuf;
466 6be81433 2024-04-14 op
467 6be81433 2024-04-14 op if (rbuf->cur >= rbuf->len)
468 6be81433 2024-04-14 op return (EOF);
469 6be81433 2024-04-14 op return (rbuf->buf[rbuf->cur++]);
470 6be81433 2024-04-14 op }
471 6be81433 2024-04-14 op
472 6be81433 2024-04-14 op int
473 6be81433 2024-04-14 op bufio_peek_cb(void *d)
474 6be81433 2024-04-14 op {
475 6be81433 2024-04-14 op struct bufio *bio = d;
476 6be81433 2024-04-14 op struct buf *rbuf = &bio->rbuf;
477 6be81433 2024-04-14 op
478 6be81433 2024-04-14 op if (rbuf->cur >= rbuf->len)
479 6be81433 2024-04-14 op return (EOF);
480 6be81433 2024-04-14 op return (rbuf->buf[rbuf->cur]);
481 6be81433 2024-04-14 op }