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 <poll.h>
31 b8a11905 2023-08-31 op #include <stdarg.h>
32 cc89e101 2023-09-02 op #include <stdint.h>
33 b8a11905 2023-08-31 op #include <stdio.h>
34 b8a11905 2023-08-31 op #include <stdlib.h>
35 b8a11905 2023-08-31 op #include <string.h>
36 b8a11905 2023-08-31 op #include <unistd.h>
37 b8a11905 2023-08-31 op
38 b8a11905 2023-08-31 op #include "bufio.h"
39 b8a11905 2023-08-31 op
40 b8a11905 2023-08-31 op int
41 b8a11905 2023-08-31 op buf_init(struct buffer *buf)
42 b8a11905 2023-08-31 op {
43 b8a11905 2023-08-31 op const size_t cap = BIO_CHUNK;
44 b8a11905 2023-08-31 op
45 b8a11905 2023-08-31 op memset(buf, 0, sizeof(*buf));
46 b8a11905 2023-08-31 op if ((buf->buf = malloc(cap)) == NULL)
47 b8a11905 2023-08-31 op return (-1);
48 b8a11905 2023-08-31 op buf->cap = cap;
49 b8a11905 2023-08-31 op return (0);
50 b8a11905 2023-08-31 op }
51 b8a11905 2023-08-31 op
52 b8a11905 2023-08-31 op static int
53 b8a11905 2023-08-31 op buf_grow(struct buffer *buf)
54 b8a11905 2023-08-31 op {
55 b8a11905 2023-08-31 op size_t newcap;
56 b8a11905 2023-08-31 op void *t;
57 b8a11905 2023-08-31 op
58 b8a11905 2023-08-31 op newcap = buf->cap + BIO_CHUNK;
59 b8a11905 2023-08-31 op t = realloc(buf->buf, newcap);
60 b8a11905 2023-08-31 op if (t == NULL)
61 b8a11905 2023-08-31 op return (-1);
62 b8a11905 2023-08-31 op buf->buf = t;
63 b8a11905 2023-08-31 op buf->cap = newcap;
64 2216d3fb 2023-09-07 op return (0);
65 2216d3fb 2023-09-07 op }
66 2216d3fb 2023-09-07 op
67 2216d3fb 2023-09-07 op int
68 2216d3fb 2023-09-07 op buf_write(struct buffer *buf, const void *d, size_t len)
69 2216d3fb 2023-09-07 op {
70 d20f7b51 2023-09-08 op while (buf->len + len > buf->cap) {
71 2216d3fb 2023-09-07 op if (buf_grow(buf) == -1)
72 2216d3fb 2023-09-07 op return (-1);
73 2216d3fb 2023-09-07 op }
74 2216d3fb 2023-09-07 op memcpy(buf->buf + buf->len, d, len);
75 2216d3fb 2023-09-07 op buf->len += len;
76 b8a11905 2023-08-31 op return (0);
77 b8a11905 2023-08-31 op }
78 b8a11905 2023-08-31 op
79 b8a11905 2023-08-31 op int
80 b8a11905 2023-08-31 op buf_has_line(struct buffer *buf, const char *nl)
81 b8a11905 2023-08-31 op {
82 b8a11905 2023-08-31 op return (memmem(buf->buf, buf->len, nl, strlen(nl)) != NULL);
83 b8a11905 2023-08-31 op }
84 b8a11905 2023-08-31 op
85 b8a11905 2023-08-31 op void
86 b8a11905 2023-08-31 op buf_drain(struct buffer *buf, size_t l)
87 b8a11905 2023-08-31 op {
88 b8a11905 2023-08-31 op if (l >= buf->len) {
89 b8a11905 2023-08-31 op buf->len = 0;
90 b8a11905 2023-08-31 op return;
91 b8a11905 2023-08-31 op }
92 b8a11905 2023-08-31 op
93 b8a11905 2023-08-31 op memmove(buf->buf, buf->buf + l, buf->len - l);
94 b8a11905 2023-08-31 op buf->len -= l;
95 b8a11905 2023-08-31 op }
96 b8a11905 2023-08-31 op
97 b8a11905 2023-08-31 op void
98 b8a11905 2023-08-31 op buf_drain_line(struct buffer *buf, const char *nl)
99 b8a11905 2023-08-31 op {
100 b8a11905 2023-08-31 op uint8_t *endln;
101 b8a11905 2023-08-31 op size_t nlen;
102 b8a11905 2023-08-31 op
103 b8a11905 2023-08-31 op nlen = strlen(nl);
104 b8a11905 2023-08-31 op if ((endln = memmem(buf->buf, buf->len, nl, nlen)) == NULL)
105 b8a11905 2023-08-31 op return;
106 b8a11905 2023-08-31 op buf_drain(buf, endln + nlen - buf->buf);
107 b8a11905 2023-08-31 op }
108 b8a11905 2023-08-31 op
109 b8a11905 2023-08-31 op void
110 b8a11905 2023-08-31 op buf_free(struct buffer *buf)
111 b8a11905 2023-08-31 op {
112 b8a11905 2023-08-31 op free(buf->buf);
113 b8a11905 2023-08-31 op memset(buf, 0, sizeof(*buf));
114 b8a11905 2023-08-31 op }
115 b8a11905 2023-08-31 op
116 b8a11905 2023-08-31 op int
117 b8a11905 2023-08-31 op bufio_init(struct bufio *bio)
118 b8a11905 2023-08-31 op {
119 b8a11905 2023-08-31 op memset(bio, 0, sizeof(*bio));
120 b8a11905 2023-08-31 op bio->fd = -1;
121 b8a11905 2023-08-31 op
122 b8a11905 2023-08-31 op if (buf_init(&bio->wbuf) == -1)
123 b8a11905 2023-08-31 op return (-1);
124 b8a11905 2023-08-31 op if (buf_init(&bio->rbuf) == -1) {
125 b8a11905 2023-08-31 op buf_free(&bio->wbuf);
126 b8a11905 2023-08-31 op return (-1);
127 b8a11905 2023-08-31 op }
128 b8a11905 2023-08-31 op return (0);
129 b8a11905 2023-08-31 op }
130 b8a11905 2023-08-31 op
131 d48ffc66 2023-08-31 op void
132 d48ffc66 2023-08-31 op bufio_free(struct bufio *bio)
133 b8a11905 2023-08-31 op {
134 b8a11905 2023-08-31 op if (bio->fd != -1)
135 b8a11905 2023-08-31 op close(bio->fd);
136 b8a11905 2023-08-31 op
137 b8a11905 2023-08-31 op buf_free(&bio->rbuf);
138 b8a11905 2023-08-31 op buf_free(&bio->wbuf);
139 d48ffc66 2023-08-31 op }
140 d48ffc66 2023-08-31 op
141 d48ffc66 2023-08-31 op int
142 d48ffc66 2023-08-31 op bufio_reset(struct bufio *bio)
143 d48ffc66 2023-08-31 op {
144 d48ffc66 2023-08-31 op bufio_free(bio);
145 b8a11905 2023-08-31 op return (bufio_init(bio));
146 b8a11905 2023-08-31 op }
147 b8a11905 2023-08-31 op
148 b8a11905 2023-08-31 op void
149 b8a11905 2023-08-31 op bufio_set_fd(struct bufio *bio, int fd)
150 b8a11905 2023-08-31 op {
151 b8a11905 2023-08-31 op bio->fd = fd;
152 b8a11905 2023-08-31 op }
153 b8a11905 2023-08-31 op
154 d48ffc66 2023-08-31 op void
155 d48ffc66 2023-08-31 op bufio_set_chunked(struct bufio *bio, int chunked)
156 d48ffc66 2023-08-31 op {
157 d48ffc66 2023-08-31 op bio->chunked = chunked;
158 d48ffc66 2023-08-31 op }
159 d48ffc66 2023-08-31 op
160 b8a11905 2023-08-31 op short
161 b8a11905 2023-08-31 op bufio_pollev(struct bufio *bio)
162 b8a11905 2023-08-31 op {
163 b8a11905 2023-08-31 op short ev;
164 b8a11905 2023-08-31 op
165 b8a11905 2023-08-31 op ev = POLLIN;
166 b8a11905 2023-08-31 op if (bio->wbuf.len != 0)
167 b8a11905 2023-08-31 op ev |= POLLOUT;
168 b8a11905 2023-08-31 op
169 b8a11905 2023-08-31 op return (ev);
170 b8a11905 2023-08-31 op }
171 b8a11905 2023-08-31 op
172 b8a11905 2023-08-31 op ssize_t
173 b8a11905 2023-08-31 op bufio_read(struct bufio *bio)
174 b8a11905 2023-08-31 op {
175 b8a11905 2023-08-31 op struct buffer *rbuf = &bio->rbuf;
176 b8a11905 2023-08-31 op ssize_t r;
177 b8a11905 2023-08-31 op
178 b8a11905 2023-08-31 op assert(rbuf->cap >= rbuf->len);
179 b8a11905 2023-08-31 op if (rbuf->cap - rbuf->len < BIO_CHUNK) {
180 b8a11905 2023-08-31 op if (buf_grow(rbuf) == -1)
181 b8a11905 2023-08-31 op return (-1);
182 b8a11905 2023-08-31 op }
183 b8a11905 2023-08-31 op
184 b8a11905 2023-08-31 op r = read(bio->fd, rbuf->buf + rbuf->len, rbuf->cap - rbuf->len);
185 b8a11905 2023-08-31 op if (r == -1)
186 b8a11905 2023-08-31 op return (-1);
187 b8a11905 2023-08-31 op rbuf->len += r;
188 b8a11905 2023-08-31 op return (r);
189 b8a11905 2023-08-31 op }
190 b8a11905 2023-08-31 op
191 d48ffc66 2023-08-31 op size_t
192 d48ffc66 2023-08-31 op bufio_drain(struct bufio *bio, void *d, size_t len)
193 d48ffc66 2023-08-31 op {
194 d48ffc66 2023-08-31 op struct buffer *rbuf = &bio->rbuf;
195 d48ffc66 2023-08-31 op
196 d48ffc66 2023-08-31 op if (len > rbuf->len)
197 d48ffc66 2023-08-31 op len = rbuf->len;
198 d48ffc66 2023-08-31 op memcpy(d, rbuf->buf, len);
199 d48ffc66 2023-08-31 op buf_drain(rbuf, len);
200 d48ffc66 2023-08-31 op return (len);
201 d48ffc66 2023-08-31 op }
202 d48ffc66 2023-08-31 op
203 b8a11905 2023-08-31 op ssize_t
204 b8a11905 2023-08-31 op bufio_write(struct bufio *bio)
205 b8a11905 2023-08-31 op {
206 b8a11905 2023-08-31 op struct buffer *wbuf = &bio->wbuf;
207 b8a11905 2023-08-31 op ssize_t w;
208 b8a11905 2023-08-31 op
209 b8a11905 2023-08-31 op w = write(bio->fd, wbuf->buf, wbuf->len);
210 b8a11905 2023-08-31 op if (w == -1)
211 b8a11905 2023-08-31 op return (-1);
212 b8a11905 2023-08-31 op buf_drain(wbuf, w);
213 b8a11905 2023-08-31 op return (w);
214 b8a11905 2023-08-31 op }
215 b8a11905 2023-08-31 op
216 d48ffc66 2023-08-31 op static int
217 d48ffc66 2023-08-31 op bufio_append(struct bufio *bio, const void *d, size_t len)
218 b8a11905 2023-08-31 op {
219 b8a11905 2023-08-31 op struct buffer *wbuf = &bio->wbuf;
220 b8a11905 2023-08-31 op
221 d48ffc66 2023-08-31 op if (len == 0)
222 d48ffc66 2023-08-31 op return (0);
223 d48ffc66 2023-08-31 op
224 b8a11905 2023-08-31 op while (wbuf->cap - wbuf->len < len) {
225 b8a11905 2023-08-31 op if (buf_grow(wbuf) == -1)
226 b8a11905 2023-08-31 op return (-1);
227 b8a11905 2023-08-31 op }
228 b8a11905 2023-08-31 op
229 b8a11905 2023-08-31 op memcpy(wbuf->buf + wbuf->len, d, len);
230 b8a11905 2023-08-31 op wbuf->len += len;
231 b8a11905 2023-08-31 op return (0);
232 b8a11905 2023-08-31 op }
233 b8a11905 2023-08-31 op
234 b8a11905 2023-08-31 op int
235 d48ffc66 2023-08-31 op bufio_compose(struct bufio *bio, const void *d, size_t len)
236 d48ffc66 2023-08-31 op {
237 d48ffc66 2023-08-31 op char n[16];
238 d48ffc66 2023-08-31 op int r;
239 d48ffc66 2023-08-31 op
240 d48ffc66 2023-08-31 op if (bio->chunked) {
241 d48ffc66 2023-08-31 op r = snprintf(n, sizeof(n), "%zx\r\n", len);
242 d48ffc66 2023-08-31 op if (r < 0 || (size_t)r >= sizeof(n))
243 d48ffc66 2023-08-31 op return (-1);
244 d48ffc66 2023-08-31 op if (bufio_append(bio, n, r) == -1)
245 d48ffc66 2023-08-31 op return (-1);
246 d48ffc66 2023-08-31 op }
247 d48ffc66 2023-08-31 op
248 d48ffc66 2023-08-31 op if (bufio_append(bio, d, len) == -1)
249 d48ffc66 2023-08-31 op return (-1);
250 d48ffc66 2023-08-31 op
251 d48ffc66 2023-08-31 op if (bio->chunked)
252 d48ffc66 2023-08-31 op return bufio_append(bio, "\r\n", 2);
253 d48ffc66 2023-08-31 op
254 d48ffc66 2023-08-31 op return (0);
255 d48ffc66 2023-08-31 op }
256 d48ffc66 2023-08-31 op
257 d48ffc66 2023-08-31 op int
258 b8a11905 2023-08-31 op bufio_compose_str(struct bufio *bio, const char *str)
259 b8a11905 2023-08-31 op {
260 b8a11905 2023-08-31 op return (bufio_compose(bio, str, strlen(str)));
261 b8a11905 2023-08-31 op }
262 b8a11905 2023-08-31 op
263 b8a11905 2023-08-31 op int
264 b8a11905 2023-08-31 op bufio_compose_fmt(struct bufio *bio, const char *fmt, ...)
265 b8a11905 2023-08-31 op {
266 b8a11905 2023-08-31 op va_list ap;
267 b8a11905 2023-08-31 op char *str;
268 b8a11905 2023-08-31 op int r;
269 b8a11905 2023-08-31 op
270 b8a11905 2023-08-31 op va_start(ap, fmt);
271 b8a11905 2023-08-31 op r = vasprintf(&str, fmt, ap);
272 b8a11905 2023-08-31 op va_end(ap);
273 b8a11905 2023-08-31 op
274 b8a11905 2023-08-31 op if (r == -1)
275 b8a11905 2023-08-31 op return (-1);
276 b8a11905 2023-08-31 op r = bufio_compose(bio, str, r);
277 b8a11905 2023-08-31 op free(str);
278 b8a11905 2023-08-31 op return (r);
279 b8a11905 2023-08-31 op }