Blame


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