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 a58e44b0 2024-03-30 thomas
28 a58e44b0 2024-03-30 thomas #include "got_compat.h"
29 94a3f4e9 2024-03-30 thomas
30 94a3f4e9 2024-03-30 thomas #include <assert.h>
31 94a3f4e9 2024-03-30 thomas #include <errno.h>
32 94a3f4e9 2024-03-30 thomas #include <stdarg.h>
33 94a3f4e9 2024-03-30 thomas #include <stdint.h>
34 94a3f4e9 2024-03-30 thomas #include <stdio.h>
35 94a3f4e9 2024-03-30 thomas #include <stdlib.h>
36 94a3f4e9 2024-03-30 thomas #include <tls.h>
37 a58e44b0 2024-03-30 thomas #include <string.h>
38 94a3f4e9 2024-03-30 thomas #include <unistd.h>
39 94a3f4e9 2024-03-30 thomas
40 94a3f4e9 2024-03-30 thomas #include "bufio.h"
41 94a3f4e9 2024-03-30 thomas
42 94a3f4e9 2024-03-30 thomas int
43 94a3f4e9 2024-03-30 thomas buf_init(struct buf *buf)
44 94a3f4e9 2024-03-30 thomas {
45 94a3f4e9 2024-03-30 thomas const size_t cap = BIO_CHUNK;
46 94a3f4e9 2024-03-30 thomas
47 94a3f4e9 2024-03-30 thomas memset(buf, 0, sizeof(*buf));
48 94a3f4e9 2024-03-30 thomas if ((buf->buf = malloc(cap)) == NULL)
49 94a3f4e9 2024-03-30 thomas return (-1);
50 94a3f4e9 2024-03-30 thomas buf->cap = cap;
51 94a3f4e9 2024-03-30 thomas return (0);
52 94a3f4e9 2024-03-30 thomas }
53 94a3f4e9 2024-03-30 thomas
54 94a3f4e9 2024-03-30 thomas static int
55 94a3f4e9 2024-03-30 thomas buf_grow(struct buf *buf)
56 94a3f4e9 2024-03-30 thomas {
57 94a3f4e9 2024-03-30 thomas size_t newcap;
58 94a3f4e9 2024-03-30 thomas void *t;
59 94a3f4e9 2024-03-30 thomas
60 94a3f4e9 2024-03-30 thomas newcap = buf->cap + BIO_CHUNK;
61 94a3f4e9 2024-03-30 thomas t = realloc(buf->buf, newcap);
62 94a3f4e9 2024-03-30 thomas if (t == NULL)
63 94a3f4e9 2024-03-30 thomas return (-1);
64 94a3f4e9 2024-03-30 thomas buf->buf = t;
65 94a3f4e9 2024-03-30 thomas buf->cap = newcap;
66 94a3f4e9 2024-03-30 thomas return (0);
67 94a3f4e9 2024-03-30 thomas }
68 94a3f4e9 2024-03-30 thomas
69 94a3f4e9 2024-03-30 thomas int
70 94a3f4e9 2024-03-30 thomas buf_has_line(struct buf *buf, const char *nl)
71 94a3f4e9 2024-03-30 thomas {
72 94a3f4e9 2024-03-30 thomas return (memmem(buf->buf, buf->len, nl, strlen(nl)) != NULL);
73 94a3f4e9 2024-03-30 thomas }
74 94a3f4e9 2024-03-30 thomas
75 94a3f4e9 2024-03-30 thomas char *
76 94a3f4e9 2024-03-30 thomas buf_getdelim(struct buf *buf, const char *nl, size_t *len)
77 94a3f4e9 2024-03-30 thomas {
78 94a3f4e9 2024-03-30 thomas uint8_t *endl;
79 94a3f4e9 2024-03-30 thomas size_t nlen;
80 94a3f4e9 2024-03-30 thomas
81 94a3f4e9 2024-03-30 thomas *len = 0;
82 94a3f4e9 2024-03-30 thomas
83 94a3f4e9 2024-03-30 thomas nlen = strlen(nl);
84 94a3f4e9 2024-03-30 thomas if ((endl = memmem(buf->buf, buf->len, nl, nlen)) == NULL)
85 94a3f4e9 2024-03-30 thomas return (NULL);
86 94a3f4e9 2024-03-30 thomas *len = endl + nlen - buf->buf;
87 94a3f4e9 2024-03-30 thomas *endl = '\0';
88 94a3f4e9 2024-03-30 thomas return (buf->buf);
89 94a3f4e9 2024-03-30 thomas }
90 94a3f4e9 2024-03-30 thomas
91 94a3f4e9 2024-03-30 thomas void
92 94a3f4e9 2024-03-30 thomas buf_drain(struct buf *buf, size_t l)
93 94a3f4e9 2024-03-30 thomas {
94 94a3f4e9 2024-03-30 thomas buf->cur = 0;
95 94a3f4e9 2024-03-30 thomas
96 94a3f4e9 2024-03-30 thomas if (l >= buf->len) {
97 94a3f4e9 2024-03-30 thomas buf->len = 0;
98 94a3f4e9 2024-03-30 thomas return;
99 94a3f4e9 2024-03-30 thomas }
100 94a3f4e9 2024-03-30 thomas
101 94a3f4e9 2024-03-30 thomas memmove(buf->buf, buf->buf + l, buf->len - l);
102 94a3f4e9 2024-03-30 thomas buf->len -= l;
103 94a3f4e9 2024-03-30 thomas }
104 94a3f4e9 2024-03-30 thomas
105 94a3f4e9 2024-03-30 thomas void
106 94a3f4e9 2024-03-30 thomas buf_drain_line(struct buf *buf, const char *nl)
107 94a3f4e9 2024-03-30 thomas {
108 94a3f4e9 2024-03-30 thomas uint8_t *endln;
109 94a3f4e9 2024-03-30 thomas size_t nlen;
110 94a3f4e9 2024-03-30 thomas
111 94a3f4e9 2024-03-30 thomas nlen = strlen(nl);
112 94a3f4e9 2024-03-30 thomas if ((endln = memmem(buf->buf, buf->len, nl, nlen)) == NULL)
113 94a3f4e9 2024-03-30 thomas return;
114 94a3f4e9 2024-03-30 thomas buf_drain(buf, endln + nlen - buf->buf);
115 94a3f4e9 2024-03-30 thomas }
116 94a3f4e9 2024-03-30 thomas
117 94a3f4e9 2024-03-30 thomas void
118 94a3f4e9 2024-03-30 thomas buf_free(struct buf *buf)
119 94a3f4e9 2024-03-30 thomas {
120 94a3f4e9 2024-03-30 thomas free(buf->buf);
121 94a3f4e9 2024-03-30 thomas memset(buf, 0, sizeof(*buf));
122 94a3f4e9 2024-03-30 thomas }
123 94a3f4e9 2024-03-30 thomas
124 94a3f4e9 2024-03-30 thomas int
125 94a3f4e9 2024-03-30 thomas bufio_init(struct bufio *bio)
126 94a3f4e9 2024-03-30 thomas {
127 94a3f4e9 2024-03-30 thomas memset(bio, 0, sizeof(*bio));
128 94a3f4e9 2024-03-30 thomas bio->fd = -1;
129 94a3f4e9 2024-03-30 thomas
130 94a3f4e9 2024-03-30 thomas if (buf_init(&bio->wbuf) == -1)
131 94a3f4e9 2024-03-30 thomas return (-1);
132 94a3f4e9 2024-03-30 thomas if (buf_init(&bio->rbuf) == -1) {
133 94a3f4e9 2024-03-30 thomas buf_free(&bio->wbuf);
134 94a3f4e9 2024-03-30 thomas return (-1);
135 94a3f4e9 2024-03-30 thomas }
136 94a3f4e9 2024-03-30 thomas return (0);
137 94a3f4e9 2024-03-30 thomas }
138 94a3f4e9 2024-03-30 thomas
139 94a3f4e9 2024-03-30 thomas void
140 94a3f4e9 2024-03-30 thomas bufio_free(struct bufio *bio)
141 94a3f4e9 2024-03-30 thomas {
142 94a3f4e9 2024-03-30 thomas if (bio->ctx)
143 94a3f4e9 2024-03-30 thomas tls_free(bio->ctx);
144 94a3f4e9 2024-03-30 thomas bio->ctx = NULL;
145 94a3f4e9 2024-03-30 thomas
146 94a3f4e9 2024-03-30 thomas if (bio->fd != -1)
147 94a3f4e9 2024-03-30 thomas close(bio->fd);
148 94a3f4e9 2024-03-30 thomas bio->fd = -1;
149 94a3f4e9 2024-03-30 thomas
150 94a3f4e9 2024-03-30 thomas buf_free(&bio->rbuf);
151 94a3f4e9 2024-03-30 thomas buf_free(&bio->wbuf);
152 94a3f4e9 2024-03-30 thomas }
153 94a3f4e9 2024-03-30 thomas
154 94a3f4e9 2024-03-30 thomas int
155 94a3f4e9 2024-03-30 thomas bufio_close(struct bufio *bio)
156 94a3f4e9 2024-03-30 thomas {
157 94a3f4e9 2024-03-30 thomas if (bio->ctx == NULL)
158 94a3f4e9 2024-03-30 thomas return (0);
159 94a3f4e9 2024-03-30 thomas
160 94a3f4e9 2024-03-30 thomas switch (tls_close(bio->ctx)) {
161 94a3f4e9 2024-03-30 thomas case 0:
162 94a3f4e9 2024-03-30 thomas return 0;
163 94a3f4e9 2024-03-30 thomas case TLS_WANT_POLLIN:
164 94a3f4e9 2024-03-30 thomas errno = EAGAIN;
165 94a3f4e9 2024-03-30 thomas bio->wantev = BUFIO_WANT_READ;
166 94a3f4e9 2024-03-30 thomas return (-1);
167 94a3f4e9 2024-03-30 thomas case TLS_WANT_POLLOUT:
168 94a3f4e9 2024-03-30 thomas errno = EAGAIN;
169 94a3f4e9 2024-03-30 thomas bio->wantev = BUFIO_WANT_WRITE;
170 94a3f4e9 2024-03-30 thomas return (-1);
171 94a3f4e9 2024-03-30 thomas default:
172 94a3f4e9 2024-03-30 thomas return (-1);
173 94a3f4e9 2024-03-30 thomas }
174 94a3f4e9 2024-03-30 thomas }
175 94a3f4e9 2024-03-30 thomas
176 94a3f4e9 2024-03-30 thomas int
177 94a3f4e9 2024-03-30 thomas bufio_reset(struct bufio *bio)
178 94a3f4e9 2024-03-30 thomas {
179 94a3f4e9 2024-03-30 thomas bufio_free(bio);
180 94a3f4e9 2024-03-30 thomas return (bufio_init(bio));
181 94a3f4e9 2024-03-30 thomas }
182 94a3f4e9 2024-03-30 thomas
183 94a3f4e9 2024-03-30 thomas void
184 94a3f4e9 2024-03-30 thomas bufio_set_fd(struct bufio *bio, int fd)
185 94a3f4e9 2024-03-30 thomas {
186 94a3f4e9 2024-03-30 thomas bio->fd = fd;
187 94a3f4e9 2024-03-30 thomas }
188 94a3f4e9 2024-03-30 thomas
189 94a3f4e9 2024-03-30 thomas int
190 94a3f4e9 2024-03-30 thomas bufio_starttls(struct bufio *bio, const char *host, int insecure,
191 94a3f4e9 2024-03-30 thomas const uint8_t *cert, size_t certlen, const uint8_t *key, size_t keylen)
192 94a3f4e9 2024-03-30 thomas {
193 94a3f4e9 2024-03-30 thomas struct tls_config *conf;
194 94a3f4e9 2024-03-30 thomas
195 94a3f4e9 2024-03-30 thomas if ((conf = tls_config_new()) == NULL)
196 94a3f4e9 2024-03-30 thomas return (-1);
197 94a3f4e9 2024-03-30 thomas
198 94a3f4e9 2024-03-30 thomas if (insecure) {
199 94a3f4e9 2024-03-30 thomas tls_config_insecure_noverifycert(conf);
200 94a3f4e9 2024-03-30 thomas tls_config_insecure_noverifyname(conf);
201 94a3f4e9 2024-03-30 thomas tls_config_insecure_noverifytime(conf);
202 94a3f4e9 2024-03-30 thomas }
203 94a3f4e9 2024-03-30 thomas
204 94a3f4e9 2024-03-30 thomas if (cert && tls_config_set_keypair_mem(conf, cert, certlen,
205 94a3f4e9 2024-03-30 thomas key, keylen) == -1) {
206 94a3f4e9 2024-03-30 thomas tls_config_free(conf);
207 94a3f4e9 2024-03-30 thomas return (-1);
208 94a3f4e9 2024-03-30 thomas }
209 94a3f4e9 2024-03-30 thomas
210 94a3f4e9 2024-03-30 thomas if ((bio->ctx = tls_client()) == NULL) {
211 94a3f4e9 2024-03-30 thomas tls_config_free(conf);
212 94a3f4e9 2024-03-30 thomas return (-1);
213 94a3f4e9 2024-03-30 thomas }
214 94a3f4e9 2024-03-30 thomas
215 94a3f4e9 2024-03-30 thomas if (tls_configure(bio->ctx, conf) == -1) {
216 94a3f4e9 2024-03-30 thomas tls_config_free(conf);
217 94a3f4e9 2024-03-30 thomas return (-1);
218 94a3f4e9 2024-03-30 thomas }
219 94a3f4e9 2024-03-30 thomas
220 94a3f4e9 2024-03-30 thomas tls_config_free(conf);
221 94a3f4e9 2024-03-30 thomas
222 94a3f4e9 2024-03-30 thomas if (tls_connect_socket(bio->ctx, bio->fd, host) == -1)
223 94a3f4e9 2024-03-30 thomas return (-1);
224 94a3f4e9 2024-03-30 thomas
225 94a3f4e9 2024-03-30 thomas return (0);
226 94a3f4e9 2024-03-30 thomas }
227 94a3f4e9 2024-03-30 thomas
228 94a3f4e9 2024-03-30 thomas int
229 94a3f4e9 2024-03-30 thomas bufio_ev(struct bufio *bio)
230 94a3f4e9 2024-03-30 thomas {
231 94a3f4e9 2024-03-30 thomas short ev;
232 94a3f4e9 2024-03-30 thomas
233 94a3f4e9 2024-03-30 thomas if (bio->wantev)
234 94a3f4e9 2024-03-30 thomas return (bio->wantev);
235 94a3f4e9 2024-03-30 thomas
236 94a3f4e9 2024-03-30 thomas ev = BUFIO_WANT_READ;
237 94a3f4e9 2024-03-30 thomas if (bio->wbuf.len != 0)
238 94a3f4e9 2024-03-30 thomas ev |= BUFIO_WANT_WRITE;
239 94a3f4e9 2024-03-30 thomas
240 94a3f4e9 2024-03-30 thomas return (ev);
241 94a3f4e9 2024-03-30 thomas }
242 94a3f4e9 2024-03-30 thomas
243 94a3f4e9 2024-03-30 thomas int
244 94a3f4e9 2024-03-30 thomas bufio_handshake(struct bufio *bio)
245 94a3f4e9 2024-03-30 thomas {
246 94a3f4e9 2024-03-30 thomas if (bio->ctx == NULL) {
247 94a3f4e9 2024-03-30 thomas errno = EINVAL;
248 94a3f4e9 2024-03-30 thomas return (-1);
249 94a3f4e9 2024-03-30 thomas }
250 94a3f4e9 2024-03-30 thomas
251 94a3f4e9 2024-03-30 thomas switch (tls_handshake(bio->ctx)) {
252 94a3f4e9 2024-03-30 thomas case 0:
253 94a3f4e9 2024-03-30 thomas return (0);
254 94a3f4e9 2024-03-30 thomas case TLS_WANT_POLLIN:
255 94a3f4e9 2024-03-30 thomas errno = EAGAIN;
256 94a3f4e9 2024-03-30 thomas bio->wantev = BUFIO_WANT_READ;
257 94a3f4e9 2024-03-30 thomas return (-1);
258 94a3f4e9 2024-03-30 thomas case TLS_WANT_POLLOUT:
259 94a3f4e9 2024-03-30 thomas errno = EAGAIN;
260 94a3f4e9 2024-03-30 thomas bio->wantev = BUFIO_WANT_WRITE;
261 94a3f4e9 2024-03-30 thomas return (-1);
262 94a3f4e9 2024-03-30 thomas default:
263 94a3f4e9 2024-03-30 thomas return (-1);
264 94a3f4e9 2024-03-30 thomas }
265 94a3f4e9 2024-03-30 thomas }
266 94a3f4e9 2024-03-30 thomas
267 94a3f4e9 2024-03-30 thomas ssize_t
268 94a3f4e9 2024-03-30 thomas bufio_read(struct bufio *bio)
269 94a3f4e9 2024-03-30 thomas {
270 94a3f4e9 2024-03-30 thomas struct buf *rbuf = &bio->rbuf;
271 94a3f4e9 2024-03-30 thomas ssize_t r;
272 94a3f4e9 2024-03-30 thomas
273 94a3f4e9 2024-03-30 thomas assert(rbuf->cap >= rbuf->len);
274 94a3f4e9 2024-03-30 thomas if (rbuf->cap - rbuf->len < BIO_CHUNK) {
275 94a3f4e9 2024-03-30 thomas if (buf_grow(rbuf) == -1)
276 94a3f4e9 2024-03-30 thomas return (-1);
277 94a3f4e9 2024-03-30 thomas }
278 94a3f4e9 2024-03-30 thomas
279 94a3f4e9 2024-03-30 thomas if (bio->ctx) {
280 94a3f4e9 2024-03-30 thomas r = tls_read(bio->ctx, rbuf->buf + rbuf->len,
281 94a3f4e9 2024-03-30 thomas rbuf->cap - rbuf->len);
282 94a3f4e9 2024-03-30 thomas switch (r) {
283 94a3f4e9 2024-03-30 thomas case TLS_WANT_POLLIN:
284 94a3f4e9 2024-03-30 thomas errno = EAGAIN;
285 94a3f4e9 2024-03-30 thomas bio->wantev = BUFIO_WANT_READ;
286 94a3f4e9 2024-03-30 thomas return (-1);
287 94a3f4e9 2024-03-30 thomas case TLS_WANT_POLLOUT:
288 94a3f4e9 2024-03-30 thomas errno = EAGAIN;
289 94a3f4e9 2024-03-30 thomas bio->wantev = BUFIO_WANT_WRITE;
290 94a3f4e9 2024-03-30 thomas return (-1);
291 94a3f4e9 2024-03-30 thomas case -1:
292 94a3f4e9 2024-03-30 thomas return (-1);
293 94a3f4e9 2024-03-30 thomas default:
294 94a3f4e9 2024-03-30 thomas bio->wantev = 0;
295 94a3f4e9 2024-03-30 thomas rbuf->len += r;
296 94a3f4e9 2024-03-30 thomas return (r);
297 94a3f4e9 2024-03-30 thomas }
298 94a3f4e9 2024-03-30 thomas }
299 94a3f4e9 2024-03-30 thomas
300 94a3f4e9 2024-03-30 thomas r = read(bio->fd, rbuf->buf + rbuf->len, rbuf->cap - rbuf->len);
301 94a3f4e9 2024-03-30 thomas if (r == -1)
302 94a3f4e9 2024-03-30 thomas return (-1);
303 94a3f4e9 2024-03-30 thomas rbuf->len += r;
304 94a3f4e9 2024-03-30 thomas return (r);
305 94a3f4e9 2024-03-30 thomas }
306 94a3f4e9 2024-03-30 thomas
307 94a3f4e9 2024-03-30 thomas size_t
308 94a3f4e9 2024-03-30 thomas bufio_drain(struct bufio *bio, void *d, size_t len)
309 94a3f4e9 2024-03-30 thomas {
310 94a3f4e9 2024-03-30 thomas struct buf *rbuf = &bio->rbuf;
311 94a3f4e9 2024-03-30 thomas
312 94a3f4e9 2024-03-30 thomas if (len > rbuf->len)
313 94a3f4e9 2024-03-30 thomas len = rbuf->len;
314 94a3f4e9 2024-03-30 thomas memcpy(d, rbuf->buf, len);
315 94a3f4e9 2024-03-30 thomas buf_drain(rbuf, len);
316 94a3f4e9 2024-03-30 thomas return (len);
317 94a3f4e9 2024-03-30 thomas }
318 94a3f4e9 2024-03-30 thomas
319 94a3f4e9 2024-03-30 thomas ssize_t
320 94a3f4e9 2024-03-30 thomas bufio_write(struct bufio *bio)
321 94a3f4e9 2024-03-30 thomas {
322 94a3f4e9 2024-03-30 thomas struct buf *wbuf = &bio->wbuf;
323 94a3f4e9 2024-03-30 thomas ssize_t w;
324 94a3f4e9 2024-03-30 thomas
325 94a3f4e9 2024-03-30 thomas if (bio->ctx) {
326 94a3f4e9 2024-03-30 thomas switch (w = tls_write(bio->ctx, wbuf->buf, wbuf->len)) {
327 94a3f4e9 2024-03-30 thomas case TLS_WANT_POLLIN:
328 94a3f4e9 2024-03-30 thomas errno = EAGAIN;
329 94a3f4e9 2024-03-30 thomas bio->wantev = BUFIO_WANT_READ;
330 94a3f4e9 2024-03-30 thomas return (-1);
331 94a3f4e9 2024-03-30 thomas case TLS_WANT_POLLOUT:
332 94a3f4e9 2024-03-30 thomas errno = EAGAIN;
333 94a3f4e9 2024-03-30 thomas bio->wantev = BUFIO_WANT_WRITE;
334 94a3f4e9 2024-03-30 thomas return (-1);
335 94a3f4e9 2024-03-30 thomas case -1:
336 94a3f4e9 2024-03-30 thomas return (-1);
337 94a3f4e9 2024-03-30 thomas default:
338 94a3f4e9 2024-03-30 thomas bio->wantev = 0;
339 94a3f4e9 2024-03-30 thomas buf_drain(wbuf, w);
340 94a3f4e9 2024-03-30 thomas return (w);
341 94a3f4e9 2024-03-30 thomas }
342 94a3f4e9 2024-03-30 thomas }
343 94a3f4e9 2024-03-30 thomas
344 94a3f4e9 2024-03-30 thomas w = write(bio->fd, wbuf->buf, wbuf->len);
345 94a3f4e9 2024-03-30 thomas if (w == -1)
346 94a3f4e9 2024-03-30 thomas return (-1);
347 94a3f4e9 2024-03-30 thomas buf_drain(wbuf, w);
348 94a3f4e9 2024-03-30 thomas return (w);
349 94a3f4e9 2024-03-30 thomas }
350 94a3f4e9 2024-03-30 thomas
351 94a3f4e9 2024-03-30 thomas const char *
352 94a3f4e9 2024-03-30 thomas bufio_io_err(struct bufio *bio)
353 94a3f4e9 2024-03-30 thomas {
354 94a3f4e9 2024-03-30 thomas if (bio->ctx)
355 94a3f4e9 2024-03-30 thomas return tls_error(bio->ctx);
356 94a3f4e9 2024-03-30 thomas
357 94a3f4e9 2024-03-30 thomas return strerror(errno);
358 94a3f4e9 2024-03-30 thomas }
359 94a3f4e9 2024-03-30 thomas
360 94a3f4e9 2024-03-30 thomas int
361 94a3f4e9 2024-03-30 thomas bufio_compose(struct bufio *bio, const void *d, size_t len)
362 94a3f4e9 2024-03-30 thomas {
363 94a3f4e9 2024-03-30 thomas struct buf *wbuf = &bio->wbuf;
364 94a3f4e9 2024-03-30 thomas
365 94a3f4e9 2024-03-30 thomas while (wbuf->cap - wbuf->len < len) {
366 94a3f4e9 2024-03-30 thomas if (buf_grow(wbuf) == -1)
367 94a3f4e9 2024-03-30 thomas return (-1);
368 94a3f4e9 2024-03-30 thomas }
369 94a3f4e9 2024-03-30 thomas
370 94a3f4e9 2024-03-30 thomas memcpy(wbuf->buf + wbuf->len, d, len);
371 94a3f4e9 2024-03-30 thomas wbuf->len += len;
372 94a3f4e9 2024-03-30 thomas return (0);
373 94a3f4e9 2024-03-30 thomas }
374 94a3f4e9 2024-03-30 thomas
375 94a3f4e9 2024-03-30 thomas int
376 94a3f4e9 2024-03-30 thomas bufio_compose_str(struct bufio *bio, const char *str)
377 94a3f4e9 2024-03-30 thomas {
378 94a3f4e9 2024-03-30 thomas return (bufio_compose(bio, str, strlen(str)));
379 94a3f4e9 2024-03-30 thomas }
380 94a3f4e9 2024-03-30 thomas
381 94a3f4e9 2024-03-30 thomas int
382 94a3f4e9 2024-03-30 thomas bufio_compose_fmt(struct bufio *bio, const char *fmt, ...)
383 94a3f4e9 2024-03-30 thomas {
384 94a3f4e9 2024-03-30 thomas va_list ap;
385 94a3f4e9 2024-03-30 thomas char *str;
386 94a3f4e9 2024-03-30 thomas int r;
387 94a3f4e9 2024-03-30 thomas
388 94a3f4e9 2024-03-30 thomas va_start(ap, fmt);
389 94a3f4e9 2024-03-30 thomas r = vasprintf(&str, fmt, ap);
390 94a3f4e9 2024-03-30 thomas va_end(ap);
391 94a3f4e9 2024-03-30 thomas
392 94a3f4e9 2024-03-30 thomas if (r == -1)
393 94a3f4e9 2024-03-30 thomas return (-1);
394 94a3f4e9 2024-03-30 thomas r = bufio_compose(bio, str, r);
395 94a3f4e9 2024-03-30 thomas free(str);
396 94a3f4e9 2024-03-30 thomas return (r);
397 94a3f4e9 2024-03-30 thomas }
398 94a3f4e9 2024-03-30 thomas
399 94a3f4e9 2024-03-30 thomas void
400 94a3f4e9 2024-03-30 thomas bufio_rewind_cursor(struct bufio *bio)
401 94a3f4e9 2024-03-30 thomas {
402 94a3f4e9 2024-03-30 thomas bio->rbuf.cur = 0;
403 94a3f4e9 2024-03-30 thomas }
404 94a3f4e9 2024-03-30 thomas
405 94a3f4e9 2024-03-30 thomas int
406 94a3f4e9 2024-03-30 thomas bufio_get_cb(void *d)
407 94a3f4e9 2024-03-30 thomas {
408 94a3f4e9 2024-03-30 thomas struct bufio *bio = d;
409 94a3f4e9 2024-03-30 thomas struct buf *rbuf = &bio->rbuf;
410 94a3f4e9 2024-03-30 thomas
411 94a3f4e9 2024-03-30 thomas if (rbuf->cur >= rbuf->len)
412 94a3f4e9 2024-03-30 thomas return (EOF);
413 94a3f4e9 2024-03-30 thomas return (rbuf->buf[rbuf->cur++]);
414 94a3f4e9 2024-03-30 thomas }
415 94a3f4e9 2024-03-30 thomas
416 94a3f4e9 2024-03-30 thomas int
417 94a3f4e9 2024-03-30 thomas bufio_peek_cb(void *d)
418 94a3f4e9 2024-03-30 thomas {
419 94a3f4e9 2024-03-30 thomas struct bufio *bio = d;
420 94a3f4e9 2024-03-30 thomas struct buf *rbuf = &bio->rbuf;
421 94a3f4e9 2024-03-30 thomas
422 94a3f4e9 2024-03-30 thomas if (rbuf->cur >= rbuf->len)
423 94a3f4e9 2024-03-30 thomas return (EOF);
424 94a3f4e9 2024-03-30 thomas return (rbuf->buf[rbuf->cur]);
425 94a3f4e9 2024-03-30 thomas }