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 f36fd90a 2022-07-09 op static void (* volatile ssh_memset)(void *, int, size_t) = memset;
249 f36fd90a 2022-07-09 op
250 f36fd90a 2022-07-09 op void
251 f36fd90a 2022-07-09 op explicit_bzero(void *p, size_t n)
252 f36fd90a 2022-07-09 op {
253 f36fd90a 2022-07-09 op if (n == 0)
254 f36fd90a 2022-07-09 op return;
255 f36fd90a 2022-07-09 op /*
256 f36fd90a 2022-07-09 op * clang -fsanitize=memory needs to intercept memset-like functions
257 f36fd90a 2022-07-09 op * to correctly detect memory initialisation. Make sure one is called
258 f36fd90a 2022-07-09 op * directly since our indirection trick above sucessfully confuses it.
259 f36fd90a 2022-07-09 op */
260 f36fd90a 2022-07-09 op #if defined(__has_feature)
261 f36fd90a 2022-07-09 op # if __has_feature(memory_sanitizer)
262 f36fd90a 2022-07-09 op memset(p, 0, n);
263 f36fd90a 2022-07-09 op # endif
264 f36fd90a 2022-07-09 op #endif
265 f36fd90a 2022-07-09 op
266 f36fd90a 2022-07-09 op ssh_memset(p, 0, n);
267 f36fd90a 2022-07-09 op }
268 f36fd90a 2022-07-09 op
269 f36fd90a 2022-07-09 op #endif /* HAVE_MEMSET_S */
270 f36fd90a 2022-07-09 op #endif /* !HAVE_EXPLICIT_BZERO */
271 f36fd90a 2022-07-09 op #if !HAVE_GETPROGNAME
272 f36fd90a 2022-07-09 op /*
273 f36fd90a 2022-07-09 op * Copyright (c) 2016 Nicholas Marriott <nicholas.marriott@gmail.com>
274 f36fd90a 2022-07-09 op * Copyright (c) 2017 Kristaps Dzonsons <kristaps@bsd.lv>
275 f36fd90a 2022-07-09 op * Copyright (c) 2020 Stephen Gregoratto <dev@sgregoratto.me>
276 f36fd90a 2022-07-09 op *
277 f36fd90a 2022-07-09 op * Permission to use, copy, modify, and distribute this software for any
278 f36fd90a 2022-07-09 op * purpose with or without fee is hereby granted, provided that the above
279 f36fd90a 2022-07-09 op * copyright notice and this permission notice appear in all copies.
280 f36fd90a 2022-07-09 op *
281 f36fd90a 2022-07-09 op * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
282 f36fd90a 2022-07-09 op * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
283 f36fd90a 2022-07-09 op * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
284 f36fd90a 2022-07-09 op * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
285 f36fd90a 2022-07-09 op * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
286 f36fd90a 2022-07-09 op * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
287 f36fd90a 2022-07-09 op * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
288 f36fd90a 2022-07-09 op */
289 f36fd90a 2022-07-09 op
290 f36fd90a 2022-07-09 op #include <sys/types.h>
291 f36fd90a 2022-07-09 op
292 f36fd90a 2022-07-09 op #include <errno.h>
293 f36fd90a 2022-07-09 op
294 f36fd90a 2022-07-09 op #if HAVE_GETEXECNAME
295 f36fd90a 2022-07-09 op #include <stdlib.h>
296 f36fd90a 2022-07-09 op const char *
297 f36fd90a 2022-07-09 op getprogname(void)
298 f36fd90a 2022-07-09 op {
299 f36fd90a 2022-07-09 op return getexecname();
300 f36fd90a 2022-07-09 op }
301 f36fd90a 2022-07-09 op #elif HAVE_PROGRAM_INVOCATION_SHORT_NAME
302 f36fd90a 2022-07-09 op const char *
303 f36fd90a 2022-07-09 op getprogname(void)
304 f36fd90a 2022-07-09 op {
305 f36fd90a 2022-07-09 op return (program_invocation_short_name);
306 f36fd90a 2022-07-09 op }
307 f36fd90a 2022-07-09 op #elif HAVE___PROGNAME
308 f36fd90a 2022-07-09 op const char *
309 f36fd90a 2022-07-09 op getprogname(void)
310 f36fd90a 2022-07-09 op {
311 f36fd90a 2022-07-09 op extern char *__progname;
312 f36fd90a 2022-07-09 op
313 f36fd90a 2022-07-09 op return (__progname);
314 f36fd90a 2022-07-09 op }
315 f36fd90a 2022-07-09 op #else
316 f36fd90a 2022-07-09 op #warning No getprogname available.
317 f36fd90a 2022-07-09 op const char *
318 f36fd90a 2022-07-09 op getprogname(void)
319 f36fd90a 2022-07-09 op {
320 f36fd90a 2022-07-09 op return ("amused");
321 f36fd90a 2022-07-09 op }
322 f36fd90a 2022-07-09 op #endif
323 f36fd90a 2022-07-09 op #endif /* !HAVE_GETPROGNAME */
324 f36fd90a 2022-07-09 op #if !HAVE_IMSG
325 f36fd90a 2022-07-09 op /* $OpenBSD: imsg-buffer.c,v 1.13 2021/03/31 17:42:24 eric Exp $ */
326 f36fd90a 2022-07-09 op /* $OpenBSD: imsg.c,v 1.17 2022/01/28 10:41:44 claudio Exp $ */
327 f36fd90a 2022-07-09 op
328 f36fd90a 2022-07-09 op /*
329 f36fd90a 2022-07-09 op * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
330 f36fd90a 2022-07-09 op *
331 f36fd90a 2022-07-09 op * Permission to use, copy, modify, and distribute this software for any
332 f36fd90a 2022-07-09 op * purpose with or without fee is hereby granted, provided that the above
333 f36fd90a 2022-07-09 op * copyright notice and this permission notice appear in all copies.
334 f36fd90a 2022-07-09 op *
335 f36fd90a 2022-07-09 op * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
336 f36fd90a 2022-07-09 op * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
337 f36fd90a 2022-07-09 op * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
338 f36fd90a 2022-07-09 op * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
339 f36fd90a 2022-07-09 op * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
340 f36fd90a 2022-07-09 op * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
341 f36fd90a 2022-07-09 op * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
342 f36fd90a 2022-07-09 op */
343 f36fd90a 2022-07-09 op
344 f36fd90a 2022-07-09 op #include "config.h"
345 f36fd90a 2022-07-09 op
346 f36fd90a 2022-07-09 op #include <sys/types.h>
347 f36fd90a 2022-07-09 op #include <sys/socket.h>
348 f36fd90a 2022-07-09 op #include <sys/uio.h>
349 f36fd90a 2022-07-09 op
350 f36fd90a 2022-07-09 op #include <limits.h>
351 f36fd90a 2022-07-09 op #include <errno.h>
352 f36fd90a 2022-07-09 op #include <stdlib.h>
353 f36fd90a 2022-07-09 op #include <string.h>
354 f36fd90a 2022-07-09 op #include <unistd.h>
355 f36fd90a 2022-07-09 op
356 f36fd90a 2022-07-09 op #include "imsg.h"
357 f36fd90a 2022-07-09 op
358 f36fd90a 2022-07-09 op static int ibuf_realloc(struct ibuf *, size_t);
359 f36fd90a 2022-07-09 op static void ibuf_enqueue(struct msgbuf *, struct ibuf *);
360 f36fd90a 2022-07-09 op static void ibuf_dequeue(struct msgbuf *, struct ibuf *);
361 f36fd90a 2022-07-09 op
362 f36fd90a 2022-07-09 op struct ibuf *
363 f36fd90a 2022-07-09 op ibuf_open(size_t len)
364 f36fd90a 2022-07-09 op {
365 f36fd90a 2022-07-09 op struct ibuf *buf;
366 f36fd90a 2022-07-09 op
367 f36fd90a 2022-07-09 op if ((buf = calloc(1, sizeof(struct ibuf))) == NULL)
368 f36fd90a 2022-07-09 op return (NULL);
369 f36fd90a 2022-07-09 op if ((buf->buf = malloc(len)) == NULL) {
370 f36fd90a 2022-07-09 op free(buf);
371 f36fd90a 2022-07-09 op return (NULL);
372 f36fd90a 2022-07-09 op }
373 f36fd90a 2022-07-09 op buf->size = buf->max = len;
374 f36fd90a 2022-07-09 op buf->fd = -1;
375 f36fd90a 2022-07-09 op
376 f36fd90a 2022-07-09 op return (buf);
377 f36fd90a 2022-07-09 op }
378 f36fd90a 2022-07-09 op
379 f36fd90a 2022-07-09 op struct ibuf *
380 f36fd90a 2022-07-09 op ibuf_dynamic(size_t len, size_t max)
381 f36fd90a 2022-07-09 op {
382 f36fd90a 2022-07-09 op struct ibuf *buf;
383 f36fd90a 2022-07-09 op
384 f36fd90a 2022-07-09 op if (max < len)
385 f36fd90a 2022-07-09 op return (NULL);
386 f36fd90a 2022-07-09 op
387 f36fd90a 2022-07-09 op if ((buf = ibuf_open(len)) == NULL)
388 f36fd90a 2022-07-09 op return (NULL);
389 f36fd90a 2022-07-09 op
390 f36fd90a 2022-07-09 op if (max > 0)
391 f36fd90a 2022-07-09 op buf->max = max;
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 static int
397 f36fd90a 2022-07-09 op ibuf_realloc(struct ibuf *buf, size_t len)
398 f36fd90a 2022-07-09 op {
399 f36fd90a 2022-07-09 op unsigned char *b;
400 f36fd90a 2022-07-09 op
401 f36fd90a 2022-07-09 op /* on static buffers max is eq size and so the following fails */
402 f36fd90a 2022-07-09 op if (buf->wpos + len > buf->max) {
403 f36fd90a 2022-07-09 op errno = ERANGE;
404 f36fd90a 2022-07-09 op return (-1);
405 f36fd90a 2022-07-09 op }
406 f36fd90a 2022-07-09 op
407 f36fd90a 2022-07-09 op b = recallocarray(buf->buf, buf->size, buf->wpos + len, 1);
408 f36fd90a 2022-07-09 op if (b == NULL)
409 f36fd90a 2022-07-09 op return (-1);
410 f36fd90a 2022-07-09 op buf->buf = b;
411 f36fd90a 2022-07-09 op buf->size = buf->wpos + len;
412 f36fd90a 2022-07-09 op
413 f36fd90a 2022-07-09 op return (0);
414 f36fd90a 2022-07-09 op }
415 f36fd90a 2022-07-09 op
416 f36fd90a 2022-07-09 op int
417 f36fd90a 2022-07-09 op ibuf_add(struct ibuf *buf, const void *data, size_t len)
418 f36fd90a 2022-07-09 op {
419 f36fd90a 2022-07-09 op if (buf->wpos + len > buf->size)
420 f36fd90a 2022-07-09 op if (ibuf_realloc(buf, len) == -1)
421 f36fd90a 2022-07-09 op return (-1);
422 f36fd90a 2022-07-09 op
423 f36fd90a 2022-07-09 op memcpy(buf->buf + buf->wpos, data, len);
424 f36fd90a 2022-07-09 op buf->wpos += len;
425 f36fd90a 2022-07-09 op return (0);
426 f36fd90a 2022-07-09 op }
427 f36fd90a 2022-07-09 op
428 f36fd90a 2022-07-09 op void *
429 f36fd90a 2022-07-09 op ibuf_reserve(struct ibuf *buf, size_t len)
430 f36fd90a 2022-07-09 op {
431 f36fd90a 2022-07-09 op void *b;
432 f36fd90a 2022-07-09 op
433 f36fd90a 2022-07-09 op if (buf->wpos + len > buf->size)
434 f36fd90a 2022-07-09 op if (ibuf_realloc(buf, len) == -1)
435 f36fd90a 2022-07-09 op return (NULL);
436 f36fd90a 2022-07-09 op
437 f36fd90a 2022-07-09 op b = buf->buf + buf->wpos;
438 f36fd90a 2022-07-09 op buf->wpos += len;
439 f36fd90a 2022-07-09 op return (b);
440 f36fd90a 2022-07-09 op }
441 f36fd90a 2022-07-09 op
442 f36fd90a 2022-07-09 op void *
443 f36fd90a 2022-07-09 op ibuf_seek(struct ibuf *buf, size_t pos, size_t len)
444 f36fd90a 2022-07-09 op {
445 f36fd90a 2022-07-09 op /* only allowed to seek in already written parts */
446 f36fd90a 2022-07-09 op if (pos + len > buf->wpos)
447 f36fd90a 2022-07-09 op return (NULL);
448 f36fd90a 2022-07-09 op
449 f36fd90a 2022-07-09 op return (buf->buf + pos);
450 f36fd90a 2022-07-09 op }
451 f36fd90a 2022-07-09 op
452 f36fd90a 2022-07-09 op size_t
453 f36fd90a 2022-07-09 op ibuf_size(struct ibuf *buf)
454 f36fd90a 2022-07-09 op {
455 f36fd90a 2022-07-09 op return (buf->wpos);
456 f36fd90a 2022-07-09 op }
457 f36fd90a 2022-07-09 op
458 f36fd90a 2022-07-09 op size_t
459 f36fd90a 2022-07-09 op ibuf_left(struct ibuf *buf)
460 f36fd90a 2022-07-09 op {
461 f36fd90a 2022-07-09 op return (buf->max - buf->wpos);
462 f36fd90a 2022-07-09 op }
463 f36fd90a 2022-07-09 op
464 f36fd90a 2022-07-09 op void
465 f36fd90a 2022-07-09 op ibuf_close(struct msgbuf *msgbuf, struct ibuf *buf)
466 f36fd90a 2022-07-09 op {
467 f36fd90a 2022-07-09 op ibuf_enqueue(msgbuf, buf);
468 f36fd90a 2022-07-09 op }
469 f36fd90a 2022-07-09 op
470 f36fd90a 2022-07-09 op int
471 f36fd90a 2022-07-09 op ibuf_write(struct msgbuf *msgbuf)
472 f36fd90a 2022-07-09 op {
473 f36fd90a 2022-07-09 op struct iovec iov[IOV_MAX];
474 f36fd90a 2022-07-09 op struct ibuf *buf;
475 f36fd90a 2022-07-09 op unsigned int i = 0;
476 f36fd90a 2022-07-09 op ssize_t n;
477 f36fd90a 2022-07-09 op
478 f36fd90a 2022-07-09 op memset(&iov, 0, sizeof(iov));
479 f36fd90a 2022-07-09 op TAILQ_FOREACH(buf, &msgbuf->bufs, entry) {
480 f36fd90a 2022-07-09 op if (i >= IOV_MAX)
481 f36fd90a 2022-07-09 op break;
482 f36fd90a 2022-07-09 op iov[i].iov_base = buf->buf + buf->rpos;
483 f36fd90a 2022-07-09 op iov[i].iov_len = buf->wpos - buf->rpos;
484 f36fd90a 2022-07-09 op i++;
485 f36fd90a 2022-07-09 op }
486 f36fd90a 2022-07-09 op
487 f36fd90a 2022-07-09 op again:
488 f36fd90a 2022-07-09 op if ((n = writev(msgbuf->fd, iov, i)) == -1) {
489 f36fd90a 2022-07-09 op if (errno == EINTR)
490 f36fd90a 2022-07-09 op goto again;
491 f36fd90a 2022-07-09 op if (errno == ENOBUFS)
492 f36fd90a 2022-07-09 op errno = EAGAIN;
493 f36fd90a 2022-07-09 op return (-1);
494 f36fd90a 2022-07-09 op }
495 f36fd90a 2022-07-09 op
496 f36fd90a 2022-07-09 op if (n == 0) { /* connection closed */
497 f36fd90a 2022-07-09 op errno = 0;
498 f36fd90a 2022-07-09 op return (0);
499 f36fd90a 2022-07-09 op }
500 f36fd90a 2022-07-09 op
501 f36fd90a 2022-07-09 op msgbuf_drain(msgbuf, n);
502 f36fd90a 2022-07-09 op
503 f36fd90a 2022-07-09 op return (1);
504 f36fd90a 2022-07-09 op }
505 f36fd90a 2022-07-09 op
506 f36fd90a 2022-07-09 op void
507 f36fd90a 2022-07-09 op ibuf_free(struct ibuf *buf)
508 f36fd90a 2022-07-09 op {
509 f36fd90a 2022-07-09 op if (buf == NULL)
510 f36fd90a 2022-07-09 op return;
511 f36fd90a 2022-07-09 op freezero(buf->buf, buf->size);
512 f36fd90a 2022-07-09 op free(buf);
513 f36fd90a 2022-07-09 op }
514 f36fd90a 2022-07-09 op
515 f36fd90a 2022-07-09 op void
516 f36fd90a 2022-07-09 op msgbuf_init(struct msgbuf *msgbuf)
517 f36fd90a 2022-07-09 op {
518 f36fd90a 2022-07-09 op msgbuf->queued = 0;
519 f36fd90a 2022-07-09 op msgbuf->fd = -1;
520 f36fd90a 2022-07-09 op TAILQ_INIT(&msgbuf->bufs);
521 f36fd90a 2022-07-09 op }
522 f36fd90a 2022-07-09 op
523 f36fd90a 2022-07-09 op void
524 f36fd90a 2022-07-09 op msgbuf_drain(struct msgbuf *msgbuf, size_t n)
525 f36fd90a 2022-07-09 op {
526 f36fd90a 2022-07-09 op struct ibuf *buf, *next;
527 f36fd90a 2022-07-09 op
528 f36fd90a 2022-07-09 op for (buf = TAILQ_FIRST(&msgbuf->bufs); buf != NULL && n > 0;
529 f36fd90a 2022-07-09 op buf = next) {
530 f36fd90a 2022-07-09 op next = TAILQ_NEXT(buf, entry);
531 f36fd90a 2022-07-09 op if (buf->rpos + n >= buf->wpos) {
532 f36fd90a 2022-07-09 op n -= buf->wpos - buf->rpos;
533 f36fd90a 2022-07-09 op ibuf_dequeue(msgbuf, buf);
534 f36fd90a 2022-07-09 op } else {
535 f36fd90a 2022-07-09 op buf->rpos += n;
536 f36fd90a 2022-07-09 op n = 0;
537 f36fd90a 2022-07-09 op }
538 f36fd90a 2022-07-09 op }
539 f36fd90a 2022-07-09 op }
540 f36fd90a 2022-07-09 op
541 f36fd90a 2022-07-09 op void
542 f36fd90a 2022-07-09 op msgbuf_clear(struct msgbuf *msgbuf)
543 f36fd90a 2022-07-09 op {
544 f36fd90a 2022-07-09 op struct ibuf *buf;
545 f36fd90a 2022-07-09 op
546 f36fd90a 2022-07-09 op while ((buf = TAILQ_FIRST(&msgbuf->bufs)) != NULL)
547 f36fd90a 2022-07-09 op ibuf_dequeue(msgbuf, buf);
548 f36fd90a 2022-07-09 op }
549 f36fd90a 2022-07-09 op
550 f36fd90a 2022-07-09 op int
551 f36fd90a 2022-07-09 op msgbuf_write(struct msgbuf *msgbuf)
552 f36fd90a 2022-07-09 op {
553 f36fd90a 2022-07-09 op struct iovec iov[IOV_MAX];
554 f36fd90a 2022-07-09 op struct ibuf *buf, *buf0 = NULL;
555 f36fd90a 2022-07-09 op unsigned int i = 0;
556 f36fd90a 2022-07-09 op ssize_t n;
557 f36fd90a 2022-07-09 op struct msghdr msg;
558 f36fd90a 2022-07-09 op struct cmsghdr *cmsg;
559 f36fd90a 2022-07-09 op union {
560 f36fd90a 2022-07-09 op struct cmsghdr hdr;
561 f36fd90a 2022-07-09 op char buf[CMSG_SPACE(sizeof(int))];
562 f36fd90a 2022-07-09 op } cmsgbuf;
563 f36fd90a 2022-07-09 op
564 f36fd90a 2022-07-09 op memset(&iov, 0, sizeof(iov));
565 f36fd90a 2022-07-09 op memset(&msg, 0, sizeof(msg));
566 f36fd90a 2022-07-09 op memset(&cmsgbuf, 0, sizeof(cmsgbuf));
567 f36fd90a 2022-07-09 op TAILQ_FOREACH(buf, &msgbuf->bufs, entry) {
568 f36fd90a 2022-07-09 op if (i >= IOV_MAX)
569 f36fd90a 2022-07-09 op break;
570 f36fd90a 2022-07-09 op if (i > 0 && buf->fd != -1)
571 f36fd90a 2022-07-09 op break;
572 f36fd90a 2022-07-09 op iov[i].iov_base = buf->buf + buf->rpos;
573 f36fd90a 2022-07-09 op iov[i].iov_len = buf->wpos - buf->rpos;
574 f36fd90a 2022-07-09 op i++;
575 f36fd90a 2022-07-09 op if (buf->fd != -1)
576 f36fd90a 2022-07-09 op buf0 = buf;
577 f36fd90a 2022-07-09 op }
578 f36fd90a 2022-07-09 op
579 f36fd90a 2022-07-09 op msg.msg_iov = iov;
580 f36fd90a 2022-07-09 op msg.msg_iovlen = i;
581 f36fd90a 2022-07-09 op
582 f36fd90a 2022-07-09 op if (buf0 != NULL) {
583 f36fd90a 2022-07-09 op msg.msg_control = (caddr_t)&cmsgbuf.buf;
584 f36fd90a 2022-07-09 op msg.msg_controllen = sizeof(cmsgbuf.buf);
585 f36fd90a 2022-07-09 op cmsg = CMSG_FIRSTHDR(&msg);
586 f36fd90a 2022-07-09 op cmsg->cmsg_len = CMSG_LEN(sizeof(int));
587 f36fd90a 2022-07-09 op cmsg->cmsg_level = SOL_SOCKET;
588 f36fd90a 2022-07-09 op cmsg->cmsg_type = SCM_RIGHTS;
589 f36fd90a 2022-07-09 op *(int *)CMSG_DATA(cmsg) = buf0->fd;
590 f36fd90a 2022-07-09 op }
591 f36fd90a 2022-07-09 op
592 f36fd90a 2022-07-09 op again:
593 f36fd90a 2022-07-09 op if ((n = sendmsg(msgbuf->fd, &msg, 0)) == -1) {
594 f36fd90a 2022-07-09 op if (errno == EINTR)
595 f36fd90a 2022-07-09 op goto again;
596 f36fd90a 2022-07-09 op if (errno == ENOBUFS)
597 f36fd90a 2022-07-09 op errno = EAGAIN;
598 f36fd90a 2022-07-09 op return (-1);
599 f36fd90a 2022-07-09 op }
600 f36fd90a 2022-07-09 op
601 f36fd90a 2022-07-09 op if (n == 0) { /* connection closed */
602 f36fd90a 2022-07-09 op errno = 0;
603 f36fd90a 2022-07-09 op return (0);
604 f36fd90a 2022-07-09 op }
605 f36fd90a 2022-07-09 op
606 f36fd90a 2022-07-09 op /*
607 f36fd90a 2022-07-09 op * assumption: fd got sent if sendmsg sent anything
608 f36fd90a 2022-07-09 op * this works because fds are passed one at a time
609 f36fd90a 2022-07-09 op */
610 f36fd90a 2022-07-09 op if (buf0 != NULL) {
611 f36fd90a 2022-07-09 op close(buf0->fd);
612 f36fd90a 2022-07-09 op buf0->fd = -1;
613 f36fd90a 2022-07-09 op }
614 f36fd90a 2022-07-09 op
615 f36fd90a 2022-07-09 op msgbuf_drain(msgbuf, n);
616 f36fd90a 2022-07-09 op
617 f36fd90a 2022-07-09 op return (1);
618 f36fd90a 2022-07-09 op }
619 f36fd90a 2022-07-09 op
620 f36fd90a 2022-07-09 op static void
621 f36fd90a 2022-07-09 op ibuf_enqueue(struct msgbuf *msgbuf, struct ibuf *buf)
622 f36fd90a 2022-07-09 op {
623 f36fd90a 2022-07-09 op TAILQ_INSERT_TAIL(&msgbuf->bufs, buf, entry);
624 f36fd90a 2022-07-09 op msgbuf->queued++;
625 f36fd90a 2022-07-09 op }
626 f36fd90a 2022-07-09 op
627 f36fd90a 2022-07-09 op static void
628 f36fd90a 2022-07-09 op ibuf_dequeue(struct msgbuf *msgbuf, struct ibuf *buf)
629 f36fd90a 2022-07-09 op {
630 f36fd90a 2022-07-09 op TAILQ_REMOVE(&msgbuf->bufs, buf, entry);
631 f36fd90a 2022-07-09 op
632 f36fd90a 2022-07-09 op if (buf->fd != -1)
633 f36fd90a 2022-07-09 op close(buf->fd);
634 f36fd90a 2022-07-09 op
635 f36fd90a 2022-07-09 op msgbuf->queued--;
636 f36fd90a 2022-07-09 op ibuf_free(buf);
637 f36fd90a 2022-07-09 op }
638 f36fd90a 2022-07-09 op
639 f36fd90a 2022-07-09 op /* imsg.c */
640 f36fd90a 2022-07-09 op
641 f36fd90a 2022-07-09 op int imsg_fd_overhead = 0;
642 f36fd90a 2022-07-09 op
643 f36fd90a 2022-07-09 op static int imsg_get_fd(struct imsgbuf *);
644 f36fd90a 2022-07-09 op
645 f36fd90a 2022-07-09 op void
646 f36fd90a 2022-07-09 op imsg_init(struct imsgbuf *ibuf, int fd)
647 f36fd90a 2022-07-09 op {
648 f36fd90a 2022-07-09 op msgbuf_init(&ibuf->w);
649 f36fd90a 2022-07-09 op memset(&ibuf->r, 0, sizeof(ibuf->r));
650 f36fd90a 2022-07-09 op ibuf->fd = fd;
651 f36fd90a 2022-07-09 op ibuf->w.fd = fd;
652 f36fd90a 2022-07-09 op ibuf->pid = getpid();
653 f36fd90a 2022-07-09 op TAILQ_INIT(&ibuf->fds);
654 f36fd90a 2022-07-09 op }
655 f36fd90a 2022-07-09 op
656 f36fd90a 2022-07-09 op ssize_t
657 f36fd90a 2022-07-09 op imsg_read(struct imsgbuf *ibuf)
658 f36fd90a 2022-07-09 op {
659 f36fd90a 2022-07-09 op struct msghdr msg;
660 f36fd90a 2022-07-09 op struct cmsghdr *cmsg;
661 f36fd90a 2022-07-09 op union {
662 f36fd90a 2022-07-09 op struct cmsghdr hdr;
663 f36fd90a 2022-07-09 op char buf[CMSG_SPACE(sizeof(int) * 1)];
664 f36fd90a 2022-07-09 op } cmsgbuf;
665 f36fd90a 2022-07-09 op struct iovec iov;
666 f36fd90a 2022-07-09 op ssize_t n = -1;
667 f36fd90a 2022-07-09 op int fd;
668 f36fd90a 2022-07-09 op struct imsg_fd *ifd;
669 f36fd90a 2022-07-09 op
670 f36fd90a 2022-07-09 op memset(&msg, 0, sizeof(msg));
671 f36fd90a 2022-07-09 op memset(&cmsgbuf, 0, sizeof(cmsgbuf));
672 f36fd90a 2022-07-09 op
673 f36fd90a 2022-07-09 op iov.iov_base = ibuf->r.buf + ibuf->r.wpos;
674 f36fd90a 2022-07-09 op iov.iov_len = sizeof(ibuf->r.buf) - ibuf->r.wpos;
675 f36fd90a 2022-07-09 op msg.msg_iov = &iov;
676 f36fd90a 2022-07-09 op msg.msg_iovlen = 1;
677 f36fd90a 2022-07-09 op msg.msg_control = &cmsgbuf.buf;
678 f36fd90a 2022-07-09 op msg.msg_controllen = sizeof(cmsgbuf.buf);
679 f36fd90a 2022-07-09 op
680 f36fd90a 2022-07-09 op if ((ifd = calloc(1, sizeof(struct imsg_fd))) == NULL)
681 f36fd90a 2022-07-09 op return (-1);
682 f36fd90a 2022-07-09 op
683 f36fd90a 2022-07-09 op again:
684 f36fd90a 2022-07-09 op if (getdtablecount() + imsg_fd_overhead +
685 f36fd90a 2022-07-09 op (int)((CMSG_SPACE(sizeof(int))-CMSG_SPACE(0))/sizeof(int))
686 f36fd90a 2022-07-09 op >= getdtablesize()) {
687 f36fd90a 2022-07-09 op errno = EAGAIN;
688 f36fd90a 2022-07-09 op free(ifd);
689 f36fd90a 2022-07-09 op return (-1);
690 f36fd90a 2022-07-09 op }
691 f36fd90a 2022-07-09 op
692 f36fd90a 2022-07-09 op if ((n = recvmsg(ibuf->fd, &msg, 0)) == -1) {
693 f36fd90a 2022-07-09 op if (errno == EINTR)
694 f36fd90a 2022-07-09 op goto again;
695 f36fd90a 2022-07-09 op goto fail;
696 f36fd90a 2022-07-09 op }
697 f36fd90a 2022-07-09 op
698 f36fd90a 2022-07-09 op ibuf->r.wpos += n;
699 f36fd90a 2022-07-09 op
700 f36fd90a 2022-07-09 op for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL;
701 f36fd90a 2022-07-09 op cmsg = CMSG_NXTHDR(&msg, cmsg)) {
702 f36fd90a 2022-07-09 op if (cmsg->cmsg_level == SOL_SOCKET &&
703 f36fd90a 2022-07-09 op cmsg->cmsg_type == SCM_RIGHTS) {
704 f36fd90a 2022-07-09 op int i;
705 f36fd90a 2022-07-09 op int j;
706 f36fd90a 2022-07-09 op
707 f36fd90a 2022-07-09 op /*
708 f36fd90a 2022-07-09 op * We only accept one file descriptor. Due to C
709 f36fd90a 2022-07-09 op * padding rules, our control buffer might contain
710 f36fd90a 2022-07-09 op * more than one fd, and we must close them.
711 f36fd90a 2022-07-09 op */
712 f36fd90a 2022-07-09 op j = ((char *)cmsg + cmsg->cmsg_len -
713 f36fd90a 2022-07-09 op (char *)CMSG_DATA(cmsg)) / sizeof(int);
714 f36fd90a 2022-07-09 op for (i = 0; i < j; i++) {
715 f36fd90a 2022-07-09 op fd = ((int *)CMSG_DATA(cmsg))[i];
716 f36fd90a 2022-07-09 op if (ifd != NULL) {
717 f36fd90a 2022-07-09 op ifd->fd = fd;
718 f36fd90a 2022-07-09 op TAILQ_INSERT_TAIL(&ibuf->fds, ifd,
719 f36fd90a 2022-07-09 op entry);
720 f36fd90a 2022-07-09 op ifd = NULL;
721 f36fd90a 2022-07-09 op } else
722 f36fd90a 2022-07-09 op close(fd);
723 f36fd90a 2022-07-09 op }
724 f36fd90a 2022-07-09 op }
725 f36fd90a 2022-07-09 op /* we do not handle other ctl data level */
726 f36fd90a 2022-07-09 op }
727 f36fd90a 2022-07-09 op
728 f36fd90a 2022-07-09 op fail:
729 f36fd90a 2022-07-09 op free(ifd);
730 f36fd90a 2022-07-09 op return (n);
731 f36fd90a 2022-07-09 op }
732 f36fd90a 2022-07-09 op
733 f36fd90a 2022-07-09 op ssize_t
734 f36fd90a 2022-07-09 op imsg_get(struct imsgbuf *ibuf, struct imsg *imsg)
735 f36fd90a 2022-07-09 op {
736 f36fd90a 2022-07-09 op size_t av, left, datalen;
737 f36fd90a 2022-07-09 op
738 f36fd90a 2022-07-09 op av = ibuf->r.wpos;
739 f36fd90a 2022-07-09 op
740 f36fd90a 2022-07-09 op if (IMSG_HEADER_SIZE > av)
741 f36fd90a 2022-07-09 op return (0);
742 f36fd90a 2022-07-09 op
743 f36fd90a 2022-07-09 op memcpy(&imsg->hdr, ibuf->r.buf, sizeof(imsg->hdr));
744 f36fd90a 2022-07-09 op if (imsg->hdr.len < IMSG_HEADER_SIZE ||
745 f36fd90a 2022-07-09 op imsg->hdr.len > MAX_IMSGSIZE) {
746 f36fd90a 2022-07-09 op errno = ERANGE;
747 f36fd90a 2022-07-09 op return (-1);
748 f36fd90a 2022-07-09 op }
749 f36fd90a 2022-07-09 op if (imsg->hdr.len > av)
750 f36fd90a 2022-07-09 op return (0);
751 f36fd90a 2022-07-09 op datalen = imsg->hdr.len - IMSG_HEADER_SIZE;
752 f36fd90a 2022-07-09 op ibuf->r.rptr = ibuf->r.buf + IMSG_HEADER_SIZE;
753 f36fd90a 2022-07-09 op if (datalen == 0)
754 f36fd90a 2022-07-09 op imsg->data = NULL;
755 f36fd90a 2022-07-09 op else if ((imsg->data = malloc(datalen)) == NULL)
756 f36fd90a 2022-07-09 op return (-1);
757 f36fd90a 2022-07-09 op
758 f36fd90a 2022-07-09 op if (imsg->hdr.flags & IMSGF_HASFD)
759 f36fd90a 2022-07-09 op imsg->fd = imsg_get_fd(ibuf);
760 f36fd90a 2022-07-09 op else
761 f36fd90a 2022-07-09 op imsg->fd = -1;
762 f36fd90a 2022-07-09 op
763 f36fd90a 2022-07-09 op if (datalen != 0)
764 f36fd90a 2022-07-09 op memcpy(imsg->data, ibuf->r.rptr, datalen);
765 f36fd90a 2022-07-09 op
766 f36fd90a 2022-07-09 op if (imsg->hdr.len < av) {
767 f36fd90a 2022-07-09 op left = av - imsg->hdr.len;
768 f36fd90a 2022-07-09 op memmove(&ibuf->r.buf, ibuf->r.buf + imsg->hdr.len, left);
769 f36fd90a 2022-07-09 op ibuf->r.wpos = left;
770 f36fd90a 2022-07-09 op } else
771 f36fd90a 2022-07-09 op ibuf->r.wpos = 0;
772 f36fd90a 2022-07-09 op
773 f36fd90a 2022-07-09 op return (datalen + IMSG_HEADER_SIZE);
774 f36fd90a 2022-07-09 op }
775 f36fd90a 2022-07-09 op
776 f36fd90a 2022-07-09 op int
777 f36fd90a 2022-07-09 op imsg_compose(struct imsgbuf *ibuf, uint32_t type, uint32_t peerid, pid_t pid,
778 f36fd90a 2022-07-09 op int fd, const void *data, uint16_t datalen)
779 f36fd90a 2022-07-09 op {
780 f36fd90a 2022-07-09 op struct ibuf *wbuf;
781 f36fd90a 2022-07-09 op
782 f36fd90a 2022-07-09 op if ((wbuf = imsg_create(ibuf, type, peerid, pid, datalen)) == NULL)
783 f36fd90a 2022-07-09 op return (-1);
784 f36fd90a 2022-07-09 op
785 f36fd90a 2022-07-09 op if (imsg_add(wbuf, data, datalen) == -1)
786 f36fd90a 2022-07-09 op return (-1);
787 f36fd90a 2022-07-09 op
788 f36fd90a 2022-07-09 op wbuf->fd = fd;
789 f36fd90a 2022-07-09 op
790 f36fd90a 2022-07-09 op imsg_close(ibuf, wbuf);
791 f36fd90a 2022-07-09 op
792 f36fd90a 2022-07-09 op return (1);
793 f36fd90a 2022-07-09 op }
794 f36fd90a 2022-07-09 op
795 f36fd90a 2022-07-09 op int
796 f36fd90a 2022-07-09 op imsg_composev(struct imsgbuf *ibuf, uint32_t type, uint32_t peerid, pid_t pid,
797 f36fd90a 2022-07-09 op int fd, const struct iovec *iov, int iovcnt)
798 f36fd90a 2022-07-09 op {
799 f36fd90a 2022-07-09 op struct ibuf *wbuf;
800 f36fd90a 2022-07-09 op int i, datalen = 0;
801 f36fd90a 2022-07-09 op
802 f36fd90a 2022-07-09 op for (i = 0; i < iovcnt; i++)
803 f36fd90a 2022-07-09 op datalen += iov[i].iov_len;
804 f36fd90a 2022-07-09 op
805 f36fd90a 2022-07-09 op if ((wbuf = imsg_create(ibuf, type, peerid, pid, datalen)) == NULL)
806 f36fd90a 2022-07-09 op return (-1);
807 f36fd90a 2022-07-09 op
808 f36fd90a 2022-07-09 op for (i = 0; i < iovcnt; i++)
809 f36fd90a 2022-07-09 op if (imsg_add(wbuf, iov[i].iov_base, iov[i].iov_len) == -1)
810 f36fd90a 2022-07-09 op return (-1);
811 f36fd90a 2022-07-09 op
812 f36fd90a 2022-07-09 op wbuf->fd = fd;
813 f36fd90a 2022-07-09 op
814 f36fd90a 2022-07-09 op imsg_close(ibuf, wbuf);
815 f36fd90a 2022-07-09 op
816 f36fd90a 2022-07-09 op return (1);
817 f36fd90a 2022-07-09 op }
818 f36fd90a 2022-07-09 op
819 f36fd90a 2022-07-09 op /* ARGSUSED */
820 f36fd90a 2022-07-09 op struct ibuf *
821 f36fd90a 2022-07-09 op imsg_create(struct imsgbuf *ibuf, uint32_t type, uint32_t peerid, pid_t pid,
822 f36fd90a 2022-07-09 op uint16_t datalen)
823 f36fd90a 2022-07-09 op {
824 f36fd90a 2022-07-09 op struct ibuf *wbuf;
825 f36fd90a 2022-07-09 op struct imsg_hdr hdr;
826 f36fd90a 2022-07-09 op
827 f36fd90a 2022-07-09 op datalen += IMSG_HEADER_SIZE;
828 f36fd90a 2022-07-09 op if (datalen > MAX_IMSGSIZE) {
829 f36fd90a 2022-07-09 op errno = ERANGE;
830 f36fd90a 2022-07-09 op return (NULL);
831 f36fd90a 2022-07-09 op }
832 f36fd90a 2022-07-09 op
833 f36fd90a 2022-07-09 op hdr.type = type;
834 f36fd90a 2022-07-09 op hdr.flags = 0;
835 f36fd90a 2022-07-09 op hdr.peerid = peerid;
836 f36fd90a 2022-07-09 op if ((hdr.pid = pid) == 0)
837 f36fd90a 2022-07-09 op hdr.pid = ibuf->pid;
838 f36fd90a 2022-07-09 op if ((wbuf = ibuf_dynamic(datalen, MAX_IMSGSIZE)) == NULL) {
839 f36fd90a 2022-07-09 op return (NULL);
840 f36fd90a 2022-07-09 op }
841 f36fd90a 2022-07-09 op if (imsg_add(wbuf, &hdr, sizeof(hdr)) == -1)
842 f36fd90a 2022-07-09 op return (NULL);
843 f36fd90a 2022-07-09 op
844 f36fd90a 2022-07-09 op return (wbuf);
845 f36fd90a 2022-07-09 op }
846 f36fd90a 2022-07-09 op
847 f36fd90a 2022-07-09 op int
848 f36fd90a 2022-07-09 op imsg_add(struct ibuf *msg, const void *data, uint16_t datalen)
849 f36fd90a 2022-07-09 op {
850 f36fd90a 2022-07-09 op if (datalen)
851 f36fd90a 2022-07-09 op if (ibuf_add(msg, data, datalen) == -1) {
852 f36fd90a 2022-07-09 op ibuf_free(msg);
853 f36fd90a 2022-07-09 op return (-1);
854 f36fd90a 2022-07-09 op }
855 f36fd90a 2022-07-09 op return (datalen);
856 f36fd90a 2022-07-09 op }
857 f36fd90a 2022-07-09 op
858 f36fd90a 2022-07-09 op void
859 f36fd90a 2022-07-09 op imsg_close(struct imsgbuf *ibuf, struct ibuf *msg)
860 f36fd90a 2022-07-09 op {
861 f36fd90a 2022-07-09 op struct imsg_hdr *hdr;
862 f36fd90a 2022-07-09 op
863 f36fd90a 2022-07-09 op hdr = (struct imsg_hdr *)msg->buf;
864 f36fd90a 2022-07-09 op
865 f36fd90a 2022-07-09 op hdr->flags &= ~IMSGF_HASFD;
866 f36fd90a 2022-07-09 op if (msg->fd != -1)
867 f36fd90a 2022-07-09 op hdr->flags |= IMSGF_HASFD;
868 f36fd90a 2022-07-09 op
869 f36fd90a 2022-07-09 op hdr->len = (uint16_t)msg->wpos;
870 f36fd90a 2022-07-09 op
871 f36fd90a 2022-07-09 op ibuf_close(&ibuf->w, msg);
872 f36fd90a 2022-07-09 op }
873 f36fd90a 2022-07-09 op
874 f36fd90a 2022-07-09 op void
875 f36fd90a 2022-07-09 op imsg_free(struct imsg *imsg)
876 f36fd90a 2022-07-09 op {
877 f36fd90a 2022-07-09 op freezero(imsg->data, imsg->hdr.len - IMSG_HEADER_SIZE);
878 f36fd90a 2022-07-09 op }
879 f36fd90a 2022-07-09 op
880 f36fd90a 2022-07-09 op static int
881 f36fd90a 2022-07-09 op imsg_get_fd(struct imsgbuf *ibuf)
882 f36fd90a 2022-07-09 op {
883 f36fd90a 2022-07-09 op int fd;
884 f36fd90a 2022-07-09 op struct imsg_fd *ifd;
885 f36fd90a 2022-07-09 op
886 f36fd90a 2022-07-09 op if ((ifd = TAILQ_FIRST(&ibuf->fds)) == NULL)
887 f36fd90a 2022-07-09 op return (-1);
888 f36fd90a 2022-07-09 op
889 f36fd90a 2022-07-09 op fd = ifd->fd;
890 f36fd90a 2022-07-09 op TAILQ_REMOVE(&ibuf->fds, ifd, entry);
891 f36fd90a 2022-07-09 op free(ifd);
892 f36fd90a 2022-07-09 op
893 f36fd90a 2022-07-09 op return (fd);
894 f36fd90a 2022-07-09 op }
895 f36fd90a 2022-07-09 op
896 f36fd90a 2022-07-09 op int
897 f36fd90a 2022-07-09 op imsg_flush(struct imsgbuf *ibuf)
898 f36fd90a 2022-07-09 op {
899 f36fd90a 2022-07-09 op while (ibuf->w.queued)
900 f36fd90a 2022-07-09 op if (msgbuf_write(&ibuf->w) <= 0)
901 f36fd90a 2022-07-09 op return (-1);
902 f36fd90a 2022-07-09 op return (0);
903 f36fd90a 2022-07-09 op }
904 f36fd90a 2022-07-09 op
905 f36fd90a 2022-07-09 op void
906 f36fd90a 2022-07-09 op imsg_clear(struct imsgbuf *ibuf)
907 f36fd90a 2022-07-09 op {
908 f36fd90a 2022-07-09 op int fd;
909 f36fd90a 2022-07-09 op
910 f36fd90a 2022-07-09 op msgbuf_clear(&ibuf->w);
911 f36fd90a 2022-07-09 op while ((fd = imsg_get_fd(ibuf)) != -1)
912 f36fd90a 2022-07-09 op close(fd);
913 f36fd90a 2022-07-09 op }
914 f36fd90a 2022-07-09 op #endif /* HAVE_IMSG */
915 f36fd90a 2022-07-09 op #if !HAVE_MEMMEM
916 f36fd90a 2022-07-09 op /*-
917 f36fd90a 2022-07-09 op * Copyright (c) 2005 Pascal Gloor <pascal.gloor@spale.com>
918 f36fd90a 2022-07-09 op *
919 f36fd90a 2022-07-09 op * Redistribution and use in source and binary forms, with or without
920 f36fd90a 2022-07-09 op * modification, are permitted provided that the following conditions
921 f36fd90a 2022-07-09 op * are met:
922 f36fd90a 2022-07-09 op * 1. Redistributions of source code must retain the above copyright
923 f36fd90a 2022-07-09 op * notice, this list of conditions and the following disclaimer.
924 f36fd90a 2022-07-09 op * 2. Redistributions in binary form must reproduce the above copyright
925 f36fd90a 2022-07-09 op * notice, this list of conditions and the following disclaimer in
926 f36fd90a 2022-07-09 op * the documentation and/or other materials provided with the
927 f36fd90a 2022-07-09 op * distribution.
928 f36fd90a 2022-07-09 op * 3. The name of the author may not be used to endorse or promote
929 f36fd90a 2022-07-09 op * products derived from this software without specific prior written
930 f36fd90a 2022-07-09 op * permission.
931 f36fd90a 2022-07-09 op *
932 f36fd90a 2022-07-09 op * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS''
933 f36fd90a 2022-07-09 op * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
934 f36fd90a 2022-07-09 op * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
935 f36fd90a 2022-07-09 op * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR
936 f36fd90a 2022-07-09 op * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
937 f36fd90a 2022-07-09 op * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
938 f36fd90a 2022-07-09 op * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
939 f36fd90a 2022-07-09 op * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
940 f36fd90a 2022-07-09 op * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
941 f36fd90a 2022-07-09 op * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
942 f36fd90a 2022-07-09 op * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
943 f36fd90a 2022-07-09 op */
944 f36fd90a 2022-07-09 op /*
945 f36fd90a 2022-07-09 op * Find the first occurrence of the byte string s in byte string l.
946 f36fd90a 2022-07-09 op */
947 f36fd90a 2022-07-09 op void *
948 f36fd90a 2022-07-09 op memmem(const void *l, size_t l_len, const void *s, size_t s_len)
949 f36fd90a 2022-07-09 op {
950 f36fd90a 2022-07-09 op const char *cur, *last;
951 f36fd90a 2022-07-09 op const char *cl = l;
952 f36fd90a 2022-07-09 op const char *cs = s;
953 f36fd90a 2022-07-09 op
954 f36fd90a 2022-07-09 op /* a zero length needle should just return the haystack */
955 f36fd90a 2022-07-09 op if (l_len == 0)
956 f36fd90a 2022-07-09 op return (void *)cl;
957 f36fd90a 2022-07-09 op
958 f36fd90a 2022-07-09 op /* "s" must be smaller or equal to "l" */
959 f36fd90a 2022-07-09 op if (l_len < s_len)
960 f36fd90a 2022-07-09 op return NULL;
961 f36fd90a 2022-07-09 op
962 f36fd90a 2022-07-09 op /* special case where s_len == 1 */
963 f36fd90a 2022-07-09 op if (s_len == 1)
964 f36fd90a 2022-07-09 op return memchr(l, *cs, l_len);
965 f36fd90a 2022-07-09 op
966 f36fd90a 2022-07-09 op /* the last position where its possible to find "s" in "l" */
967 f36fd90a 2022-07-09 op last = cl + l_len - s_len;
968 f36fd90a 2022-07-09 op
969 f36fd90a 2022-07-09 op for (cur = cl; cur <= last; cur++)
970 f36fd90a 2022-07-09 op if (cur[0] == cs[0] && memcmp(cur, cs, s_len) == 0)
971 f36fd90a 2022-07-09 op return (void *)cur;
972 f36fd90a 2022-07-09 op
973 f36fd90a 2022-07-09 op return NULL;
974 f36fd90a 2022-07-09 op }
975 f36fd90a 2022-07-09 op #endif /* !HAVE_MEMMEM */
976 f36fd90a 2022-07-09 op #if !HAVE_MEMRCHR
977 f36fd90a 2022-07-09 op /*
978 f36fd90a 2022-07-09 op * Copyright (c) 2007 Todd C. Miller <Todd.Miller@courtesan.com>
979 f36fd90a 2022-07-09 op *
980 f36fd90a 2022-07-09 op * Permission to use, copy, modify, and distribute this software for any
981 f36fd90a 2022-07-09 op * purpose with or without fee is hereby granted, provided that the above
982 f36fd90a 2022-07-09 op * copyright notice and this permission notice appear in all copies.
983 f36fd90a 2022-07-09 op *
984 f36fd90a 2022-07-09 op * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
985 f36fd90a 2022-07-09 op * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
986 f36fd90a 2022-07-09 op * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
987 f36fd90a 2022-07-09 op * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
988 f36fd90a 2022-07-09 op * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
989 f36fd90a 2022-07-09 op * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
990 f36fd90a 2022-07-09 op * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
991 f36fd90a 2022-07-09 op *
992 f36fd90a 2022-07-09 op */
993 f36fd90a 2022-07-09 op
994 f36fd90a 2022-07-09 op #include <string.h>
995 f36fd90a 2022-07-09 op
996 f36fd90a 2022-07-09 op /*
997 f36fd90a 2022-07-09 op * Reverse memchr()
998 f36fd90a 2022-07-09 op * Find the last occurrence of 'c' in the buffer 's' of size 'n'.
999 f36fd90a 2022-07-09 op */
1000 f36fd90a 2022-07-09 op void *
1001 f36fd90a 2022-07-09 op memrchr(const void *s, int c, size_t n)
1002 f36fd90a 2022-07-09 op {
1003 f36fd90a 2022-07-09 op const unsigned char *cp;
1004 f36fd90a 2022-07-09 op
1005 f36fd90a 2022-07-09 op if (n != 0) {
1006 f36fd90a 2022-07-09 op cp = (unsigned char *)s + n;
1007 f36fd90a 2022-07-09 op do {
1008 f36fd90a 2022-07-09 op if (*(--cp) == (unsigned char)c)
1009 f36fd90a 2022-07-09 op return((void *)cp);
1010 f36fd90a 2022-07-09 op } while (--n != 0);
1011 f36fd90a 2022-07-09 op }
1012 f36fd90a 2022-07-09 op return(NULL);
1013 f36fd90a 2022-07-09 op }
1014 f36fd90a 2022-07-09 op #endif /* !HAVE_MEMRCHR */
1015 f36fd90a 2022-07-09 op #if !HAVE_OPTRESET
1016 f36fd90a 2022-07-09 op /*
1017 f36fd90a 2022-07-09 op * Copyright (c) 1987, 1993, 1994
1018 f36fd90a 2022-07-09 op * The Regents of the University of California. All rights reserved.
1019 f36fd90a 2022-07-09 op *
1020 f36fd90a 2022-07-09 op * Redistribution and use in source and binary forms, with or without
1021 f36fd90a 2022-07-09 op * modification, are permitted provided that the following conditions
1022 f36fd90a 2022-07-09 op * are met:
1023 f36fd90a 2022-07-09 op * 1. Redistributions of source code must retain the above copyright
1024 f36fd90a 2022-07-09 op * notice, this list of conditions and the following disclaimer.
1025 f36fd90a 2022-07-09 op * 2. Redistributions in binary form must reproduce the above copyright
1026 f36fd90a 2022-07-09 op * notice, this list of conditions and the following disclaimer in the
1027 f36fd90a 2022-07-09 op * documentation and/or other materials provided with the distribution.
1028 f36fd90a 2022-07-09 op * 3. Neither the name of the University nor the names of its contributors
1029 f36fd90a 2022-07-09 op * may be used to endorse or promote products derived from this software
1030 f36fd90a 2022-07-09 op * without specific prior written permission.
1031 f36fd90a 2022-07-09 op *
1032 f36fd90a 2022-07-09 op * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
1033 f36fd90a 2022-07-09 op * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1034 f36fd90a 2022-07-09 op * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1035 f36fd90a 2022-07-09 op * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
1036 f36fd90a 2022-07-09 op * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1037 f36fd90a 2022-07-09 op * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
1038 f36fd90a 2022-07-09 op * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1039 f36fd90a 2022-07-09 op * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1040 f36fd90a 2022-07-09 op * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
1041 f36fd90a 2022-07-09 op * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
1042 f36fd90a 2022-07-09 op * SUCH DAMAGE.
1043 f36fd90a 2022-07-09 op */
1044 f36fd90a 2022-07-09 op
1045 f36fd90a 2022-07-09 op /* OPENBSD ORIGINAL: lib/libc/stdlib/getopt.c */
1046 f36fd90a 2022-07-09 op
1047 f36fd90a 2022-07-09 op #include <stdio.h>
1048 f36fd90a 2022-07-09 op #include <stdlib.h>
1049 f36fd90a 2022-07-09 op #include <string.h>
1050 f36fd90a 2022-07-09 op
1051 f36fd90a 2022-07-09 op int BSDopterr = 1, /* if error message should be printed */
1052 f36fd90a 2022-07-09 op BSDoptind = 1, /* index into parent argv vector */
1053 f36fd90a 2022-07-09 op BSDoptopt, /* character checked for validity */
1054 f36fd90a 2022-07-09 op BSDoptreset; /* reset getopt */
1055 f36fd90a 2022-07-09 op char *BSDoptarg; /* argument associated with option */
1056 f36fd90a 2022-07-09 op
1057 f36fd90a 2022-07-09 op #define BADCH (int)'?'
1058 f36fd90a 2022-07-09 op #define BADARG (int)':'
1059 f36fd90a 2022-07-09 op #define EMSG ""
1060 f36fd90a 2022-07-09 op
1061 f36fd90a 2022-07-09 op /*
1062 f36fd90a 2022-07-09 op * getopt --
1063 f36fd90a 2022-07-09 op * Parse argc/argv argument vector.
1064 f36fd90a 2022-07-09 op */
1065 f36fd90a 2022-07-09 op int
1066 f36fd90a 2022-07-09 op BSDgetopt(int nargc, char *const *nargv, const char *ostr)
1067 f36fd90a 2022-07-09 op {
1068 f36fd90a 2022-07-09 op static const char *place = EMSG; /* option letter processing */
1069 f36fd90a 2022-07-09 op char *oli; /* option letter list index */
1070 f36fd90a 2022-07-09 op
1071 f36fd90a 2022-07-09 op if (ostr == NULL)
1072 f36fd90a 2022-07-09 op return (-1);
1073 f36fd90a 2022-07-09 op
1074 f36fd90a 2022-07-09 op if (BSDoptreset || !*place) { /* update scanning pointer */
1075 f36fd90a 2022-07-09 op BSDoptreset = 0;
1076 f36fd90a 2022-07-09 op if (BSDoptind >= nargc || *(place = nargv[BSDoptind]) != '-') {
1077 f36fd90a 2022-07-09 op place = EMSG;
1078 f36fd90a 2022-07-09 op return (-1);
1079 f36fd90a 2022-07-09 op }
1080 f36fd90a 2022-07-09 op if (place[1] && *++place == '-') { /* found "--" */
1081 f36fd90a 2022-07-09 op if (place[1])
1082 f36fd90a 2022-07-09 op return (BADCH);
1083 f36fd90a 2022-07-09 op ++BSDoptind;
1084 f36fd90a 2022-07-09 op place = EMSG;
1085 f36fd90a 2022-07-09 op return (-1);
1086 f36fd90a 2022-07-09 op }
1087 f36fd90a 2022-07-09 op } /* option letter okay? */
1088 f36fd90a 2022-07-09 op if ((BSDoptopt = (int)*place++) == (int)':' ||
1089 f36fd90a 2022-07-09 op !(oli = strchr(ostr, BSDoptopt))) {
1090 f36fd90a 2022-07-09 op /*
1091 f36fd90a 2022-07-09 op * if the user didn't specify '-' as an option,
1092 f36fd90a 2022-07-09 op * assume it means -1.
1093 f36fd90a 2022-07-09 op */
1094 f36fd90a 2022-07-09 op if (BSDoptopt == (int)'-')
1095 f36fd90a 2022-07-09 op return (-1);
1096 f36fd90a 2022-07-09 op if (!*place)
1097 f36fd90a 2022-07-09 op ++BSDoptind;
1098 f36fd90a 2022-07-09 op if (BSDopterr && *ostr != ':')
1099 f36fd90a 2022-07-09 op (void)fprintf(stderr,
1100 f36fd90a 2022-07-09 op "%s: unknown option -- %c\n", getprogname(),
1101 f36fd90a 2022-07-09 op BSDoptopt);
1102 f36fd90a 2022-07-09 op return (BADCH);
1103 f36fd90a 2022-07-09 op }
1104 f36fd90a 2022-07-09 op if (*++oli != ':') { /* don't need argument */
1105 f36fd90a 2022-07-09 op BSDoptarg = NULL;
1106 f36fd90a 2022-07-09 op if (!*place)
1107 f36fd90a 2022-07-09 op ++BSDoptind;
1108 f36fd90a 2022-07-09 op }
1109 f36fd90a 2022-07-09 op else { /* need an argument */
1110 f36fd90a 2022-07-09 op if (*place) /* no white space */
1111 f36fd90a 2022-07-09 op BSDoptarg = (char *)place;
1112 f36fd90a 2022-07-09 op else if (nargc <= ++BSDoptind) { /* no arg */
1113 f36fd90a 2022-07-09 op place = EMSG;
1114 f36fd90a 2022-07-09 op if (*ostr == ':')
1115 f36fd90a 2022-07-09 op return (BADARG);
1116 f36fd90a 2022-07-09 op if (BSDopterr)
1117 f36fd90a 2022-07-09 op (void)fprintf(stderr,
1118 f36fd90a 2022-07-09 op "%s: option requires an argument -- %c\n",
1119 f36fd90a 2022-07-09 op getprogname(), BSDoptopt);
1120 f36fd90a 2022-07-09 op return (BADCH);
1121 f36fd90a 2022-07-09 op }
1122 f36fd90a 2022-07-09 op else /* white space */
1123 f36fd90a 2022-07-09 op BSDoptarg = nargv[BSDoptind];
1124 f36fd90a 2022-07-09 op place = EMSG;
1125 f36fd90a 2022-07-09 op ++BSDoptind;
1126 f36fd90a 2022-07-09 op }
1127 f36fd90a 2022-07-09 op return (BSDoptopt); /* dump back option letter */
1128 f36fd90a 2022-07-09 op }
1129 f36fd90a 2022-07-09 op #endif
1130 f36fd90a 2022-07-09 op #if !HAVE_REALLOCARRAY
1131 f36fd90a 2022-07-09 op /*
1132 f36fd90a 2022-07-09 op * Copyright (c) 2008 Otto Moerbeek <otto@drijf.net>
1133 f36fd90a 2022-07-09 op *
1134 f36fd90a 2022-07-09 op * Permission to use, copy, modify, and distribute this software for any
1135 f36fd90a 2022-07-09 op * purpose with or without fee is hereby granted, provided that the above
1136 f36fd90a 2022-07-09 op * copyright notice and this permission notice appear in all copies.
1137 f36fd90a 2022-07-09 op *
1138 f36fd90a 2022-07-09 op * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
1139 f36fd90a 2022-07-09 op * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
1140 f36fd90a 2022-07-09 op * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
1141 f36fd90a 2022-07-09 op * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
1142 f36fd90a 2022-07-09 op * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
1143 f36fd90a 2022-07-09 op * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
1144 f36fd90a 2022-07-09 op * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1145 f36fd90a 2022-07-09 op */
1146 f36fd90a 2022-07-09 op
1147 f36fd90a 2022-07-09 op #include <sys/types.h>
1148 f36fd90a 2022-07-09 op #include <errno.h>
1149 f36fd90a 2022-07-09 op #include <stdint.h>
1150 f36fd90a 2022-07-09 op #include <stdlib.h>
1151 f36fd90a 2022-07-09 op
1152 f36fd90a 2022-07-09 op /*
1153 f36fd90a 2022-07-09 op * This is sqrt(SIZE_MAX+1), as s1*s2 <= SIZE_MAX
1154 f36fd90a 2022-07-09 op * if both s1 < MUL_NO_OVERFLOW and s2 < MUL_NO_OVERFLOW
1155 f36fd90a 2022-07-09 op */
1156 f36fd90a 2022-07-09 op #define MUL_NO_OVERFLOW ((size_t)1 << (sizeof(size_t) * 4))
1157 f36fd90a 2022-07-09 op
1158 f36fd90a 2022-07-09 op void *
1159 f36fd90a 2022-07-09 op reallocarray(void *optr, size_t nmemb, size_t size)
1160 f36fd90a 2022-07-09 op {
1161 f36fd90a 2022-07-09 op if ((nmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) &&
1162 f36fd90a 2022-07-09 op nmemb > 0 && SIZE_MAX / nmemb < size) {
1163 f36fd90a 2022-07-09 op errno = ENOMEM;
1164 f36fd90a 2022-07-09 op return NULL;
1165 f36fd90a 2022-07-09 op }
1166 f36fd90a 2022-07-09 op return realloc(optr, size * nmemb);
1167 f36fd90a 2022-07-09 op }
1168 f36fd90a 2022-07-09 op #endif /* !HAVE_REALLOCARRAY */
1169 f36fd90a 2022-07-09 op #if !HAVE_RECALLOCARRAY
1170 f36fd90a 2022-07-09 op /*
1171 f36fd90a 2022-07-09 op * Copyright (c) 2008, 2017 Otto Moerbeek <otto@drijf.net>
1172 f36fd90a 2022-07-09 op *
1173 f36fd90a 2022-07-09 op * Permission to use, copy, modify, and distribute this software for any
1174 f36fd90a 2022-07-09 op * purpose with or without fee is hereby granted, provided that the above
1175 f36fd90a 2022-07-09 op * copyright notice and this permission notice appear in all copies.
1176 f36fd90a 2022-07-09 op *
1177 f36fd90a 2022-07-09 op * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
1178 f36fd90a 2022-07-09 op * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
1179 f36fd90a 2022-07-09 op * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
1180 f36fd90a 2022-07-09 op * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
1181 f36fd90a 2022-07-09 op * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
1182 f36fd90a 2022-07-09 op * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
1183 f36fd90a 2022-07-09 op * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1184 f36fd90a 2022-07-09 op */
1185 f36fd90a 2022-07-09 op
1186 f36fd90a 2022-07-09 op /* OPENBSD ORIGINAL: lib/libc/stdlib/recallocarray.c */
1187 f36fd90a 2022-07-09 op
1188 f36fd90a 2022-07-09 op #include <errno.h>
1189 f36fd90a 2022-07-09 op #include <stdlib.h>
1190 f36fd90a 2022-07-09 op #include <stdint.h>
1191 f36fd90a 2022-07-09 op #include <string.h>
1192 f36fd90a 2022-07-09 op #include <unistd.h>
1193 f36fd90a 2022-07-09 op
1194 f36fd90a 2022-07-09 op /*
1195 f36fd90a 2022-07-09 op * This is sqrt(SIZE_MAX+1), as s1*s2 <= SIZE_MAX
1196 f36fd90a 2022-07-09 op * if both s1 < MUL_NO_OVERFLOW and s2 < MUL_NO_OVERFLOW
1197 f36fd90a 2022-07-09 op */
1198 f36fd90a 2022-07-09 op #define MUL_NO_OVERFLOW ((size_t)1 << (sizeof(size_t) * 4))
1199 f36fd90a 2022-07-09 op
1200 f36fd90a 2022-07-09 op void *
1201 f36fd90a 2022-07-09 op recallocarray(void *ptr, size_t oldnmemb, size_t newnmemb, size_t size)
1202 f36fd90a 2022-07-09 op {
1203 f36fd90a 2022-07-09 op size_t oldsize, newsize;
1204 f36fd90a 2022-07-09 op void *newptr;
1205 f36fd90a 2022-07-09 op
1206 f36fd90a 2022-07-09 op if (ptr == NULL)
1207 f36fd90a 2022-07-09 op return calloc(newnmemb, size);
1208 f36fd90a 2022-07-09 op
1209 f36fd90a 2022-07-09 op if ((newnmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) &&
1210 f36fd90a 2022-07-09 op newnmemb > 0 && SIZE_MAX / newnmemb < size) {
1211 f36fd90a 2022-07-09 op errno = ENOMEM;
1212 f36fd90a 2022-07-09 op return NULL;
1213 f36fd90a 2022-07-09 op }
1214 f36fd90a 2022-07-09 op newsize = newnmemb * size;
1215 f36fd90a 2022-07-09 op
1216 f36fd90a 2022-07-09 op if ((oldnmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) &&
1217 f36fd90a 2022-07-09 op oldnmemb > 0 && SIZE_MAX / oldnmemb < size) {
1218 f36fd90a 2022-07-09 op errno = EINVAL;
1219 f36fd90a 2022-07-09 op return NULL;
1220 f36fd90a 2022-07-09 op }
1221 f36fd90a 2022-07-09 op oldsize = oldnmemb * size;
1222 f36fd90a 2022-07-09 op
1223 f36fd90a 2022-07-09 op /*
1224 f36fd90a 2022-07-09 op * Don't bother too much if we're shrinking just a bit,
1225 f36fd90a 2022-07-09 op * we do not shrink for series of small steps, oh well.
1226 f36fd90a 2022-07-09 op */
1227 f36fd90a 2022-07-09 op if (newsize <= oldsize) {
1228 f36fd90a 2022-07-09 op size_t d = oldsize - newsize;
1229 f36fd90a 2022-07-09 op
1230 f36fd90a 2022-07-09 op if (d < oldsize / 2 && d < (size_t)getpagesize()) {
1231 f36fd90a 2022-07-09 op memset((char *)ptr + newsize, 0, d);
1232 f36fd90a 2022-07-09 op return ptr;
1233 f36fd90a 2022-07-09 op }
1234 f36fd90a 2022-07-09 op }
1235 f36fd90a 2022-07-09 op
1236 f36fd90a 2022-07-09 op newptr = malloc(newsize);
1237 f36fd90a 2022-07-09 op if (newptr == NULL)
1238 f36fd90a 2022-07-09 op return NULL;
1239 f36fd90a 2022-07-09 op
1240 f36fd90a 2022-07-09 op if (newsize > oldsize) {
1241 f36fd90a 2022-07-09 op memcpy(newptr, ptr, oldsize);
1242 f36fd90a 2022-07-09 op memset((char *)newptr + oldsize, 0, newsize - oldsize);
1243 f36fd90a 2022-07-09 op } else
1244 f36fd90a 2022-07-09 op memcpy(newptr, ptr, newsize);
1245 f36fd90a 2022-07-09 op
1246 f36fd90a 2022-07-09 op explicit_bzero(ptr, oldsize);
1247 f36fd90a 2022-07-09 op free(ptr);
1248 f36fd90a 2022-07-09 op
1249 f36fd90a 2022-07-09 op return newptr;
1250 f36fd90a 2022-07-09 op }
1251 f36fd90a 2022-07-09 op #endif /* !HAVE_RECALLOCARRAY */
1252 f36fd90a 2022-07-09 op #if !HAVE_SETPROCTITLE
1253 f36fd90a 2022-07-09 op /*
1254 f36fd90a 2022-07-09 op * Copyright (c) 2016 Nicholas Marriott <nicholas.marriott@gmail.com>
1255 f36fd90a 2022-07-09 op *
1256 f36fd90a 2022-07-09 op * Permission to use, copy, modify, and distribute this software for any
1257 f36fd90a 2022-07-09 op * purpose with or without fee is hereby granted, provided that the above
1258 f36fd90a 2022-07-09 op * copyright notice and this permission notice appear in all copies.
1259 f36fd90a 2022-07-09 op *
1260 f36fd90a 2022-07-09 op * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
1261 f36fd90a 2022-07-09 op * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
1262 f36fd90a 2022-07-09 op * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
1263 f36fd90a 2022-07-09 op * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
1264 f36fd90a 2022-07-09 op * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
1265 f36fd90a 2022-07-09 op * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
1266 f36fd90a 2022-07-09 op * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1267 f36fd90a 2022-07-09 op */
1268 f36fd90a 2022-07-09 op
1269 f36fd90a 2022-07-09 op # if HAVE_PR_SET_NAME
1270 f36fd90a 2022-07-09 op #include <sys/types.h>
1271 f36fd90a 2022-07-09 op #include <stdarg.h>
1272 f36fd90a 2022-07-09 op #include <stdio.h>
1273 f36fd90a 2022-07-09 op #include <string.h>
1274 f36fd90a 2022-07-09 op #include <sys/prctl.h>
1275 f36fd90a 2022-07-09 op void
1276 f36fd90a 2022-07-09 op setproctitle(const char *fmt, ...)
1277 f36fd90a 2022-07-09 op {
1278 f36fd90a 2022-07-09 op char title[16], name[16], *cp;
1279 f36fd90a 2022-07-09 op va_list ap;
1280 f36fd90a 2022-07-09 op int used;
1281 f36fd90a 2022-07-09 op
1282 f36fd90a 2022-07-09 op va_start(ap, fmt);
1283 f36fd90a 2022-07-09 op vsnprintf(title, sizeof(title), fmt, ap);
1284 f36fd90a 2022-07-09 op va_end(ap);
1285 f36fd90a 2022-07-09 op
1286 f36fd90a 2022-07-09 op used = snprintf(name, sizeof(name), "%s: %s", getprogname(), title);
1287 f36fd90a 2022-07-09 op if (used >= (int)sizeof(name)) {
1288 f36fd90a 2022-07-09 op cp = strrchr(name, ' ');
1289 f36fd90a 2022-07-09 op if (cp != NULL)
1290 f36fd90a 2022-07-09 op *cp = '\0';
1291 f36fd90a 2022-07-09 op }
1292 f36fd90a 2022-07-09 op prctl(PR_SET_NAME, name);
1293 f36fd90a 2022-07-09 op }
1294 f36fd90a 2022-07-09 op # else
1295 f36fd90a 2022-07-09 op void
1296 f36fd90a 2022-07-09 op setproctitle(const char *fmt, ...)
1297 f36fd90a 2022-07-09 op {
1298 f36fd90a 2022-07-09 op return;
1299 f36fd90a 2022-07-09 op }
1300 f36fd90a 2022-07-09 op # endif
1301 f36fd90a 2022-07-09 op #endif /* !HAVE_SETPROCTITLE */
1302 f36fd90a 2022-07-09 op #if !HAVE_STRLCAT
1303 f36fd90a 2022-07-09 op /*
1304 f36fd90a 2022-07-09 op * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
1305 f36fd90a 2022-07-09 op *
1306 f36fd90a 2022-07-09 op * Permission to use, copy, modify, and distribute this software for any
1307 f36fd90a 2022-07-09 op * purpose with or without fee is hereby granted, provided that the above
1308 f36fd90a 2022-07-09 op * copyright notice and this permission notice appear in all copies.
1309 f36fd90a 2022-07-09 op *
1310 f36fd90a 2022-07-09 op * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
1311 f36fd90a 2022-07-09 op * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
1312 f36fd90a 2022-07-09 op * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
1313 f36fd90a 2022-07-09 op * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
1314 f36fd90a 2022-07-09 op * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
1315 f36fd90a 2022-07-09 op * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
1316 f36fd90a 2022-07-09 op * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1317 f36fd90a 2022-07-09 op */
1318 f36fd90a 2022-07-09 op
1319 f36fd90a 2022-07-09 op #include <sys/types.h>
1320 f36fd90a 2022-07-09 op #include <string.h>
1321 f36fd90a 2022-07-09 op
1322 f36fd90a 2022-07-09 op /*
1323 f36fd90a 2022-07-09 op * Appends src to string dst of size siz (unlike strncat, siz is the
1324 f36fd90a 2022-07-09 op * full size of dst, not space left). At most siz-1 characters
1325 f36fd90a 2022-07-09 op * will be copied. Always NUL terminates (unless siz <= strlen(dst)).
1326 f36fd90a 2022-07-09 op * Returns strlen(src) + MIN(siz, strlen(initial dst)).
1327 f36fd90a 2022-07-09 op * If retval >= siz, truncation occurred.
1328 f36fd90a 2022-07-09 op */
1329 f36fd90a 2022-07-09 op size_t
1330 f36fd90a 2022-07-09 op strlcat(char *dst, const char *src, size_t siz)
1331 f36fd90a 2022-07-09 op {
1332 f36fd90a 2022-07-09 op char *d = dst;
1333 f36fd90a 2022-07-09 op const char *s = src;
1334 f36fd90a 2022-07-09 op size_t n = siz;
1335 f36fd90a 2022-07-09 op size_t dlen;
1336 f36fd90a 2022-07-09 op
1337 f36fd90a 2022-07-09 op /* Find the end of dst and adjust bytes left but don't go past end */
1338 f36fd90a 2022-07-09 op while (n-- != 0 && *d != '\0')
1339 f36fd90a 2022-07-09 op d++;
1340 f36fd90a 2022-07-09 op dlen = d - dst;
1341 f36fd90a 2022-07-09 op n = siz - dlen;
1342 f36fd90a 2022-07-09 op
1343 f36fd90a 2022-07-09 op if (n == 0)
1344 f36fd90a 2022-07-09 op return(dlen + strlen(s));
1345 f36fd90a 2022-07-09 op while (*s != '\0') {
1346 f36fd90a 2022-07-09 op if (n != 1) {
1347 f36fd90a 2022-07-09 op *d++ = *s;
1348 f36fd90a 2022-07-09 op n--;
1349 f36fd90a 2022-07-09 op }
1350 f36fd90a 2022-07-09 op s++;
1351 f36fd90a 2022-07-09 op }
1352 f36fd90a 2022-07-09 op *d = '\0';
1353 f36fd90a 2022-07-09 op
1354 f36fd90a 2022-07-09 op return(dlen + (s - src)); /* count does not include NUL */
1355 f36fd90a 2022-07-09 op }
1356 f36fd90a 2022-07-09 op #endif /* !HAVE_STRLCAT */
1357 f36fd90a 2022-07-09 op #if !HAVE_STRLCPY
1358 f36fd90a 2022-07-09 op /*
1359 f36fd90a 2022-07-09 op * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
1360 f36fd90a 2022-07-09 op *
1361 f36fd90a 2022-07-09 op * Permission to use, copy, modify, and distribute this software for any
1362 f36fd90a 2022-07-09 op * purpose with or without fee is hereby granted, provided that the above
1363 f36fd90a 2022-07-09 op * copyright notice and this permission notice appear in all copies.
1364 f36fd90a 2022-07-09 op *
1365 f36fd90a 2022-07-09 op * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
1366 f36fd90a 2022-07-09 op * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
1367 f36fd90a 2022-07-09 op * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
1368 f36fd90a 2022-07-09 op * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
1369 f36fd90a 2022-07-09 op * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
1370 f36fd90a 2022-07-09 op * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
1371 f36fd90a 2022-07-09 op * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1372 f36fd90a 2022-07-09 op */
1373 f36fd90a 2022-07-09 op
1374 f36fd90a 2022-07-09 op #include <sys/types.h>
1375 f36fd90a 2022-07-09 op #include <string.h>
1376 f36fd90a 2022-07-09 op
1377 f36fd90a 2022-07-09 op /*
1378 f36fd90a 2022-07-09 op * Copy src to string dst of size siz. At most siz-1 characters
1379 f36fd90a 2022-07-09 op * will be copied. Always NUL terminates (unless siz == 0).
1380 f36fd90a 2022-07-09 op * Returns strlen(src); if retval >= siz, truncation occurred.
1381 f36fd90a 2022-07-09 op */
1382 f36fd90a 2022-07-09 op size_t
1383 f36fd90a 2022-07-09 op strlcpy(char *dst, const char *src, size_t siz)
1384 f36fd90a 2022-07-09 op {
1385 f36fd90a 2022-07-09 op char *d = dst;
1386 f36fd90a 2022-07-09 op const char *s = src;
1387 f36fd90a 2022-07-09 op size_t n = siz;
1388 f36fd90a 2022-07-09 op
1389 f36fd90a 2022-07-09 op /* Copy as many bytes as will fit */
1390 f36fd90a 2022-07-09 op if (n != 0) {
1391 f36fd90a 2022-07-09 op while (--n != 0) {
1392 f36fd90a 2022-07-09 op if ((*d++ = *s++) == '\0')
1393 f36fd90a 2022-07-09 op break;
1394 f36fd90a 2022-07-09 op }
1395 f36fd90a 2022-07-09 op }
1396 f36fd90a 2022-07-09 op
1397 f36fd90a 2022-07-09 op /* Not enough room in dst, add NUL and traverse rest of src */
1398 f36fd90a 2022-07-09 op if (n == 0) {
1399 f36fd90a 2022-07-09 op if (siz != 0)
1400 f36fd90a 2022-07-09 op *d = '\0'; /* NUL-terminate dst */
1401 f36fd90a 2022-07-09 op while (*s++)
1402 f36fd90a 2022-07-09 op ;
1403 f36fd90a 2022-07-09 op }
1404 f36fd90a 2022-07-09 op
1405 f36fd90a 2022-07-09 op return(s - src - 1); /* count does not include NUL */
1406 f36fd90a 2022-07-09 op }
1407 f36fd90a 2022-07-09 op #endif /* !HAVE_STRLCPY */
1408 f36fd90a 2022-07-09 op #if !HAVE_STRNDUP
1409 f36fd90a 2022-07-09 op /* $OpenBSD$ */
1410 f36fd90a 2022-07-09 op /*
1411 f36fd90a 2022-07-09 op * Copyright (c) 2010 Todd C. Miller <Todd.Miller@courtesan.com>
1412 f36fd90a 2022-07-09 op *
1413 f36fd90a 2022-07-09 op * Permission to use, copy, modify, and distribute this software for any
1414 f36fd90a 2022-07-09 op * purpose with or without fee is hereby granted, provided that the above
1415 f36fd90a 2022-07-09 op * copyright notice and this permission notice appear in all copies.
1416 f36fd90a 2022-07-09 op *
1417 f36fd90a 2022-07-09 op * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
1418 f36fd90a 2022-07-09 op * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
1419 f36fd90a 2022-07-09 op * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
1420 f36fd90a 2022-07-09 op * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
1421 f36fd90a 2022-07-09 op * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
1422 f36fd90a 2022-07-09 op * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
1423 f36fd90a 2022-07-09 op * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1424 f36fd90a 2022-07-09 op */
1425 f36fd90a 2022-07-09 op
1426 f36fd90a 2022-07-09 op #include <sys/types.h>
1427 f36fd90a 2022-07-09 op
1428 f36fd90a 2022-07-09 op #include <stddef.h>
1429 f36fd90a 2022-07-09 op #include <stdlib.h>
1430 f36fd90a 2022-07-09 op #include <string.h>
1431 f36fd90a 2022-07-09 op
1432 f36fd90a 2022-07-09 op char *
1433 f36fd90a 2022-07-09 op strndup(const char *str, size_t maxlen)
1434 f36fd90a 2022-07-09 op {
1435 f36fd90a 2022-07-09 op char *copy;
1436 f36fd90a 2022-07-09 op size_t len;
1437 f36fd90a 2022-07-09 op
1438 f36fd90a 2022-07-09 op len = strnlen(str, maxlen);
1439 f36fd90a 2022-07-09 op copy = malloc(len + 1);
1440 f36fd90a 2022-07-09 op if (copy != NULL) {
1441 f36fd90a 2022-07-09 op (void)memcpy(copy, str, len);
1442 f36fd90a 2022-07-09 op copy[len] = '\0';
1443 f36fd90a 2022-07-09 op }
1444 f36fd90a 2022-07-09 op
1445 f36fd90a 2022-07-09 op return copy;
1446 f36fd90a 2022-07-09 op }
1447 f36fd90a 2022-07-09 op #endif /* !HAVE_STRNDUP */
1448 f36fd90a 2022-07-09 op #if !HAVE_STRNLEN
1449 f36fd90a 2022-07-09 op /* $OpenBSD$ */
1450 f36fd90a 2022-07-09 op
1451 f36fd90a 2022-07-09 op /*
1452 f36fd90a 2022-07-09 op * Copyright (c) 2010 Todd C. Miller <Todd.Miller@courtesan.com>
1453 f36fd90a 2022-07-09 op *
1454 f36fd90a 2022-07-09 op * Permission to use, copy, modify, and distribute this software for any
1455 f36fd90a 2022-07-09 op * purpose with or without fee is hereby granted, provided that the above
1456 f36fd90a 2022-07-09 op * copyright notice and this permission notice appear in all copies.
1457 f36fd90a 2022-07-09 op *
1458 f36fd90a 2022-07-09 op * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
1459 f36fd90a 2022-07-09 op * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
1460 f36fd90a 2022-07-09 op * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
1461 f36fd90a 2022-07-09 op * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
1462 f36fd90a 2022-07-09 op * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
1463 f36fd90a 2022-07-09 op * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
1464 f36fd90a 2022-07-09 op * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1465 f36fd90a 2022-07-09 op */
1466 f36fd90a 2022-07-09 op
1467 f36fd90a 2022-07-09 op #include <sys/types.h>
1468 f36fd90a 2022-07-09 op #include <string.h>
1469 f36fd90a 2022-07-09 op
1470 f36fd90a 2022-07-09 op size_t
1471 f36fd90a 2022-07-09 op strnlen(const char *str, size_t maxlen)
1472 f36fd90a 2022-07-09 op {
1473 f36fd90a 2022-07-09 op const char *cp;
1474 f36fd90a 2022-07-09 op
1475 f36fd90a 2022-07-09 op for (cp = str; maxlen != 0 && *cp != '\0'; cp++, maxlen--)
1476 f36fd90a 2022-07-09 op ;
1477 f36fd90a 2022-07-09 op
1478 f36fd90a 2022-07-09 op return (size_t)(cp - str);
1479 f36fd90a 2022-07-09 op }
1480 f36fd90a 2022-07-09 op #endif /* !HAVE_STRNLEN */
1481 f36fd90a 2022-07-09 op #if !HAVE_STRTONUM
1482 f36fd90a 2022-07-09 op /*
1483 f36fd90a 2022-07-09 op * Copyright (c) 2004 Ted Unangst and Todd Miller
1484 f36fd90a 2022-07-09 op * All rights reserved.
1485 f36fd90a 2022-07-09 op *
1486 f36fd90a 2022-07-09 op * Permission to use, copy, modify, and distribute this software for any
1487 f36fd90a 2022-07-09 op * purpose with or without fee is hereby granted, provided that the above
1488 f36fd90a 2022-07-09 op * copyright notice and this permission notice appear in all copies.
1489 f36fd90a 2022-07-09 op *
1490 f36fd90a 2022-07-09 op * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
1491 f36fd90a 2022-07-09 op * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
1492 f36fd90a 2022-07-09 op * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
1493 f36fd90a 2022-07-09 op * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
1494 f36fd90a 2022-07-09 op * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
1495 f36fd90a 2022-07-09 op * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
1496 f36fd90a 2022-07-09 op * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1497 f36fd90a 2022-07-09 op */
1498 f36fd90a 2022-07-09 op
1499 f36fd90a 2022-07-09 op #include <errno.h>
1500 f36fd90a 2022-07-09 op #include <limits.h>
1501 f36fd90a 2022-07-09 op #include <stdlib.h>
1502 f36fd90a 2022-07-09 op
1503 f36fd90a 2022-07-09 op #define INVALID 1
1504 f36fd90a 2022-07-09 op #define TOOSMALL 2
1505 f36fd90a 2022-07-09 op #define TOOLARGE 3
1506 f36fd90a 2022-07-09 op
1507 f36fd90a 2022-07-09 op long long
1508 f36fd90a 2022-07-09 op strtonum(const char *numstr, long long minval, long long maxval,
1509 f36fd90a 2022-07-09 op const char **errstrp)
1510 f36fd90a 2022-07-09 op {
1511 f36fd90a 2022-07-09 op long long ll = 0;
1512 f36fd90a 2022-07-09 op int error = 0;
1513 f36fd90a 2022-07-09 op char *ep;
1514 f36fd90a 2022-07-09 op struct errval {
1515 f36fd90a 2022-07-09 op const char *errstr;
1516 f36fd90a 2022-07-09 op int err;
1517 f36fd90a 2022-07-09 op } ev[4] = {
1518 f36fd90a 2022-07-09 op { NULL, 0 },
1519 f36fd90a 2022-07-09 op { "invalid", EINVAL },
1520 f36fd90a 2022-07-09 op { "too small", ERANGE },
1521 f36fd90a 2022-07-09 op { "too large", ERANGE },
1522 f36fd90a 2022-07-09 op };
1523 f36fd90a 2022-07-09 op
1524 f36fd90a 2022-07-09 op ev[0].err = errno;
1525 f36fd90a 2022-07-09 op errno = 0;
1526 f36fd90a 2022-07-09 op if (minval > maxval) {
1527 f36fd90a 2022-07-09 op error = INVALID;
1528 f36fd90a 2022-07-09 op } else {
1529 f36fd90a 2022-07-09 op ll = strtoll(numstr, &ep, 10);
1530 f36fd90a 2022-07-09 op if (numstr == ep || *ep != '\0')
1531 f36fd90a 2022-07-09 op error = INVALID;
1532 f36fd90a 2022-07-09 op else if ((ll == LLONG_MIN && errno == ERANGE) || ll < minval)
1533 f36fd90a 2022-07-09 op error = TOOSMALL;
1534 f36fd90a 2022-07-09 op else if ((ll == LLONG_MAX && errno == ERANGE) || ll > maxval)
1535 f36fd90a 2022-07-09 op error = TOOLARGE;
1536 f36fd90a 2022-07-09 op }
1537 f36fd90a 2022-07-09 op if (errstrp != NULL)
1538 f36fd90a 2022-07-09 op *errstrp = ev[error].errstr;
1539 f36fd90a 2022-07-09 op errno = ev[error].err;
1540 f36fd90a 2022-07-09 op if (error)
1541 f36fd90a 2022-07-09 op ll = 0;
1542 f36fd90a 2022-07-09 op
1543 f36fd90a 2022-07-09 op return (ll);
1544 f36fd90a 2022-07-09 op }
1545 f36fd90a 2022-07-09 op #endif /* !HAVE_STRTONUM */