Blame


1 f36fd90a 2022-07-09 op #include "config.h"
2 f36fd90a 2022-07-09 op #if !HAVE_ERR
3 f36fd90a 2022-07-09 op /*
4 f36fd90a 2022-07-09 op * Copyright (c) 1993
5 f36fd90a 2022-07-09 op * The Regents of the University of California. All rights reserved.
6 f36fd90a 2022-07-09 op *
7 f36fd90a 2022-07-09 op * Redistribution and use in source and binary forms, with or without
8 f36fd90a 2022-07-09 op * modification, are permitted provided that the following conditions
9 f36fd90a 2022-07-09 op * are met:
10 f36fd90a 2022-07-09 op * 1. Redistributions of source code must retain the above copyright
11 f36fd90a 2022-07-09 op * notice, this list of conditions and the following disclaimer.
12 f36fd90a 2022-07-09 op * 2. Redistributions in binary form must reproduce the above copyright
13 f36fd90a 2022-07-09 op * notice, this list of conditions and the following disclaimer in the
14 f36fd90a 2022-07-09 op * documentation and/or other materials provided with the distribution.
15 f36fd90a 2022-07-09 op * 3. Neither the name of the University nor the names of its contributors
16 f36fd90a 2022-07-09 op * may be used to endorse or promote products derived from this software
17 f36fd90a 2022-07-09 op * without specific prior written permission.
18 f36fd90a 2022-07-09 op *
19 f36fd90a 2022-07-09 op * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 f36fd90a 2022-07-09 op * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 f36fd90a 2022-07-09 op * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 f36fd90a 2022-07-09 op * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 f36fd90a 2022-07-09 op * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 f36fd90a 2022-07-09 op * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 f36fd90a 2022-07-09 op * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 f36fd90a 2022-07-09 op * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 f36fd90a 2022-07-09 op * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 f36fd90a 2022-07-09 op * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 f36fd90a 2022-07-09 op * SUCH DAMAGE.
30 f36fd90a 2022-07-09 op */
31 f36fd90a 2022-07-09 op
32 f36fd90a 2022-07-09 op #include <errno.h>
33 f36fd90a 2022-07-09 op #include <stdarg.h>
34 f36fd90a 2022-07-09 op #include <stdio.h>
35 f36fd90a 2022-07-09 op #include <stdlib.h>
36 f36fd90a 2022-07-09 op #include <string.h>
37 f36fd90a 2022-07-09 op
38 f36fd90a 2022-07-09 op void
39 f36fd90a 2022-07-09 op vwarnx(const char *fmt, va_list ap)
40 f36fd90a 2022-07-09 op {
41 f36fd90a 2022-07-09 op fprintf(stderr, "%s: ", getprogname());
42 f36fd90a 2022-07-09 op if (fmt != NULL)
43 f36fd90a 2022-07-09 op vfprintf(stderr, fmt, ap);
44 f36fd90a 2022-07-09 op fprintf(stderr, "\n");
45 f36fd90a 2022-07-09 op }
46 f36fd90a 2022-07-09 op
47 f36fd90a 2022-07-09 op void
48 f36fd90a 2022-07-09 op vwarnc(int code, const char *fmt, va_list ap)
49 f36fd90a 2022-07-09 op {
50 f36fd90a 2022-07-09 op fprintf(stderr, "%s: ", getprogname());
51 f36fd90a 2022-07-09 op if (fmt != NULL) {
52 f36fd90a 2022-07-09 op vfprintf(stderr, fmt, ap);
53 f36fd90a 2022-07-09 op fprintf(stderr, ": ");
54 f36fd90a 2022-07-09 op }
55 f36fd90a 2022-07-09 op fprintf(stderr, "%s\n", strerror(code));
56 f36fd90a 2022-07-09 op }
57 f36fd90a 2022-07-09 op
58 f36fd90a 2022-07-09 op void
59 f36fd90a 2022-07-09 op vwarn(const char *fmt, va_list ap)
60 f36fd90a 2022-07-09 op {
61 f36fd90a 2022-07-09 op int sverrno;
62 f36fd90a 2022-07-09 op
63 f36fd90a 2022-07-09 op sverrno = errno;
64 f36fd90a 2022-07-09 op fprintf(stderr, "%s: ", getprogname());
65 f36fd90a 2022-07-09 op if (fmt != NULL) {
66 f36fd90a 2022-07-09 op vfprintf(stderr, fmt, ap);
67 f36fd90a 2022-07-09 op fprintf(stderr, ": ");
68 f36fd90a 2022-07-09 op }
69 f36fd90a 2022-07-09 op fprintf(stderr, "%s\n", strerror(sverrno));
70 f36fd90a 2022-07-09 op }
71 f36fd90a 2022-07-09 op
72 f36fd90a 2022-07-09 op void
73 f36fd90a 2022-07-09 op verrc(int eval, int code, const char *fmt, va_list ap)
74 f36fd90a 2022-07-09 op {
75 f36fd90a 2022-07-09 op fprintf(stderr, "%s: ", getprogname());
76 f36fd90a 2022-07-09 op if (fmt != NULL) {
77 f36fd90a 2022-07-09 op vfprintf(stderr, fmt, ap);
78 f36fd90a 2022-07-09 op fprintf(stderr, ": ");
79 f36fd90a 2022-07-09 op }
80 f36fd90a 2022-07-09 op fprintf(stderr, "%s\n", strerror(code));
81 f36fd90a 2022-07-09 op exit(eval);
82 f36fd90a 2022-07-09 op }
83 f36fd90a 2022-07-09 op
84 f36fd90a 2022-07-09 op void
85 f36fd90a 2022-07-09 op verrx(int eval, const char *fmt, va_list ap)
86 f36fd90a 2022-07-09 op {
87 f36fd90a 2022-07-09 op fprintf(stderr, "%s: ", getprogname());
88 f36fd90a 2022-07-09 op if (fmt != NULL)
89 f36fd90a 2022-07-09 op vfprintf(stderr, fmt, ap);
90 f36fd90a 2022-07-09 op fprintf(stderr, "\n");
91 f36fd90a 2022-07-09 op exit(eval);
92 f36fd90a 2022-07-09 op }
93 f36fd90a 2022-07-09 op
94 f36fd90a 2022-07-09 op void
95 f36fd90a 2022-07-09 op verr(int eval, const char *fmt, va_list ap)
96 f36fd90a 2022-07-09 op {
97 f36fd90a 2022-07-09 op int sverrno;
98 f36fd90a 2022-07-09 op
99 f36fd90a 2022-07-09 op sverrno = errno;
100 f36fd90a 2022-07-09 op fprintf(stderr, "%s: ", getprogname());
101 f36fd90a 2022-07-09 op if (fmt != NULL) {
102 f36fd90a 2022-07-09 op vfprintf(stderr, fmt, ap);
103 f36fd90a 2022-07-09 op fprintf(stderr, ": ");
104 f36fd90a 2022-07-09 op }
105 f36fd90a 2022-07-09 op fprintf(stderr, "%s\n", strerror(sverrno));
106 f36fd90a 2022-07-09 op exit(eval);
107 f36fd90a 2022-07-09 op }
108 f36fd90a 2022-07-09 op
109 f36fd90a 2022-07-09 op void
110 f36fd90a 2022-07-09 op err(int eval, const char *fmt, ...)
111 f36fd90a 2022-07-09 op {
112 f36fd90a 2022-07-09 op va_list ap;
113 f36fd90a 2022-07-09 op
114 f36fd90a 2022-07-09 op va_start(ap, fmt);
115 f36fd90a 2022-07-09 op verr(eval, fmt, ap);
116 f36fd90a 2022-07-09 op va_end(ap);
117 f36fd90a 2022-07-09 op }
118 f36fd90a 2022-07-09 op
119 f36fd90a 2022-07-09 op void
120 f36fd90a 2022-07-09 op errc(int eval, int code, const char *fmt, ...)
121 f36fd90a 2022-07-09 op {
122 f36fd90a 2022-07-09 op va_list ap;
123 f36fd90a 2022-07-09 op
124 f36fd90a 2022-07-09 op va_start(ap, fmt);
125 f36fd90a 2022-07-09 op verrc(eval, code, fmt, ap);
126 f36fd90a 2022-07-09 op va_end(ap);
127 f36fd90a 2022-07-09 op }
128 f36fd90a 2022-07-09 op
129 f36fd90a 2022-07-09 op void
130 f36fd90a 2022-07-09 op errx(int eval, const char *fmt, ...)
131 f36fd90a 2022-07-09 op {
132 f36fd90a 2022-07-09 op va_list ap;
133 f36fd90a 2022-07-09 op
134 f36fd90a 2022-07-09 op va_start(ap, fmt);
135 f36fd90a 2022-07-09 op verrx(eval, fmt, ap);
136 f36fd90a 2022-07-09 op va_end(ap);
137 f36fd90a 2022-07-09 op }
138 f36fd90a 2022-07-09 op
139 f36fd90a 2022-07-09 op void
140 f36fd90a 2022-07-09 op warn(const char *fmt, ...)
141 f36fd90a 2022-07-09 op {
142 f36fd90a 2022-07-09 op va_list ap;
143 f36fd90a 2022-07-09 op
144 f36fd90a 2022-07-09 op va_start(ap, fmt);
145 f36fd90a 2022-07-09 op vwarn(fmt, ap);
146 f36fd90a 2022-07-09 op va_end(ap);
147 f36fd90a 2022-07-09 op }
148 f36fd90a 2022-07-09 op
149 f36fd90a 2022-07-09 op void
150 f36fd90a 2022-07-09 op warnc(int code, const char *fmt, ...)
151 f36fd90a 2022-07-09 op {
152 f36fd90a 2022-07-09 op va_list ap;
153 f36fd90a 2022-07-09 op
154 f36fd90a 2022-07-09 op va_start(ap, fmt);
155 f36fd90a 2022-07-09 op vwarnc(code, fmt, ap);
156 f36fd90a 2022-07-09 op va_end(ap);
157 f36fd90a 2022-07-09 op }
158 f36fd90a 2022-07-09 op
159 f36fd90a 2022-07-09 op void
160 f36fd90a 2022-07-09 op warnx(const char *fmt, ...)
161 f36fd90a 2022-07-09 op {
162 f36fd90a 2022-07-09 op va_list ap;
163 f36fd90a 2022-07-09 op
164 f36fd90a 2022-07-09 op va_start(ap, fmt);
165 f36fd90a 2022-07-09 op vwarnx(fmt, ap);
166 f36fd90a 2022-07-09 op va_end(ap);
167 f36fd90a 2022-07-09 op }
168 f36fd90a 2022-07-09 op #endif /* !HAVE_ERR */
169 f36fd90a 2022-07-09 op #if !HAVE_FLOCK
170 f36fd90a 2022-07-09 op #include <errno.h>
171 f36fd90a 2022-07-09 op #include <fcntl.h>
172 f36fd90a 2022-07-09 op #include <string.h>
173 f36fd90a 2022-07-09 op
174 f36fd90a 2022-07-09 op /*
175 f36fd90a 2022-07-09 op * flock(2) emulation on top of fcntl advisory locks. This is "good
176 f36fd90a 2022-07-09 op * enough" for amused, not a _real_ emulation. flock and fcntl locks
177 f36fd90a 2022-07-09 op * have subtly different behaviours!
178 f36fd90a 2022-07-09 op */
179 f36fd90a 2022-07-09 op int
180 f36fd90a 2022-07-09 op flock(int fd, int op)
181 f36fd90a 2022-07-09 op {
182 f36fd90a 2022-07-09 op struct flock l;
183 f36fd90a 2022-07-09 op int cmd;
184 f36fd90a 2022-07-09 op
185 f36fd90a 2022-07-09 op memset(&l, 0, sizeof(l));
186 f36fd90a 2022-07-09 op l.l_whence = SEEK_SET;
187 f36fd90a 2022-07-09 op
188 f36fd90a 2022-07-09 op if (op & LOCK_SH)
189 f36fd90a 2022-07-09 op l.l_type = F_RDLCK;
190 f36fd90a 2022-07-09 op else if (op & LOCK_EX)
191 f36fd90a 2022-07-09 op l.l_type = F_WRLCK;
192 f36fd90a 2022-07-09 op else {
193 f36fd90a 2022-07-09 op errno = EINVAL;
194 f36fd90a 2022-07-09 op return -1;
195 f36fd90a 2022-07-09 op }
196 f36fd90a 2022-07-09 op
197 f36fd90a 2022-07-09 op cmd = F_SETLKW;
198 f36fd90a 2022-07-09 op if (op & LOCK_NB)
199 f36fd90a 2022-07-09 op cmd = F_SETLK;
200 f36fd90a 2022-07-09 op
201 f36fd90a 2022-07-09 op return fcntl(fd, cmd, &l);
202 f36fd90a 2022-07-09 op }
203 f36fd90a 2022-07-09 op #endif /* HAVE_FLOCK */
204 f36fd90a 2022-07-09 op #if !HAVE_FREEZERO
205 f36fd90a 2022-07-09 op #include <stdlib.h>
206 f36fd90a 2022-07-09 op #include <string.h>
207 f36fd90a 2022-07-09 op
208 f36fd90a 2022-07-09 op void
209 f36fd90a 2022-07-09 op freezero(void *ptr, size_t len)
210 f36fd90a 2022-07-09 op {
211 f36fd90a 2022-07-09 op if (ptr == NULL)
212 f36fd90a 2022-07-09 op return;
213 f36fd90a 2022-07-09 op memset(ptr, 0, len);
214 f36fd90a 2022-07-09 op free(ptr);
215 f36fd90a 2022-07-09 op }
216 f36fd90a 2022-07-09 op #endif /* HAVE_FREEZERO */
217 f36fd90a 2022-07-09 op #if !HAVE_EXPLICIT_BZERO
218 f36fd90a 2022-07-09 op /* OPENBSD ORIGINAL: lib/libc/string/explicit_bzero.c */
219 f36fd90a 2022-07-09 op /*
220 f36fd90a 2022-07-09 op * Public domain.
221 f36fd90a 2022-07-09 op * Written by Ted Unangst
222 f36fd90a 2022-07-09 op */
223 f36fd90a 2022-07-09 op
224 f36fd90a 2022-07-09 op #include <string.h>
225 f36fd90a 2022-07-09 op
226 f36fd90a 2022-07-09 op /*
227 f36fd90a 2022-07-09 op * explicit_bzero - don't let the compiler optimize away bzero
228 f36fd90a 2022-07-09 op */
229 f36fd90a 2022-07-09 op
230 f36fd90a 2022-07-09 op #if HAVE_MEMSET_S
231 f36fd90a 2022-07-09 op
232 f36fd90a 2022-07-09 op void
233 f36fd90a 2022-07-09 op explicit_bzero(void *p, size_t n)
234 f36fd90a 2022-07-09 op {
235 f36fd90a 2022-07-09 op if (n == 0)
236 f36fd90a 2022-07-09 op return;
237 f36fd90a 2022-07-09 op (void)memset_s(p, n, 0, n);
238 f36fd90a 2022-07-09 op }
239 f36fd90a 2022-07-09 op
240 f36fd90a 2022-07-09 op #else /* HAVE_MEMSET_S */
241 f36fd90a 2022-07-09 op
242 f36fd90a 2022-07-09 op #include <strings.h>
243 f36fd90a 2022-07-09 op
244 f36fd90a 2022-07-09 op /*
245 f36fd90a 2022-07-09 op * Indirect memset through a volatile pointer to hopefully avoid
246 f36fd90a 2022-07-09 op * dead-store optimisation eliminating the call.
247 f36fd90a 2022-07-09 op */
248 c2297fa3 2023-12-10 op static void (* volatile ssh_memset)(void *, int, size_t) =
249 c2297fa3 2023-12-10 op (void (*volatile)(void *, int, size_t))memset;
250 f36fd90a 2022-07-09 op
251 f36fd90a 2022-07-09 op void
252 f36fd90a 2022-07-09 op explicit_bzero(void *p, size_t n)
253 f36fd90a 2022-07-09 op {
254 f36fd90a 2022-07-09 op if (n == 0)
255 f36fd90a 2022-07-09 op return;
256 f36fd90a 2022-07-09 op /*
257 f36fd90a 2022-07-09 op * clang -fsanitize=memory needs to intercept memset-like functions
258 f36fd90a 2022-07-09 op * to correctly detect memory initialisation. Make sure one is called
259 f36fd90a 2022-07-09 op * directly since our indirection trick above sucessfully confuses it.
260 f36fd90a 2022-07-09 op */
261 f36fd90a 2022-07-09 op #if defined(__has_feature)
262 f36fd90a 2022-07-09 op # if __has_feature(memory_sanitizer)
263 f36fd90a 2022-07-09 op memset(p, 0, n);
264 f36fd90a 2022-07-09 op # endif
265 f36fd90a 2022-07-09 op #endif
266 f36fd90a 2022-07-09 op
267 f36fd90a 2022-07-09 op ssh_memset(p, 0, n);
268 f36fd90a 2022-07-09 op }
269 f36fd90a 2022-07-09 op
270 f36fd90a 2022-07-09 op #endif /* HAVE_MEMSET_S */
271 f36fd90a 2022-07-09 op #endif /* !HAVE_EXPLICIT_BZERO */
272 4e457e62 2023-12-10 op #if !HAVE_GETDTABLESIZE
273 4e457e62 2023-12-10 op /* public domain */
274 4e457e62 2023-12-10 op #include <unistd.h>
275 4e457e62 2023-12-10 op
276 4e457e62 2023-12-10 op int
277 4e457e62 2023-12-10 op getdtablesize(void)
278 4e457e62 2023-12-10 op {
279 4e457e62 2023-12-10 op return sysconf(_SC_OPEN_MAX);
280 4e457e62 2023-12-10 op }
281 4e457e62 2023-12-10 op #endif /* !HAVE_GETDTABLESIZE */
282 f36fd90a 2022-07-09 op #if !HAVE_GETPROGNAME
283 f36fd90a 2022-07-09 op /*
284 f36fd90a 2022-07-09 op * Copyright (c) 2016 Nicholas Marriott <nicholas.marriott@gmail.com>
285 f36fd90a 2022-07-09 op * Copyright (c) 2017 Kristaps Dzonsons <kristaps@bsd.lv>
286 f36fd90a 2022-07-09 op * Copyright (c) 2020 Stephen Gregoratto <dev@sgregoratto.me>
287 f36fd90a 2022-07-09 op *
288 f36fd90a 2022-07-09 op * Permission to use, copy, modify, and distribute this software for any
289 f36fd90a 2022-07-09 op * purpose with or without fee is hereby granted, provided that the above
290 f36fd90a 2022-07-09 op * copyright notice and this permission notice appear in all copies.
291 f36fd90a 2022-07-09 op *
292 f36fd90a 2022-07-09 op * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
293 f36fd90a 2022-07-09 op * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
294 f36fd90a 2022-07-09 op * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
295 f36fd90a 2022-07-09 op * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
296 f36fd90a 2022-07-09 op * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
297 f36fd90a 2022-07-09 op * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
298 f36fd90a 2022-07-09 op * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
299 f36fd90a 2022-07-09 op */
300 f36fd90a 2022-07-09 op
301 f36fd90a 2022-07-09 op #include <sys/types.h>
302 f36fd90a 2022-07-09 op
303 f36fd90a 2022-07-09 op #include <errno.h>
304 f36fd90a 2022-07-09 op
305 f36fd90a 2022-07-09 op #if HAVE_GETEXECNAME
306 f36fd90a 2022-07-09 op #include <stdlib.h>
307 f36fd90a 2022-07-09 op const char *
308 f36fd90a 2022-07-09 op getprogname(void)
309 f36fd90a 2022-07-09 op {
310 f36fd90a 2022-07-09 op return getexecname();
311 f36fd90a 2022-07-09 op }
312 f36fd90a 2022-07-09 op #elif HAVE_PROGRAM_INVOCATION_SHORT_NAME
313 f36fd90a 2022-07-09 op const char *
314 f36fd90a 2022-07-09 op getprogname(void)
315 f36fd90a 2022-07-09 op {
316 f36fd90a 2022-07-09 op return (program_invocation_short_name);
317 f36fd90a 2022-07-09 op }
318 f36fd90a 2022-07-09 op #elif HAVE___PROGNAME
319 f36fd90a 2022-07-09 op const char *
320 f36fd90a 2022-07-09 op getprogname(void)
321 f36fd90a 2022-07-09 op {
322 f36fd90a 2022-07-09 op extern char *__progname;
323 f36fd90a 2022-07-09 op
324 f36fd90a 2022-07-09 op return (__progname);
325 f36fd90a 2022-07-09 op }
326 f36fd90a 2022-07-09 op #else
327 f36fd90a 2022-07-09 op #warning No getprogname available.
328 f36fd90a 2022-07-09 op const char *
329 f36fd90a 2022-07-09 op getprogname(void)
330 f36fd90a 2022-07-09 op {
331 f36fd90a 2022-07-09 op return ("amused");
332 f36fd90a 2022-07-09 op }
333 f36fd90a 2022-07-09 op #endif
334 f36fd90a 2022-07-09 op #endif /* !HAVE_GETPROGNAME */
335 82556d5b 2023-09-07 op #if !HAVE_LIB_IMSG
336 fb5efbfa 2024-01-21 op /* $OpenBSD: imsg-buffer.c,v 1.18 2023/12/12 15:47:41 claudio Exp $ */
337 fb5efbfa 2024-01-21 op /* $OpenBSD: imsg.c,v 1.23 2023/12/12 15:47:41 claudio Exp $ */
338 f36fd90a 2022-07-09 op
339 f36fd90a 2022-07-09 op /*
340 fb5efbfa 2024-01-21 op * Copyright (c) 2023 Claudio Jeker <claudio@openbsd.org>
341 f36fd90a 2022-07-09 op * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
342 f36fd90a 2022-07-09 op *
343 f36fd90a 2022-07-09 op * Permission to use, copy, modify, and distribute this software for any
344 f36fd90a 2022-07-09 op * purpose with or without fee is hereby granted, provided that the above
345 f36fd90a 2022-07-09 op * copyright notice and this permission notice appear in all copies.
346 f36fd90a 2022-07-09 op *
347 f36fd90a 2022-07-09 op * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
348 f36fd90a 2022-07-09 op * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
349 f36fd90a 2022-07-09 op * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
350 f36fd90a 2022-07-09 op * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
351 f36fd90a 2022-07-09 op * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
352 f36fd90a 2022-07-09 op * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
353 f36fd90a 2022-07-09 op * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
354 f36fd90a 2022-07-09 op */
355 f36fd90a 2022-07-09 op
356 f36fd90a 2022-07-09 op #include <sys/types.h>
357 f36fd90a 2022-07-09 op #include <sys/socket.h>
358 f36fd90a 2022-07-09 op #include <sys/uio.h>
359 f36fd90a 2022-07-09 op
360 f36fd90a 2022-07-09 op #include <limits.h>
361 f36fd90a 2022-07-09 op #include <errno.h>
362 263426d8 2023-10-09 op #include <endian.h>
363 fb5efbfa 2024-01-21 op #include <stdint.h>
364 f36fd90a 2022-07-09 op #include <stdlib.h>
365 f36fd90a 2022-07-09 op #include <string.h>
366 f36fd90a 2022-07-09 op #include <unistd.h>
367 f36fd90a 2022-07-09 op
368 f36fd90a 2022-07-09 op #include "imsg.h"
369 f36fd90a 2022-07-09 op
370 f36fd90a 2022-07-09 op static int ibuf_realloc(struct ibuf *, size_t);
371 f36fd90a 2022-07-09 op static void ibuf_enqueue(struct msgbuf *, struct ibuf *);
372 f36fd90a 2022-07-09 op static void ibuf_dequeue(struct msgbuf *, struct ibuf *);
373 3ac93df9 2023-07-02 op static void msgbuf_drain(struct msgbuf *, size_t);
374 f36fd90a 2022-07-09 op
375 f36fd90a 2022-07-09 op struct ibuf *
376 f36fd90a 2022-07-09 op ibuf_open(size_t len)
377 f36fd90a 2022-07-09 op {
378 f36fd90a 2022-07-09 op struct ibuf *buf;
379 f36fd90a 2022-07-09 op
380 3ac93df9 2023-07-02 op if (len == 0) {
381 3ac93df9 2023-07-02 op errno = EINVAL;
382 3ac93df9 2023-07-02 op return (NULL);
383 3ac93df9 2023-07-02 op }
384 f36fd90a 2022-07-09 op if ((buf = calloc(1, sizeof(struct ibuf))) == NULL)
385 f36fd90a 2022-07-09 op return (NULL);
386 3ac93df9 2023-07-02 op if ((buf->buf = calloc(len, 1)) == NULL) {
387 f36fd90a 2022-07-09 op free(buf);
388 f36fd90a 2022-07-09 op return (NULL);
389 f36fd90a 2022-07-09 op }
390 f36fd90a 2022-07-09 op buf->size = buf->max = len;
391 f36fd90a 2022-07-09 op buf->fd = -1;
392 f36fd90a 2022-07-09 op
393 f36fd90a 2022-07-09 op return (buf);
394 f36fd90a 2022-07-09 op }
395 f36fd90a 2022-07-09 op
396 f36fd90a 2022-07-09 op struct ibuf *
397 f36fd90a 2022-07-09 op ibuf_dynamic(size_t len, size_t max)
398 f36fd90a 2022-07-09 op {
399 f36fd90a 2022-07-09 op struct ibuf *buf;
400 f36fd90a 2022-07-09 op
401 fb5efbfa 2024-01-21 op if (max == 0 || max < len) {
402 3ac93df9 2023-07-02 op errno = EINVAL;
403 f36fd90a 2022-07-09 op return (NULL);
404 3ac93df9 2023-07-02 op }
405 f36fd90a 2022-07-09 op
406 3ac93df9 2023-07-02 op if ((buf = calloc(1, sizeof(struct ibuf))) == NULL)
407 f36fd90a 2022-07-09 op return (NULL);
408 3ac93df9 2023-07-02 op if (len > 0) {
409 3ac93df9 2023-07-02 op if ((buf->buf = calloc(len, 1)) == NULL) {
410 3ac93df9 2023-07-02 op free(buf);
411 3ac93df9 2023-07-02 op return (NULL);
412 3ac93df9 2023-07-02 op }
413 3ac93df9 2023-07-02 op }
414 3ac93df9 2023-07-02 op buf->size = len;
415 3ac93df9 2023-07-02 op buf->max = max;
416 3ac93df9 2023-07-02 op buf->fd = -1;
417 f36fd90a 2022-07-09 op
418 f36fd90a 2022-07-09 op return (buf);
419 f36fd90a 2022-07-09 op }
420 f36fd90a 2022-07-09 op
421 f36fd90a 2022-07-09 op static int
422 f36fd90a 2022-07-09 op ibuf_realloc(struct ibuf *buf, size_t len)
423 f36fd90a 2022-07-09 op {
424 f36fd90a 2022-07-09 op unsigned char *b;
425 f36fd90a 2022-07-09 op
426 f36fd90a 2022-07-09 op /* on static buffers max is eq size and so the following fails */
427 3ac93df9 2023-07-02 op if (len > SIZE_MAX - buf->wpos || buf->wpos + len > buf->max) {
428 f36fd90a 2022-07-09 op errno = ERANGE;
429 f36fd90a 2022-07-09 op return (-1);
430 f36fd90a 2022-07-09 op }
431 f36fd90a 2022-07-09 op
432 f36fd90a 2022-07-09 op b = recallocarray(buf->buf, buf->size, buf->wpos + len, 1);
433 f36fd90a 2022-07-09 op if (b == NULL)
434 f36fd90a 2022-07-09 op return (-1);
435 f36fd90a 2022-07-09 op buf->buf = b;
436 f36fd90a 2022-07-09 op buf->size = buf->wpos + len;
437 f36fd90a 2022-07-09 op
438 f36fd90a 2022-07-09 op return (0);
439 f36fd90a 2022-07-09 op }
440 f36fd90a 2022-07-09 op
441 f36fd90a 2022-07-09 op void *
442 f36fd90a 2022-07-09 op ibuf_reserve(struct ibuf *buf, size_t len)
443 f36fd90a 2022-07-09 op {
444 f36fd90a 2022-07-09 op void *b;
445 f36fd90a 2022-07-09 op
446 fb5efbfa 2024-01-21 op if (len > SIZE_MAX - buf->wpos || buf->max == 0) {
447 3ac93df9 2023-07-02 op errno = ERANGE;
448 3ac93df9 2023-07-02 op return (NULL);
449 3ac93df9 2023-07-02 op }
450 3ac93df9 2023-07-02 op
451 f36fd90a 2022-07-09 op if (buf->wpos + len > buf->size)
452 f36fd90a 2022-07-09 op if (ibuf_realloc(buf, len) == -1)
453 f36fd90a 2022-07-09 op return (NULL);
454 f36fd90a 2022-07-09 op
455 f36fd90a 2022-07-09 op b = buf->buf + buf->wpos;
456 f36fd90a 2022-07-09 op buf->wpos += len;
457 f36fd90a 2022-07-09 op return (b);
458 3ac93df9 2023-07-02 op }
459 3ac93df9 2023-07-02 op
460 3ac93df9 2023-07-02 op int
461 3ac93df9 2023-07-02 op ibuf_add(struct ibuf *buf, const void *data, size_t len)
462 3ac93df9 2023-07-02 op {
463 3ac93df9 2023-07-02 op void *b;
464 3ac93df9 2023-07-02 op
465 3ac93df9 2023-07-02 op if ((b = ibuf_reserve(buf, len)) == NULL)
466 3ac93df9 2023-07-02 op return (-1);
467 3ac93df9 2023-07-02 op
468 3ac93df9 2023-07-02 op memcpy(b, data, len);
469 3ac93df9 2023-07-02 op return (0);
470 fb5efbfa 2024-01-21 op }
471 fb5efbfa 2024-01-21 op
472 fb5efbfa 2024-01-21 op int
473 fb5efbfa 2024-01-21 op ibuf_add_ibuf(struct ibuf *buf, const struct ibuf *from)
474 fb5efbfa 2024-01-21 op {
475 fb5efbfa 2024-01-21 op return ibuf_add(buf, ibuf_data(from), ibuf_size(from));
476 3ac93df9 2023-07-02 op }
477 3ac93df9 2023-07-02 op
478 fb5efbfa 2024-01-21 op /* remove after tree is converted */
479 3ac93df9 2023-07-02 op int
480 3ac93df9 2023-07-02 op ibuf_add_buf(struct ibuf *buf, const struct ibuf *from)
481 3ac93df9 2023-07-02 op {
482 fb5efbfa 2024-01-21 op return ibuf_add_ibuf(buf, from);
483 3ac93df9 2023-07-02 op }
484 3ac93df9 2023-07-02 op
485 3ac93df9 2023-07-02 op int
486 3ac93df9 2023-07-02 op ibuf_add_n8(struct ibuf *buf, uint64_t value)
487 3ac93df9 2023-07-02 op {
488 3ac93df9 2023-07-02 op uint8_t v;
489 3ac93df9 2023-07-02 op
490 3ac93df9 2023-07-02 op if (value > UINT8_MAX) {
491 3ac93df9 2023-07-02 op errno = EINVAL;
492 3ac93df9 2023-07-02 op return (-1);
493 3ac93df9 2023-07-02 op }
494 3ac93df9 2023-07-02 op v = value;
495 3ac93df9 2023-07-02 op return ibuf_add(buf, &v, sizeof(v));
496 f36fd90a 2022-07-09 op }
497 f36fd90a 2022-07-09 op
498 3ac93df9 2023-07-02 op int
499 3ac93df9 2023-07-02 op ibuf_add_n16(struct ibuf *buf, uint64_t value)
500 3ac93df9 2023-07-02 op {
501 3ac93df9 2023-07-02 op uint16_t v;
502 3ac93df9 2023-07-02 op
503 3ac93df9 2023-07-02 op if (value > UINT16_MAX) {
504 3ac93df9 2023-07-02 op errno = EINVAL;
505 3ac93df9 2023-07-02 op return (-1);
506 3ac93df9 2023-07-02 op }
507 3ac93df9 2023-07-02 op v = htobe16(value);
508 3ac93df9 2023-07-02 op return ibuf_add(buf, &v, sizeof(v));
509 3ac93df9 2023-07-02 op }
510 3ac93df9 2023-07-02 op
511 3ac93df9 2023-07-02 op int
512 3ac93df9 2023-07-02 op ibuf_add_n32(struct ibuf *buf, uint64_t value)
513 3ac93df9 2023-07-02 op {
514 3ac93df9 2023-07-02 op uint32_t v;
515 3ac93df9 2023-07-02 op
516 3ac93df9 2023-07-02 op if (value > UINT32_MAX) {
517 3ac93df9 2023-07-02 op errno = EINVAL;
518 3ac93df9 2023-07-02 op return (-1);
519 3ac93df9 2023-07-02 op }
520 3ac93df9 2023-07-02 op v = htobe32(value);
521 3ac93df9 2023-07-02 op return ibuf_add(buf, &v, sizeof(v));
522 3ac93df9 2023-07-02 op }
523 3ac93df9 2023-07-02 op
524 3ac93df9 2023-07-02 op int
525 3ac93df9 2023-07-02 op ibuf_add_n64(struct ibuf *buf, uint64_t value)
526 3ac93df9 2023-07-02 op {
527 3ac93df9 2023-07-02 op value = htobe64(value);
528 3ac93df9 2023-07-02 op return ibuf_add(buf, &value, sizeof(value));
529 3ac93df9 2023-07-02 op }
530 3ac93df9 2023-07-02 op
531 3ac93df9 2023-07-02 op int
532 fb5efbfa 2024-01-21 op ibuf_add_h16(struct ibuf *buf, uint64_t value)
533 fb5efbfa 2024-01-21 op {
534 fb5efbfa 2024-01-21 op uint16_t v;
535 fb5efbfa 2024-01-21 op
536 fb5efbfa 2024-01-21 op if (value > UINT16_MAX) {
537 fb5efbfa 2024-01-21 op errno = EINVAL;
538 fb5efbfa 2024-01-21 op return (-1);
539 fb5efbfa 2024-01-21 op }
540 fb5efbfa 2024-01-21 op v = value;
541 fb5efbfa 2024-01-21 op return ibuf_add(buf, &v, sizeof(v));
542 fb5efbfa 2024-01-21 op }
543 fb5efbfa 2024-01-21 op
544 fb5efbfa 2024-01-21 op int
545 fb5efbfa 2024-01-21 op ibuf_add_h32(struct ibuf *buf, uint64_t value)
546 fb5efbfa 2024-01-21 op {
547 fb5efbfa 2024-01-21 op uint32_t v;
548 fb5efbfa 2024-01-21 op
549 fb5efbfa 2024-01-21 op if (value > UINT32_MAX) {
550 fb5efbfa 2024-01-21 op errno = EINVAL;
551 fb5efbfa 2024-01-21 op return (-1);
552 fb5efbfa 2024-01-21 op }
553 fb5efbfa 2024-01-21 op v = value;
554 fb5efbfa 2024-01-21 op return ibuf_add(buf, &v, sizeof(v));
555 fb5efbfa 2024-01-21 op }
556 fb5efbfa 2024-01-21 op
557 fb5efbfa 2024-01-21 op int
558 fb5efbfa 2024-01-21 op ibuf_add_h64(struct ibuf *buf, uint64_t value)
559 fb5efbfa 2024-01-21 op {
560 fb5efbfa 2024-01-21 op return ibuf_add(buf, &value, sizeof(value));
561 fb5efbfa 2024-01-21 op }
562 fb5efbfa 2024-01-21 op
563 fb5efbfa 2024-01-21 op int
564 3ac93df9 2023-07-02 op ibuf_add_zero(struct ibuf *buf, size_t len)
565 3ac93df9 2023-07-02 op {
566 3ac93df9 2023-07-02 op void *b;
567 3ac93df9 2023-07-02 op
568 3ac93df9 2023-07-02 op if ((b = ibuf_reserve(buf, len)) == NULL)
569 3ac93df9 2023-07-02 op return (-1);
570 fb5efbfa 2024-01-21 op memset(b, 0, len);
571 3ac93df9 2023-07-02 op return (0);
572 3ac93df9 2023-07-02 op }
573 3ac93df9 2023-07-02 op
574 f36fd90a 2022-07-09 op void *
575 f36fd90a 2022-07-09 op ibuf_seek(struct ibuf *buf, size_t pos, size_t len)
576 f36fd90a 2022-07-09 op {
577 fb5efbfa 2024-01-21 op /* only allow seeking between rpos and wpos */
578 fb5efbfa 2024-01-21 op if (ibuf_size(buf) < pos || SIZE_MAX - pos < len ||
579 fb5efbfa 2024-01-21 op ibuf_size(buf) < pos + len) {
580 3ac93df9 2023-07-02 op errno = ERANGE;
581 f36fd90a 2022-07-09 op return (NULL);
582 3ac93df9 2023-07-02 op }
583 f36fd90a 2022-07-09 op
584 fb5efbfa 2024-01-21 op return (buf->buf + buf->rpos + pos);
585 3ac93df9 2023-07-02 op }
586 3ac93df9 2023-07-02 op
587 3ac93df9 2023-07-02 op int
588 3ac93df9 2023-07-02 op ibuf_set(struct ibuf *buf, size_t pos, const void *data, size_t len)
589 3ac93df9 2023-07-02 op {
590 3ac93df9 2023-07-02 op void *b;
591 3ac93df9 2023-07-02 op
592 3ac93df9 2023-07-02 op if ((b = ibuf_seek(buf, pos, len)) == NULL)
593 3ac93df9 2023-07-02 op return (-1);
594 3ac93df9 2023-07-02 op
595 3ac93df9 2023-07-02 op memcpy(b, data, len);
596 3ac93df9 2023-07-02 op return (0);
597 3ac93df9 2023-07-02 op }
598 3ac93df9 2023-07-02 op
599 3ac93df9 2023-07-02 op int
600 3ac93df9 2023-07-02 op ibuf_set_n8(struct ibuf *buf, size_t pos, uint64_t value)
601 3ac93df9 2023-07-02 op {
602 3ac93df9 2023-07-02 op uint8_t v;
603 3ac93df9 2023-07-02 op
604 3ac93df9 2023-07-02 op if (value > UINT8_MAX) {
605 3ac93df9 2023-07-02 op errno = EINVAL;
606 3ac93df9 2023-07-02 op return (-1);
607 3ac93df9 2023-07-02 op }
608 3ac93df9 2023-07-02 op v = value;
609 3ac93df9 2023-07-02 op return (ibuf_set(buf, pos, &v, sizeof(v)));
610 f36fd90a 2022-07-09 op }
611 f36fd90a 2022-07-09 op
612 3ac93df9 2023-07-02 op int
613 3ac93df9 2023-07-02 op ibuf_set_n16(struct ibuf *buf, size_t pos, uint64_t value)
614 3ac93df9 2023-07-02 op {
615 3ac93df9 2023-07-02 op uint16_t v;
616 3ac93df9 2023-07-02 op
617 3ac93df9 2023-07-02 op if (value > UINT16_MAX) {
618 3ac93df9 2023-07-02 op errno = EINVAL;
619 3ac93df9 2023-07-02 op return (-1);
620 3ac93df9 2023-07-02 op }
621 3ac93df9 2023-07-02 op v = htobe16(value);
622 3ac93df9 2023-07-02 op return (ibuf_set(buf, pos, &v, sizeof(v)));
623 3ac93df9 2023-07-02 op }
624 3ac93df9 2023-07-02 op
625 3ac93df9 2023-07-02 op int
626 3ac93df9 2023-07-02 op ibuf_set_n32(struct ibuf *buf, size_t pos, uint64_t value)
627 3ac93df9 2023-07-02 op {
628 3ac93df9 2023-07-02 op uint32_t v;
629 3ac93df9 2023-07-02 op
630 3ac93df9 2023-07-02 op if (value > UINT32_MAX) {
631 3ac93df9 2023-07-02 op errno = EINVAL;
632 3ac93df9 2023-07-02 op return (-1);
633 3ac93df9 2023-07-02 op }
634 3ac93df9 2023-07-02 op v = htobe32(value);
635 3ac93df9 2023-07-02 op return (ibuf_set(buf, pos, &v, sizeof(v)));
636 3ac93df9 2023-07-02 op }
637 3ac93df9 2023-07-02 op
638 3ac93df9 2023-07-02 op int
639 3ac93df9 2023-07-02 op ibuf_set_n64(struct ibuf *buf, size_t pos, uint64_t value)
640 3ac93df9 2023-07-02 op {
641 3ac93df9 2023-07-02 op value = htobe64(value);
642 3ac93df9 2023-07-02 op return (ibuf_set(buf, pos, &value, sizeof(value)));
643 3ac93df9 2023-07-02 op }
644 3ac93df9 2023-07-02 op
645 fb5efbfa 2024-01-21 op int
646 fb5efbfa 2024-01-21 op ibuf_set_h16(struct ibuf *buf, size_t pos, uint64_t value)
647 3ac93df9 2023-07-02 op {
648 fb5efbfa 2024-01-21 op uint16_t v;
649 fb5efbfa 2024-01-21 op
650 fb5efbfa 2024-01-21 op if (value > UINT16_MAX) {
651 fb5efbfa 2024-01-21 op errno = EINVAL;
652 fb5efbfa 2024-01-21 op return (-1);
653 fb5efbfa 2024-01-21 op }
654 fb5efbfa 2024-01-21 op v = value;
655 fb5efbfa 2024-01-21 op return (ibuf_set(buf, pos, &v, sizeof(v)));
656 3ac93df9 2023-07-02 op }
657 3ac93df9 2023-07-02 op
658 fb5efbfa 2024-01-21 op int
659 fb5efbfa 2024-01-21 op ibuf_set_h32(struct ibuf *buf, size_t pos, uint64_t value)
660 fb5efbfa 2024-01-21 op {
661 fb5efbfa 2024-01-21 op uint32_t v;
662 fb5efbfa 2024-01-21 op
663 fb5efbfa 2024-01-21 op if (value > UINT32_MAX) {
664 fb5efbfa 2024-01-21 op errno = EINVAL;
665 fb5efbfa 2024-01-21 op return (-1);
666 fb5efbfa 2024-01-21 op }
667 fb5efbfa 2024-01-21 op v = value;
668 fb5efbfa 2024-01-21 op return (ibuf_set(buf, pos, &v, sizeof(v)));
669 fb5efbfa 2024-01-21 op }
670 fb5efbfa 2024-01-21 op
671 fb5efbfa 2024-01-21 op int
672 fb5efbfa 2024-01-21 op ibuf_set_h64(struct ibuf *buf, size_t pos, uint64_t value)
673 fb5efbfa 2024-01-21 op {
674 fb5efbfa 2024-01-21 op return (ibuf_set(buf, pos, &value, sizeof(value)));
675 fb5efbfa 2024-01-21 op }
676 fb5efbfa 2024-01-21 op
677 fb5efbfa 2024-01-21 op void *
678 fb5efbfa 2024-01-21 op ibuf_data(const struct ibuf *buf)
679 fb5efbfa 2024-01-21 op {
680 fb5efbfa 2024-01-21 op return (buf->buf + buf->rpos);
681 fb5efbfa 2024-01-21 op }
682 fb5efbfa 2024-01-21 op
683 f36fd90a 2022-07-09 op size_t
684 fb5efbfa 2024-01-21 op ibuf_size(const struct ibuf *buf)
685 f36fd90a 2022-07-09 op {
686 fb5efbfa 2024-01-21 op return (buf->wpos - buf->rpos);
687 f36fd90a 2022-07-09 op }
688 f36fd90a 2022-07-09 op
689 f36fd90a 2022-07-09 op size_t
690 fb5efbfa 2024-01-21 op ibuf_left(const struct ibuf *buf)
691 f36fd90a 2022-07-09 op {
692 fb5efbfa 2024-01-21 op if (buf->max == 0)
693 fb5efbfa 2024-01-21 op return (0);
694 f36fd90a 2022-07-09 op return (buf->max - buf->wpos);
695 f36fd90a 2022-07-09 op }
696 f36fd90a 2022-07-09 op
697 fb5efbfa 2024-01-21 op int
698 fb5efbfa 2024-01-21 op ibuf_truncate(struct ibuf *buf, size_t len)
699 fb5efbfa 2024-01-21 op {
700 fb5efbfa 2024-01-21 op if (ibuf_size(buf) >= len) {
701 fb5efbfa 2024-01-21 op buf->wpos = buf->rpos + len;
702 fb5efbfa 2024-01-21 op return (0);
703 fb5efbfa 2024-01-21 op }
704 fb5efbfa 2024-01-21 op if (buf->max == 0) {
705 fb5efbfa 2024-01-21 op /* only allow to truncate down */
706 fb5efbfa 2024-01-21 op errno = ERANGE;
707 fb5efbfa 2024-01-21 op return (-1);
708 fb5efbfa 2024-01-21 op }
709 fb5efbfa 2024-01-21 op return ibuf_add_zero(buf, len - ibuf_size(buf));
710 fb5efbfa 2024-01-21 op }
711 fb5efbfa 2024-01-21 op
712 f36fd90a 2022-07-09 op void
713 fb5efbfa 2024-01-21 op ibuf_rewind(struct ibuf *buf)
714 fb5efbfa 2024-01-21 op {
715 fb5efbfa 2024-01-21 op buf->rpos = 0;
716 fb5efbfa 2024-01-21 op }
717 fb5efbfa 2024-01-21 op
718 fb5efbfa 2024-01-21 op void
719 f36fd90a 2022-07-09 op ibuf_close(struct msgbuf *msgbuf, struct ibuf *buf)
720 f36fd90a 2022-07-09 op {
721 f36fd90a 2022-07-09 op ibuf_enqueue(msgbuf, buf);
722 fb5efbfa 2024-01-21 op }
723 fb5efbfa 2024-01-21 op
724 fb5efbfa 2024-01-21 op void
725 fb5efbfa 2024-01-21 op ibuf_from_buffer(struct ibuf *buf, void *data, size_t len)
726 fb5efbfa 2024-01-21 op {
727 fb5efbfa 2024-01-21 op memset(buf, 0, sizeof(*buf));
728 fb5efbfa 2024-01-21 op buf->buf = data;
729 fb5efbfa 2024-01-21 op buf->size = buf->wpos = len;
730 fb5efbfa 2024-01-21 op buf->fd = -1;
731 fb5efbfa 2024-01-21 op }
732 fb5efbfa 2024-01-21 op
733 fb5efbfa 2024-01-21 op void
734 fb5efbfa 2024-01-21 op ibuf_from_ibuf(struct ibuf *buf, const struct ibuf *from)
735 fb5efbfa 2024-01-21 op {
736 fb5efbfa 2024-01-21 op ibuf_from_buffer(buf, ibuf_data(from), ibuf_size(from));
737 fb5efbfa 2024-01-21 op }
738 fb5efbfa 2024-01-21 op
739 fb5efbfa 2024-01-21 op int
740 fb5efbfa 2024-01-21 op ibuf_get(struct ibuf *buf, void *data, size_t len)
741 fb5efbfa 2024-01-21 op {
742 fb5efbfa 2024-01-21 op if (ibuf_size(buf) < len) {
743 fb5efbfa 2024-01-21 op errno = EBADMSG;
744 fb5efbfa 2024-01-21 op return (-1);
745 fb5efbfa 2024-01-21 op }
746 fb5efbfa 2024-01-21 op
747 fb5efbfa 2024-01-21 op memcpy(data, ibuf_data(buf), len);
748 fb5efbfa 2024-01-21 op buf->rpos += len;
749 fb5efbfa 2024-01-21 op return (0);
750 fb5efbfa 2024-01-21 op }
751 fb5efbfa 2024-01-21 op
752 fb5efbfa 2024-01-21 op int
753 fb5efbfa 2024-01-21 op ibuf_get_ibuf(struct ibuf *buf, size_t len, struct ibuf *new)
754 fb5efbfa 2024-01-21 op {
755 fb5efbfa 2024-01-21 op if (ibuf_size(buf) < len) {
756 fb5efbfa 2024-01-21 op errno = EBADMSG;
757 fb5efbfa 2024-01-21 op return (-1);
758 fb5efbfa 2024-01-21 op }
759 fb5efbfa 2024-01-21 op
760 fb5efbfa 2024-01-21 op ibuf_from_buffer(new, ibuf_data(buf), len);
761 fb5efbfa 2024-01-21 op buf->rpos += len;
762 fb5efbfa 2024-01-21 op return (0);
763 fb5efbfa 2024-01-21 op }
764 fb5efbfa 2024-01-21 op
765 fb5efbfa 2024-01-21 op int
766 fb5efbfa 2024-01-21 op ibuf_get_n8(struct ibuf *buf, uint8_t *value)
767 fb5efbfa 2024-01-21 op {
768 fb5efbfa 2024-01-21 op return ibuf_get(buf, value, sizeof(*value));
769 fb5efbfa 2024-01-21 op }
770 fb5efbfa 2024-01-21 op
771 fb5efbfa 2024-01-21 op int
772 fb5efbfa 2024-01-21 op ibuf_get_n16(struct ibuf *buf, uint16_t *value)
773 fb5efbfa 2024-01-21 op {
774 fb5efbfa 2024-01-21 op int rv;
775 fb5efbfa 2024-01-21 op
776 fb5efbfa 2024-01-21 op rv = ibuf_get(buf, value, sizeof(*value));
777 fb5efbfa 2024-01-21 op *value = be16toh(*value);
778 fb5efbfa 2024-01-21 op return (rv);
779 fb5efbfa 2024-01-21 op }
780 fb5efbfa 2024-01-21 op
781 fb5efbfa 2024-01-21 op int
782 fb5efbfa 2024-01-21 op ibuf_get_n32(struct ibuf *buf, uint32_t *value)
783 fb5efbfa 2024-01-21 op {
784 fb5efbfa 2024-01-21 op int rv;
785 fb5efbfa 2024-01-21 op
786 fb5efbfa 2024-01-21 op rv = ibuf_get(buf, value, sizeof(*value));
787 fb5efbfa 2024-01-21 op *value = be32toh(*value);
788 fb5efbfa 2024-01-21 op return (rv);
789 fb5efbfa 2024-01-21 op }
790 fb5efbfa 2024-01-21 op
791 fb5efbfa 2024-01-21 op int
792 fb5efbfa 2024-01-21 op ibuf_get_n64(struct ibuf *buf, uint64_t *value)
793 fb5efbfa 2024-01-21 op {
794 fb5efbfa 2024-01-21 op int rv;
795 fb5efbfa 2024-01-21 op
796 fb5efbfa 2024-01-21 op rv = ibuf_get(buf, value, sizeof(*value));
797 fb5efbfa 2024-01-21 op *value = be64toh(*value);
798 fb5efbfa 2024-01-21 op return (rv);
799 fb5efbfa 2024-01-21 op }
800 fb5efbfa 2024-01-21 op
801 fb5efbfa 2024-01-21 op int
802 fb5efbfa 2024-01-21 op ibuf_get_h16(struct ibuf *buf, uint16_t *value)
803 fb5efbfa 2024-01-21 op {
804 fb5efbfa 2024-01-21 op return ibuf_get(buf, value, sizeof(*value));
805 f36fd90a 2022-07-09 op }
806 f36fd90a 2022-07-09 op
807 fb5efbfa 2024-01-21 op int
808 fb5efbfa 2024-01-21 op ibuf_get_h32(struct ibuf *buf, uint32_t *value)
809 fb5efbfa 2024-01-21 op {
810 fb5efbfa 2024-01-21 op return ibuf_get(buf, value, sizeof(*value));
811 fb5efbfa 2024-01-21 op }
812 fb5efbfa 2024-01-21 op
813 fb5efbfa 2024-01-21 op int
814 fb5efbfa 2024-01-21 op ibuf_get_h64(struct ibuf *buf, uint64_t *value)
815 fb5efbfa 2024-01-21 op {
816 fb5efbfa 2024-01-21 op return ibuf_get(buf, value, sizeof(*value));
817 fb5efbfa 2024-01-21 op }
818 fb5efbfa 2024-01-21 op
819 fb5efbfa 2024-01-21 op int
820 fb5efbfa 2024-01-21 op ibuf_skip(struct ibuf *buf, size_t len)
821 fb5efbfa 2024-01-21 op {
822 fb5efbfa 2024-01-21 op if (ibuf_size(buf) < len) {
823 fb5efbfa 2024-01-21 op errno = EBADMSG;
824 fb5efbfa 2024-01-21 op return (-1);
825 fb5efbfa 2024-01-21 op }
826 fb5efbfa 2024-01-21 op
827 fb5efbfa 2024-01-21 op buf->rpos += len;
828 fb5efbfa 2024-01-21 op return (0);
829 fb5efbfa 2024-01-21 op }
830 fb5efbfa 2024-01-21 op
831 3ac93df9 2023-07-02 op void
832 3ac93df9 2023-07-02 op ibuf_free(struct ibuf *buf)
833 3ac93df9 2023-07-02 op {
834 3ac93df9 2023-07-02 op if (buf == NULL)
835 3ac93df9 2023-07-02 op return;
836 fb5efbfa 2024-01-21 op if (buf->max == 0) /* if buf lives on the stack */
837 fb5efbfa 2024-01-21 op abort(); /* abort before causing more harm */
838 3ac93df9 2023-07-02 op if (buf->fd != -1)
839 3ac93df9 2023-07-02 op close(buf->fd);
840 3ac93df9 2023-07-02 op freezero(buf->buf, buf->size);
841 3ac93df9 2023-07-02 op free(buf);
842 3ac93df9 2023-07-02 op }
843 3ac93df9 2023-07-02 op
844 f36fd90a 2022-07-09 op int
845 3ac93df9 2023-07-02 op ibuf_fd_avail(struct ibuf *buf)
846 3ac93df9 2023-07-02 op {
847 3ac93df9 2023-07-02 op return (buf->fd != -1);
848 3ac93df9 2023-07-02 op }
849 3ac93df9 2023-07-02 op
850 3ac93df9 2023-07-02 op int
851 3ac93df9 2023-07-02 op ibuf_fd_get(struct ibuf *buf)
852 3ac93df9 2023-07-02 op {
853 3ac93df9 2023-07-02 op int fd;
854 3ac93df9 2023-07-02 op
855 3ac93df9 2023-07-02 op fd = buf->fd;
856 3ac93df9 2023-07-02 op buf->fd = -1;
857 3ac93df9 2023-07-02 op return (fd);
858 3ac93df9 2023-07-02 op }
859 3ac93df9 2023-07-02 op
860 3ac93df9 2023-07-02 op void
861 3ac93df9 2023-07-02 op ibuf_fd_set(struct ibuf *buf, int fd)
862 3ac93df9 2023-07-02 op {
863 fb5efbfa 2024-01-21 op if (buf->max == 0) /* if buf lives on the stack */
864 fb5efbfa 2024-01-21 op abort(); /* abort before causing more harm */
865 3ac93df9 2023-07-02 op if (buf->fd != -1)
866 3ac93df9 2023-07-02 op close(buf->fd);
867 3ac93df9 2023-07-02 op buf->fd = fd;
868 3ac93df9 2023-07-02 op }
869 3ac93df9 2023-07-02 op
870 3ac93df9 2023-07-02 op int
871 f36fd90a 2022-07-09 op ibuf_write(struct msgbuf *msgbuf)
872 f36fd90a 2022-07-09 op {
873 f36fd90a 2022-07-09 op struct iovec iov[IOV_MAX];
874 f36fd90a 2022-07-09 op struct ibuf *buf;
875 f36fd90a 2022-07-09 op unsigned int i = 0;
876 f36fd90a 2022-07-09 op ssize_t n;
877 f36fd90a 2022-07-09 op
878 f36fd90a 2022-07-09 op memset(&iov, 0, sizeof(iov));
879 f36fd90a 2022-07-09 op TAILQ_FOREACH(buf, &msgbuf->bufs, entry) {
880 f36fd90a 2022-07-09 op if (i >= IOV_MAX)
881 f36fd90a 2022-07-09 op break;
882 fb5efbfa 2024-01-21 op iov[i].iov_base = ibuf_data(buf);
883 fb5efbfa 2024-01-21 op iov[i].iov_len = ibuf_size(buf);
884 f36fd90a 2022-07-09 op i++;
885 f36fd90a 2022-07-09 op }
886 f36fd90a 2022-07-09 op
887 f36fd90a 2022-07-09 op again:
888 f36fd90a 2022-07-09 op if ((n = writev(msgbuf->fd, iov, i)) == -1) {
889 f36fd90a 2022-07-09 op if (errno == EINTR)
890 f36fd90a 2022-07-09 op goto again;
891 f36fd90a 2022-07-09 op if (errno == ENOBUFS)
892 f36fd90a 2022-07-09 op errno = EAGAIN;
893 f36fd90a 2022-07-09 op return (-1);
894 f36fd90a 2022-07-09 op }
895 f36fd90a 2022-07-09 op
896 f36fd90a 2022-07-09 op if (n == 0) { /* connection closed */
897 f36fd90a 2022-07-09 op errno = 0;
898 f36fd90a 2022-07-09 op return (0);
899 f36fd90a 2022-07-09 op }
900 f36fd90a 2022-07-09 op
901 f36fd90a 2022-07-09 op msgbuf_drain(msgbuf, n);
902 f36fd90a 2022-07-09 op
903 f36fd90a 2022-07-09 op return (1);
904 f36fd90a 2022-07-09 op }
905 f36fd90a 2022-07-09 op
906 f36fd90a 2022-07-09 op void
907 f36fd90a 2022-07-09 op msgbuf_init(struct msgbuf *msgbuf)
908 f36fd90a 2022-07-09 op {
909 f36fd90a 2022-07-09 op msgbuf->queued = 0;
910 f36fd90a 2022-07-09 op msgbuf->fd = -1;
911 f36fd90a 2022-07-09 op TAILQ_INIT(&msgbuf->bufs);
912 f36fd90a 2022-07-09 op }
913 f36fd90a 2022-07-09 op
914 3ac93df9 2023-07-02 op static void
915 f36fd90a 2022-07-09 op msgbuf_drain(struct msgbuf *msgbuf, size_t n)
916 f36fd90a 2022-07-09 op {
917 f36fd90a 2022-07-09 op struct ibuf *buf, *next;
918 f36fd90a 2022-07-09 op
919 f36fd90a 2022-07-09 op for (buf = TAILQ_FIRST(&msgbuf->bufs); buf != NULL && n > 0;
920 f36fd90a 2022-07-09 op buf = next) {
921 f36fd90a 2022-07-09 op next = TAILQ_NEXT(buf, entry);
922 fb5efbfa 2024-01-21 op if (n >= ibuf_size(buf)) {
923 fb5efbfa 2024-01-21 op n -= ibuf_size(buf);
924 f36fd90a 2022-07-09 op ibuf_dequeue(msgbuf, buf);
925 f36fd90a 2022-07-09 op } else {
926 f36fd90a 2022-07-09 op buf->rpos += n;
927 f36fd90a 2022-07-09 op n = 0;
928 f36fd90a 2022-07-09 op }
929 f36fd90a 2022-07-09 op }
930 f36fd90a 2022-07-09 op }
931 f36fd90a 2022-07-09 op
932 f36fd90a 2022-07-09 op void
933 f36fd90a 2022-07-09 op msgbuf_clear(struct msgbuf *msgbuf)
934 f36fd90a 2022-07-09 op {
935 f36fd90a 2022-07-09 op struct ibuf *buf;
936 f36fd90a 2022-07-09 op
937 f36fd90a 2022-07-09 op while ((buf = TAILQ_FIRST(&msgbuf->bufs)) != NULL)
938 f36fd90a 2022-07-09 op ibuf_dequeue(msgbuf, buf);
939 f36fd90a 2022-07-09 op }
940 f36fd90a 2022-07-09 op
941 f36fd90a 2022-07-09 op int
942 f36fd90a 2022-07-09 op msgbuf_write(struct msgbuf *msgbuf)
943 f36fd90a 2022-07-09 op {
944 f36fd90a 2022-07-09 op struct iovec iov[IOV_MAX];
945 f36fd90a 2022-07-09 op struct ibuf *buf, *buf0 = NULL;
946 f36fd90a 2022-07-09 op unsigned int i = 0;
947 f36fd90a 2022-07-09 op ssize_t n;
948 f36fd90a 2022-07-09 op struct msghdr msg;
949 f36fd90a 2022-07-09 op struct cmsghdr *cmsg;
950 f36fd90a 2022-07-09 op union {
951 f36fd90a 2022-07-09 op struct cmsghdr hdr;
952 f36fd90a 2022-07-09 op char buf[CMSG_SPACE(sizeof(int))];
953 f36fd90a 2022-07-09 op } cmsgbuf;
954 f36fd90a 2022-07-09 op
955 f36fd90a 2022-07-09 op memset(&iov, 0, sizeof(iov));
956 f36fd90a 2022-07-09 op memset(&msg, 0, sizeof(msg));
957 f36fd90a 2022-07-09 op memset(&cmsgbuf, 0, sizeof(cmsgbuf));
958 f36fd90a 2022-07-09 op TAILQ_FOREACH(buf, &msgbuf->bufs, entry) {
959 f36fd90a 2022-07-09 op if (i >= IOV_MAX)
960 f36fd90a 2022-07-09 op break;
961 f36fd90a 2022-07-09 op if (i > 0 && buf->fd != -1)
962 f36fd90a 2022-07-09 op break;
963 fb5efbfa 2024-01-21 op iov[i].iov_base = ibuf_data(buf);
964 fb5efbfa 2024-01-21 op iov[i].iov_len = ibuf_size(buf);
965 f36fd90a 2022-07-09 op i++;
966 f36fd90a 2022-07-09 op if (buf->fd != -1)
967 f36fd90a 2022-07-09 op buf0 = buf;
968 f36fd90a 2022-07-09 op }
969 f36fd90a 2022-07-09 op
970 f36fd90a 2022-07-09 op msg.msg_iov = iov;
971 f36fd90a 2022-07-09 op msg.msg_iovlen = i;
972 f36fd90a 2022-07-09 op
973 f36fd90a 2022-07-09 op if (buf0 != NULL) {
974 f36fd90a 2022-07-09 op msg.msg_control = (caddr_t)&cmsgbuf.buf;
975 f36fd90a 2022-07-09 op msg.msg_controllen = sizeof(cmsgbuf.buf);
976 f36fd90a 2022-07-09 op cmsg = CMSG_FIRSTHDR(&msg);
977 f36fd90a 2022-07-09 op cmsg->cmsg_len = CMSG_LEN(sizeof(int));
978 f36fd90a 2022-07-09 op cmsg->cmsg_level = SOL_SOCKET;
979 f36fd90a 2022-07-09 op cmsg->cmsg_type = SCM_RIGHTS;
980 f36fd90a 2022-07-09 op *(int *)CMSG_DATA(cmsg) = buf0->fd;
981 f36fd90a 2022-07-09 op }
982 f36fd90a 2022-07-09 op
983 f36fd90a 2022-07-09 op again:
984 f36fd90a 2022-07-09 op if ((n = sendmsg(msgbuf->fd, &msg, 0)) == -1) {
985 f36fd90a 2022-07-09 op if (errno == EINTR)
986 f36fd90a 2022-07-09 op goto again;
987 f36fd90a 2022-07-09 op if (errno == ENOBUFS)
988 f36fd90a 2022-07-09 op errno = EAGAIN;
989 f36fd90a 2022-07-09 op return (-1);
990 f36fd90a 2022-07-09 op }
991 f36fd90a 2022-07-09 op
992 f36fd90a 2022-07-09 op if (n == 0) { /* connection closed */
993 f36fd90a 2022-07-09 op errno = 0;
994 f36fd90a 2022-07-09 op return (0);
995 f36fd90a 2022-07-09 op }
996 f36fd90a 2022-07-09 op
997 f36fd90a 2022-07-09 op /*
998 f36fd90a 2022-07-09 op * assumption: fd got sent if sendmsg sent anything
999 f36fd90a 2022-07-09 op * this works because fds are passed one at a time
1000 f36fd90a 2022-07-09 op */
1001 f36fd90a 2022-07-09 op if (buf0 != NULL) {
1002 f36fd90a 2022-07-09 op close(buf0->fd);
1003 f36fd90a 2022-07-09 op buf0->fd = -1;
1004 f36fd90a 2022-07-09 op }
1005 f36fd90a 2022-07-09 op
1006 f36fd90a 2022-07-09 op msgbuf_drain(msgbuf, n);
1007 f36fd90a 2022-07-09 op
1008 f36fd90a 2022-07-09 op return (1);
1009 f36fd90a 2022-07-09 op }
1010 f36fd90a 2022-07-09 op
1011 fb5efbfa 2024-01-21 op uint32_t
1012 fb5efbfa 2024-01-21 op msgbuf_queuelen(struct msgbuf *msgbuf)
1013 fb5efbfa 2024-01-21 op {
1014 fb5efbfa 2024-01-21 op return (msgbuf->queued);
1015 fb5efbfa 2024-01-21 op }
1016 fb5efbfa 2024-01-21 op
1017 f36fd90a 2022-07-09 op static void
1018 f36fd90a 2022-07-09 op ibuf_enqueue(struct msgbuf *msgbuf, struct ibuf *buf)
1019 f36fd90a 2022-07-09 op {
1020 fb5efbfa 2024-01-21 op if (buf->max == 0) /* if buf lives on the stack */
1021 fb5efbfa 2024-01-21 op abort(); /* abort before causing more harm */
1022 f36fd90a 2022-07-09 op TAILQ_INSERT_TAIL(&msgbuf->bufs, buf, entry);
1023 f36fd90a 2022-07-09 op msgbuf->queued++;
1024 f36fd90a 2022-07-09 op }
1025 f36fd90a 2022-07-09 op
1026 f36fd90a 2022-07-09 op static void
1027 f36fd90a 2022-07-09 op ibuf_dequeue(struct msgbuf *msgbuf, struct ibuf *buf)
1028 f36fd90a 2022-07-09 op {
1029 f36fd90a 2022-07-09 op TAILQ_REMOVE(&msgbuf->bufs, buf, entry);
1030 f36fd90a 2022-07-09 op msgbuf->queued--;
1031 f36fd90a 2022-07-09 op ibuf_free(buf);
1032 f36fd90a 2022-07-09 op }
1033 f36fd90a 2022-07-09 op
1034 f36fd90a 2022-07-09 op /* imsg.c */
1035 f36fd90a 2022-07-09 op
1036 fb5efbfa 2024-01-21 op struct imsg_fd {
1037 fb5efbfa 2024-01-21 op TAILQ_ENTRY(imsg_fd) entry;
1038 fb5efbfa 2024-01-21 op int fd;
1039 fb5efbfa 2024-01-21 op };
1040 fb5efbfa 2024-01-21 op
1041 f36fd90a 2022-07-09 op int imsg_fd_overhead = 0;
1042 f36fd90a 2022-07-09 op
1043 fb5efbfa 2024-01-21 op static int imsg_dequeue_fd(struct imsgbuf *);
1044 f36fd90a 2022-07-09 op
1045 f36fd90a 2022-07-09 op void
1046 fb5efbfa 2024-01-21 op imsg_init(struct imsgbuf *imsgbuf, int fd)
1047 f36fd90a 2022-07-09 op {
1048 fb5efbfa 2024-01-21 op msgbuf_init(&imsgbuf->w);
1049 fb5efbfa 2024-01-21 op memset(&imsgbuf->r, 0, sizeof(imsgbuf->r));
1050 fb5efbfa 2024-01-21 op imsgbuf->fd = fd;
1051 fb5efbfa 2024-01-21 op imsgbuf->w.fd = fd;
1052 fb5efbfa 2024-01-21 op imsgbuf->pid = getpid();
1053 fb5efbfa 2024-01-21 op TAILQ_INIT(&imsgbuf->fds);
1054 f36fd90a 2022-07-09 op }
1055 f36fd90a 2022-07-09 op
1056 f36fd90a 2022-07-09 op ssize_t
1057 fb5efbfa 2024-01-21 op imsg_read(struct imsgbuf *imsgbuf)
1058 f36fd90a 2022-07-09 op {
1059 f36fd90a 2022-07-09 op struct msghdr msg;
1060 f36fd90a 2022-07-09 op struct cmsghdr *cmsg;
1061 f36fd90a 2022-07-09 op union {
1062 f36fd90a 2022-07-09 op struct cmsghdr hdr;
1063 f36fd90a 2022-07-09 op char buf[CMSG_SPACE(sizeof(int) * 1)];
1064 f36fd90a 2022-07-09 op } cmsgbuf;
1065 f36fd90a 2022-07-09 op struct iovec iov;
1066 f36fd90a 2022-07-09 op ssize_t n = -1;
1067 f36fd90a 2022-07-09 op int fd;
1068 f36fd90a 2022-07-09 op struct imsg_fd *ifd;
1069 f36fd90a 2022-07-09 op
1070 f36fd90a 2022-07-09 op memset(&msg, 0, sizeof(msg));
1071 f36fd90a 2022-07-09 op memset(&cmsgbuf, 0, sizeof(cmsgbuf));
1072 f36fd90a 2022-07-09 op
1073 fb5efbfa 2024-01-21 op iov.iov_base = imsgbuf->r.buf + imsgbuf->r.wpos;
1074 fb5efbfa 2024-01-21 op iov.iov_len = sizeof(imsgbuf->r.buf) - imsgbuf->r.wpos;
1075 f36fd90a 2022-07-09 op msg.msg_iov = &iov;
1076 f36fd90a 2022-07-09 op msg.msg_iovlen = 1;
1077 f36fd90a 2022-07-09 op msg.msg_control = &cmsgbuf.buf;
1078 f36fd90a 2022-07-09 op msg.msg_controllen = sizeof(cmsgbuf.buf);
1079 f36fd90a 2022-07-09 op
1080 f36fd90a 2022-07-09 op if ((ifd = calloc(1, sizeof(struct imsg_fd))) == NULL)
1081 f36fd90a 2022-07-09 op return (-1);
1082 f36fd90a 2022-07-09 op
1083 f36fd90a 2022-07-09 op again:
1084 f36fd90a 2022-07-09 op if (getdtablecount() + imsg_fd_overhead +
1085 f36fd90a 2022-07-09 op (int)((CMSG_SPACE(sizeof(int))-CMSG_SPACE(0))/sizeof(int))
1086 f36fd90a 2022-07-09 op >= getdtablesize()) {
1087 f36fd90a 2022-07-09 op errno = EAGAIN;
1088 f36fd90a 2022-07-09 op free(ifd);
1089 f36fd90a 2022-07-09 op return (-1);
1090 f36fd90a 2022-07-09 op }
1091 f36fd90a 2022-07-09 op
1092 fb5efbfa 2024-01-21 op if ((n = recvmsg(imsgbuf->fd, &msg, 0)) == -1) {
1093 f36fd90a 2022-07-09 op if (errno == EINTR)
1094 f36fd90a 2022-07-09 op goto again;
1095 f36fd90a 2022-07-09 op goto fail;
1096 f36fd90a 2022-07-09 op }
1097 f36fd90a 2022-07-09 op
1098 fb5efbfa 2024-01-21 op imsgbuf->r.wpos += n;
1099 f36fd90a 2022-07-09 op
1100 f36fd90a 2022-07-09 op for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL;
1101 f36fd90a 2022-07-09 op cmsg = CMSG_NXTHDR(&msg, cmsg)) {
1102 f36fd90a 2022-07-09 op if (cmsg->cmsg_level == SOL_SOCKET &&
1103 f36fd90a 2022-07-09 op cmsg->cmsg_type == SCM_RIGHTS) {
1104 f36fd90a 2022-07-09 op int i;
1105 f36fd90a 2022-07-09 op int j;
1106 f36fd90a 2022-07-09 op
1107 f36fd90a 2022-07-09 op /*
1108 f36fd90a 2022-07-09 op * We only accept one file descriptor. Due to C
1109 f36fd90a 2022-07-09 op * padding rules, our control buffer might contain
1110 f36fd90a 2022-07-09 op * more than one fd, and we must close them.
1111 f36fd90a 2022-07-09 op */
1112 f36fd90a 2022-07-09 op j = ((char *)cmsg + cmsg->cmsg_len -
1113 f36fd90a 2022-07-09 op (char *)CMSG_DATA(cmsg)) / sizeof(int);
1114 f36fd90a 2022-07-09 op for (i = 0; i < j; i++) {
1115 f36fd90a 2022-07-09 op fd = ((int *)CMSG_DATA(cmsg))[i];
1116 f36fd90a 2022-07-09 op if (ifd != NULL) {
1117 f36fd90a 2022-07-09 op ifd->fd = fd;
1118 fb5efbfa 2024-01-21 op TAILQ_INSERT_TAIL(&imsgbuf->fds, ifd,
1119 f36fd90a 2022-07-09 op entry);
1120 f36fd90a 2022-07-09 op ifd = NULL;
1121 f36fd90a 2022-07-09 op } else
1122 f36fd90a 2022-07-09 op close(fd);
1123 f36fd90a 2022-07-09 op }
1124 f36fd90a 2022-07-09 op }
1125 f36fd90a 2022-07-09 op /* we do not handle other ctl data level */
1126 f36fd90a 2022-07-09 op }
1127 f36fd90a 2022-07-09 op
1128 f36fd90a 2022-07-09 op fail:
1129 f36fd90a 2022-07-09 op free(ifd);
1130 f36fd90a 2022-07-09 op return (n);
1131 f36fd90a 2022-07-09 op }
1132 f36fd90a 2022-07-09 op
1133 f36fd90a 2022-07-09 op ssize_t
1134 fb5efbfa 2024-01-21 op imsg_get(struct imsgbuf *imsgbuf, struct imsg *imsg)
1135 f36fd90a 2022-07-09 op {
1136 fb5efbfa 2024-01-21 op struct imsg m;
1137 f36fd90a 2022-07-09 op size_t av, left, datalen;
1138 f36fd90a 2022-07-09 op
1139 fb5efbfa 2024-01-21 op av = imsgbuf->r.wpos;
1140 f36fd90a 2022-07-09 op
1141 f36fd90a 2022-07-09 op if (IMSG_HEADER_SIZE > av)
1142 f36fd90a 2022-07-09 op return (0);
1143 f36fd90a 2022-07-09 op
1144 fb5efbfa 2024-01-21 op memcpy(&m.hdr, imsgbuf->r.buf, sizeof(m.hdr));
1145 fb5efbfa 2024-01-21 op if (m.hdr.len < IMSG_HEADER_SIZE ||
1146 fb5efbfa 2024-01-21 op m.hdr.len > MAX_IMSGSIZE) {
1147 f36fd90a 2022-07-09 op errno = ERANGE;
1148 f36fd90a 2022-07-09 op return (-1);
1149 f36fd90a 2022-07-09 op }
1150 fb5efbfa 2024-01-21 op if (m.hdr.len > av)
1151 f36fd90a 2022-07-09 op return (0);
1152 f36fd90a 2022-07-09 op
1153 fb5efbfa 2024-01-21 op m.fd = -1;
1154 fb5efbfa 2024-01-21 op m.buf = NULL;
1155 fb5efbfa 2024-01-21 op m.data = NULL;
1156 f36fd90a 2022-07-09 op
1157 fb5efbfa 2024-01-21 op datalen = m.hdr.len - IMSG_HEADER_SIZE;
1158 fb5efbfa 2024-01-21 op imsgbuf->r.rptr = imsgbuf->r.buf + IMSG_HEADER_SIZE;
1159 fb5efbfa 2024-01-21 op if (datalen != 0) {
1160 fb5efbfa 2024-01-21 op if ((m.buf = ibuf_open(datalen)) == NULL)
1161 fb5efbfa 2024-01-21 op return (-1);
1162 fb5efbfa 2024-01-21 op if (ibuf_add(m.buf, imsgbuf->r.rptr, datalen) == -1) {
1163 fb5efbfa 2024-01-21 op /* this should never fail */
1164 fb5efbfa 2024-01-21 op ibuf_free(m.buf);
1165 fb5efbfa 2024-01-21 op return (-1);
1166 fb5efbfa 2024-01-21 op }
1167 fb5efbfa 2024-01-21 op m.data = ibuf_data(m.buf);
1168 fb5efbfa 2024-01-21 op }
1169 f36fd90a 2022-07-09 op
1170 fb5efbfa 2024-01-21 op if (m.hdr.flags & IMSGF_HASFD)
1171 fb5efbfa 2024-01-21 op m.fd = imsg_dequeue_fd(imsgbuf);
1172 fb5efbfa 2024-01-21 op
1173 fb5efbfa 2024-01-21 op if (m.hdr.len < av) {
1174 fb5efbfa 2024-01-21 op left = av - m.hdr.len;
1175 fb5efbfa 2024-01-21 op memmove(&imsgbuf->r.buf, imsgbuf->r.buf + m.hdr.len, left);
1176 fb5efbfa 2024-01-21 op imsgbuf->r.wpos = left;
1177 f36fd90a 2022-07-09 op } else
1178 fb5efbfa 2024-01-21 op imsgbuf->r.wpos = 0;
1179 f36fd90a 2022-07-09 op
1180 fb5efbfa 2024-01-21 op *imsg = m;
1181 f36fd90a 2022-07-09 op return (datalen + IMSG_HEADER_SIZE);
1182 f36fd90a 2022-07-09 op }
1183 f36fd90a 2022-07-09 op
1184 f36fd90a 2022-07-09 op int
1185 fb5efbfa 2024-01-21 op imsg_get_ibuf(struct imsg *imsg, struct ibuf *ibuf)
1186 fb5efbfa 2024-01-21 op {
1187 fb5efbfa 2024-01-21 op if (imsg->buf == NULL) {
1188 fb5efbfa 2024-01-21 op errno = EBADMSG;
1189 fb5efbfa 2024-01-21 op return (-1);
1190 fb5efbfa 2024-01-21 op }
1191 fb5efbfa 2024-01-21 op return ibuf_get_ibuf(imsg->buf, ibuf_size(imsg->buf), ibuf);
1192 fb5efbfa 2024-01-21 op }
1193 fb5efbfa 2024-01-21 op
1194 fb5efbfa 2024-01-21 op int
1195 fb5efbfa 2024-01-21 op imsg_get_data(struct imsg *imsg, void *data, size_t len)
1196 fb5efbfa 2024-01-21 op {
1197 fb5efbfa 2024-01-21 op if (len == 0) {
1198 fb5efbfa 2024-01-21 op errno = EINVAL;
1199 fb5efbfa 2024-01-21 op return (-1);
1200 fb5efbfa 2024-01-21 op }
1201 fb5efbfa 2024-01-21 op if (imsg->buf == NULL || ibuf_size(imsg->buf) != len) {
1202 fb5efbfa 2024-01-21 op errno = EBADMSG;
1203 fb5efbfa 2024-01-21 op return (-1);
1204 fb5efbfa 2024-01-21 op }
1205 fb5efbfa 2024-01-21 op return ibuf_get(imsg->buf, data, len);
1206 fb5efbfa 2024-01-21 op }
1207 fb5efbfa 2024-01-21 op
1208 fb5efbfa 2024-01-21 op int
1209 fb5efbfa 2024-01-21 op imsg_get_fd(struct imsg *imsg)
1210 fb5efbfa 2024-01-21 op {
1211 fb5efbfa 2024-01-21 op int fd = imsg->fd;
1212 fb5efbfa 2024-01-21 op
1213 fb5efbfa 2024-01-21 op imsg->fd = -1;
1214 fb5efbfa 2024-01-21 op return fd;
1215 fb5efbfa 2024-01-21 op }
1216 fb5efbfa 2024-01-21 op
1217 fb5efbfa 2024-01-21 op uint32_t
1218 fb5efbfa 2024-01-21 op imsg_get_id(struct imsg *imsg)
1219 fb5efbfa 2024-01-21 op {
1220 fb5efbfa 2024-01-21 op return (imsg->hdr.peerid);
1221 fb5efbfa 2024-01-21 op }
1222 fb5efbfa 2024-01-21 op
1223 fb5efbfa 2024-01-21 op size_t
1224 fb5efbfa 2024-01-21 op imsg_get_len(struct imsg *imsg)
1225 fb5efbfa 2024-01-21 op {
1226 fb5efbfa 2024-01-21 op if (imsg->buf == NULL)
1227 fb5efbfa 2024-01-21 op return 0;
1228 fb5efbfa 2024-01-21 op return ibuf_size(imsg->buf);
1229 fb5efbfa 2024-01-21 op }
1230 fb5efbfa 2024-01-21 op
1231 fb5efbfa 2024-01-21 op pid_t
1232 fb5efbfa 2024-01-21 op imsg_get_pid(struct imsg *imsg)
1233 fb5efbfa 2024-01-21 op {
1234 fb5efbfa 2024-01-21 op return (imsg->hdr.pid);
1235 fb5efbfa 2024-01-21 op }
1236 fb5efbfa 2024-01-21 op
1237 fb5efbfa 2024-01-21 op uint32_t
1238 fb5efbfa 2024-01-21 op imsg_get_type(struct imsg *imsg)
1239 f36fd90a 2022-07-09 op {
1240 fb5efbfa 2024-01-21 op return (imsg->hdr.type);
1241 fb5efbfa 2024-01-21 op }
1242 fb5efbfa 2024-01-21 op
1243 fb5efbfa 2024-01-21 op int
1244 fb5efbfa 2024-01-21 op imsg_compose(struct imsgbuf *imsgbuf, uint32_t type, uint32_t id, pid_t pid,
1245 fb5efbfa 2024-01-21 op int fd, const void *data, size_t datalen)
1246 fb5efbfa 2024-01-21 op {
1247 f36fd90a 2022-07-09 op struct ibuf *wbuf;
1248 f36fd90a 2022-07-09 op
1249 fb5efbfa 2024-01-21 op if ((wbuf = imsg_create(imsgbuf, type, id, pid, datalen)) == NULL)
1250 f36fd90a 2022-07-09 op return (-1);
1251 f36fd90a 2022-07-09 op
1252 f36fd90a 2022-07-09 op if (imsg_add(wbuf, data, datalen) == -1)
1253 f36fd90a 2022-07-09 op return (-1);
1254 f36fd90a 2022-07-09 op
1255 3ac93df9 2023-07-02 op ibuf_fd_set(wbuf, fd);
1256 fb5efbfa 2024-01-21 op imsg_close(imsgbuf, wbuf);
1257 f36fd90a 2022-07-09 op
1258 f36fd90a 2022-07-09 op return (1);
1259 f36fd90a 2022-07-09 op }
1260 f36fd90a 2022-07-09 op
1261 f36fd90a 2022-07-09 op int
1262 fb5efbfa 2024-01-21 op imsg_composev(struct imsgbuf *imsgbuf, uint32_t type, uint32_t id, pid_t pid,
1263 f36fd90a 2022-07-09 op int fd, const struct iovec *iov, int iovcnt)
1264 f36fd90a 2022-07-09 op {
1265 f36fd90a 2022-07-09 op struct ibuf *wbuf;
1266 fb5efbfa 2024-01-21 op int i;
1267 fb5efbfa 2024-01-21 op size_t datalen = 0;
1268 f36fd90a 2022-07-09 op
1269 f36fd90a 2022-07-09 op for (i = 0; i < iovcnt; i++)
1270 f36fd90a 2022-07-09 op datalen += iov[i].iov_len;
1271 f36fd90a 2022-07-09 op
1272 fb5efbfa 2024-01-21 op if ((wbuf = imsg_create(imsgbuf, type, id, pid, datalen)) == NULL)
1273 f36fd90a 2022-07-09 op return (-1);
1274 f36fd90a 2022-07-09 op
1275 f36fd90a 2022-07-09 op for (i = 0; i < iovcnt; i++)
1276 f36fd90a 2022-07-09 op if (imsg_add(wbuf, iov[i].iov_base, iov[i].iov_len) == -1)
1277 f36fd90a 2022-07-09 op return (-1);
1278 f36fd90a 2022-07-09 op
1279 3ac93df9 2023-07-02 op ibuf_fd_set(wbuf, fd);
1280 fb5efbfa 2024-01-21 op imsg_close(imsgbuf, wbuf);
1281 f36fd90a 2022-07-09 op
1282 f36fd90a 2022-07-09 op return (1);
1283 f36fd90a 2022-07-09 op }
1284 f36fd90a 2022-07-09 op
1285 fb5efbfa 2024-01-21 op /*
1286 fb5efbfa 2024-01-21 op * Enqueue imsg with payload from ibuf buf. fd passing is not possible
1287 fb5efbfa 2024-01-21 op * with this function.
1288 fb5efbfa 2024-01-21 op */
1289 3ac93df9 2023-07-02 op int
1290 fb5efbfa 2024-01-21 op imsg_compose_ibuf(struct imsgbuf *imsgbuf, uint32_t type, uint32_t id,
1291 3ac93df9 2023-07-02 op pid_t pid, struct ibuf *buf)
1292 3ac93df9 2023-07-02 op {
1293 fb5efbfa 2024-01-21 op struct ibuf *hdrbuf = NULL;
1294 3ac93df9 2023-07-02 op struct imsg_hdr hdr;
1295 3ac93df9 2023-07-02 op int save_errno;
1296 3ac93df9 2023-07-02 op
1297 3ac93df9 2023-07-02 op if (ibuf_size(buf) + IMSG_HEADER_SIZE > MAX_IMSGSIZE) {
1298 3ac93df9 2023-07-02 op errno = ERANGE;
1299 3ac93df9 2023-07-02 op goto fail;
1300 3ac93df9 2023-07-02 op }
1301 3ac93df9 2023-07-02 op
1302 3ac93df9 2023-07-02 op hdr.type = type;
1303 3ac93df9 2023-07-02 op hdr.len = ibuf_size(buf) + IMSG_HEADER_SIZE;
1304 3ac93df9 2023-07-02 op hdr.flags = 0;
1305 fb5efbfa 2024-01-21 op hdr.peerid = id;
1306 3ac93df9 2023-07-02 op if ((hdr.pid = pid) == 0)
1307 fb5efbfa 2024-01-21 op hdr.pid = imsgbuf->pid;
1308 3ac93df9 2023-07-02 op
1309 fb5efbfa 2024-01-21 op if ((hdrbuf = ibuf_open(IMSG_HEADER_SIZE)) == NULL)
1310 3ac93df9 2023-07-02 op goto fail;
1311 fb5efbfa 2024-01-21 op if (imsg_add(hdrbuf, &hdr, sizeof(hdr)) == -1)
1312 3ac93df9 2023-07-02 op goto fail;
1313 3ac93df9 2023-07-02 op
1314 fb5efbfa 2024-01-21 op ibuf_close(&imsgbuf->w, hdrbuf);
1315 fb5efbfa 2024-01-21 op ibuf_close(&imsgbuf->w, buf);
1316 3ac93df9 2023-07-02 op return (1);
1317 3ac93df9 2023-07-02 op
1318 3ac93df9 2023-07-02 op fail:
1319 3ac93df9 2023-07-02 op save_errno = errno;
1320 3ac93df9 2023-07-02 op ibuf_free(buf);
1321 fb5efbfa 2024-01-21 op ibuf_free(hdrbuf);
1322 3ac93df9 2023-07-02 op errno = save_errno;
1323 3ac93df9 2023-07-02 op return (-1);
1324 3ac93df9 2023-07-02 op }
1325 3ac93df9 2023-07-02 op
1326 fb5efbfa 2024-01-21 op /*
1327 fb5efbfa 2024-01-21 op * Forward imsg to another channel. Any attached fd is closed.
1328 fb5efbfa 2024-01-21 op */
1329 fb5efbfa 2024-01-21 op int
1330 fb5efbfa 2024-01-21 op imsg_forward(struct imsgbuf *imsgbuf, struct imsg *msg)
1331 fb5efbfa 2024-01-21 op {
1332 fb5efbfa 2024-01-21 op struct ibuf *wbuf;
1333 fb5efbfa 2024-01-21 op size_t len = 0;
1334 fb5efbfa 2024-01-21 op
1335 fb5efbfa 2024-01-21 op if (msg->fd != -1) {
1336 fb5efbfa 2024-01-21 op close(msg->fd);
1337 fb5efbfa 2024-01-21 op msg->fd = -1;
1338 fb5efbfa 2024-01-21 op }
1339 fb5efbfa 2024-01-21 op
1340 fb5efbfa 2024-01-21 op if (msg->buf != NULL) {
1341 fb5efbfa 2024-01-21 op ibuf_rewind(msg->buf);
1342 fb5efbfa 2024-01-21 op len = ibuf_size(msg->buf);
1343 fb5efbfa 2024-01-21 op }
1344 fb5efbfa 2024-01-21 op
1345 fb5efbfa 2024-01-21 op if ((wbuf = imsg_create(imsgbuf, msg->hdr.type, msg->hdr.peerid,
1346 fb5efbfa 2024-01-21 op msg->hdr.pid, len)) == NULL)
1347 fb5efbfa 2024-01-21 op return (-1);
1348 fb5efbfa 2024-01-21 op
1349 fb5efbfa 2024-01-21 op if (msg->buf != NULL) {
1350 fb5efbfa 2024-01-21 op if (ibuf_add_buf(wbuf, msg->buf) == -1) {
1351 fb5efbfa 2024-01-21 op ibuf_free(wbuf);
1352 fb5efbfa 2024-01-21 op return (-1);
1353 fb5efbfa 2024-01-21 op }
1354 fb5efbfa 2024-01-21 op }
1355 fb5efbfa 2024-01-21 op
1356 fb5efbfa 2024-01-21 op imsg_close(imsgbuf, wbuf);
1357 fb5efbfa 2024-01-21 op return (1);
1358 fb5efbfa 2024-01-21 op }
1359 fb5efbfa 2024-01-21 op
1360 f36fd90a 2022-07-09 op struct ibuf *
1361 fb5efbfa 2024-01-21 op imsg_create(struct imsgbuf *imsgbuf, uint32_t type, uint32_t id, pid_t pid,
1362 fb5efbfa 2024-01-21 op size_t datalen)
1363 f36fd90a 2022-07-09 op {
1364 f36fd90a 2022-07-09 op struct ibuf *wbuf;
1365 f36fd90a 2022-07-09 op struct imsg_hdr hdr;
1366 f36fd90a 2022-07-09 op
1367 f36fd90a 2022-07-09 op datalen += IMSG_HEADER_SIZE;
1368 f36fd90a 2022-07-09 op if (datalen > MAX_IMSGSIZE) {
1369 f36fd90a 2022-07-09 op errno = ERANGE;
1370 f36fd90a 2022-07-09 op return (NULL);
1371 f36fd90a 2022-07-09 op }
1372 f36fd90a 2022-07-09 op
1373 f36fd90a 2022-07-09 op hdr.type = type;
1374 f36fd90a 2022-07-09 op hdr.flags = 0;
1375 fb5efbfa 2024-01-21 op hdr.peerid = id;
1376 f36fd90a 2022-07-09 op if ((hdr.pid = pid) == 0)
1377 fb5efbfa 2024-01-21 op hdr.pid = imsgbuf->pid;
1378 f36fd90a 2022-07-09 op if ((wbuf = ibuf_dynamic(datalen, MAX_IMSGSIZE)) == NULL) {
1379 f36fd90a 2022-07-09 op return (NULL);
1380 f36fd90a 2022-07-09 op }
1381 f36fd90a 2022-07-09 op if (imsg_add(wbuf, &hdr, sizeof(hdr)) == -1)
1382 f36fd90a 2022-07-09 op return (NULL);
1383 f36fd90a 2022-07-09 op
1384 f36fd90a 2022-07-09 op return (wbuf);
1385 f36fd90a 2022-07-09 op }
1386 f36fd90a 2022-07-09 op
1387 f36fd90a 2022-07-09 op int
1388 fb5efbfa 2024-01-21 op imsg_add(struct ibuf *msg, const void *data, size_t datalen)
1389 f36fd90a 2022-07-09 op {
1390 f36fd90a 2022-07-09 op if (datalen)
1391 f36fd90a 2022-07-09 op if (ibuf_add(msg, data, datalen) == -1) {
1392 f36fd90a 2022-07-09 op ibuf_free(msg);
1393 f36fd90a 2022-07-09 op return (-1);
1394 f36fd90a 2022-07-09 op }
1395 f36fd90a 2022-07-09 op return (datalen);
1396 f36fd90a 2022-07-09 op }
1397 f36fd90a 2022-07-09 op
1398 f36fd90a 2022-07-09 op void
1399 fb5efbfa 2024-01-21 op imsg_close(struct imsgbuf *imsgbuf, struct ibuf *msg)
1400 f36fd90a 2022-07-09 op {
1401 f36fd90a 2022-07-09 op struct imsg_hdr *hdr;
1402 f36fd90a 2022-07-09 op
1403 f36fd90a 2022-07-09 op hdr = (struct imsg_hdr *)msg->buf;
1404 f36fd90a 2022-07-09 op
1405 f36fd90a 2022-07-09 op hdr->flags &= ~IMSGF_HASFD;
1406 3ac93df9 2023-07-02 op if (ibuf_fd_avail(msg))
1407 f36fd90a 2022-07-09 op hdr->flags |= IMSGF_HASFD;
1408 3ac93df9 2023-07-02 op hdr->len = ibuf_size(msg);
1409 f36fd90a 2022-07-09 op
1410 fb5efbfa 2024-01-21 op ibuf_close(&imsgbuf->w, msg);
1411 f36fd90a 2022-07-09 op }
1412 f36fd90a 2022-07-09 op
1413 f36fd90a 2022-07-09 op void
1414 f36fd90a 2022-07-09 op imsg_free(struct imsg *imsg)
1415 f36fd90a 2022-07-09 op {
1416 fb5efbfa 2024-01-21 op ibuf_free(imsg->buf);
1417 f36fd90a 2022-07-09 op }
1418 f36fd90a 2022-07-09 op
1419 f36fd90a 2022-07-09 op static int
1420 fb5efbfa 2024-01-21 op imsg_dequeue_fd(struct imsgbuf *imsgbuf)
1421 f36fd90a 2022-07-09 op {
1422 f36fd90a 2022-07-09 op int fd;
1423 f36fd90a 2022-07-09 op struct imsg_fd *ifd;
1424 f36fd90a 2022-07-09 op
1425 fb5efbfa 2024-01-21 op if ((ifd = TAILQ_FIRST(&imsgbuf->fds)) == NULL)
1426 f36fd90a 2022-07-09 op return (-1);
1427 f36fd90a 2022-07-09 op
1428 f36fd90a 2022-07-09 op fd = ifd->fd;
1429 fb5efbfa 2024-01-21 op TAILQ_REMOVE(&imsgbuf->fds, ifd, entry);
1430 f36fd90a 2022-07-09 op free(ifd);
1431 f36fd90a 2022-07-09 op
1432 f36fd90a 2022-07-09 op return (fd);
1433 f36fd90a 2022-07-09 op }
1434 f36fd90a 2022-07-09 op
1435 f36fd90a 2022-07-09 op int
1436 fb5efbfa 2024-01-21 op imsg_flush(struct imsgbuf *imsgbuf)
1437 f36fd90a 2022-07-09 op {
1438 fb5efbfa 2024-01-21 op while (imsgbuf->w.queued)
1439 fb5efbfa 2024-01-21 op if (msgbuf_write(&imsgbuf->w) <= 0)
1440 f36fd90a 2022-07-09 op return (-1);
1441 f36fd90a 2022-07-09 op return (0);
1442 f36fd90a 2022-07-09 op }
1443 f36fd90a 2022-07-09 op
1444 f36fd90a 2022-07-09 op void
1445 fb5efbfa 2024-01-21 op imsg_clear(struct imsgbuf *imsgbuf)
1446 f36fd90a 2022-07-09 op {
1447 f36fd90a 2022-07-09 op int fd;
1448 f36fd90a 2022-07-09 op
1449 fb5efbfa 2024-01-21 op msgbuf_clear(&imsgbuf->w);
1450 fb5efbfa 2024-01-21 op while ((fd = imsg_dequeue_fd(imsgbuf)) != -1)
1451 f36fd90a 2022-07-09 op close(fd);
1452 f36fd90a 2022-07-09 op }
1453 82556d5b 2023-09-07 op #endif /* HAVE_LIB_IMSG */
1454 f36fd90a 2022-07-09 op #if !HAVE_MEMMEM
1455 f36fd90a 2022-07-09 op /*-
1456 f36fd90a 2022-07-09 op * Copyright (c) 2005 Pascal Gloor <pascal.gloor@spale.com>
1457 f36fd90a 2022-07-09 op *
1458 f36fd90a 2022-07-09 op * Redistribution and use in source and binary forms, with or without
1459 f36fd90a 2022-07-09 op * modification, are permitted provided that the following conditions
1460 f36fd90a 2022-07-09 op * are met:
1461 f36fd90a 2022-07-09 op * 1. Redistributions of source code must retain the above copyright
1462 f36fd90a 2022-07-09 op * notice, this list of conditions and the following disclaimer.
1463 f36fd90a 2022-07-09 op * 2. Redistributions in binary form must reproduce the above copyright
1464 f36fd90a 2022-07-09 op * notice, this list of conditions and the following disclaimer in
1465 f36fd90a 2022-07-09 op * the documentation and/or other materials provided with the
1466 f36fd90a 2022-07-09 op * distribution.
1467 f36fd90a 2022-07-09 op * 3. The name of the author may not be used to endorse or promote
1468 f36fd90a 2022-07-09 op * products derived from this software without specific prior written
1469 f36fd90a 2022-07-09 op * permission.
1470 f36fd90a 2022-07-09 op *
1471 f36fd90a 2022-07-09 op * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS''
1472 f36fd90a 2022-07-09 op * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
1473 f36fd90a 2022-07-09 op * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
1474 f36fd90a 2022-07-09 op * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR
1475 f36fd90a 2022-07-09 op * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
1476 f36fd90a 2022-07-09 op * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
1477 f36fd90a 2022-07-09 op * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
1478 f36fd90a 2022-07-09 op * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
1479 f36fd90a 2022-07-09 op * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
1480 f36fd90a 2022-07-09 op * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
1481 f36fd90a 2022-07-09 op * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1482 f36fd90a 2022-07-09 op */
1483 f36fd90a 2022-07-09 op /*
1484 f36fd90a 2022-07-09 op * Find the first occurrence of the byte string s in byte string l.
1485 f36fd90a 2022-07-09 op */
1486 f36fd90a 2022-07-09 op void *
1487 f36fd90a 2022-07-09 op memmem(const void *l, size_t l_len, const void *s, size_t s_len)
1488 f36fd90a 2022-07-09 op {
1489 f36fd90a 2022-07-09 op const char *cur, *last;
1490 f36fd90a 2022-07-09 op const char *cl = l;
1491 f36fd90a 2022-07-09 op const char *cs = s;
1492 f36fd90a 2022-07-09 op
1493 f36fd90a 2022-07-09 op /* a zero length needle should just return the haystack */
1494 f36fd90a 2022-07-09 op if (l_len == 0)
1495 f36fd90a 2022-07-09 op return (void *)cl;
1496 f36fd90a 2022-07-09 op
1497 f36fd90a 2022-07-09 op /* "s" must be smaller or equal to "l" */
1498 f36fd90a 2022-07-09 op if (l_len < s_len)
1499 f36fd90a 2022-07-09 op return NULL;
1500 f36fd90a 2022-07-09 op
1501 f36fd90a 2022-07-09 op /* special case where s_len == 1 */
1502 f36fd90a 2022-07-09 op if (s_len == 1)
1503 f36fd90a 2022-07-09 op return memchr(l, *cs, l_len);
1504 f36fd90a 2022-07-09 op
1505 f36fd90a 2022-07-09 op /* the last position where its possible to find "s" in "l" */
1506 f36fd90a 2022-07-09 op last = cl + l_len - s_len;
1507 f36fd90a 2022-07-09 op
1508 f36fd90a 2022-07-09 op for (cur = cl; cur <= last; cur++)
1509 f36fd90a 2022-07-09 op if (cur[0] == cs[0] && memcmp(cur, cs, s_len) == 0)
1510 f36fd90a 2022-07-09 op return (void *)cur;
1511 f36fd90a 2022-07-09 op
1512 f36fd90a 2022-07-09 op return NULL;
1513 f36fd90a 2022-07-09 op }
1514 f36fd90a 2022-07-09 op #endif /* !HAVE_MEMMEM */
1515 f36fd90a 2022-07-09 op #if !HAVE_MEMRCHR
1516 f36fd90a 2022-07-09 op /*
1517 f36fd90a 2022-07-09 op * Copyright (c) 2007 Todd C. Miller <Todd.Miller@courtesan.com>
1518 f36fd90a 2022-07-09 op *
1519 f36fd90a 2022-07-09 op * Permission to use, copy, modify, and distribute this software for any
1520 f36fd90a 2022-07-09 op * purpose with or without fee is hereby granted, provided that the above
1521 f36fd90a 2022-07-09 op * copyright notice and this permission notice appear in all copies.
1522 f36fd90a 2022-07-09 op *
1523 f36fd90a 2022-07-09 op * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
1524 f36fd90a 2022-07-09 op * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
1525 f36fd90a 2022-07-09 op * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
1526 f36fd90a 2022-07-09 op * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
1527 f36fd90a 2022-07-09 op * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
1528 f36fd90a 2022-07-09 op * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
1529 f36fd90a 2022-07-09 op * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1530 f36fd90a 2022-07-09 op *
1531 f36fd90a 2022-07-09 op */
1532 f36fd90a 2022-07-09 op
1533 f36fd90a 2022-07-09 op #include <string.h>
1534 f36fd90a 2022-07-09 op
1535 f36fd90a 2022-07-09 op /*
1536 f36fd90a 2022-07-09 op * Reverse memchr()
1537 f36fd90a 2022-07-09 op * Find the last occurrence of 'c' in the buffer 's' of size 'n'.
1538 f36fd90a 2022-07-09 op */
1539 f36fd90a 2022-07-09 op void *
1540 f36fd90a 2022-07-09 op memrchr(const void *s, int c, size_t n)
1541 f36fd90a 2022-07-09 op {
1542 f36fd90a 2022-07-09 op const unsigned char *cp;
1543 f36fd90a 2022-07-09 op
1544 f36fd90a 2022-07-09 op if (n != 0) {
1545 f36fd90a 2022-07-09 op cp = (unsigned char *)s + n;
1546 f36fd90a 2022-07-09 op do {
1547 f36fd90a 2022-07-09 op if (*(--cp) == (unsigned char)c)
1548 f36fd90a 2022-07-09 op return((void *)cp);
1549 f36fd90a 2022-07-09 op } while (--n != 0);
1550 f36fd90a 2022-07-09 op }
1551 f36fd90a 2022-07-09 op return(NULL);
1552 f36fd90a 2022-07-09 op }
1553 f36fd90a 2022-07-09 op #endif /* !HAVE_MEMRCHR */
1554 f36fd90a 2022-07-09 op #if !HAVE_OPTRESET
1555 f36fd90a 2022-07-09 op /*
1556 f36fd90a 2022-07-09 op * Copyright (c) 1987, 1993, 1994
1557 f36fd90a 2022-07-09 op * The Regents of the University of California. All rights reserved.
1558 f36fd90a 2022-07-09 op *
1559 f36fd90a 2022-07-09 op * Redistribution and use in source and binary forms, with or without
1560 f36fd90a 2022-07-09 op * modification, are permitted provided that the following conditions
1561 f36fd90a 2022-07-09 op * are met:
1562 f36fd90a 2022-07-09 op * 1. Redistributions of source code must retain the above copyright
1563 f36fd90a 2022-07-09 op * notice, this list of conditions and the following disclaimer.
1564 f36fd90a 2022-07-09 op * 2. Redistributions in binary form must reproduce the above copyright
1565 f36fd90a 2022-07-09 op * notice, this list of conditions and the following disclaimer in the
1566 f36fd90a 2022-07-09 op * documentation and/or other materials provided with the distribution.
1567 f36fd90a 2022-07-09 op * 3. Neither the name of the University nor the names of its contributors
1568 f36fd90a 2022-07-09 op * may be used to endorse or promote products derived from this software
1569 f36fd90a 2022-07-09 op * without specific prior written permission.
1570 f36fd90a 2022-07-09 op *
1571 f36fd90a 2022-07-09 op * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
1572 f36fd90a 2022-07-09 op * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1573 f36fd90a 2022-07-09 op * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1574 f36fd90a 2022-07-09 op * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
1575 f36fd90a 2022-07-09 op * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1576 f36fd90a 2022-07-09 op * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
1577 f36fd90a 2022-07-09 op * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1578 f36fd90a 2022-07-09 op * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1579 f36fd90a 2022-07-09 op * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
1580 f36fd90a 2022-07-09 op * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
1581 f36fd90a 2022-07-09 op * SUCH DAMAGE.
1582 f36fd90a 2022-07-09 op */
1583 f36fd90a 2022-07-09 op
1584 f36fd90a 2022-07-09 op /* OPENBSD ORIGINAL: lib/libc/stdlib/getopt.c */
1585 f36fd90a 2022-07-09 op
1586 f36fd90a 2022-07-09 op #include <stdio.h>
1587 f36fd90a 2022-07-09 op #include <stdlib.h>
1588 f36fd90a 2022-07-09 op #include <string.h>
1589 f36fd90a 2022-07-09 op
1590 f36fd90a 2022-07-09 op int BSDopterr = 1, /* if error message should be printed */
1591 f36fd90a 2022-07-09 op BSDoptind = 1, /* index into parent argv vector */
1592 f36fd90a 2022-07-09 op BSDoptopt, /* character checked for validity */
1593 f36fd90a 2022-07-09 op BSDoptreset; /* reset getopt */
1594 f36fd90a 2022-07-09 op char *BSDoptarg; /* argument associated with option */
1595 f36fd90a 2022-07-09 op
1596 f36fd90a 2022-07-09 op #define BADCH (int)'?'
1597 f36fd90a 2022-07-09 op #define BADARG (int)':'
1598 f36fd90a 2022-07-09 op #define EMSG ""
1599 f36fd90a 2022-07-09 op
1600 f36fd90a 2022-07-09 op /*
1601 f36fd90a 2022-07-09 op * getopt --
1602 f36fd90a 2022-07-09 op * Parse argc/argv argument vector.
1603 f36fd90a 2022-07-09 op */
1604 f36fd90a 2022-07-09 op int
1605 f36fd90a 2022-07-09 op BSDgetopt(int nargc, char *const *nargv, const char *ostr)
1606 f36fd90a 2022-07-09 op {
1607 f36fd90a 2022-07-09 op static const char *place = EMSG; /* option letter processing */
1608 f36fd90a 2022-07-09 op char *oli; /* option letter list index */
1609 f36fd90a 2022-07-09 op
1610 f36fd90a 2022-07-09 op if (ostr == NULL)
1611 f36fd90a 2022-07-09 op return (-1);
1612 f36fd90a 2022-07-09 op
1613 f36fd90a 2022-07-09 op if (BSDoptreset || !*place) { /* update scanning pointer */
1614 f36fd90a 2022-07-09 op BSDoptreset = 0;
1615 f36fd90a 2022-07-09 op if (BSDoptind >= nargc || *(place = nargv[BSDoptind]) != '-') {
1616 f36fd90a 2022-07-09 op place = EMSG;
1617 f36fd90a 2022-07-09 op return (-1);
1618 f36fd90a 2022-07-09 op }
1619 f36fd90a 2022-07-09 op if (place[1] && *++place == '-') { /* found "--" */
1620 f36fd90a 2022-07-09 op if (place[1])
1621 f36fd90a 2022-07-09 op return (BADCH);
1622 f36fd90a 2022-07-09 op ++BSDoptind;
1623 f36fd90a 2022-07-09 op place = EMSG;
1624 f36fd90a 2022-07-09 op return (-1);
1625 f36fd90a 2022-07-09 op }
1626 f36fd90a 2022-07-09 op } /* option letter okay? */
1627 f36fd90a 2022-07-09 op if ((BSDoptopt = (int)*place++) == (int)':' ||
1628 f36fd90a 2022-07-09 op !(oli = strchr(ostr, BSDoptopt))) {
1629 f36fd90a 2022-07-09 op /*
1630 f36fd90a 2022-07-09 op * if the user didn't specify '-' as an option,
1631 f36fd90a 2022-07-09 op * assume it means -1.
1632 f36fd90a 2022-07-09 op */
1633 f36fd90a 2022-07-09 op if (BSDoptopt == (int)'-')
1634 f36fd90a 2022-07-09 op return (-1);
1635 f36fd90a 2022-07-09 op if (!*place)
1636 f36fd90a 2022-07-09 op ++BSDoptind;
1637 f36fd90a 2022-07-09 op if (BSDopterr && *ostr != ':')
1638 f36fd90a 2022-07-09 op (void)fprintf(stderr,
1639 f36fd90a 2022-07-09 op "%s: unknown option -- %c\n", getprogname(),
1640 f36fd90a 2022-07-09 op BSDoptopt);
1641 f36fd90a 2022-07-09 op return (BADCH);
1642 f36fd90a 2022-07-09 op }
1643 f36fd90a 2022-07-09 op if (*++oli != ':') { /* don't need argument */
1644 f36fd90a 2022-07-09 op BSDoptarg = NULL;
1645 f36fd90a 2022-07-09 op if (!*place)
1646 f36fd90a 2022-07-09 op ++BSDoptind;
1647 f36fd90a 2022-07-09 op }
1648 f36fd90a 2022-07-09 op else { /* need an argument */
1649 f36fd90a 2022-07-09 op if (*place) /* no white space */
1650 f36fd90a 2022-07-09 op BSDoptarg = (char *)place;
1651 f36fd90a 2022-07-09 op else if (nargc <= ++BSDoptind) { /* no arg */
1652 f36fd90a 2022-07-09 op place = EMSG;
1653 f36fd90a 2022-07-09 op if (*ostr == ':')
1654 f36fd90a 2022-07-09 op return (BADARG);
1655 f36fd90a 2022-07-09 op if (BSDopterr)
1656 f36fd90a 2022-07-09 op (void)fprintf(stderr,
1657 f36fd90a 2022-07-09 op "%s: option requires an argument -- %c\n",
1658 f36fd90a 2022-07-09 op getprogname(), BSDoptopt);
1659 f36fd90a 2022-07-09 op return (BADCH);
1660 f36fd90a 2022-07-09 op }
1661 f36fd90a 2022-07-09 op else /* white space */
1662 f36fd90a 2022-07-09 op BSDoptarg = nargv[BSDoptind];
1663 f36fd90a 2022-07-09 op place = EMSG;
1664 f36fd90a 2022-07-09 op ++BSDoptind;
1665 f36fd90a 2022-07-09 op }
1666 f36fd90a 2022-07-09 op return (BSDoptopt); /* dump back option letter */
1667 f36fd90a 2022-07-09 op }
1668 f36fd90a 2022-07-09 op #endif
1669 f36fd90a 2022-07-09 op #if !HAVE_REALLOCARRAY
1670 f36fd90a 2022-07-09 op /*
1671 f36fd90a 2022-07-09 op * Copyright (c) 2008 Otto Moerbeek <otto@drijf.net>
1672 f36fd90a 2022-07-09 op *
1673 f36fd90a 2022-07-09 op * Permission to use, copy, modify, and distribute this software for any
1674 f36fd90a 2022-07-09 op * purpose with or without fee is hereby granted, provided that the above
1675 f36fd90a 2022-07-09 op * copyright notice and this permission notice appear in all copies.
1676 f36fd90a 2022-07-09 op *
1677 f36fd90a 2022-07-09 op * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
1678 f36fd90a 2022-07-09 op * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
1679 f36fd90a 2022-07-09 op * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
1680 f36fd90a 2022-07-09 op * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
1681 f36fd90a 2022-07-09 op * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
1682 f36fd90a 2022-07-09 op * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
1683 f36fd90a 2022-07-09 op * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1684 f36fd90a 2022-07-09 op */
1685 f36fd90a 2022-07-09 op
1686 f36fd90a 2022-07-09 op #include <sys/types.h>
1687 f36fd90a 2022-07-09 op #include <errno.h>
1688 f36fd90a 2022-07-09 op #include <stdint.h>
1689 f36fd90a 2022-07-09 op #include <stdlib.h>
1690 f36fd90a 2022-07-09 op
1691 f36fd90a 2022-07-09 op /*
1692 f36fd90a 2022-07-09 op * This is sqrt(SIZE_MAX+1), as s1*s2 <= SIZE_MAX
1693 f36fd90a 2022-07-09 op * if both s1 < MUL_NO_OVERFLOW and s2 < MUL_NO_OVERFLOW
1694 f36fd90a 2022-07-09 op */
1695 f36fd90a 2022-07-09 op #define MUL_NO_OVERFLOW ((size_t)1 << (sizeof(size_t) * 4))
1696 f36fd90a 2022-07-09 op
1697 f36fd90a 2022-07-09 op void *
1698 f36fd90a 2022-07-09 op reallocarray(void *optr, size_t nmemb, size_t size)
1699 f36fd90a 2022-07-09 op {
1700 f36fd90a 2022-07-09 op if ((nmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) &&
1701 f36fd90a 2022-07-09 op nmemb > 0 && SIZE_MAX / nmemb < size) {
1702 f36fd90a 2022-07-09 op errno = ENOMEM;
1703 f36fd90a 2022-07-09 op return NULL;
1704 f36fd90a 2022-07-09 op }
1705 f36fd90a 2022-07-09 op return realloc(optr, size * nmemb);
1706 f36fd90a 2022-07-09 op }
1707 f36fd90a 2022-07-09 op #endif /* !HAVE_REALLOCARRAY */
1708 f36fd90a 2022-07-09 op #if !HAVE_RECALLOCARRAY
1709 f36fd90a 2022-07-09 op /*
1710 f36fd90a 2022-07-09 op * Copyright (c) 2008, 2017 Otto Moerbeek <otto@drijf.net>
1711 f36fd90a 2022-07-09 op *
1712 f36fd90a 2022-07-09 op * Permission to use, copy, modify, and distribute this software for any
1713 f36fd90a 2022-07-09 op * purpose with or without fee is hereby granted, provided that the above
1714 f36fd90a 2022-07-09 op * copyright notice and this permission notice appear in all copies.
1715 f36fd90a 2022-07-09 op *
1716 f36fd90a 2022-07-09 op * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
1717 f36fd90a 2022-07-09 op * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
1718 f36fd90a 2022-07-09 op * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
1719 f36fd90a 2022-07-09 op * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
1720 f36fd90a 2022-07-09 op * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
1721 f36fd90a 2022-07-09 op * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
1722 f36fd90a 2022-07-09 op * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1723 f36fd90a 2022-07-09 op */
1724 f36fd90a 2022-07-09 op
1725 f36fd90a 2022-07-09 op /* OPENBSD ORIGINAL: lib/libc/stdlib/recallocarray.c */
1726 f36fd90a 2022-07-09 op
1727 f36fd90a 2022-07-09 op #include <errno.h>
1728 f36fd90a 2022-07-09 op #include <stdlib.h>
1729 f36fd90a 2022-07-09 op #include <stdint.h>
1730 f36fd90a 2022-07-09 op #include <string.h>
1731 f36fd90a 2022-07-09 op #include <unistd.h>
1732 f36fd90a 2022-07-09 op
1733 f36fd90a 2022-07-09 op /*
1734 f36fd90a 2022-07-09 op * This is sqrt(SIZE_MAX+1), as s1*s2 <= SIZE_MAX
1735 f36fd90a 2022-07-09 op * if both s1 < MUL_NO_OVERFLOW and s2 < MUL_NO_OVERFLOW
1736 f36fd90a 2022-07-09 op */
1737 f36fd90a 2022-07-09 op #define MUL_NO_OVERFLOW ((size_t)1 << (sizeof(size_t) * 4))
1738 f36fd90a 2022-07-09 op
1739 f36fd90a 2022-07-09 op void *
1740 f36fd90a 2022-07-09 op recallocarray(void *ptr, size_t oldnmemb, size_t newnmemb, size_t size)
1741 f36fd90a 2022-07-09 op {
1742 f36fd90a 2022-07-09 op size_t oldsize, newsize;
1743 f36fd90a 2022-07-09 op void *newptr;
1744 f36fd90a 2022-07-09 op
1745 f36fd90a 2022-07-09 op if (ptr == NULL)
1746 f36fd90a 2022-07-09 op return calloc(newnmemb, size);
1747 f36fd90a 2022-07-09 op
1748 f36fd90a 2022-07-09 op if ((newnmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) &&
1749 f36fd90a 2022-07-09 op newnmemb > 0 && SIZE_MAX / newnmemb < size) {
1750 f36fd90a 2022-07-09 op errno = ENOMEM;
1751 f36fd90a 2022-07-09 op return NULL;
1752 f36fd90a 2022-07-09 op }
1753 f36fd90a 2022-07-09 op newsize = newnmemb * size;
1754 f36fd90a 2022-07-09 op
1755 f36fd90a 2022-07-09 op if ((oldnmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) &&
1756 f36fd90a 2022-07-09 op oldnmemb > 0 && SIZE_MAX / oldnmemb < size) {
1757 f36fd90a 2022-07-09 op errno = EINVAL;
1758 f36fd90a 2022-07-09 op return NULL;
1759 f36fd90a 2022-07-09 op }
1760 f36fd90a 2022-07-09 op oldsize = oldnmemb * size;
1761 f36fd90a 2022-07-09 op
1762 f36fd90a 2022-07-09 op /*
1763 f36fd90a 2022-07-09 op * Don't bother too much if we're shrinking just a bit,
1764 f36fd90a 2022-07-09 op * we do not shrink for series of small steps, oh well.
1765 f36fd90a 2022-07-09 op */
1766 f36fd90a 2022-07-09 op if (newsize <= oldsize) {
1767 f36fd90a 2022-07-09 op size_t d = oldsize - newsize;
1768 f36fd90a 2022-07-09 op
1769 f36fd90a 2022-07-09 op if (d < oldsize / 2 && d < (size_t)getpagesize()) {
1770 f36fd90a 2022-07-09 op memset((char *)ptr + newsize, 0, d);
1771 f36fd90a 2022-07-09 op return ptr;
1772 f36fd90a 2022-07-09 op }
1773 f36fd90a 2022-07-09 op }
1774 f36fd90a 2022-07-09 op
1775 f36fd90a 2022-07-09 op newptr = malloc(newsize);
1776 f36fd90a 2022-07-09 op if (newptr == NULL)
1777 f36fd90a 2022-07-09 op return NULL;
1778 f36fd90a 2022-07-09 op
1779 f36fd90a 2022-07-09 op if (newsize > oldsize) {
1780 f36fd90a 2022-07-09 op memcpy(newptr, ptr, oldsize);
1781 f36fd90a 2022-07-09 op memset((char *)newptr + oldsize, 0, newsize - oldsize);
1782 f36fd90a 2022-07-09 op } else
1783 f36fd90a 2022-07-09 op memcpy(newptr, ptr, newsize);
1784 f36fd90a 2022-07-09 op
1785 f36fd90a 2022-07-09 op explicit_bzero(ptr, oldsize);
1786 f36fd90a 2022-07-09 op free(ptr);
1787 f36fd90a 2022-07-09 op
1788 f36fd90a 2022-07-09 op return newptr;
1789 f36fd90a 2022-07-09 op }
1790 f36fd90a 2022-07-09 op #endif /* !HAVE_RECALLOCARRAY */
1791 f36fd90a 2022-07-09 op #if !HAVE_SETPROCTITLE
1792 f36fd90a 2022-07-09 op /*
1793 f36fd90a 2022-07-09 op * Copyright (c) 2016 Nicholas Marriott <nicholas.marriott@gmail.com>
1794 f36fd90a 2022-07-09 op *
1795 f36fd90a 2022-07-09 op * Permission to use, copy, modify, and distribute this software for any
1796 f36fd90a 2022-07-09 op * purpose with or without fee is hereby granted, provided that the above
1797 f36fd90a 2022-07-09 op * copyright notice and this permission notice appear in all copies.
1798 f36fd90a 2022-07-09 op *
1799 f36fd90a 2022-07-09 op * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
1800 f36fd90a 2022-07-09 op * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
1801 f36fd90a 2022-07-09 op * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
1802 f36fd90a 2022-07-09 op * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
1803 f36fd90a 2022-07-09 op * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
1804 f36fd90a 2022-07-09 op * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
1805 f36fd90a 2022-07-09 op * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1806 f36fd90a 2022-07-09 op */
1807 f36fd90a 2022-07-09 op
1808 f36fd90a 2022-07-09 op # if HAVE_PR_SET_NAME
1809 f36fd90a 2022-07-09 op #include <sys/types.h>
1810 f36fd90a 2022-07-09 op #include <stdarg.h>
1811 f36fd90a 2022-07-09 op #include <stdio.h>
1812 f36fd90a 2022-07-09 op #include <string.h>
1813 f36fd90a 2022-07-09 op #include <sys/prctl.h>
1814 f36fd90a 2022-07-09 op void
1815 f36fd90a 2022-07-09 op setproctitle(const char *fmt, ...)
1816 f36fd90a 2022-07-09 op {
1817 f36fd90a 2022-07-09 op char title[16], name[16], *cp;
1818 f36fd90a 2022-07-09 op va_list ap;
1819 f36fd90a 2022-07-09 op int used;
1820 f36fd90a 2022-07-09 op
1821 f36fd90a 2022-07-09 op va_start(ap, fmt);
1822 f36fd90a 2022-07-09 op vsnprintf(title, sizeof(title), fmt, ap);
1823 f36fd90a 2022-07-09 op va_end(ap);
1824 f36fd90a 2022-07-09 op
1825 f36fd90a 2022-07-09 op used = snprintf(name, sizeof(name), "%s: %s", getprogname(), title);
1826 f36fd90a 2022-07-09 op if (used >= (int)sizeof(name)) {
1827 f36fd90a 2022-07-09 op cp = strrchr(name, ' ');
1828 f36fd90a 2022-07-09 op if (cp != NULL)
1829 f36fd90a 2022-07-09 op *cp = '\0';
1830 f36fd90a 2022-07-09 op }
1831 f36fd90a 2022-07-09 op prctl(PR_SET_NAME, name);
1832 f36fd90a 2022-07-09 op }
1833 f36fd90a 2022-07-09 op # else
1834 f36fd90a 2022-07-09 op void
1835 f36fd90a 2022-07-09 op setproctitle(const char *fmt, ...)
1836 f36fd90a 2022-07-09 op {
1837 f36fd90a 2022-07-09 op return;
1838 f36fd90a 2022-07-09 op }
1839 f36fd90a 2022-07-09 op # endif
1840 f36fd90a 2022-07-09 op #endif /* !HAVE_SETPROCTITLE */
1841 f36fd90a 2022-07-09 op #if !HAVE_STRLCAT
1842 f36fd90a 2022-07-09 op /*
1843 f36fd90a 2022-07-09 op * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
1844 f36fd90a 2022-07-09 op *
1845 f36fd90a 2022-07-09 op * Permission to use, copy, modify, and distribute this software for any
1846 f36fd90a 2022-07-09 op * purpose with or without fee is hereby granted, provided that the above
1847 f36fd90a 2022-07-09 op * copyright notice and this permission notice appear in all copies.
1848 f36fd90a 2022-07-09 op *
1849 f36fd90a 2022-07-09 op * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
1850 f36fd90a 2022-07-09 op * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
1851 f36fd90a 2022-07-09 op * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
1852 f36fd90a 2022-07-09 op * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
1853 f36fd90a 2022-07-09 op * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
1854 f36fd90a 2022-07-09 op * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
1855 f36fd90a 2022-07-09 op * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1856 f36fd90a 2022-07-09 op */
1857 f36fd90a 2022-07-09 op
1858 f36fd90a 2022-07-09 op #include <sys/types.h>
1859 f36fd90a 2022-07-09 op #include <string.h>
1860 f36fd90a 2022-07-09 op
1861 f36fd90a 2022-07-09 op /*
1862 f36fd90a 2022-07-09 op * Appends src to string dst of size siz (unlike strncat, siz is the
1863 f36fd90a 2022-07-09 op * full size of dst, not space left). At most siz-1 characters
1864 f36fd90a 2022-07-09 op * will be copied. Always NUL terminates (unless siz <= strlen(dst)).
1865 f36fd90a 2022-07-09 op * Returns strlen(src) + MIN(siz, strlen(initial dst)).
1866 f36fd90a 2022-07-09 op * If retval >= siz, truncation occurred.
1867 f36fd90a 2022-07-09 op */
1868 f36fd90a 2022-07-09 op size_t
1869 f36fd90a 2022-07-09 op strlcat(char *dst, const char *src, size_t siz)
1870 f36fd90a 2022-07-09 op {
1871 f36fd90a 2022-07-09 op char *d = dst;
1872 f36fd90a 2022-07-09 op const char *s = src;
1873 f36fd90a 2022-07-09 op size_t n = siz;
1874 f36fd90a 2022-07-09 op size_t dlen;
1875 f36fd90a 2022-07-09 op
1876 f36fd90a 2022-07-09 op /* Find the end of dst and adjust bytes left but don't go past end */
1877 f36fd90a 2022-07-09 op while (n-- != 0 && *d != '\0')
1878 f36fd90a 2022-07-09 op d++;
1879 f36fd90a 2022-07-09 op dlen = d - dst;
1880 f36fd90a 2022-07-09 op n = siz - dlen;
1881 f36fd90a 2022-07-09 op
1882 f36fd90a 2022-07-09 op if (n == 0)
1883 f36fd90a 2022-07-09 op return(dlen + strlen(s));
1884 f36fd90a 2022-07-09 op while (*s != '\0') {
1885 f36fd90a 2022-07-09 op if (n != 1) {
1886 f36fd90a 2022-07-09 op *d++ = *s;
1887 f36fd90a 2022-07-09 op n--;
1888 f36fd90a 2022-07-09 op }
1889 f36fd90a 2022-07-09 op s++;
1890 f36fd90a 2022-07-09 op }
1891 f36fd90a 2022-07-09 op *d = '\0';
1892 f36fd90a 2022-07-09 op
1893 f36fd90a 2022-07-09 op return(dlen + (s - src)); /* count does not include NUL */
1894 f36fd90a 2022-07-09 op }
1895 f36fd90a 2022-07-09 op #endif /* !HAVE_STRLCAT */
1896 f36fd90a 2022-07-09 op #if !HAVE_STRLCPY
1897 f36fd90a 2022-07-09 op /*
1898 f36fd90a 2022-07-09 op * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
1899 f36fd90a 2022-07-09 op *
1900 f36fd90a 2022-07-09 op * Permission to use, copy, modify, and distribute this software for any
1901 f36fd90a 2022-07-09 op * purpose with or without fee is hereby granted, provided that the above
1902 f36fd90a 2022-07-09 op * copyright notice and this permission notice appear in all copies.
1903 f36fd90a 2022-07-09 op *
1904 f36fd90a 2022-07-09 op * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
1905 f36fd90a 2022-07-09 op * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
1906 f36fd90a 2022-07-09 op * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
1907 f36fd90a 2022-07-09 op * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
1908 f36fd90a 2022-07-09 op * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
1909 f36fd90a 2022-07-09 op * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
1910 f36fd90a 2022-07-09 op * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1911 f36fd90a 2022-07-09 op */
1912 f36fd90a 2022-07-09 op
1913 f36fd90a 2022-07-09 op #include <sys/types.h>
1914 f36fd90a 2022-07-09 op #include <string.h>
1915 f36fd90a 2022-07-09 op
1916 f36fd90a 2022-07-09 op /*
1917 f36fd90a 2022-07-09 op * Copy src to string dst of size siz. At most siz-1 characters
1918 f36fd90a 2022-07-09 op * will be copied. Always NUL terminates (unless siz == 0).
1919 f36fd90a 2022-07-09 op * Returns strlen(src); if retval >= siz, truncation occurred.
1920 f36fd90a 2022-07-09 op */
1921 f36fd90a 2022-07-09 op size_t
1922 f36fd90a 2022-07-09 op strlcpy(char *dst, const char *src, size_t siz)
1923 f36fd90a 2022-07-09 op {
1924 f36fd90a 2022-07-09 op char *d = dst;
1925 f36fd90a 2022-07-09 op const char *s = src;
1926 f36fd90a 2022-07-09 op size_t n = siz;
1927 f36fd90a 2022-07-09 op
1928 f36fd90a 2022-07-09 op /* Copy as many bytes as will fit */
1929 f36fd90a 2022-07-09 op if (n != 0) {
1930 f36fd90a 2022-07-09 op while (--n != 0) {
1931 f36fd90a 2022-07-09 op if ((*d++ = *s++) == '\0')
1932 f36fd90a 2022-07-09 op break;
1933 f36fd90a 2022-07-09 op }
1934 f36fd90a 2022-07-09 op }
1935 f36fd90a 2022-07-09 op
1936 f36fd90a 2022-07-09 op /* Not enough room in dst, add NUL and traverse rest of src */
1937 f36fd90a 2022-07-09 op if (n == 0) {
1938 f36fd90a 2022-07-09 op if (siz != 0)
1939 f36fd90a 2022-07-09 op *d = '\0'; /* NUL-terminate dst */
1940 f36fd90a 2022-07-09 op while (*s++)
1941 f36fd90a 2022-07-09 op ;
1942 f36fd90a 2022-07-09 op }
1943 f36fd90a 2022-07-09 op
1944 f36fd90a 2022-07-09 op return(s - src - 1); /* count does not include NUL */
1945 f36fd90a 2022-07-09 op }
1946 f36fd90a 2022-07-09 op #endif /* !HAVE_STRLCPY */
1947 f36fd90a 2022-07-09 op #if !HAVE_STRNDUP
1948 f36fd90a 2022-07-09 op /* $OpenBSD$ */
1949 f36fd90a 2022-07-09 op /*
1950 f36fd90a 2022-07-09 op * Copyright (c) 2010 Todd C. Miller <Todd.Miller@courtesan.com>
1951 f36fd90a 2022-07-09 op *
1952 f36fd90a 2022-07-09 op * Permission to use, copy, modify, and distribute this software for any
1953 f36fd90a 2022-07-09 op * purpose with or without fee is hereby granted, provided that the above
1954 f36fd90a 2022-07-09 op * copyright notice and this permission notice appear in all copies.
1955 f36fd90a 2022-07-09 op *
1956 f36fd90a 2022-07-09 op * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
1957 f36fd90a 2022-07-09 op * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
1958 f36fd90a 2022-07-09 op * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
1959 f36fd90a 2022-07-09 op * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
1960 f36fd90a 2022-07-09 op * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
1961 f36fd90a 2022-07-09 op * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
1962 f36fd90a 2022-07-09 op * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1963 f36fd90a 2022-07-09 op */
1964 f36fd90a 2022-07-09 op
1965 f36fd90a 2022-07-09 op #include <sys/types.h>
1966 f36fd90a 2022-07-09 op
1967 f36fd90a 2022-07-09 op #include <stddef.h>
1968 f36fd90a 2022-07-09 op #include <stdlib.h>
1969 f36fd90a 2022-07-09 op #include <string.h>
1970 f36fd90a 2022-07-09 op
1971 f36fd90a 2022-07-09 op char *
1972 f36fd90a 2022-07-09 op strndup(const char *str, size_t maxlen)
1973 f36fd90a 2022-07-09 op {
1974 f36fd90a 2022-07-09 op char *copy;
1975 f36fd90a 2022-07-09 op size_t len;
1976 f36fd90a 2022-07-09 op
1977 f36fd90a 2022-07-09 op len = strnlen(str, maxlen);
1978 f36fd90a 2022-07-09 op copy = malloc(len + 1);
1979 f36fd90a 2022-07-09 op if (copy != NULL) {
1980 f36fd90a 2022-07-09 op (void)memcpy(copy, str, len);
1981 f36fd90a 2022-07-09 op copy[len] = '\0';
1982 f36fd90a 2022-07-09 op }
1983 f36fd90a 2022-07-09 op
1984 f36fd90a 2022-07-09 op return copy;
1985 f36fd90a 2022-07-09 op }
1986 f36fd90a 2022-07-09 op #endif /* !HAVE_STRNDUP */
1987 f36fd90a 2022-07-09 op #if !HAVE_STRNLEN
1988 f36fd90a 2022-07-09 op /* $OpenBSD$ */
1989 f36fd90a 2022-07-09 op
1990 f36fd90a 2022-07-09 op /*
1991 f36fd90a 2022-07-09 op * Copyright (c) 2010 Todd C. Miller <Todd.Miller@courtesan.com>
1992 f36fd90a 2022-07-09 op *
1993 f36fd90a 2022-07-09 op * Permission to use, copy, modify, and distribute this software for any
1994 f36fd90a 2022-07-09 op * purpose with or without fee is hereby granted, provided that the above
1995 f36fd90a 2022-07-09 op * copyright notice and this permission notice appear in all copies.
1996 f36fd90a 2022-07-09 op *
1997 f36fd90a 2022-07-09 op * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
1998 f36fd90a 2022-07-09 op * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
1999 f36fd90a 2022-07-09 op * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
2000 f36fd90a 2022-07-09 op * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
2001 f36fd90a 2022-07-09 op * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
2002 f36fd90a 2022-07-09 op * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
2003 f36fd90a 2022-07-09 op * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
2004 f36fd90a 2022-07-09 op */
2005 f36fd90a 2022-07-09 op
2006 f36fd90a 2022-07-09 op #include <sys/types.h>
2007 f36fd90a 2022-07-09 op #include <string.h>
2008 f36fd90a 2022-07-09 op
2009 f36fd90a 2022-07-09 op size_t
2010 f36fd90a 2022-07-09 op strnlen(const char *str, size_t maxlen)
2011 f36fd90a 2022-07-09 op {
2012 f36fd90a 2022-07-09 op const char *cp;
2013 f36fd90a 2022-07-09 op
2014 f36fd90a 2022-07-09 op for (cp = str; maxlen != 0 && *cp != '\0'; cp++, maxlen--)
2015 f36fd90a 2022-07-09 op ;
2016 f36fd90a 2022-07-09 op
2017 f36fd90a 2022-07-09 op return (size_t)(cp - str);
2018 f36fd90a 2022-07-09 op }
2019 f36fd90a 2022-07-09 op #endif /* !HAVE_STRNLEN */
2020 f36fd90a 2022-07-09 op #if !HAVE_STRTONUM
2021 f36fd90a 2022-07-09 op /*
2022 f36fd90a 2022-07-09 op * Copyright (c) 2004 Ted Unangst and Todd Miller
2023 f36fd90a 2022-07-09 op * All rights reserved.
2024 f36fd90a 2022-07-09 op *
2025 f36fd90a 2022-07-09 op * Permission to use, copy, modify, and distribute this software for any
2026 f36fd90a 2022-07-09 op * purpose with or without fee is hereby granted, provided that the above
2027 f36fd90a 2022-07-09 op * copyright notice and this permission notice appear in all copies.
2028 f36fd90a 2022-07-09 op *
2029 f36fd90a 2022-07-09 op * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
2030 f36fd90a 2022-07-09 op * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
2031 f36fd90a 2022-07-09 op * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
2032 f36fd90a 2022-07-09 op * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
2033 f36fd90a 2022-07-09 op * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
2034 f36fd90a 2022-07-09 op * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
2035 f36fd90a 2022-07-09 op * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
2036 f36fd90a 2022-07-09 op */
2037 f36fd90a 2022-07-09 op
2038 f36fd90a 2022-07-09 op #include <errno.h>
2039 f36fd90a 2022-07-09 op #include <limits.h>
2040 f36fd90a 2022-07-09 op #include <stdlib.h>
2041 f36fd90a 2022-07-09 op
2042 f36fd90a 2022-07-09 op #define INVALID 1
2043 f36fd90a 2022-07-09 op #define TOOSMALL 2
2044 f36fd90a 2022-07-09 op #define TOOLARGE 3
2045 f36fd90a 2022-07-09 op
2046 f36fd90a 2022-07-09 op long long
2047 f36fd90a 2022-07-09 op strtonum(const char *numstr, long long minval, long long maxval,
2048 f36fd90a 2022-07-09 op const char **errstrp)
2049 f36fd90a 2022-07-09 op {
2050 f36fd90a 2022-07-09 op long long ll = 0;
2051 f36fd90a 2022-07-09 op int error = 0;
2052 f36fd90a 2022-07-09 op char *ep;
2053 f36fd90a 2022-07-09 op struct errval {
2054 f36fd90a 2022-07-09 op const char *errstr;
2055 f36fd90a 2022-07-09 op int err;
2056 f36fd90a 2022-07-09 op } ev[4] = {
2057 f36fd90a 2022-07-09 op { NULL, 0 },
2058 f36fd90a 2022-07-09 op { "invalid", EINVAL },
2059 f36fd90a 2022-07-09 op { "too small", ERANGE },
2060 f36fd90a 2022-07-09 op { "too large", ERANGE },
2061 f36fd90a 2022-07-09 op };
2062 f36fd90a 2022-07-09 op
2063 f36fd90a 2022-07-09 op ev[0].err = errno;
2064 f36fd90a 2022-07-09 op errno = 0;
2065 f36fd90a 2022-07-09 op if (minval > maxval) {
2066 f36fd90a 2022-07-09 op error = INVALID;
2067 f36fd90a 2022-07-09 op } else {
2068 f36fd90a 2022-07-09 op ll = strtoll(numstr, &ep, 10);
2069 f36fd90a 2022-07-09 op if (numstr == ep || *ep != '\0')
2070 f36fd90a 2022-07-09 op error = INVALID;
2071 f36fd90a 2022-07-09 op else if ((ll == LLONG_MIN && errno == ERANGE) || ll < minval)
2072 f36fd90a 2022-07-09 op error = TOOSMALL;
2073 f36fd90a 2022-07-09 op else if ((ll == LLONG_MAX && errno == ERANGE) || ll > maxval)
2074 f36fd90a 2022-07-09 op error = TOOLARGE;
2075 f36fd90a 2022-07-09 op }
2076 f36fd90a 2022-07-09 op if (errstrp != NULL)
2077 f36fd90a 2022-07-09 op *errstrp = ev[error].errstr;
2078 f36fd90a 2022-07-09 op errno = ev[error].err;
2079 f36fd90a 2022-07-09 op if (error)
2080 f36fd90a 2022-07-09 op ll = 0;
2081 f36fd90a 2022-07-09 op
2082 f36fd90a 2022-07-09 op return (ll);
2083 f36fd90a 2022-07-09 op }
2084 f36fd90a 2022-07-09 op #endif /* !HAVE_STRTONUM */
2085 31e12e67 2023-09-07 op #if !HAVE_TIMESPECSUB
2086 31e12e67 2023-09-07 op #include <sys/time.h>
2087 31e12e67 2023-09-07 op void
2088 31e12e67 2023-09-07 op timespecsub(struct timespec *a, struct timespec *b, struct timespec *ret)
2089 31e12e67 2023-09-07 op {
2090 31e12e67 2023-09-07 op ret->tv_sec = a->tv_sec - b->tv_sec;
2091 31e12e67 2023-09-07 op ret->tv_nsec = a->tv_nsec - b->tv_nsec;
2092 31e12e67 2023-09-07 op if (ret->tv_nsec < 0) {
2093 31e12e67 2023-09-07 op ret->tv_sec--;
2094 31e12e67 2023-09-07 op ret->tv_nsec += 1000000000L;
2095 31e12e67 2023-09-07 op }
2096 31e12e67 2023-09-07 op }
2097 31e12e67 2023-09-07 op #endif /* !HAVE_TIMESPECSUB */