ksgi
/
compats.c
4184 строки · 113.8 Кб
1#include "config.h"2#if !HAVE_ERR3/*
4* Copyright (c) 1993
5* The Regents of the University of California. All rights reserved.
6*
7* Redistribution and use in source and binary forms, with or without
8* modification, are permitted provided that the following conditions
9* are met:
10* 1. Redistributions of source code must retain the above copyright
11* notice, this list of conditions and the following disclaimer.
12* 2. Redistributions in binary form must reproduce the above copyright
13* notice, this list of conditions and the following disclaimer in the
14* documentation and/or other materials provided with the distribution.
15* 3. Neither the name of the University nor the names of its contributors
16* may be used to endorse or promote products derived from this software
17* without specific prior written permission.
18*
19* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29* SUCH DAMAGE.
30*/
31
32#include <errno.h>33#include <stdarg.h>34#include <stdio.h>35#include <stdlib.h>36#include <string.h>37
38void
39vwarnx(const char *fmt, va_list ap)40{
41fprintf(stderr, "%s: ", getprogname());42if (fmt != NULL)43vfprintf(stderr, fmt, ap);44fprintf(stderr, "\n");45}
46
47void
48vwarnc(int code, const char *fmt, va_list ap)49{
50fprintf(stderr, "%s: ", getprogname());51if (fmt != NULL) {52vfprintf(stderr, fmt, ap);53fprintf(stderr, ": ");54}55fprintf(stderr, "%s\n", strerror(code));56}
57
58void
59vwarn(const char *fmt, va_list ap)60{
61int sverrno;62
63sverrno = errno;64fprintf(stderr, "%s: ", getprogname());65if (fmt != NULL) {66vfprintf(stderr, fmt, ap);67fprintf(stderr, ": ");68}69fprintf(stderr, "%s\n", strerror(sverrno));70}
71
72void
73verrc(int eval, int code, const char *fmt, va_list ap)74{
75fprintf(stderr, "%s: ", getprogname());76if (fmt != NULL) {77vfprintf(stderr, fmt, ap);78fprintf(stderr, ": ");79}80fprintf(stderr, "%s\n", strerror(code));81exit(eval);82}
83
84void
85verrx(int eval, const char *fmt, va_list ap)86{
87fprintf(stderr, "%s: ", getprogname());88if (fmt != NULL)89vfprintf(stderr, fmt, ap);90fprintf(stderr, "\n");91exit(eval);92}
93
94void
95verr(int eval, const char *fmt, va_list ap)96{
97int sverrno;98
99sverrno = errno;100fprintf(stderr, "%s: ", getprogname());101if (fmt != NULL) {102vfprintf(stderr, fmt, ap);103fprintf(stderr, ": ");104}105fprintf(stderr, "%s\n", strerror(sverrno));106exit(eval);107}
108
109void
110err(int eval, const char *fmt, ...)111{
112va_list ap;113
114va_start(ap, fmt);115verr(eval, fmt, ap);116va_end(ap);117}
118
119void
120errc(int eval, int code, const char *fmt, ...)121{
122va_list ap;123
124va_start(ap, fmt);125verrc(eval, code, fmt, ap);126va_end(ap);127}
128
129void
130errx(int eval, const char *fmt, ...)131{
132va_list ap;133
134va_start(ap, fmt);135verrx(eval, fmt, ap);136va_end(ap);137}
138
139void
140warn(const char *fmt, ...)141{
142va_list ap;143
144va_start(ap, fmt);145vwarn(fmt, ap);146va_end(ap);147}
148
149void
150warnc(int code, const char *fmt, ...)151{
152va_list ap;153
154va_start(ap, fmt);155vwarnc(code, fmt, ap);156va_end(ap);157}
158
159void
160warnx(const char *fmt, ...)161{
162va_list ap;163
164va_start(ap, fmt);165vwarnx(fmt, ap);166va_end(ap);167}
168#endif /* !HAVE_ERR */169#if !HAVE_B64_NTOP170/* $OpenBSD$ */
171
172/*
173* Copyright (c) 1996 by Internet Software Consortium.
174*
175* Permission to use, copy, modify, and distribute this software for any
176* purpose with or without fee is hereby granted, provided that the above
177* copyright notice and this permission notice appear in all copies.
178*
179* THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
180* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
181* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
182* CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
183* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
184* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
185* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
186* SOFTWARE.
187*/
188
189/*
190* Portions Copyright (c) 1995 by International Business Machines, Inc.
191*
192* International Business Machines, Inc. (hereinafter called IBM) grants
193* permission under its copyrights to use, copy, modify, and distribute this
194* Software with or without fee, provided that the above copyright notice and
195* all paragraphs of this notice appear in all copies, and that the name of IBM
196* not be used in connection with the marketing of any product incorporating
197* the Software or modifications thereof, without specific, written prior
198* permission.
199*
200* To the extent it has a right to do so, IBM grants an immunity from suit
201* under its patents, if any, for the use, sale or manufacture of products to
202* the extent that such products are used for performing Domain Name System
203* dynamic updates in TCP/IP networks by means of the Software. No immunity is
204* granted for any product per se or for any other function of any product.
205*
206* THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES,
207* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
208* PARTICULAR PURPOSE. IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL,
209* DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING
210* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN
211* IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES.
212*/
213
214#include <sys/types.h>215#include <sys/socket.h>216#include <netinet/in.h>217#include <arpa/inet.h>218#include <arpa/nameser.h>219
220#include <ctype.h>221#include <resolv.h>222#include <stdio.h>223
224#include <stdlib.h>225#include <string.h>226
227static const char b64_Base64[] =228"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";229static const char b64_Pad64 = '=';230
231/* (From RFC1521 and draft-ietf-dnssec-secext-03.txt)
232The following encoding technique is taken from RFC 1521 by Borenstein
233and Freed. It is reproduced here in a slightly edited form for
234convenience.
235
236A 65-character subset of US-ASCII is used, enabling 6 bits to be
237represented per printable character. (The extra 65th character, "=",
238is used to signify a special processing function.)
239
240The encoding process represents 24-bit groups of input bits as output
241strings of 4 encoded characters. Proceeding from left to right, a
24224-bit input group is formed by concatenating 3 8-bit input groups.
243These 24 bits are then treated as 4 concatenated 6-bit groups, each
244of which is translated into a single digit in the base64 alphabet.
245
246Each 6-bit group is used as an index into an array of 64 printable
247characters. The character referenced by the index is placed in the
248output string.
249
250Table 1: The Base64 Alphabet
251
252Value Encoding Value Encoding Value Encoding Value Encoding
2530 A 17 R 34 i 51 z
2541 B 18 S 35 j 52 0
2552 C 19 T 36 k 53 1
2563 D 20 U 37 l 54 2
2574 E 21 V 38 m 55 3
2585 F 22 W 39 n 56 4
2596 G 23 X 40 o 57 5
2607 H 24 Y 41 p 58 6
2618 I 25 Z 42 q 59 7
2629 J 26 a 43 r 60 8
26310 K 27 b 44 s 61 9
26411 L 28 c 45 t 62 +
26512 M 29 d 46 u 63 /
26613 N 30 e 47 v
26714 O 31 f 48 w (pad) =
26815 P 32 g 49 x
26916 Q 33 h 50 y
270
271Special processing is performed if fewer than 24 bits are available
272at the end of the data being encoded. A full encoding quantum is
273always completed at the end of a quantity. When fewer than 24 input
274bits are available in an input group, zero bits are added (on the
275right) to form an integral number of 6-bit groups. Padding at the
276end of the data is performed using the '=' character.
277
278Since all base64 input is an integral number of octets, only the
279-------------------------------------------------
280following cases can arise:
281
282(1) the final quantum of encoding input is an integral
283multiple of 24 bits; here, the final unit of encoded
284output will be an integral multiple of 4 characters
285with no "=" padding,
286(2) the final quantum of encoding input is exactly 8 bits;
287here, the final unit of encoded output will be two
288characters followed by two "=" padding characters, or
289(3) the final quantum of encoding input is exactly 16 bits;
290here, the final unit of encoded output will be three
291characters followed by one "=" padding character.
292*/
293
294int
295b64_ntop(u_char const *src, size_t srclength, char *target, size_t targsize)296{
297size_t datalength = 0;298u_char input[3];299u_char output[4];300size_t i;301
302while (2 < srclength) {303input[0] = *src++;304input[1] = *src++;305input[2] = *src++;306srclength -= 3;307
308output[0] = input[0] >> 2;309output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4);310output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6);311output[3] = input[2] & 0x3f;312
313if (datalength + 4 > targsize)314return (-1);315target[datalength++] = b64_Base64[output[0]];316target[datalength++] = b64_Base64[output[1]];317target[datalength++] = b64_Base64[output[2]];318target[datalength++] = b64_Base64[output[3]];319}320
321/* Now we worry about padding. */322if (0 != srclength) {323/* Get what's left. */324input[0] = input[1] = input[2] = '\0';325for (i = 0; i < srclength; i++)326input[i] = *src++;327
328output[0] = input[0] >> 2;329output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4);330output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6);331
332if (datalength + 4 > targsize)333return (-1);334target[datalength++] = b64_Base64[output[0]];335target[datalength++] = b64_Base64[output[1]];336if (srclength == 1)337target[datalength++] = b64_Pad64;338else339target[datalength++] = b64_Base64[output[2]];340target[datalength++] = b64_Pad64;341}342if (datalength >= targsize)343return (-1);344target[datalength] = '\0'; /* Returned value doesn't count \0. */345return (datalength);346}
347
348/* skips all whitespace anywhere.
349converts characters, four at a time, starting at (or after)
350src from base - 64 numbers into three 8 bit bytes in the target area.
351it returns the number of data bytes stored at the target, or -1 on error.
352*/
353
354int
355b64_pton(char const *src, u_char *target, size_t targsize)356{
357int state, ch;358size_t tarindex;359u_char nextbyte;360char *pos;361
362state = 0;363tarindex = 0;364
365while ((ch = (unsigned char)*src++) != '\0') {366if (isspace(ch)) /* Skip whitespace anywhere. */367continue;368
369if (ch == b64_Pad64)370break;371
372pos = strchr(b64_Base64, ch);373if (pos == 0) /* A non-base64 character. */374return (-1);375
376switch (state) {377case 0:378if (target) {379if (tarindex >= targsize)380return (-1);381target[tarindex] = (pos - b64_Base64) << 2;382}383state = 1;384break;385case 1:386if (target) {387if (tarindex >= targsize)388return (-1);389target[tarindex] |= (pos - b64_Base64) >> 4;390nextbyte = ((pos - b64_Base64) & 0x0f) << 4;391if (tarindex + 1 < targsize)392target[tarindex+1] = nextbyte;393else if (nextbyte)394return (-1);395}396tarindex++;397state = 2;398break;399case 2:400if (target) {401if (tarindex >= targsize)402return (-1);403target[tarindex] |= (pos - b64_Base64) >> 2;404nextbyte = ((pos - b64_Base64) & 0x03) << 6;405if (tarindex + 1 < targsize)406target[tarindex+1] = nextbyte;407else if (nextbyte)408return (-1);409}410tarindex++;411state = 3;412break;413case 3:414if (target) {415if (tarindex >= targsize)416return (-1);417target[tarindex] |= (pos - b64_Base64);418}419tarindex++;420state = 0;421break;422}423}424
425/*426* We are done decoding Base-64 chars. Let's see if we ended
427* on a byte boundary, and/or with erroneous trailing characters.
428*/
429
430if (ch == b64_Pad64) { /* We got a pad char. */431ch = (unsigned char)*src++; /* Skip it, get next. */432switch (state) {433case 0: /* Invalid = in first position */434case 1: /* Invalid = in second position */435return (-1);436
437case 2: /* Valid, means one byte of info */438/* Skip any number of spaces. */439for (; ch != '\0'; ch = (unsigned char)*src++)440if (!isspace(ch))441break;442/* Make sure there is another trailing = sign. */443if (ch != b64_Pad64)444return (-1);445ch = (unsigned char)*src++; /* Skip the = */446/* Fall through to "single trailing =" case. */447/* FALLTHROUGH */448
449case 3: /* Valid, means two bytes of info */450/*451* We know this char is an =. Is there anything but
452* whitespace after it?
453*/
454for (; ch != '\0'; ch = (unsigned char)*src++)455if (!isspace(ch))456return (-1);457
458/*459* Now make sure for cases 2 and 3 that the "extra"
460* bits that slopped past the last full byte were
461* zeros. If we don't check them, they become a
462* subliminal channel.
463*/
464if (target && tarindex < targsize &&465target[tarindex] != 0)466return (-1);467}468} else {469/*470* We ended by seeing the end of the string. Make sure we
471* have no partial bytes lying around.
472*/
473if (state != 0)474return (-1);475}476
477return (tarindex);478}
479#endif /* !HAVE_B64_NTOP */480#if !HAVE_EXPLICIT_BZERO481/* OPENBSD ORIGINAL: lib/libc/string/explicit_bzero.c */
482/*
483* Public domain.
484* Written by Ted Unangst
485*/
486
487#include <string.h>488
489/*
490* explicit_bzero - don't let the compiler optimize away bzero
491*/
492
493#if HAVE_MEMSET_S494
495void
496explicit_bzero(void *p, size_t n)497{
498if (n == 0)499return;500(void)memset_s(p, n, 0, n);501}
502
503#else /* HAVE_MEMSET_S */504
505#include <strings.h>506
507/*
508* Indirect memset through a volatile pointer to hopefully avoid
509* dead-store optimisation eliminating the call.
510*/
511static void (* volatile ssh_memset)(void *, int, size_t) = memset;512
513void
514explicit_bzero(void *p, size_t n)515{
516if (n == 0)517return;518/*519* clang -fsanitize=memory needs to intercept memset-like functions
520* to correctly detect memory initialisation. Make sure one is called
521* directly since our indirection trick above sucessfully confuses it.
522*/
523#if defined(__has_feature)524# if __has_feature(memory_sanitizer)525memset(p, 0, n);526# endif527#endif528
529ssh_memset(p, 0, n);530}
531
532#endif /* HAVE_MEMSET_S */533#endif /* !HAVE_EXPLICIT_BZERO */534#if !HAVE_FTS535/* $OpenBSD$ */
536
537/*-
538* Copyright (c) 1990, 1993, 1994
539* The Regents of the University of California. All rights reserved.
540*
541* Redistribution and use in source and binary forms, with or without
542* modification, are permitted provided that the following conditions
543* are met:
544* 1. Redistributions of source code must retain the above copyright
545* notice, this list of conditions and the following disclaimer.
546* 2. Redistributions in binary form must reproduce the above copyright
547* notice, this list of conditions and the following disclaimer in the
548* documentation and/or other materials provided with the distribution.
549* 3. Neither the name of the University nor the names of its contributors
550* may be used to endorse or promote products derived from this software
551* without specific prior written permission.
552*
553* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
554* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
555* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
556* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
557* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
558* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
559* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
560* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
561* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
562* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
563* SUCH DAMAGE.
564*/
565
566#include <sys/stat.h>567#include <sys/types.h>568
569#include <dirent.h>570#include <errno.h>571#include <fcntl.h>572#include <limits.h>573#include <stdlib.h>574#include <string.h>575#include <unistd.h>576
577/*
578* oconfigure: Adapted from sys/_types.h.
579* oconfigure: Be conservative with ALIGNBYTES.
580*/
581#define FTS_ALIGNBYTES (sizeof(long) - 1)582#define FTS_ALIGN(p) (((unsigned long)(p) + FTS_ALIGNBYTES) &~ FTS_ALIGNBYTES)583
584static FTSENT *fts_alloc(FTS *, char *, size_t);585static FTSENT *fts_build(FTS *, int);586static void fts_lfree(FTSENT *);587static void fts_load(FTS *, FTSENT *);588static size_t fts_maxarglen(char * const *);589static void fts_padjust(FTS *, FTSENT *);590static int fts_palloc(FTS *, size_t);591static FTSENT *fts_sort(FTS *, FTSENT *, int);592static u_short fts_stat(FTS *, FTSENT *, int, int);593static int fts_safe_changedir(FTS *, FTSENT *, int, char *);594
595/* oconfigure: Prefix with FTS_. */
596
597#define FTS_MAX(a, b) (((a) > (b)) ? (a) : (b))598#define FTS_ISDOT(a) (a[0] == '.' && (!a[1] || (a[1] == '.' && !a[2])))599#define FTS_CLR(opt) (sp->fts_options &= ~(opt))600#define FTS_ISSET(opt) (sp->fts_options & (opt))601#define FTS_SET(opt) (sp->fts_options |= (opt))602#define FTS_FCHDIR(sp, fd) (!FTS_ISSET(FTS_NOCHDIR) && fchdir(fd))603/* fts_build flags */
604#define FTS_BCHILD 1 /* fts_children */605#define FTS_BNAMES 2 /* fts_children, names only */606#define FTS_BREAD 3 /* fts_read */607
608FTS *609fts_open(char * const *argv, int options,610int (*compar)(const FTSENT **, const FTSENT **))611{
612FTS *sp;613FTSENT *p, *root;614int nitems;615FTSENT *parent, *prev;616char empty[1] = { '\0' };617
618/* Options check. */619if (options & ~FTS_OPTIONMASK) {620errno = EINVAL;621return (NULL);622}623
624/* At least one path must be specified. */625if (*argv == NULL) {626errno = EINVAL;627return (NULL);628}629
630/* Allocate/initialize the stream */631if ((sp = calloc(1, sizeof(FTS))) == NULL)632return (NULL);633sp->fts_compar = compar;634sp->fts_options = options;635
636/* Logical walks turn on NOCHDIR; symbolic links are too hard. */637if (FTS_ISSET(FTS_LOGICAL))638FTS_SET(FTS_NOCHDIR);639
640/*641* Start out with 1K of path space, and enough, in any case,
642* to hold the user's paths.
643*/
644if (fts_palloc(sp, FTS_MAX(fts_maxarglen(argv), PATH_MAX)))645goto mem1;646
647/* Allocate/initialize root's parent. */648if ((parent = fts_alloc(sp, empty, 0)) == NULL)649goto mem2;650parent->fts_level = FTS_ROOTPARENTLEVEL;651
652/* Allocate/initialize root(s). */653for (root = prev = NULL, nitems = 0; *argv; ++argv, ++nitems) {654if ((p = fts_alloc(sp, *argv, strlen(*argv))) == NULL)655goto mem3;656p->fts_level = FTS_ROOTLEVEL;657p->fts_parent = parent;658p->fts_accpath = p->fts_name;659p->fts_info = fts_stat(sp, p, FTS_ISSET(FTS_COMFOLLOW), -1);660
661/* Command-line "." and ".." are real directories. */662if (p->fts_info == FTS_DOT)663p->fts_info = FTS_D;664
665/*666* If comparison routine supplied, traverse in sorted
667* order; otherwise traverse in the order specified.
668*/
669if (compar) {670p->fts_link = root;671root = p;672} else {673p->fts_link = NULL;674if (root == NULL)675root = p;676else677prev->fts_link = p;678prev = p;679}680}681if (compar && nitems > 1)682root = fts_sort(sp, root, nitems);683
684/*685* Allocate a dummy pointer and make fts_read think that we've just
686* finished the node before the root(s); set p->fts_info to FTS_INIT
687* so that everything about the "current" node is ignored.
688*/
689if ((sp->fts_cur = fts_alloc(sp, empty, 0)) == NULL)690goto mem3;691sp->fts_cur->fts_link = root;692sp->fts_cur->fts_info = FTS_INIT;693
694/*695* If using chdir(2), grab a file descriptor pointing to dot to ensure
696* that we can get back here; this could be avoided for some paths,
697* but almost certainly not worth the effort. Slashes, symbolic links,
698* and ".." are all fairly nasty problems. Note, if we can't get the
699* descriptor we run anyway, just more slowly.
700*/
701if (!FTS_ISSET(FTS_NOCHDIR) &&702(sp->fts_rfd = open(".", O_RDONLY | O_CLOEXEC)) == -1)703FTS_SET(FTS_NOCHDIR);704
705if (nitems == 0)706free(parent);707
708return (sp);709
710mem3: fts_lfree(root);711free(parent);712mem2: free(sp->fts_path);713mem1: free(sp);714return (NULL);715}
716
717static void718fts_load(FTS *sp, FTSENT *p)719{
720size_t len;721char *cp;722
723/*724* Load the stream structure for the next traversal. Since we don't
725* actually enter the directory until after the preorder visit, set
726* the fts_accpath field specially so the chdir gets done to the right
727* place and the user can access the first node. From fts_open it's
728* known that the path will fit.
729*/
730len = p->fts_pathlen = p->fts_namelen;731memmove(sp->fts_path, p->fts_name, len + 1);732if ((cp = strrchr(p->fts_name, '/')) && (cp != p->fts_name || cp[1])) {733len = strlen(++cp);734memmove(p->fts_name, cp, len + 1);735p->fts_namelen = len;736}737p->fts_accpath = p->fts_path = sp->fts_path;738sp->fts_dev = p->fts_dev;739}
740
741int
742fts_close(FTS *sp)743{
744FTSENT *freep, *p;745int rfd, error = 0;746
747/*748* This still works if we haven't read anything -- the dummy structure
749* points to the root list, so we step through to the end of the root
750* list which has a valid parent pointer.
751*/
752if (sp->fts_cur) {753for (p = sp->fts_cur; p->fts_level >= FTS_ROOTLEVEL;) {754freep = p;755p = p->fts_link ? p->fts_link : p->fts_parent;756free(freep);757}758free(p);759}760
761/* Stash the original directory fd if needed. */762rfd = FTS_ISSET(FTS_NOCHDIR) ? -1 : sp->fts_rfd;763
764/* Free up child linked list, sort array, path buffer, stream ptr.*/765if (sp->fts_child)766fts_lfree(sp->fts_child);767free(sp->fts_array);768free(sp->fts_path);769free(sp);770
771/* Return to original directory, checking for error. */772if (rfd != -1) {773int saved_errno;774error = fchdir(rfd);775saved_errno = errno;776(void)close(rfd);777errno = saved_errno;778}779
780return (error);781}
782
783/*
784* Special case of "/" at the end of the path so that slashes aren't
785* appended which would cause paths to be written as "....//foo".
786*/
787#define NAPPEND(p) \788(p->fts_path[p->fts_pathlen - 1] == '/' \789? p->fts_pathlen - 1 : p->fts_pathlen)790
791FTSENT *792fts_read(FTS *sp)793{
794FTSENT *p, *tmp;795int instr;796char *t;797char up[3] = { '.', '.', '\0' };798int saved_errno;799
800/* If finished or unrecoverable error, return NULL. */801if (sp->fts_cur == NULL || FTS_ISSET(FTS_STOP))802return (NULL);803
804/* Set current node pointer. */805p = sp->fts_cur;806
807/* Save and zero out user instructions. */808instr = p->fts_instr;809p->fts_instr = FTS_NOINSTR;810
811/* Any type of file may be re-visited; re-stat and re-turn. */812if (instr == FTS_AGAIN) {813p->fts_info = fts_stat(sp, p, 0, -1);814return (p);815}816
817/*818* Following a symlink -- SLNONE test allows application to see
819* SLNONE and recover. If indirecting through a symlink, have
820* keep a pointer to current location. If unable to get that
821* pointer, follow fails.
822*/
823if (instr == FTS_FOLLOW &&824(p->fts_info == FTS_SL || p->fts_info == FTS_SLNONE)) {825p->fts_info = fts_stat(sp, p, 1, -1);826if (p->fts_info == FTS_D && !FTS_ISSET(FTS_NOCHDIR)) {827if ((p->fts_symfd =828open(".", O_RDONLY | O_CLOEXEC)) == -1) {829p->fts_errno = errno;830p->fts_info = FTS_ERR;831} else832p->fts_flags |= FTS_SYMFOLLOW;833}834return (p);835}836
837/* Directory in pre-order. */838if (p->fts_info == FTS_D) {839/* If skipped or crossed mount point, do post-order visit. */840if (instr == FTS_SKIP ||841(FTS_ISSET(FTS_XDEV) && p->fts_dev != sp->fts_dev)) {842if (p->fts_flags & FTS_SYMFOLLOW)843(void)close(p->fts_symfd);844if (sp->fts_child) {845fts_lfree(sp->fts_child);846sp->fts_child = NULL;847}848p->fts_info = FTS_DP;849return (p);850}851
852/* Rebuild if only read the names and now traversing. */853if (sp->fts_child && FTS_ISSET(FTS_NAMEONLY)) {854FTS_CLR(FTS_NAMEONLY);855fts_lfree(sp->fts_child);856sp->fts_child = NULL;857}858
859/*860* Cd to the subdirectory.
861*
862* If have already read and now fail to chdir, whack the list
863* to make the names come out right, and set the parent errno
864* so the application will eventually get an error condition.
865* Set the FTS_DONTCHDIR flag so that when we logically change
866* directories back to the parent we don't do a chdir.
867*
868* If haven't read do so. If the read fails, fts_build sets
869* FTS_STOP or the fts_info field of the node.
870*/
871if (sp->fts_child) {872if (fts_safe_changedir(sp, p, -1, p->fts_accpath)) {873p->fts_errno = errno;874p->fts_flags |= FTS_DONTCHDIR;875for (p = sp->fts_child; p; p = p->fts_link)876p->fts_accpath =877p->fts_parent->fts_accpath;878}879} else if ((sp->fts_child = fts_build(sp, FTS_BREAD)) == NULL) {880if (FTS_ISSET(FTS_STOP))881return (NULL);882return (p);883}884p = sp->fts_child;885sp->fts_child = NULL;886goto name;887}888
889/* Move to the next node on this level. */890next: tmp = p;891if ((p = p->fts_link)) {892free(tmp);893
894/*895* If reached the top, return to the original directory (or
896* the root of the tree), and load the paths for the next root.
897*/
898if (p->fts_level == FTS_ROOTLEVEL) {899if (FTS_FCHDIR(sp, sp->fts_rfd)) {900FTS_SET(FTS_STOP);901return (NULL);902}903fts_load(sp, p);904return (sp->fts_cur = p);905}906
907/*908* User may have called fts_set on the node. If skipped,
909* ignore. If followed, get a file descriptor so we can
910* get back if necessary.
911*/
912if (p->fts_instr == FTS_SKIP)913goto next;914if (p->fts_instr == FTS_FOLLOW) {915p->fts_info = fts_stat(sp, p, 1, -1);916if (p->fts_info == FTS_D && !FTS_ISSET(FTS_NOCHDIR)) {917if ((p->fts_symfd =918open(".", O_RDONLY | O_CLOEXEC)) == -1) {919p->fts_errno = errno;920p->fts_info = FTS_ERR;921} else922p->fts_flags |= FTS_SYMFOLLOW;923}924p->fts_instr = FTS_NOINSTR;925}926
927name: t = sp->fts_path + NAPPEND(p->fts_parent);928*t++ = '/';929memmove(t, p->fts_name, p->fts_namelen + 1);930return (sp->fts_cur = p);931}932
933/* Move up to the parent node. */934p = tmp->fts_parent;935free(tmp);936
937if (p->fts_level == FTS_ROOTPARENTLEVEL) {938/*939* Done; free everything up and set errno to 0 so the user
940* can distinguish between error and EOF.
941*/
942free(p);943errno = 0;944return (sp->fts_cur = NULL);945}946
947/* NUL terminate the pathname. */948sp->fts_path[p->fts_pathlen] = '\0';949
950/*951* Return to the parent directory. If at a root node or came through
952* a symlink, go back through the file descriptor. Otherwise, cd up
953* one directory.
954*/
955if (p->fts_level == FTS_ROOTLEVEL) {956if (FTS_FCHDIR(sp, sp->fts_rfd)) {957FTS_SET(FTS_STOP);958sp->fts_cur = p;959return (NULL);960}961} else if (p->fts_flags & FTS_SYMFOLLOW) {962if (FTS_FCHDIR(sp, p->fts_symfd)) {963saved_errno = errno;964(void)close(p->fts_symfd);965errno = saved_errno;966FTS_SET(FTS_STOP);967sp->fts_cur = p;968return (NULL);969}970(void)close(p->fts_symfd);971} else if (!(p->fts_flags & FTS_DONTCHDIR) &&972fts_safe_changedir(sp, p->fts_parent, -1, up)) {973FTS_SET(FTS_STOP);974sp->fts_cur = p;975return (NULL);976}977p->fts_info = p->fts_errno ? FTS_ERR : FTS_DP;978return (sp->fts_cur = p);979}
980
981/*
982* Fts_set takes the stream as an argument although it's not used in this
983* implementation; it would be necessary if anyone wanted to add global
984* semantics to fts using fts_set. An error return is allowed for similar
985* reasons.
986*/
987int
988fts_set(FTS *sp, FTSENT *p, int instr)989{
990if (instr && instr != FTS_AGAIN && instr != FTS_FOLLOW &&991instr != FTS_NOINSTR && instr != FTS_SKIP) {992errno = EINVAL;993return (1);994}995p->fts_instr = instr;996return (0);997}
998
999FTSENT *1000fts_children(FTS *sp, int instr)1001{
1002FTSENT *p;1003int fd;1004
1005if (instr && instr != FTS_NAMEONLY) {1006errno = EINVAL;1007return (NULL);1008}1009
1010/* Set current node pointer. */1011p = sp->fts_cur;1012
1013/*1014* Errno set to 0 so user can distinguish empty directory from
1015* an error.
1016*/
1017errno = 0;1018
1019/* Fatal errors stop here. */1020if (FTS_ISSET(FTS_STOP))1021return (NULL);1022
1023/* Return logical hierarchy of user's arguments. */1024if (p->fts_info == FTS_INIT)1025return (p->fts_link);1026
1027/*1028* If not a directory being visited in pre-order, stop here. Could
1029* allow FTS_DNR, assuming the user has fixed the problem, but the
1030* same effect is available with FTS_AGAIN.
1031*/
1032if (p->fts_info != FTS_D /* && p->fts_info != FTS_DNR */)1033return (NULL);1034
1035/* Free up any previous child list. */1036if (sp->fts_child)1037fts_lfree(sp->fts_child);1038
1039if (instr == FTS_NAMEONLY) {1040FTS_SET(FTS_NAMEONLY);1041instr = FTS_BNAMES;1042} else1043instr = FTS_BCHILD;1044
1045/*1046* If using chdir on a relative path and called BEFORE fts_read does
1047* its chdir to the root of a traversal, we can lose -- we need to
1048* chdir into the subdirectory, and we don't know where the current
1049* directory is, so we can't get back so that the upcoming chdir by
1050* fts_read will work.
1051*/
1052if (p->fts_level != FTS_ROOTLEVEL || p->fts_accpath[0] == '/' ||1053FTS_ISSET(FTS_NOCHDIR))1054return (sp->fts_child = fts_build(sp, instr));1055
1056if ((fd = open(".", O_RDONLY | O_CLOEXEC)) == -1)1057return (NULL);1058sp->fts_child = fts_build(sp, instr);1059if (fchdir(fd)) {1060(void)close(fd);1061return (NULL);1062}1063(void)close(fd);1064return (sp->fts_child);1065}
1066
1067/*
1068* This is the tricky part -- do not casually change *anything* in here. The
1069* idea is to build the linked list of entries that are used by fts_children
1070* and fts_read. There are lots of special cases.
1071*
1072* The real slowdown in walking the tree is the stat calls. If FTS_NOSTAT is
1073* set and it's a physical walk (so that symbolic links can't be directories),
1074* we can do things quickly. First, if it's a 4.4BSD file system, the type
1075* of the file is in the directory entry. Otherwise, we assume that the number
1076* of subdirectories in a node is equal to the number of links to the parent.
1077* The former skips all stat calls. The latter skips stat calls in any leaf
1078* directories and for any files after the subdirectories in the directory have
1079* been found, cutting the stat calls by about 2/3.
1080*/
1081static FTSENT *1082fts_build(FTS *sp, int type)1083{
1084struct dirent *dp;1085FTSENT *p, *head;1086FTSENT *cur, *tail;1087DIR *dirp;1088void *oldaddr;1089size_t len, maxlen, namlen;1090int nitems, cderrno, descend, level, nlinks, nostat, doadjust;1091int saved_errno;1092char *cp;1093char up[3] = { '.', '.', '\0' };1094
1095/* Set current node pointer. */1096cur = sp->fts_cur;1097
1098/*1099* Open the directory for reading. If this fails, we're done.
1100* If being called from fts_read, set the fts_info field.
1101*/
1102if ((dirp = opendir(cur->fts_accpath)) == NULL) {1103if (type == FTS_BREAD) {1104cur->fts_info = FTS_DNR;1105cur->fts_errno = errno;1106}1107return (NULL);1108}1109
1110/*1111* Nlinks is the number of possible entries of type directory in the
1112* directory if we're cheating on stat calls, 0 if we're not doing
1113* any stat calls at all, -1 if we're doing stats on everything.
1114*/
1115if (type == FTS_BNAMES)1116nlinks = 0;1117else if (FTS_ISSET(FTS_NOSTAT) && FTS_ISSET(FTS_PHYSICAL)) {1118nlinks = cur->fts_nlink - (FTS_ISSET(FTS_SEEDOT) ? 0 : 2);1119nostat = 1;1120} else {1121nlinks = -1;1122nostat = 0;1123}1124
1125#ifdef notdef1126(void)printf("nlinks == %d (cur: %u)\n", nlinks, cur->fts_nlink);1127(void)printf("NOSTAT %d PHYSICAL %d SEEDOT %d\n",1128FTS_ISSET(FTS_NOSTAT), FTS_ISSET(FTS_PHYSICAL), FTS_ISSET(FTS_SEEDOT));1129#endif1130/*1131* If we're going to need to stat anything or we want to descend
1132* and stay in the directory, chdir. If this fails we keep going,
1133* but set a flag so we don't chdir after the post-order visit.
1134* We won't be able to stat anything, but we can still return the
1135* names themselves. Note, that since fts_read won't be able to
1136* chdir into the directory, it will have to return different path
1137* names than before, i.e. "a/b" instead of "b". Since the node
1138* has already been visited in pre-order, have to wait until the
1139* post-order visit to return the error. There is a special case
1140* here, if there was nothing to stat then it's not an error to
1141* not be able to stat. This is all fairly nasty. If a program
1142* needed sorted entries or stat information, they had better be
1143* checking FTS_NS on the returned nodes.
1144*/
1145cderrno = 0;1146if (nlinks || type == FTS_BREAD) {1147if (fts_safe_changedir(sp, cur, dirfd(dirp), NULL)) {1148if (nlinks && type == FTS_BREAD)1149cur->fts_errno = errno;1150cur->fts_flags |= FTS_DONTCHDIR;1151descend = 0;1152cderrno = errno;1153(void)closedir(dirp);1154dirp = NULL;1155} else1156descend = 1;1157} else1158descend = 0;1159
1160/*1161* Figure out the max file name length that can be stored in the
1162* current path -- the inner loop allocates more path as necessary.
1163* We really wouldn't have to do the maxlen calculations here, we
1164* could do them in fts_read before returning the path, but it's a
1165* lot easier here since the length is part of the dirent structure.
1166*
1167* If not changing directories set a pointer so that can just append
1168* each new name into the path.
1169*/
1170len = NAPPEND(cur);1171if (FTS_ISSET(FTS_NOCHDIR)) {1172cp = sp->fts_path + len;1173*cp++ = '/';1174}1175len++;1176maxlen = sp->fts_pathlen - len;1177
1178/*1179* fts_level is signed so we must prevent it from wrapping
1180* around to FTS_ROOTLEVEL and FTS_ROOTPARENTLEVEL.
1181*/
1182level = cur->fts_level;1183if (level < FTS_MAXLEVEL)1184level++;1185
1186/* Read the directory, attaching each entry to the `link' pointer. */1187doadjust = 0;1188for (head = tail = NULL, nitems = 0; dirp && (dp = readdir(dirp));) {1189if (!FTS_ISSET(FTS_SEEDOT) && FTS_ISDOT(dp->d_name))1190continue;1191
1192namlen = strlen(dp->d_name);1193
1194if (!(p = fts_alloc(sp, dp->d_name, namlen)))1195goto mem1;1196if (namlen >= maxlen) { /* include space for NUL */1197oldaddr = sp->fts_path;1198if (fts_palloc(sp, namlen +len + 1)) {1199/*1200* No more memory for path or structures. Save
1201* errno, free up the current structure and the
1202* structures already allocated.
1203*/
1204mem1: saved_errno = errno;1205free(p);1206fts_lfree(head);1207(void)closedir(dirp);1208cur->fts_info = FTS_ERR;1209FTS_SET(FTS_STOP);1210errno = saved_errno;1211return (NULL);1212}1213/* Did realloc() change the pointer? */1214if (oldaddr != sp->fts_path) {1215doadjust = 1;1216if (FTS_ISSET(FTS_NOCHDIR))1217cp = sp->fts_path + len;1218}1219maxlen = sp->fts_pathlen - len;1220}1221
1222p->fts_level = level;1223p->fts_parent = sp->fts_cur;1224p->fts_pathlen = len + namlen;1225if (p->fts_pathlen < len) {1226/*1227* If we wrap, free up the current structure and
1228* the structures already allocated, then error
1229* out with ENAMETOOLONG.
1230*/
1231free(p);1232fts_lfree(head);1233(void)closedir(dirp);1234cur->fts_info = FTS_ERR;1235FTS_SET(FTS_STOP);1236errno = ENAMETOOLONG;1237return (NULL);1238}1239
1240if (cderrno) {1241if (nlinks) {1242p->fts_info = FTS_NS;1243p->fts_errno = cderrno;1244} else1245p->fts_info = FTS_NSOK;1246p->fts_accpath = cur->fts_accpath;1247} else if (nlinks == 01248#ifdef DT_DIR1249|| (nostat &&1250dp->d_type != DT_DIR && dp->d_type != DT_UNKNOWN)1251#endif1252) {1253p->fts_accpath =1254FTS_ISSET(FTS_NOCHDIR) ? p->fts_path : p->fts_name;1255p->fts_info = FTS_NSOK;1256} else {1257/* Build a file name for fts_stat to stat. */1258if (FTS_ISSET(FTS_NOCHDIR)) {1259p->fts_accpath = p->fts_path;1260memmove(cp, p->fts_name, p->fts_namelen + 1);1261p->fts_info = fts_stat(sp, p, 0, dirfd(dirp));1262} else {1263p->fts_accpath = p->fts_name;1264p->fts_info = fts_stat(sp, p, 0, -1);1265}1266
1267/* Decrement link count if applicable. */1268if (nlinks > 0 && (p->fts_info == FTS_D ||1269p->fts_info == FTS_DC || p->fts_info == FTS_DOT))1270--nlinks;1271}1272
1273/* We walk in directory order so "ls -f" doesn't get upset. */1274p->fts_link = NULL;1275if (head == NULL)1276head = tail = p;1277else {1278tail->fts_link = p;1279tail = p;1280}1281++nitems;1282}1283if (dirp)1284(void)closedir(dirp);1285
1286/*1287* If realloc() changed the address of the path, adjust the
1288* addresses for the rest of the tree and the dir list.
1289*/
1290if (doadjust)1291fts_padjust(sp, head);1292
1293/*1294* If not changing directories, reset the path back to original
1295* state.
1296*/
1297if (FTS_ISSET(FTS_NOCHDIR)) {1298if (len == sp->fts_pathlen || nitems == 0)1299--cp;1300*cp = '\0';1301}1302
1303/*1304* If descended after called from fts_children or after called from
1305* fts_read and nothing found, get back. At the root level we use
1306* the saved fd; if one of fts_open()'s arguments is a relative path
1307* to an empty directory, we wind up here with no other way back. If
1308* can't get back, we're done.
1309*/
1310if (descend && (type == FTS_BCHILD || !nitems) &&1311(cur->fts_level == FTS_ROOTLEVEL ? FTS_FCHDIR(sp, sp->fts_rfd) :1312fts_safe_changedir(sp, cur->fts_parent, -1, up))) {1313cur->fts_info = FTS_ERR;1314FTS_SET(FTS_STOP);1315return (NULL);1316}1317
1318/* If didn't find anything, return NULL. */1319if (!nitems) {1320if (type == FTS_BREAD)1321cur->fts_info = FTS_DP;1322return (NULL);1323}1324
1325/* Sort the entries. */1326if (sp->fts_compar && nitems > 1)1327head = fts_sort(sp, head, nitems);1328return (head);1329}
1330
1331static u_short1332fts_stat(FTS *sp, FTSENT *p, int follow, int dfd)1333{
1334FTSENT *t;1335dev_t dev;1336ino_t ino;1337struct stat *sbp, sb;1338int saved_errno;1339const char *path;1340
1341if (dfd == -1) {1342path = p->fts_accpath;1343dfd = AT_FDCWD;1344} else1345path = p->fts_name;1346
1347/* If user needs stat info, stat buffer already allocated. */1348sbp = FTS_ISSET(FTS_NOSTAT) ? &sb : p->fts_statp;1349
1350/*1351* If doing a logical walk, or application requested FTS_FOLLOW, do
1352* a stat(2). If that fails, check for a non-existent symlink. If
1353* fail, set the errno from the stat call.
1354*/
1355if (FTS_ISSET(FTS_LOGICAL) || follow) {1356if (fstatat(dfd, path, sbp, 0)) {1357saved_errno = errno;1358if (!fstatat(dfd, path, sbp, AT_SYMLINK_NOFOLLOW)) {1359errno = 0;1360return (FTS_SLNONE);1361}1362p->fts_errno = saved_errno;1363goto err;1364}1365} else if (fstatat(dfd, path, sbp, AT_SYMLINK_NOFOLLOW)) {1366p->fts_errno = errno;1367err: memset(sbp, 0, sizeof(struct stat));1368return (FTS_NS);1369}1370
1371if (S_ISDIR(sbp->st_mode)) {1372/*1373* Set the device/inode. Used to find cycles and check for
1374* crossing mount points. Also remember the link count, used
1375* in fts_build to limit the number of stat calls. It is
1376* understood that these fields are only referenced if fts_info
1377* is set to FTS_D.
1378*/
1379dev = p->fts_dev = sbp->st_dev;1380ino = p->fts_ino = sbp->st_ino;1381p->fts_nlink = sbp->st_nlink;1382
1383if (FTS_ISDOT(p->fts_name))1384return (FTS_DOT);1385
1386/*1387* Cycle detection is done by brute force when the directory
1388* is first encountered. If the tree gets deep enough or the
1389* number of symbolic links to directories is high enough,
1390* something faster might be worthwhile.
1391*/
1392for (t = p->fts_parent;1393t->fts_level >= FTS_ROOTLEVEL; t = t->fts_parent)1394if (ino == t->fts_ino && dev == t->fts_dev) {1395p->fts_cycle = t;1396return (FTS_DC);1397}1398return (FTS_D);1399}1400if (S_ISLNK(sbp->st_mode))1401return (FTS_SL);1402if (S_ISREG(sbp->st_mode))1403return (FTS_F);1404return (FTS_DEFAULT);1405}
1406
1407static FTSENT *1408fts_sort(FTS *sp, FTSENT *head, int nitems)1409{
1410FTSENT **ap, *p;1411
1412/*1413* Construct an array of pointers to the structures and call qsort(3).
1414* Reassemble the array in the order returned by qsort. If unable to
1415* sort for memory reasons, return the directory entries in their
1416* current order. Allocate enough space for the current needs plus
1417* 40 so don't realloc one entry at a time.
1418*/
1419if (nitems > sp->fts_nitems) {1420struct _ftsent **a;1421
1422if ((a = reallocarray(sp->fts_array,1423nitems + 40, sizeof(FTSENT *))) == NULL) {1424free(sp->fts_array);1425sp->fts_array = NULL;1426sp->fts_nitems = 0;1427return (head);1428}1429sp->fts_nitems = nitems + 40;1430sp->fts_array = a;1431}1432for (ap = sp->fts_array, p = head; p; p = p->fts_link)1433*ap++ = p;1434qsort(sp->fts_array, nitems, sizeof(FTSENT *),1435(int(*)(const void *, const void *))sp->fts_compar);1436for (head = *(ap = sp->fts_array); --nitems; ++ap)1437ap[0]->fts_link = ap[1];1438ap[0]->fts_link = NULL;1439return (head);1440}
1441
1442static FTSENT *1443fts_alloc(FTS *sp, char *name, size_t namelen)1444{
1445FTSENT *p;1446size_t len;1447
1448/*1449* The file name is a variable length array and no stat structure is
1450* necessary if the user has set the nostat bit. Allocate the FTSENT
1451* structure, the file name and the stat structure in one chunk, but
1452* be careful that the stat structure is reasonably aligned. Since the
1453* fts_name field is declared to be of size 1, the fts_name pointer is
1454* namelen + 2 before the first possible address of the stat structure.
1455*/
1456len = sizeof(FTSENT) + namelen;1457if (!FTS_ISSET(FTS_NOSTAT))1458len += sizeof(struct stat) + FTS_ALIGNBYTES;1459if ((p = calloc(1, len)) == NULL)1460return (NULL);1461
1462p->fts_path = sp->fts_path;1463p->fts_namelen = namelen;1464p->fts_instr = FTS_NOINSTR;1465if (!FTS_ISSET(FTS_NOSTAT))1466p->fts_statp = (struct stat *)FTS_ALIGN(p->fts_name + namelen + 2);1467memcpy(p->fts_name, name, namelen);1468
1469return (p);1470}
1471
1472static void1473fts_lfree(FTSENT *head)1474{
1475FTSENT *p;1476
1477/* Free a linked list of structures. */1478while ((p = head)) {1479head = head->fts_link;1480free(p);1481}1482}
1483
1484/*
1485* Allow essentially unlimited paths; find, rm, ls should all work on any tree.
1486* Most systems will allow creation of paths much longer than PATH_MAX, even
1487* though the kernel won't resolve them. Add the size (not just what's needed)
1488* plus 256 bytes so don't realloc the path 2 bytes at a time.
1489*/
1490static int1491fts_palloc(FTS *sp, size_t more)1492{
1493char *p;1494
1495/*1496* Check for possible wraparound.
1497*/
1498more += 256;1499if (sp->fts_pathlen + more < sp->fts_pathlen) {1500free(sp->fts_path);1501sp->fts_path = NULL;1502errno = ENAMETOOLONG;1503return (1);1504}1505p = recallocarray(sp->fts_path, sp->fts_pathlen,1506sp->fts_pathlen + more, 1);1507if (p == NULL) {1508free(sp->fts_path);1509sp->fts_path = NULL;1510return (1);1511}1512sp->fts_pathlen += more;1513sp->fts_path = p;1514return (0);1515}
1516
1517/*
1518* When the path is realloc'd, have to fix all of the pointers in structures
1519* already returned.
1520*/
1521static void1522fts_padjust(FTS *sp, FTSENT *head)1523{
1524FTSENT *p;1525char *addr = sp->fts_path;1526
1527#define ADJUST(p) { \1528if ((p)->fts_accpath != (p)->fts_name) { \1529(p)->fts_accpath = \1530(char *)addr + ((p)->fts_accpath - (p)->fts_path); \1531} \1532(p)->fts_path = addr; \1533}
1534/* Adjust the current set of children. */1535for (p = sp->fts_child; p; p = p->fts_link)1536ADJUST(p);1537
1538/* Adjust the rest of the tree, including the current level. */1539for (p = head; p->fts_level >= FTS_ROOTLEVEL;) {1540ADJUST(p);1541p = p->fts_link ? p->fts_link : p->fts_parent;1542}1543}
1544
1545static size_t1546fts_maxarglen(char * const *argv)1547{
1548size_t len, max;1549
1550for (max = 0; *argv; ++argv)1551if ((len = strlen(*argv)) > max)1552max = len;1553return (max + 1);1554}
1555
1556/*
1557* Change to dir specified by fd or p->fts_accpath without getting
1558* tricked by someone changing the world out from underneath us.
1559* Assumes p->fts_dev and p->fts_ino are filled in.
1560*/
1561static int1562fts_safe_changedir(FTS *sp, FTSENT *p, int fd, char *path)1563{
1564int ret, oerrno, newfd;1565struct stat sb;1566
1567newfd = fd;1568if (FTS_ISSET(FTS_NOCHDIR))1569return (0);1570if (fd == -1 && (newfd = open(path, O_RDONLY|O_DIRECTORY|O_CLOEXEC)) == -1)1571return (-1);1572if (fstat(newfd, &sb) == -1) {1573ret = -1;1574goto bail;1575}1576if (p->fts_dev != sb.st_dev || p->fts_ino != sb.st_ino) {1577errno = ENOENT; /* disinformation */1578ret = -1;1579goto bail;1580}1581ret = fchdir(newfd);1582bail:1583oerrno = errno;1584if (fd == -1)1585(void)close(newfd);1586errno = oerrno;1587return (ret);1588}
1589#endif /* !HAVE_FTS */1590#if !HAVE_GETPROGNAME1591/*
1592* Copyright (c) 2016 Nicholas Marriott <nicholas.marriott@gmail.com>
1593* Copyright (c) 2017 Kristaps Dzonsons <kristaps@bsd.lv>
1594* Copyright (c) 2020 Stephen Gregoratto <dev@sgregoratto.me>
1595*
1596* Permission to use, copy, modify, and distribute this software for any
1597* purpose with or without fee is hereby granted, provided that the above
1598* copyright notice and this permission notice appear in all copies.
1599*
1600* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
1601* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
1602* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
1603* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
1604* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
1605* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
1606* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1607*/
1608
1609#include <sys/types.h>1610
1611#include <errno.h>1612
1613#if HAVE_GETEXECNAME1614#include <stdlib.h>1615const char *1616getprogname(void)1617{
1618return getexecname();1619}
1620#elif HAVE_PROGRAM_INVOCATION_SHORT_NAME1621const char *1622getprogname(void)1623{
1624return (program_invocation_short_name);1625}
1626#elif HAVE___PROGNAME1627const char *1628getprogname(void)1629{
1630extern char *__progname;1631
1632return (__progname);1633}
1634#else1635#error No getprogname available.1636#endif1637#endif /* !HAVE_GETPROGNAME */1638#if !HAVE_MD51639/*
1640* This code implements the MD5 message-digest algorithm.
1641* The algorithm is due to Ron Rivest. This code was
1642* written by Colin Plumb in 1993, no copyright is claimed.
1643* This code is in the public domain; do with it what you wish.
1644*
1645* Equivalent code is available from RSA Data Security, Inc.
1646* This code has been tested against that, and is equivalent,
1647* except that you don't need to include two pages of legalese
1648* with every copy.
1649*
1650* To compute the message digest of a chunk of bytes, declare an
1651* MD5Context structure, pass it to MD5Init, call MD5Update as
1652* needed on buffers full of bytes, and then call MD5Final, which
1653* will fill a supplied 16-byte array with the digest.
1654*/
1655
1656#include <sys/types.h>1657#include <stdlib.h>1658#include <string.h>1659
1660#ifndef BYTE_ORDER1661# if defined(LITTLE_ENDIAN) || defined(BIG_ENDIAN)1662# error Confusion in endian macros.1663# endif1664# if !defined(__BYTE_ORDER__)1665# error Byte order macro not found.1666# endif1667# if !defined(__ORDER_LITTLE_ENDIAN__) || !defined(__ORDER_BIG_ENDIAN__)1668# error Little/big endian macros not found.1669# endif1670# define BYTE_ORDER __BYTE_ORDER__1671# define LITTLE_ENDIAN __ORDER_LITTLE_ENDIAN__1672# define BIG_ENDIAN __ORDER_BIG_ENDIAN__1673#endif /*!BYTE_ORDER*/1674
1675#define PUT_64BIT_LE(cp, value) do { \1676(cp)[7] = (value) >> 56; \1677(cp)[6] = (value) >> 48; \1678(cp)[5] = (value) >> 40; \1679(cp)[4] = (value) >> 32; \1680(cp)[3] = (value) >> 24; \1681(cp)[2] = (value) >> 16; \1682(cp)[1] = (value) >> 8; \1683(cp)[0] = (value); } while (0)1684
1685#define PUT_32BIT_LE(cp, value) do { \1686(cp)[3] = (value) >> 24; \1687(cp)[2] = (value) >> 16; \1688(cp)[1] = (value) >> 8; \1689(cp)[0] = (value); } while (0)1690
1691static uint8_t PADDING[MD5_BLOCK_LENGTH] = {16920x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,16930, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,16940, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 01695};1696
1697/*
1698* Start MD5 accumulation. Set bit count to 0 and buffer to mysterious
1699* initialization constants.
1700*/
1701void
1702MD5Init(MD5_CTX *ctx)1703{
1704ctx->count = 0;1705ctx->state[0] = 0x67452301;1706ctx->state[1] = 0xefcdab89;1707ctx->state[2] = 0x98badcfe;1708ctx->state[3] = 0x10325476;1709}
1710
1711/*
1712* Update context to reflect the concatenation of another buffer full
1713* of bytes.
1714*/
1715void
1716MD5Update(MD5_CTX *ctx, const unsigned char *input, size_t len)1717{
1718size_t have, need;1719
1720/* Check how many bytes we already have and how many more we need. */1721have = (size_t)((ctx->count >> 3) & (MD5_BLOCK_LENGTH - 1));1722need = MD5_BLOCK_LENGTH - have;1723
1724/* Update bitcount */1725ctx->count += (uint64_t)len << 3;1726
1727if (len >= need) {1728if (have != 0) {1729memcpy(ctx->buffer + have, input, need);1730MD5Transform(ctx->state, ctx->buffer);1731input += need;1732len -= need;1733have = 0;1734}1735
1736/* Process data in MD5_BLOCK_LENGTH-byte chunks. */1737while (len >= MD5_BLOCK_LENGTH) {1738MD5Transform(ctx->state, input);1739input += MD5_BLOCK_LENGTH;1740len -= MD5_BLOCK_LENGTH;1741}1742}1743
1744/* Handle any remaining bytes of data. */1745if (len != 0)1746memcpy(ctx->buffer + have, input, len);1747}
1748
1749/*
1750* Pad pad to 64-byte boundary with the bit pattern
1751* 1 0* (64-bit count of bits processed, MSB-first)
1752*/
1753void
1754MD5Pad(MD5_CTX *ctx)1755{
1756uint8_t count[8];1757size_t padlen;1758
1759/* Convert count to 8 bytes in little endian order. */1760PUT_64BIT_LE(count, ctx->count);1761
1762/* Pad out to 56 mod 64. */1763padlen = MD5_BLOCK_LENGTH -1764((ctx->count >> 3) & (MD5_BLOCK_LENGTH - 1));1765if (padlen < 1 + 8)1766padlen += MD5_BLOCK_LENGTH;1767MD5Update(ctx, PADDING, padlen - 8); /* padlen - 8 <= 64 */1768MD5Update(ctx, count, 8);1769}
1770
1771/*
1772* Final wrapup--call MD5Pad, fill in digest and zero out ctx.
1773*/
1774void
1775MD5Final(unsigned char digest[MD5_DIGEST_LENGTH], MD5_CTX *ctx)1776{
1777int i;1778
1779MD5Pad(ctx);1780for (i = 0; i < 4; i++)1781PUT_32BIT_LE(digest + i * 4, ctx->state[i]);1782memset(ctx, 0, sizeof(*ctx));1783}
1784
1785
1786/* The four core functions - F1 is optimized somewhat */
1787
1788/* #define F1(x, y, z) (x & y | ~x & z) */
1789#define F1(x, y, z) (z ^ (x & (y ^ z)))1790#define F2(x, y, z) F1(z, x, y)1791#define F3(x, y, z) (x ^ y ^ z)1792#define F4(x, y, z) (y ^ (x | ~z))1793
1794/* This is the central step in the MD5 algorithm. */
1795#define MD5STEP(f, w, x, y, z, data, s) \1796( w += f(x, y, z) + data, w = w<<s | w>>(32-s), w += x )1797
1798/*
1799* The core of the MD5 algorithm, this alters an existing MD5 hash to
1800* reflect the addition of 16 longwords of new data. MD5Update blocks
1801* the data and converts bytes into longwords for this routine.
1802*/
1803void
1804MD5Transform(uint32_t state[4], const uint8_t block[MD5_BLOCK_LENGTH])1805{
1806uint32_t a, b, c, d, in[MD5_BLOCK_LENGTH / 4];1807
1808#if BYTE_ORDER == LITTLE_ENDIAN1809memcpy(in, block, sizeof(in));1810#else1811for (a = 0; a < MD5_BLOCK_LENGTH / 4; a++) {1812in[a] = (uint32_t)(1813(uint32_t)(block[a * 4 + 0]) |1814(uint32_t)(block[a * 4 + 1]) << 8 |1815(uint32_t)(block[a * 4 + 2]) << 16 |1816(uint32_t)(block[a * 4 + 3]) << 24);1817}1818#endif1819
1820a = state[0];1821b = state[1];1822c = state[2];1823d = state[3];1824
1825MD5STEP(F1, a, b, c, d, in[ 0] + 0xd76aa478, 7);1826MD5STEP(F1, d, a, b, c, in[ 1] + 0xe8c7b756, 12);1827MD5STEP(F1, c, d, a, b, in[ 2] + 0x242070db, 17);1828MD5STEP(F1, b, c, d, a, in[ 3] + 0xc1bdceee, 22);1829MD5STEP(F1, a, b, c, d, in[ 4] + 0xf57c0faf, 7);1830MD5STEP(F1, d, a, b, c, in[ 5] + 0x4787c62a, 12);1831MD5STEP(F1, c, d, a, b, in[ 6] + 0xa8304613, 17);1832MD5STEP(F1, b, c, d, a, in[ 7] + 0xfd469501, 22);1833MD5STEP(F1, a, b, c, d, in[ 8] + 0x698098d8, 7);1834MD5STEP(F1, d, a, b, c, in[ 9] + 0x8b44f7af, 12);1835MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);1836MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);1837MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);1838MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);1839MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);1840MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);1841
1842MD5STEP(F2, a, b, c, d, in[ 1] + 0xf61e2562, 5);1843MD5STEP(F2, d, a, b, c, in[ 6] + 0xc040b340, 9);1844MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);1845MD5STEP(F2, b, c, d, a, in[ 0] + 0xe9b6c7aa, 20);1846MD5STEP(F2, a, b, c, d, in[ 5] + 0xd62f105d, 5);1847MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);1848MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);1849MD5STEP(F2, b, c, d, a, in[ 4] + 0xe7d3fbc8, 20);1850MD5STEP(F2, a, b, c, d, in[ 9] + 0x21e1cde6, 5);1851MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);1852MD5STEP(F2, c, d, a, b, in[ 3] + 0xf4d50d87, 14);1853MD5STEP(F2, b, c, d, a, in[ 8] + 0x455a14ed, 20);1854MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);1855MD5STEP(F2, d, a, b, c, in[ 2] + 0xfcefa3f8, 9);1856MD5STEP(F2, c, d, a, b, in[ 7] + 0x676f02d9, 14);1857MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);1858
1859MD5STEP(F3, a, b, c, d, in[ 5] + 0xfffa3942, 4);1860MD5STEP(F3, d, a, b, c, in[ 8] + 0x8771f681, 11);1861MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);1862MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);1863MD5STEP(F3, a, b, c, d, in[ 1] + 0xa4beea44, 4);1864MD5STEP(F3, d, a, b, c, in[ 4] + 0x4bdecfa9, 11);1865MD5STEP(F3, c, d, a, b, in[ 7] + 0xf6bb4b60, 16);1866MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);1867MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);1868MD5STEP(F3, d, a, b, c, in[ 0] + 0xeaa127fa, 11);1869MD5STEP(F3, c, d, a, b, in[ 3] + 0xd4ef3085, 16);1870MD5STEP(F3, b, c, d, a, in[ 6] + 0x04881d05, 23);1871MD5STEP(F3, a, b, c, d, in[ 9] + 0xd9d4d039, 4);1872MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);1873MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);1874MD5STEP(F3, b, c, d, a, in[2 ] + 0xc4ac5665, 23);1875
1876MD5STEP(F4, a, b, c, d, in[ 0] + 0xf4292244, 6);1877MD5STEP(F4, d, a, b, c, in[7 ] + 0x432aff97, 10);1878MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);1879MD5STEP(F4, b, c, d, a, in[5 ] + 0xfc93a039, 21);1880MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);1881MD5STEP(F4, d, a, b, c, in[3 ] + 0x8f0ccc92, 10);1882MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);1883MD5STEP(F4, b, c, d, a, in[1 ] + 0x85845dd1, 21);1884MD5STEP(F4, a, b, c, d, in[8 ] + 0x6fa87e4f, 6);1885MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);1886MD5STEP(F4, c, d, a, b, in[6 ] + 0xa3014314, 15);1887MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);1888MD5STEP(F4, a, b, c, d, in[4 ] + 0xf7537e82, 6);1889MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);1890MD5STEP(F4, c, d, a, b, in[2 ] + 0x2ad7d2bb, 15);1891MD5STEP(F4, b, c, d, a, in[9 ] + 0xeb86d391, 21);1892
1893state[0] += a;1894state[1] += b;1895state[2] += c;1896state[3] += d;1897}
1898
1899char *1900MD5End(MD5_CTX *ctx, char *buf)1901{
1902int i;1903unsigned char digest[MD5_DIGEST_LENGTH];1904static const char hex[]="0123456789abcdef";1905
1906if (!buf)1907buf = malloc(2*MD5_DIGEST_LENGTH + 1);1908if (!buf)1909return 0;1910MD5Final(digest, ctx);1911for (i = 0; i < MD5_DIGEST_LENGTH; i++) {1912buf[i+i] = hex[digest[i] >> 4];1913buf[i+i+1] = hex[digest[i] & 0x0f];1914}1915buf[i+i] = '\0';1916return buf;1917}
1918#endif /* !HAVE_MD5 */1919#if !HAVE_MEMMEM1920/*-
1921* Copyright (c) 2005 Pascal Gloor <pascal.gloor@spale.com>
1922*
1923* Redistribution and use in source and binary forms, with or without
1924* modification, are permitted provided that the following conditions
1925* are met:
1926* 1. Redistributions of source code must retain the above copyright
1927* notice, this list of conditions and the following disclaimer.
1928* 2. Redistributions in binary form must reproduce the above copyright
1929* notice, this list of conditions and the following disclaimer in
1930* the documentation and/or other materials provided with the
1931* distribution.
1932* 3. The name of the author may not be used to endorse or promote
1933* products derived from this software without specific prior written
1934* permission.
1935*
1936* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS''
1937* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
1938* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
1939* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR
1940* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
1941* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
1942* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
1943* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
1944* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
1945* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
1946* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1947*/
1948/*
1949* Find the first occurrence of the byte string s in byte string l.
1950*/
1951void *1952memmem(const void *l, size_t l_len, const void *s, size_t s_len)1953{
1954const char *cur, *last;1955const char *cl = l;1956const char *cs = s;1957
1958/* a zero length needle should just return the haystack */1959if (l_len == 0)1960return (void *)cl;1961
1962/* "s" must be smaller or equal to "l" */1963if (l_len < s_len)1964return NULL;1965
1966/* special case where s_len == 1 */1967if (s_len == 1)1968return memchr(l, *cs, l_len);1969
1970/* the last position where its possible to find "s" in "l" */1971last = cl + l_len - s_len;1972
1973for (cur = cl; cur <= last; cur++)1974if (cur[0] == cs[0] && memcmp(cur, cs, s_len) == 0)1975return (void *)cur;1976
1977return NULL;1978}
1979#endif /* !HAVE_MEMMEM */1980#if !HAVE_MEMRCHR1981/*
1982* Copyright (c) 2007 Todd C. Miller <Todd.Miller@courtesan.com>
1983*
1984* Permission to use, copy, modify, and distribute this software for any
1985* purpose with or without fee is hereby granted, provided that the above
1986* copyright notice and this permission notice appear in all copies.
1987*
1988* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
1989* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
1990* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
1991* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
1992* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
1993* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
1994* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1995*
1996*/
1997
1998#include <string.h>1999
2000/*
2001* Reverse memchr()
2002* Find the last occurrence of 'c' in the buffer 's' of size 'n'.
2003*/
2004void *2005memrchr(const void *s, int c, size_t n)2006{
2007const unsigned char *cp;2008
2009if (n != 0) {2010cp = (unsigned char *)s + n;2011do {2012if (*(--cp) == (unsigned char)c)2013return((void *)cp);2014} while (--n != 0);2015}2016return(NULL);2017}
2018#endif /* !HAVE_MEMRCHR */2019#if !HAVE_MKFIFOAT2020#include <sys/stat.h>2021
2022#include <errno.h>2023#include <fcntl.h>2024#include <unistd.h>2025
2026int
2027mkfifoat(int fd, const char *path, mode_t mode)2028{
2029int er, curfd = -1, newfd = -1;2030
2031/* Get our current directory then switch to the given one. */2032
2033if (fd != AT_FDCWD) {2034if ((curfd = open(".", O_RDONLY | O_DIRECTORY, 0)) == -1)2035return -1;2036if (fchdir(fd) == -1)2037goto out;2038}2039
2040if ((newfd = mkfifo(path, mode)) == -1)2041goto out;2042
2043/* This leaves the fifo if it fails. */2044
2045if (curfd != -1 && fchdir(curfd) == -1)2046goto out;2047if (curfd != -1)2048close(curfd);2049
2050return newfd;2051out:2052/* Ignore errors in close(2). */2053
2054er = errno;2055if (curfd != -1)2056fchdir(curfd);2057if (curfd != -1)2058close(curfd);2059if (newfd != -1)2060close(newfd);2061errno = er;2062return -1;2063}
2064#endif /* !HAVE_MKFIFOAT */2065#if !HAVE_MKNODAT2066#include <sys/stat.h>2067
2068#include <errno.h>2069#include <fcntl.h>2070#include <unistd.h>2071
2072int
2073mknodat(int fd, const char *path, mode_t mode, dev_t dev)2074{
2075int er, curfd = -1, newfd = -1;2076
2077/* Get our current directory then switch to the given one. */2078
2079if (fd != AT_FDCWD) {2080if ((curfd = open(".", O_RDONLY | O_DIRECTORY, 0)) == -1)2081return -1;2082if (fchdir(fd) == -1)2083goto out;2084}2085
2086if ((newfd = mknod(path, mode, dev)) == -1)2087goto out;2088
2089/* This leaves the node if it fails. */2090
2091if (curfd != -1 && fchdir(curfd) == -1)2092goto out;2093if (curfd != -1)2094close(curfd);2095
2096return newfd;2097out:2098
2099/* Ignore errors in close(2). */2100
2101er = errno;2102if (curfd != -1)2103fchdir(curfd);2104if (curfd != -1)2105close(curfd);2106if (newfd != -1)2107close(newfd);2108errno = er;2109return -1;2110}
2111#endif /* !HAVE_MKNODAT */2112#if !HAVE_READPASSPHRASE2113/*
2114* Original: readpassphrase.c in OpenSSH portable
2115*/
2116/*
2117* Copyright (c) 2000-2002, 2007, 2010
2118* Todd C. Miller <millert@openbsd.org>
2119*
2120* Permission to use, copy, modify, and distribute this software for any
2121* purpose with or without fee is hereby granted, provided that the above
2122* copyright notice and this permission notice appear in all copies.
2123*
2124* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
2125* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
2126* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
2127* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
2128* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
2129* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
2130* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
2131*
2132* Sponsored in part by the Defense Advanced Research Projects
2133* Agency (DARPA) and Air Force Research Laboratory, Air Force
2134* Materiel Command, USAF, under agreement number F39502-99-1-0512.
2135*/
2136
2137#include <ctype.h>2138#include <errno.h>2139#include <fcntl.h>2140#include <paths.h>2141#include <pwd.h>2142#include <signal.h>2143#include <string.h>2144#include <termios.h>2145#include <unistd.h>2146
2147#if !defined(_NSIG) && defined(NSIG)2148# define _NSIG NSIG2149#endif2150
2151static volatile sig_atomic_t readpassphrase_signo[_NSIG];2152
2153static void2154readpassphrase_handler(int s)2155{
2156
2157readpassphrase_signo[s] = 1;2158}
2159
2160char *2161readpassphrase(const char *prompt, char *buf, size_t bufsiz, int flags)2162{
2163ssize_t nr;2164int input, output, save_errno, i, need_restart;2165char ch, *p, *end;2166struct termios term, oterm;2167struct sigaction sa, savealrm, saveint, savehup, savequit, saveterm;2168struct sigaction savetstp, savettin, savettou, savepipe;2169/* If we don't have TCSASOFT define it so that ORing it it below is a no-op. */
2170#ifndef TCSASOFT2171const int tcasoft = 0;2172#else2173const int tcasoft = TCSASOFT;2174#endif2175
2176/* I suppose we could alloc on demand in this case (XXX). */2177if (bufsiz == 0) {2178errno = EINVAL;2179return(NULL);2180}2181
2182restart:2183for (i = 0; i < _NSIG; i++)2184readpassphrase_signo[i] = 0;2185nr = -1;2186save_errno = 0;2187need_restart = 0;2188/*2189* Read and write to /dev/tty if available. If not, read from
2190* stdin and write to stderr unless a tty is required.
2191*/
2192if ((flags & RPP_STDIN) ||2193(input = output = open(_PATH_TTY, O_RDWR)) == -1) {2194if (flags & RPP_REQUIRE_TTY) {2195errno = ENOTTY;2196return(NULL);2197}2198input = STDIN_FILENO;2199output = STDERR_FILENO;2200}2201
2202/*2203* Turn off echo if possible.
2204* If we are using a tty but are not the foreground pgrp this will
2205* generate SIGTTOU, so do it *before* installing the signal handlers.
2206*/
2207if (input != STDIN_FILENO && tcgetattr(input, &oterm) == 0) {2208memcpy(&term, &oterm, sizeof(term));2209if (!(flags & RPP_ECHO_ON))2210term.c_lflag &= ~(ECHO | ECHONL);2211#ifdef VSTATUS2212if (term.c_cc[VSTATUS] != _POSIX_VDISABLE)2213term.c_cc[VSTATUS] = _POSIX_VDISABLE;2214#endif2215(void)tcsetattr(input, TCSAFLUSH|tcasoft, &term);2216} else {2217memset(&term, 0, sizeof(term));2218term.c_lflag |= ECHO;2219memset(&oterm, 0, sizeof(oterm));2220oterm.c_lflag |= ECHO;2221}2222
2223/*2224* Catch signals that would otherwise cause the user to end
2225* up with echo turned off in the shell. Don't worry about
2226* things like SIGXCPU and SIGVTALRM for now.
2227*/
2228sigemptyset(&sa.sa_mask);2229sa.sa_flags = 0; /* don't restart system calls */2230sa.sa_handler = readpassphrase_handler;2231(void)sigaction(SIGALRM, &sa, &savealrm);2232(void)sigaction(SIGHUP, &sa, &savehup);2233(void)sigaction(SIGINT, &sa, &saveint);2234(void)sigaction(SIGPIPE, &sa, &savepipe);2235(void)sigaction(SIGQUIT, &sa, &savequit);2236(void)sigaction(SIGTERM, &sa, &saveterm);2237(void)sigaction(SIGTSTP, &sa, &savetstp);2238(void)sigaction(SIGTTIN, &sa, &savettin);2239(void)sigaction(SIGTTOU, &sa, &savettou);2240
2241if (!(flags & RPP_STDIN))2242(void)write(output, prompt, strlen(prompt));2243end = buf + bufsiz - 1;2244p = buf;2245while ((nr = read(input, &ch, 1)) == 1 && ch != '\n' && ch != '\r') {2246if (p < end) {2247if ((flags & RPP_SEVENBIT))2248ch &= 0x7f;2249if (isalpha((unsigned char)ch)) {2250if ((flags & RPP_FORCELOWER))2251ch = (char)tolower((unsigned char)ch);2252if ((flags & RPP_FORCEUPPER))2253ch = (char)toupper((unsigned char)ch);2254}2255*p++ = ch;2256}2257}2258*p = '\0';2259save_errno = errno;2260if (!(term.c_lflag & ECHO))2261(void)write(output, "\n", 1);2262
2263/* Restore old terminal settings and signals. */2264if (memcmp(&term, &oterm, sizeof(term)) != 0) {2265const int sigttou = readpassphrase_signo[SIGTTOU];2266
2267/* Ignore SIGTTOU generated when we are not the fg pgrp. */2268while (tcsetattr(input, TCSAFLUSH|tcasoft, &oterm) == -1 &&2269errno == EINTR && !readpassphrase_signo[SIGTTOU])2270continue;2271readpassphrase_signo[SIGTTOU] = sigttou;2272}2273(void)sigaction(SIGALRM, &savealrm, NULL);2274(void)sigaction(SIGHUP, &savehup, NULL);2275(void)sigaction(SIGINT, &saveint, NULL);2276(void)sigaction(SIGQUIT, &savequit, NULL);2277(void)sigaction(SIGPIPE, &savepipe, NULL);2278(void)sigaction(SIGTERM, &saveterm, NULL);2279(void)sigaction(SIGTSTP, &savetstp, NULL);2280(void)sigaction(SIGTTIN, &savettin, NULL);2281(void)sigaction(SIGTTOU, &savettou, NULL);2282if (input != STDIN_FILENO)2283(void)close(input);2284
2285/*2286* If we were interrupted by a signal, resend it to ourselves
2287* now that we have restored the signal handlers.
2288*/
2289for (i = 0; i < _NSIG; i++) {2290if (readpassphrase_signo[i]) {2291kill(getpid(), i);2292switch (i) {2293case SIGTSTP:2294case SIGTTIN:2295case SIGTTOU:2296need_restart = 1;2297}2298}2299}2300if (need_restart)2301goto restart;2302
2303if (save_errno)2304errno = save_errno;2305return(nr == -1 ? NULL : buf);2306}
2307#endif /* !HAVE_READPASSPHRASE */2308#if !HAVE_REALLOCARRAY2309/*
2310* Copyright (c) 2008 Otto Moerbeek <otto@drijf.net>
2311*
2312* Permission to use, copy, modify, and distribute this software for any
2313* purpose with or without fee is hereby granted, provided that the above
2314* copyright notice and this permission notice appear in all copies.
2315*
2316* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
2317* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
2318* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
2319* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
2320* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
2321* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
2322* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
2323*/
2324
2325#include <sys/types.h>2326#include <errno.h>2327#include <stdint.h>2328#include <stdlib.h>2329
2330/*
2331* This is sqrt(SIZE_MAX+1), as s1*s2 <= SIZE_MAX
2332* if both s1 < MUL_NO_OVERFLOW and s2 < MUL_NO_OVERFLOW
2333*/
2334#define MUL_NO_OVERFLOW ((size_t)1 << (sizeof(size_t) * 4))2335
2336void *2337reallocarray(void *optr, size_t nmemb, size_t size)2338{
2339if ((nmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) &&2340nmemb > 0 && SIZE_MAX / nmemb < size) {2341errno = ENOMEM;2342return NULL;2343}2344return realloc(optr, size * nmemb);2345}
2346#endif /* !HAVE_REALLOCARRAY */2347#if !HAVE_RECALLOCARRAY2348/*
2349* Copyright (c) 2008, 2017 Otto Moerbeek <otto@drijf.net>
2350*
2351* Permission to use, copy, modify, and distribute this software for any
2352* purpose with or without fee is hereby granted, provided that the above
2353* copyright notice and this permission notice appear in all copies.
2354*
2355* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
2356* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
2357* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
2358* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
2359* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
2360* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
2361* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
2362*/
2363
2364/* OPENBSD ORIGINAL: lib/libc/stdlib/recallocarray.c */
2365
2366#include <errno.h>2367#include <stdlib.h>2368#include <stdint.h>2369#include <string.h>2370#include <unistd.h>2371
2372/*
2373* This is sqrt(SIZE_MAX+1), as s1*s2 <= SIZE_MAX
2374* if both s1 < MUL_NO_OVERFLOW and s2 < MUL_NO_OVERFLOW
2375*/
2376#define MUL_NO_OVERFLOW ((size_t)1 << (sizeof(size_t) * 4))2377
2378void *2379recallocarray(void *ptr, size_t oldnmemb, size_t newnmemb, size_t size)2380{
2381size_t oldsize, newsize;2382void *newptr;2383
2384if (ptr == NULL)2385return calloc(newnmemb, size);2386
2387if ((newnmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) &&2388newnmemb > 0 && SIZE_MAX / newnmemb < size) {2389errno = ENOMEM;2390return NULL;2391}2392newsize = newnmemb * size;2393
2394if ((oldnmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) &&2395oldnmemb > 0 && SIZE_MAX / oldnmemb < size) {2396errno = EINVAL;2397return NULL;2398}2399oldsize = oldnmemb * size;2400
2401/*2402* Don't bother too much if we're shrinking just a bit,
2403* we do not shrink for series of small steps, oh well.
2404*/
2405if (newsize <= oldsize) {2406size_t d = oldsize - newsize;2407
2408if (d < oldsize / 2 && d < (size_t)getpagesize()) {2409memset((char *)ptr + newsize, 0, d);2410return ptr;2411}2412}2413
2414newptr = malloc(newsize);2415if (newptr == NULL)2416return NULL;2417
2418if (newsize > oldsize) {2419memcpy(newptr, ptr, oldsize);2420memset((char *)newptr + oldsize, 0, newsize - oldsize);2421} else2422memcpy(newptr, ptr, newsize);2423
2424explicit_bzero(ptr, oldsize);2425free(ptr);2426
2427return newptr;2428}
2429#endif /* !HAVE_RECALLOCARRAY */2430#if !HAVE_SCAN_SCALED2431/* $OpenBSD: fmt_scaled.c,v 1.22 2022/03/11 09:04:59 dtucker Exp $ */
2432
2433/*
2434* Copyright (c) 2001, 2002, 2003 Ian F. Darwin. All rights reserved.
2435*
2436* Redistribution and use in source and binary forms, with or without
2437* modification, are permitted provided that the following conditions
2438* are met:
2439* 1. Redistributions of source code must retain the above copyright
2440* notice, this list of conditions and the following disclaimer.
2441* 2. Redistributions in binary form must reproduce the above copyright
2442* notice, this list of conditions and the following disclaimer in the
2443* documentation and/or other materials provided with the distribution.
2444* 3. The name of the author may not be used to endorse or promote products
2445* derived from this software without specific prior written permission.
2446*
2447* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
2448* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
2449* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2450* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
2451* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
2452* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2453* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2454* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2455* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
2456* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2457*/
2458
2459/*
2460* fmt_scaled: Format numbers scaled for human comprehension
2461* scan_scaled: Scan numbers in this format.
2462*
2463* "Human-readable" output uses 4 digits max, and puts a unit suffix at
2464* the end. Makes output compact and easy-to-read esp. on huge disks.
2465* Formatting code was originally in OpenBSD "df", converted to library routine.
2466* Scanning code written for OpenBSD libutil.
2467*/
2468
2469#include <stdio.h>2470#include <stdlib.h>2471#include <errno.h>2472#include <string.h>2473#include <ctype.h>2474#include <limits.h>2475
2476typedef enum {2477NONE = 0, KILO = 1, MEGA = 2, GIGA = 3, TERA = 4, PETA = 5, EXA = 62478} unit_type;2479
2480/* These three arrays MUST be in sync! XXX make a struct */
2481static const unit_type units[] = { NONE, KILO, MEGA, GIGA, TERA, PETA, EXA };2482static const char scale_chars[] = "BKMGTPE";2483static const long long scale_factors[] = {24841LL,24851024LL,24861024LL*1024,24871024LL*1024*1024,24881024LL*1024*1024*1024,24891024LL*1024*1024*1024*1024,24901024LL*1024*1024*1024*1024*1024,2491};2492#define SCALE_LENGTH (sizeof(units)/sizeof(units[0]))2493
2494#define MAX_DIGITS (SCALE_LENGTH * 3) /* XXX strlen(sprintf("%lld", -1)? */2495
2496/* Convert the given input string "scaled" into numeric in "result".
2497* Return 0 on success, -1 and errno set on error.
2498*/
2499int
2500scan_scaled(char *scaled, long long *result)2501{
2502char *p = scaled;2503int sign = 0;2504unsigned int i, ndigits = 0, fract_digits = 0;2505long long scale_fact = 1, whole = 0, fpart = 0;2506
2507/* Skip leading whitespace */2508while (isascii((unsigned char)*p) && isspace((unsigned char)*p))2509++p;2510
2511/* Then at most one leading + or - */2512while (*p == '-' || *p == '+') {2513if (*p == '-') {2514if (sign) {2515errno = EINVAL;2516return -1;2517}2518sign = -1;2519++p;2520} else if (*p == '+') {2521if (sign) {2522errno = EINVAL;2523return -1;2524}2525sign = +1;2526++p;2527}2528}2529
2530/* Main loop: Scan digits, find decimal point, if present.2531* We don't allow exponentials, so no scientific notation
2532* (but note that E for Exa might look like e to some!).
2533* Advance 'p' to end, to get scale factor.
2534*/
2535for (; isascii((unsigned char)*p) &&2536(isdigit((unsigned char)*p) || *p=='.'); ++p) {2537if (*p == '.') {2538if (fract_digits > 0) { /* oops, more than one '.' */2539errno = EINVAL;2540return -1;2541}2542fract_digits = 1;2543continue;2544}2545
2546i = (*p) - '0'; /* whew! finally a digit we can use */2547if (fract_digits > 0) {2548if (fract_digits >= MAX_DIGITS-1)2549/* ignore extra fractional digits */2550continue;2551fract_digits++; /* for later scaling */2552if (fpart > LLONG_MAX / 10) {2553errno = ERANGE;2554return -1;2555}2556fpart *= 10;2557if (i > LLONG_MAX - fpart) {2558errno = ERANGE;2559return -1;2560}2561fpart += i;2562} else { /* normal digit */2563if (++ndigits >= MAX_DIGITS) {2564errno = ERANGE;2565return -1;2566}2567if (whole > LLONG_MAX / 10) {2568errno = ERANGE;2569return -1;2570}2571whole *= 10;2572if (i > LLONG_MAX - whole) {2573errno = ERANGE;2574return -1;2575}2576whole += i;2577}2578}2579
2580if (sign)2581whole *= sign;2582
2583/* If no scale factor given, we're done. fraction is discarded. */2584if (!*p) {2585*result = whole;2586return 0;2587}2588
2589/* Validate scale factor, and scale whole and fraction by it. */2590for (i = 0; i < SCALE_LENGTH; i++) {2591
2592/* Are we there yet? */2593if (*p == scale_chars[i] ||2594*p == tolower((unsigned char)scale_chars[i])) {2595
2596/* If it ends with alphanumerics after the scale char, bad. */2597if (isalnum((unsigned char)*(p+1))) {2598errno = EINVAL;2599return -1;2600}2601scale_fact = scale_factors[i];2602
2603/* check for overflow and underflow after scaling */2604if (whole > LLONG_MAX / scale_fact ||2605whole < LLONG_MIN / scale_fact) {2606errno = ERANGE;2607return -1;2608}2609
2610/* scale whole part */2611whole *= scale_fact;2612
2613/* truncate fpart so it does't overflow.2614* then scale fractional part.
2615*/
2616while (fpart >= LLONG_MAX / scale_fact) {2617fpart /= 10;2618fract_digits--;2619}2620fpart *= scale_fact;2621if (fract_digits > 0) {2622for (i = 0; i < fract_digits -1; i++)2623fpart /= 10;2624}2625if (sign == -1)2626whole -= fpart;2627else2628whole += fpart;2629*result = whole;2630return 0;2631}2632}2633
2634/* Invalid unit or character */2635errno = EINVAL;2636return -1;2637}
2638
2639/* Format the given "number" into human-readable form in "result".
2640* Result must point to an allocated buffer of length FMT_SCALED_STRSIZE.
2641* Return 0 on success, -1 and errno set if error.
2642*/
2643int
2644fmt_scaled(long long number, char *result)2645{
2646long long abval, fract = 0;2647unsigned int i;2648unit_type unit = NONE;2649
2650/* Not every negative long long has a positive representation. */2651if (number == LLONG_MIN) {2652errno = ERANGE;2653return -1;2654}2655
2656abval = llabs(number);2657
2658/* Also check for numbers that are just too darned big to format. */2659if (abval / 1024 >= scale_factors[SCALE_LENGTH-1]) {2660errno = ERANGE;2661return -1;2662}2663
2664/* scale whole part; get unscaled fraction */2665for (i = 0; i < SCALE_LENGTH; i++) {2666if (abval/1024 < scale_factors[i]) {2667unit = units[i];2668fract = (i == 0) ? 0 : abval % scale_factors[i];2669number /= scale_factors[i];2670if (i > 0)2671fract /= scale_factors[i - 1];2672break;2673}2674}2675
2676fract = (10 * fract + 512) / 1024;2677/* if the result would be >= 10, round main number */2678if (fract >= 10) {2679if (number >= 0)2680number++;2681else2682number--;2683fract = 0;2684} else if (fract < 0) {2685/* shouldn't happen */2686fract = 0;2687}2688
2689if (number == 0)2690strlcpy(result, "0B", FMT_SCALED_STRSIZE);2691else if (unit == NONE || number >= 100 || number <= -100) {2692if (fract >= 5) {2693if (number >= 0)2694number++;2695else2696number--;2697}2698(void)snprintf(result, FMT_SCALED_STRSIZE, "%lld%c",2699number, scale_chars[unit]);2700} else2701(void)snprintf(result, FMT_SCALED_STRSIZE, "%lld.%1lld%c",2702number, fract, scale_chars[unit]);2703
2704return 0;2705}
2706
2707#endif /* !HAVE_SCAN_SCALED */2708#if !HAVE_SETRESGID2709/*
2710* Copyright (c) 2004, 2005 Darren Tucker (dtucker at zip com au).
2711*
2712* Permission to use, copy, modify, and distribute this software for any
2713* purpose with or without fee is hereby granted, provided that the above
2714* copyright notice and this permission notice appear in all copies.
2715*
2716* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
2717* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
2718* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
2719* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
2720* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
2721* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
2722* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
2723*/
2724
2725#include <sys/types.h>2726#include <unistd.h>2727
2728int
2729setresgid(gid_t rgid, gid_t egid, gid_t sgid)2730{
2731/* this is the only configuration tested */2732
2733if (rgid != egid || egid != sgid)2734return -1;2735
2736if (setregid(rgid, egid) == -1)2737return -1;2738
2739return 0;2740}
2741#endif /* !HAVE_SETRESGID */2742#if !HAVE_SETRESUID2743/*
2744* Copyright (c) 2004, 2005 Darren Tucker (dtucker at zip com au).
2745*
2746* Permission to use, copy, modify, and distribute this software for any
2747* purpose with or without fee is hereby granted, provided that the above
2748* copyright notice and this permission notice appear in all copies.
2749*
2750* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
2751* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
2752* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
2753* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
2754* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
2755* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
2756* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
2757*/
2758
2759#include <sys/types.h>2760
2761#include <errno.h>2762#include <unistd.h>2763
2764int
2765setresuid(uid_t ruid, uid_t euid, uid_t suid)2766{
2767uid_t ouid;2768int ret = -1;2769
2770/* Allow only the tested configuration. */2771
2772if (ruid != euid || euid != suid) {2773errno = ENOSYS;2774return -1;2775}2776ouid = getuid();2777
2778if ((ret = setreuid(euid, euid)) == -1)2779return -1;2780
2781/*2782* When real, effective and saved uids are the same and we have
2783* changed uids, sanity check that we cannot restore the old uid.
2784*/
2785
2786if (ruid == euid && euid == suid && ouid != ruid &&2787setuid(ouid) != -1 && seteuid(ouid) != -1) {2788errno = EINVAL;2789return -1;2790}2791
2792/*2793* Finally, check that the real and effective uids are what we
2794* expect.
2795*/
2796if (getuid() != ruid || geteuid() != euid) {2797errno = EACCES;2798return -1;2799}2800
2801return ret;2802}
2803#endif /* !HAVE_SETRESUID */2804#if !HAVE_SHA22805/* $OpenBSD$ */
2806
2807/*
2808* FILE: sha2.c
2809* AUTHOR: Aaron D. Gifford <me@aarongifford.com>
2810*
2811* Copyright (c) 2000-2001, Aaron D. Gifford
2812* All rights reserved.
2813*
2814* Redistribution and use in source and binary forms, with or without
2815* modification, are permitted provided that the following conditions
2816* are met:
2817* 1. Redistributions of source code must retain the above copyright
2818* notice, this list of conditions and the following disclaimer.
2819* 2. Redistributions in binary form must reproduce the above copyright
2820* notice, this list of conditions and the following disclaimer in the
2821* documentation and/or other materials provided with the distribution.
2822* 3. Neither the name of the copyright holder nor the names of contributors
2823* may be used to endorse or promote products derived from this software
2824* without specific prior written permission.
2825*
2826* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTOR(S) ``AS IS'' AND
2827* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2828* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2829* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTOR(S) BE LIABLE
2830* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2831* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2832* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2833* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2834* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2835* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2836* SUCH DAMAGE.
2837*
2838* $From: sha2.c,v 1.1 2001/11/08 00:01:51 adg Exp adg $
2839*/
2840
2841/* OPENBSD ORIGINAL: lib/libc/hash/sha2.c */
2842
2843/* no-op out, similar to DEF_WEAK but only needed here */
2844#define MAKE_CLONE(x, y) void __ssh_compat_make_clone_##x_##y(void)2845
2846#include <sys/types.h>2847#include <sys/stat.h>2848
2849#include <errno.h>2850#include <fcntl.h>2851#include <stdlib.h>2852#include <stdio.h>2853#include <string.h>2854#include <unistd.h>2855
2856#ifndef MINIMUM2857# define MINIMUM(a, b) (((a) < (b)) ? (a) : (b))2858#endif2859
2860#ifndef BYTE_ORDER2861# if defined(LITTLE_ENDIAN) || defined(BIG_ENDIAN)2862# error Confusion in endian macros.2863# endif2864# if !defined(__BYTE_ORDER__)2865# error Byte order macro not found.2866# endif2867# if !defined(__ORDER_LITTLE_ENDIAN__) || !defined(__ORDER_BIG_ENDIAN__)2868# error Little/big endian macros not found.2869# endif2870# define BYTE_ORDER __BYTE_ORDER__2871# define LITTLE_ENDIAN __ORDER_LITTLE_ENDIAN__2872# define BIG_ENDIAN __ORDER_BIG_ENDIAN__2873#endif /*!BYTE_ORDER*/2874
2875/*
2876* UNROLLED TRANSFORM LOOP NOTE:
2877* You can define SHA2_UNROLL_TRANSFORM to use the unrolled transform
2878* loop version for the hash transform rounds (defined using macros
2879* later in this file). Either define on the command line, for example:
2880*
2881* cc -DSHA2_UNROLL_TRANSFORM -o sha2 sha2.c sha2prog.c
2882*
2883* or define below:
2884*
2885* #define SHA2_UNROLL_TRANSFORM
2886*
2887*/
2888#if defined(__amd64__) || defined(__i386__)2889#define SHA2_UNROLL_TRANSFORM2890#endif2891
2892/*** SHA-224/256/384/512 Machine Architecture Definitions *****************/
2893/*
2894* BYTE_ORDER NOTE:
2895*
2896* Please make sure that your system defines BYTE_ORDER. If your
2897* architecture is little-endian, make sure it also defines
2898* LITTLE_ENDIAN and that the two (BYTE_ORDER and LITTLE_ENDIAN) are
2899* equivalent.
2900*
2901* If your system does not define the above, then you can do so by
2902* hand like this:
2903*
2904* #define LITTLE_ENDIAN 1234
2905* #define BIG_ENDIAN 4321
2906*
2907* And for little-endian machines, add:
2908*
2909* #define BYTE_ORDER LITTLE_ENDIAN
2910*
2911* Or for big-endian machines:
2912*
2913* #define BYTE_ORDER BIG_ENDIAN
2914*
2915* The FreeBSD machine this was written on defines BYTE_ORDER
2916* appropriately by including <sys/types.h> (which in turn includes
2917* <machine/endian.h> where the appropriate definitions are actually
2918* made).
2919*/
2920#if !defined(BYTE_ORDER) || (BYTE_ORDER != LITTLE_ENDIAN && BYTE_ORDER != BIG_ENDIAN)2921#error Define BYTE_ORDER to be equal to either LITTLE_ENDIAN or BIG_ENDIAN2922#endif2923
2924
2925/*** SHA-224/256/384/512 Various Length Definitions ***********************/
2926/* NOTE: Most of these are in sha2.h */
2927#define SHA224_SHORT_BLOCK_LENGTH (SHA224_BLOCK_LENGTH - 8)2928#define SHA256_SHORT_BLOCK_LENGTH (SHA256_BLOCK_LENGTH - 8)2929#define SHA384_SHORT_BLOCK_LENGTH (SHA384_BLOCK_LENGTH - 16)2930#define SHA512_SHORT_BLOCK_LENGTH (SHA512_BLOCK_LENGTH - 16)2931
2932/*** ENDIAN SPECIFIC COPY MACROS **************************************/
2933#define BE_8_TO_32(dst, cp) do { \2934(dst) = (uint32_t)(cp)[3] | ((uint32_t)(cp)[2] << 8) | \2935((uint32_t)(cp)[1] << 16) | ((uint32_t)(cp)[0] << 24); \2936} while(0)2937
2938#define BE_8_TO_64(dst, cp) do { \2939(dst) = (uint64_t)(cp)[7] | ((uint64_t)(cp)[6] << 8) | \2940((uint64_t)(cp)[5] << 16) | ((uint64_t)(cp)[4] << 24) | \2941((uint64_t)(cp)[3] << 32) | ((uint64_t)(cp)[2] << 40) | \2942((uint64_t)(cp)[1] << 48) | ((uint64_t)(cp)[0] << 56); \2943} while (0)2944
2945#define BE_64_TO_8(cp, src) do { \2946(cp)[0] = (src) >> 56; \2947(cp)[1] = (src) >> 48; \2948(cp)[2] = (src) >> 40; \2949(cp)[3] = (src) >> 32; \2950(cp)[4] = (src) >> 24; \2951(cp)[5] = (src) >> 16; \2952(cp)[6] = (src) >> 8; \2953(cp)[7] = (src); \2954} while (0)2955
2956#define BE_32_TO_8(cp, src) do { \2957(cp)[0] = (src) >> 24; \2958(cp)[1] = (src) >> 16; \2959(cp)[2] = (src) >> 8; \2960(cp)[3] = (src); \2961} while (0)2962
2963/*
2964* Macro for incrementally adding the unsigned 64-bit integer n to the
2965* unsigned 128-bit integer (represented using a two-element array of
2966* 64-bit words):
2967*/
2968#define ADDINC128(w,n) do { \2969(w)[0] += (uint64_t)(n); \2970if ((w)[0] < (n)) { \2971(w)[1]++; \2972} \2973} while (0)2974
2975/*** THE SIX LOGICAL FUNCTIONS ****************************************/
2976/*
2977* Bit shifting and rotation (used by the six SHA-XYZ logical functions:
2978*
2979* NOTE: The naming of R and S appears backwards here (R is a SHIFT and
2980* S is a ROTATION) because the SHA-224/256/384/512 description document
2981* (see http://csrc.nist.gov/cryptval/shs/sha256-384-512.pdf) uses this
2982* same "backwards" definition.
2983*/
2984/* Shift-right (used in SHA-224, SHA-256, SHA-384, and SHA-512): */
2985#define R(b,x) ((x) >> (b))2986/* 32-bit Rotate-right (used in SHA-224 and SHA-256): */
2987#define S32(b,x) (((x) >> (b)) | ((x) << (32 - (b))))2988/* 64-bit Rotate-right (used in SHA-384 and SHA-512): */
2989#define S64(b,x) (((x) >> (b)) | ((x) << (64 - (b))))2990
2991/* Two of six logical functions used in SHA-224, SHA-256, SHA-384, and SHA-512: */
2992#define Ch(x,y,z) (((x) & (y)) ^ ((~(x)) & (z)))2993#define Maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))2994
2995/* Four of six logical functions used in SHA-224 and SHA-256: */
2996#define Sigma0_256(x) (S32(2, (x)) ^ S32(13, (x)) ^ S32(22, (x)))2997#define Sigma1_256(x) (S32(6, (x)) ^ S32(11, (x)) ^ S32(25, (x)))2998#define sigma0_256(x) (S32(7, (x)) ^ S32(18, (x)) ^ R(3 , (x)))2999#define sigma1_256(x) (S32(17, (x)) ^ S32(19, (x)) ^ R(10, (x)))3000
3001/* Four of six logical functions used in SHA-384 and SHA-512: */
3002#define Sigma0_512(x) (S64(28, (x)) ^ S64(34, (x)) ^ S64(39, (x)))3003#define Sigma1_512(x) (S64(14, (x)) ^ S64(18, (x)) ^ S64(41, (x)))3004#define sigma0_512(x) (S64( 1, (x)) ^ S64( 8, (x)) ^ R( 7, (x)))3005#define sigma1_512(x) (S64(19, (x)) ^ S64(61, (x)) ^ R( 6, (x)))3006
3007
3008/*** SHA-XYZ INITIAL HASH VALUES AND CONSTANTS ************************/
3009/* Hash constant words K for SHA-224 and SHA-256: */
3010static const uint32_t K256[64] = {30110x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL,30120x3956c25bUL, 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL,30130xd807aa98UL, 0x12835b01UL, 0x243185beUL, 0x550c7dc3UL,30140x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, 0xc19bf174UL,30150xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL,30160x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL,30170x983e5152UL, 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL,30180xc6e00bf3UL, 0xd5a79147UL, 0x06ca6351UL, 0x14292967UL,30190x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, 0x53380d13UL,30200x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL,30210xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL,30220xd192e819UL, 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL,30230x19a4c116UL, 0x1e376c08UL, 0x2748774cUL, 0x34b0bcb5UL,30240x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, 0x682e6ff3UL,30250x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL,30260x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL3027};3028
3029/* Initial hash value H for SHA-256: */
3030static const uint32_t sha256_initial_hash_value[8] = {30310x6a09e667UL,30320xbb67ae85UL,30330x3c6ef372UL,30340xa54ff53aUL,30350x510e527fUL,30360x9b05688cUL,30370x1f83d9abUL,30380x5be0cd19UL3039};3040
3041/* Hash constant words K for SHA-384 and SHA-512: */
3042static const uint64_t K512[80] = {30430x428a2f98d728ae22ULL, 0x7137449123ef65cdULL,30440xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL,30450x3956c25bf348b538ULL, 0x59f111f1b605d019ULL,30460x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL,30470xd807aa98a3030242ULL, 0x12835b0145706fbeULL,30480x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL,30490x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL,30500x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL,30510xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL,30520x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL,30530x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL,30540x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL,30550x983e5152ee66dfabULL, 0xa831c66d2db43210ULL,30560xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL,30570xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL,30580x06ca6351e003826fULL, 0x142929670a0e6e70ULL,30590x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL,30600x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL,30610x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL,30620x81c2c92e47edaee6ULL, 0x92722c851482353bULL,30630xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL,30640xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL,30650xd192e819d6ef5218ULL, 0xd69906245565a910ULL,30660xf40e35855771202aULL, 0x106aa07032bbd1b8ULL,30670x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL,30680x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL,30690x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL,30700x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL,30710x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL,30720x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL,30730x90befffa23631e28ULL, 0xa4506cebde82bde9ULL,30740xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL,30750xca273eceea26619cULL, 0xd186b8c721c0c207ULL,30760xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL,30770x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL,30780x113f9804bef90daeULL, 0x1b710b35131c471bULL,30790x28db77f523047d84ULL, 0x32caab7b40c72493ULL,30800x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL,30810x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL,30820x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL3083};3084
3085/* Initial hash value H for SHA-512 */
3086static const uint64_t sha512_initial_hash_value[8] = {30870x6a09e667f3bcc908ULL,30880xbb67ae8584caa73bULL,30890x3c6ef372fe94f82bULL,30900xa54ff53a5f1d36f1ULL,30910x510e527fade682d1ULL,30920x9b05688c2b3e6c1fULL,30930x1f83d9abfb41bd6bULL,30940x5be0cd19137e2179ULL3095};3096
3097/* Initial hash value H for SHA-384 */
3098static const uint64_t sha384_initial_hash_value[8] = {30990xcbbb9d5dc1059ed8ULL,31000x629a292a367cd507ULL,31010x9159015a3070dd17ULL,31020x152fecd8f70e5939ULL,31030x67332667ffc00b31ULL,31040x8eb44a8768581511ULL,31050xdb0c2e0d64f98fa7ULL,31060x47b5481dbefa4fa4ULL3107};3108
3109/*** SHA-256: *********************************************************/
3110void
3111SHA256Init(SHA2_CTX *context)3112{
3113memcpy(context->state.st32, sha256_initial_hash_value,3114sizeof(sha256_initial_hash_value));3115memset(context->buffer, 0, sizeof(context->buffer));3116context->bitcount[0] = 0;3117}
3118
3119#ifdef SHA2_UNROLL_TRANSFORM3120
3121/* Unrolled SHA-256 round macros: */
3122
3123#define ROUND256_0_TO_15(a,b,c,d,e,f,g,h) do { \3124BE_8_TO_32(W256[j], data); \3125data += 4; \3126T1 = (h) + Sigma1_256((e)) + Ch((e), (f), (g)) + K256[j] + W256[j]; \3127(d) += T1; \3128(h) = T1 + Sigma0_256((a)) + Maj((a), (b), (c)); \3129j++; \3130} while(0)3131
3132#define ROUND256(a,b,c,d,e,f,g,h) do { \3133s0 = W256[(j+1)&0x0f]; \3134s0 = sigma0_256(s0); \3135s1 = W256[(j+14)&0x0f]; \3136s1 = sigma1_256(s1); \3137T1 = (h) + Sigma1_256((e)) + Ch((e), (f), (g)) + K256[j] + \3138(W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0); \3139(d) += T1; \3140(h) = T1 + Sigma0_256((a)) + Maj((a), (b), (c)); \3141j++; \3142} while(0)3143
3144void
3145SHA256Transform(uint32_t state[8], const uint8_t data[SHA256_BLOCK_LENGTH])3146{
3147uint32_t a, b, c, d, e, f, g, h, s0, s1;3148uint32_t T1, W256[16];3149int j;3150
3151/* Initialize registers with the prev. intermediate value */3152a = state[0];3153b = state[1];3154c = state[2];3155d = state[3];3156e = state[4];3157f = state[5];3158g = state[6];3159h = state[7];3160
3161j = 0;3162do {3163/* Rounds 0 to 15 (unrolled): */3164ROUND256_0_TO_15(a,b,c,d,e,f,g,h);3165ROUND256_0_TO_15(h,a,b,c,d,e,f,g);3166ROUND256_0_TO_15(g,h,a,b,c,d,e,f);3167ROUND256_0_TO_15(f,g,h,a,b,c,d,e);3168ROUND256_0_TO_15(e,f,g,h,a,b,c,d);3169ROUND256_0_TO_15(d,e,f,g,h,a,b,c);3170ROUND256_0_TO_15(c,d,e,f,g,h,a,b);3171ROUND256_0_TO_15(b,c,d,e,f,g,h,a);3172} while (j < 16);3173
3174/* Now for the remaining rounds up to 63: */3175do {3176ROUND256(a,b,c,d,e,f,g,h);3177ROUND256(h,a,b,c,d,e,f,g);3178ROUND256(g,h,a,b,c,d,e,f);3179ROUND256(f,g,h,a,b,c,d,e);3180ROUND256(e,f,g,h,a,b,c,d);3181ROUND256(d,e,f,g,h,a,b,c);3182ROUND256(c,d,e,f,g,h,a,b);3183ROUND256(b,c,d,e,f,g,h,a);3184} while (j < 64);3185
3186/* Compute the current intermediate hash value */3187state[0] += a;3188state[1] += b;3189state[2] += c;3190state[3] += d;3191state[4] += e;3192state[5] += f;3193state[6] += g;3194state[7] += h;3195
3196/* Clean up */3197a = b = c = d = e = f = g = h = T1 = 0;3198}
3199
3200#else /* SHA2_UNROLL_TRANSFORM */3201
3202void
3203SHA256Transform(uint32_t state[8], const uint8_t data[SHA256_BLOCK_LENGTH])3204{
3205uint32_t a, b, c, d, e, f, g, h, s0, s1;3206uint32_t T1, T2, W256[16];3207int j;3208
3209/* Initialize registers with the prev. intermediate value */3210a = state[0];3211b = state[1];3212c = state[2];3213d = state[3];3214e = state[4];3215f = state[5];3216g = state[6];3217h = state[7];3218
3219j = 0;3220do {3221BE_8_TO_32(W256[j], data);3222data += 4;3223/* Apply the SHA-256 compression function to update a..h */3224T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + W256[j];3225T2 = Sigma0_256(a) + Maj(a, b, c);3226h = g;3227g = f;3228f = e;3229e = d + T1;3230d = c;3231c = b;3232b = a;3233a = T1 + T2;3234
3235j++;3236} while (j < 16);3237
3238do {3239/* Part of the message block expansion: */3240s0 = W256[(j+1)&0x0f];3241s0 = sigma0_256(s0);3242s1 = W256[(j+14)&0x0f];3243s1 = sigma1_256(s1);3244
3245/* Apply the SHA-256 compression function to update a..h */3246T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] +3247(W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0);3248T2 = Sigma0_256(a) + Maj(a, b, c);3249h = g;3250g = f;3251f = e;3252e = d + T1;3253d = c;3254c = b;3255b = a;3256a = T1 + T2;3257
3258j++;3259} while (j < 64);3260
3261/* Compute the current intermediate hash value */3262state[0] += a;3263state[1] += b;3264state[2] += c;3265state[3] += d;3266state[4] += e;3267state[5] += f;3268state[6] += g;3269state[7] += h;3270
3271/* Clean up */3272a = b = c = d = e = f = g = h = T1 = T2 = 0;3273}
3274
3275#endif /* SHA2_UNROLL_TRANSFORM */3276
3277void
3278SHA256Update(SHA2_CTX *context, const uint8_t *data, size_t len)3279{
3280uint64_t freespace, usedspace;3281
3282/* Calling with no data is valid (we do nothing) */3283if (len == 0)3284return;3285
3286usedspace = (context->bitcount[0] >> 3) % SHA256_BLOCK_LENGTH;3287if (usedspace > 0) {3288/* Calculate how much free space is available in the buffer */3289freespace = SHA256_BLOCK_LENGTH - usedspace;3290
3291if (len >= freespace) {3292/* Fill the buffer completely and process it */3293memcpy(&context->buffer[usedspace], data, freespace);3294context->bitcount[0] += freespace << 3;3295len -= freespace;3296data += freespace;3297SHA256Transform(context->state.st32, context->buffer);3298} else {3299/* The buffer is not yet full */3300memcpy(&context->buffer[usedspace], data, len);3301context->bitcount[0] += (uint64_t)len << 3;3302/* Clean up: */3303usedspace = freespace = 0;3304return;3305}3306}3307while (len >= SHA256_BLOCK_LENGTH) {3308/* Process as many complete blocks as we can */3309SHA256Transform(context->state.st32, data);3310context->bitcount[0] += SHA256_BLOCK_LENGTH << 3;3311len -= SHA256_BLOCK_LENGTH;3312data += SHA256_BLOCK_LENGTH;3313}3314if (len > 0) {3315/* There's left-overs, so save 'em */3316memcpy(context->buffer, data, len);3317context->bitcount[0] += len << 3;3318}3319/* Clean up: */3320usedspace = freespace = 0;3321}
3322
3323void
3324SHA256Pad(SHA2_CTX *context)3325{
3326unsigned int usedspace;3327
3328usedspace = (context->bitcount[0] >> 3) % SHA256_BLOCK_LENGTH;3329if (usedspace > 0) {3330/* Begin padding with a 1 bit: */3331context->buffer[usedspace++] = 0x80;3332
3333if (usedspace <= SHA256_SHORT_BLOCK_LENGTH) {3334/* Set-up for the last transform: */3335memset(&context->buffer[usedspace], 0,3336SHA256_SHORT_BLOCK_LENGTH - usedspace);3337} else {3338if (usedspace < SHA256_BLOCK_LENGTH) {3339memset(&context->buffer[usedspace], 0,3340SHA256_BLOCK_LENGTH - usedspace);3341}3342/* Do second-to-last transform: */3343SHA256Transform(context->state.st32, context->buffer);3344
3345/* Prepare for last transform: */3346memset(context->buffer, 0, SHA256_SHORT_BLOCK_LENGTH);3347}3348} else {3349/* Set-up for the last transform: */3350memset(context->buffer, 0, SHA256_SHORT_BLOCK_LENGTH);3351
3352/* Begin padding with a 1 bit: */3353*context->buffer = 0x80;3354}3355/* Store the length of input data (in bits) in big endian format: */3356BE_64_TO_8(&context->buffer[SHA256_SHORT_BLOCK_LENGTH],3357context->bitcount[0]);3358
3359/* Final transform: */3360SHA256Transform(context->state.st32, context->buffer);3361
3362/* Clean up: */3363usedspace = 0;3364}
3365
3366void
3367SHA256Final(uint8_t digest[SHA256_DIGEST_LENGTH], SHA2_CTX *context)3368{
3369SHA256Pad(context);3370
3371#if BYTE_ORDER == LITTLE_ENDIAN3372int i;3373
3374/* Convert TO host byte order */3375for (i = 0; i < 8; i++)3376BE_32_TO_8(digest + i * 4, context->state.st32[i]);3377#else3378memcpy(digest, context->state.st32, SHA256_DIGEST_LENGTH);3379#endif3380explicit_bzero(context, sizeof(*context));3381}
3382
3383
3384/*** SHA-512: *********************************************************/
3385void
3386SHA512Init(SHA2_CTX *context)3387{
3388memcpy(context->state.st64, sha512_initial_hash_value,3389sizeof(sha512_initial_hash_value));3390memset(context->buffer, 0, sizeof(context->buffer));3391context->bitcount[0] = context->bitcount[1] = 0;3392}
3393
3394#ifdef SHA2_UNROLL_TRANSFORM3395
3396/* Unrolled SHA-512 round macros: */
3397
3398#define ROUND512_0_TO_15(a,b,c,d,e,f,g,h) do { \3399BE_8_TO_64(W512[j], data); \3400data += 8; \3401T1 = (h) + Sigma1_512((e)) + Ch((e), (f), (g)) + K512[j] + W512[j]; \3402(d) += T1; \3403(h) = T1 + Sigma0_512((a)) + Maj((a), (b), (c)); \3404j++; \3405} while(0)3406
3407
3408#define ROUND512(a,b,c,d,e,f,g,h) do { \3409s0 = W512[(j+1)&0x0f]; \3410s0 = sigma0_512(s0); \3411s1 = W512[(j+14)&0x0f]; \3412s1 = sigma1_512(s1); \3413T1 = (h) + Sigma1_512((e)) + Ch((e), (f), (g)) + K512[j] + \3414(W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0); \3415(d) += T1; \3416(h) = T1 + Sigma0_512((a)) + Maj((a), (b), (c)); \3417j++; \3418} while(0)3419
3420void
3421SHA512Transform(uint64_t state[8], const uint8_t data[SHA512_BLOCK_LENGTH])3422{
3423uint64_t a, b, c, d, e, f, g, h, s0, s1;3424uint64_t T1, W512[16];3425int j;3426
3427/* Initialize registers with the prev. intermediate value */3428a = state[0];3429b = state[1];3430c = state[2];3431d = state[3];3432e = state[4];3433f = state[5];3434g = state[6];3435h = state[7];3436
3437j = 0;3438do {3439/* Rounds 0 to 15 (unrolled): */3440ROUND512_0_TO_15(a,b,c,d,e,f,g,h);3441ROUND512_0_TO_15(h,a,b,c,d,e,f,g);3442ROUND512_0_TO_15(g,h,a,b,c,d,e,f);3443ROUND512_0_TO_15(f,g,h,a,b,c,d,e);3444ROUND512_0_TO_15(e,f,g,h,a,b,c,d);3445ROUND512_0_TO_15(d,e,f,g,h,a,b,c);3446ROUND512_0_TO_15(c,d,e,f,g,h,a,b);3447ROUND512_0_TO_15(b,c,d,e,f,g,h,a);3448} while (j < 16);3449
3450/* Now for the remaining rounds up to 79: */3451do {3452ROUND512(a,b,c,d,e,f,g,h);3453ROUND512(h,a,b,c,d,e,f,g);3454ROUND512(g,h,a,b,c,d,e,f);3455ROUND512(f,g,h,a,b,c,d,e);3456ROUND512(e,f,g,h,a,b,c,d);3457ROUND512(d,e,f,g,h,a,b,c);3458ROUND512(c,d,e,f,g,h,a,b);3459ROUND512(b,c,d,e,f,g,h,a);3460} while (j < 80);3461
3462/* Compute the current intermediate hash value */3463state[0] += a;3464state[1] += b;3465state[2] += c;3466state[3] += d;3467state[4] += e;3468state[5] += f;3469state[6] += g;3470state[7] += h;3471
3472/* Clean up */3473a = b = c = d = e = f = g = h = T1 = 0;3474}
3475
3476#else /* SHA2_UNROLL_TRANSFORM */3477
3478void
3479SHA512Transform(uint64_t state[8], const uint8_t data[SHA512_BLOCK_LENGTH])3480{
3481uint64_t a, b, c, d, e, f, g, h, s0, s1;3482uint64_t T1, T2, W512[16];3483int j;3484
3485/* Initialize registers with the prev. intermediate value */3486a = state[0];3487b = state[1];3488c = state[2];3489d = state[3];3490e = state[4];3491f = state[5];3492g = state[6];3493h = state[7];3494
3495j = 0;3496do {3497BE_8_TO_64(W512[j], data);3498data += 8;3499/* Apply the SHA-512 compression function to update a..h */3500T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + W512[j];3501T2 = Sigma0_512(a) + Maj(a, b, c);3502h = g;3503g = f;3504f = e;3505e = d + T1;3506d = c;3507c = b;3508b = a;3509a = T1 + T2;3510
3511j++;3512} while (j < 16);3513
3514do {3515/* Part of the message block expansion: */3516s0 = W512[(j+1)&0x0f];3517s0 = sigma0_512(s0);3518s1 = W512[(j+14)&0x0f];3519s1 = sigma1_512(s1);3520
3521/* Apply the SHA-512 compression function to update a..h */3522T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] +3523(W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0);3524T2 = Sigma0_512(a) + Maj(a, b, c);3525h = g;3526g = f;3527f = e;3528e = d + T1;3529d = c;3530c = b;3531b = a;3532a = T1 + T2;3533
3534j++;3535} while (j < 80);3536
3537/* Compute the current intermediate hash value */3538state[0] += a;3539state[1] += b;3540state[2] += c;3541state[3] += d;3542state[4] += e;3543state[5] += f;3544state[6] += g;3545state[7] += h;3546
3547/* Clean up */3548a = b = c = d = e = f = g = h = T1 = T2 = 0;3549}
3550
3551#endif /* SHA2_UNROLL_TRANSFORM */3552
3553void
3554SHA512Update(SHA2_CTX *context, const uint8_t *data, size_t len)3555{
3556size_t freespace, usedspace;3557
3558/* Calling with no data is valid (we do nothing) */3559if (len == 0)3560return;3561
3562usedspace = (context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH;3563if (usedspace > 0) {3564/* Calculate how much free space is available in the buffer */3565freespace = SHA512_BLOCK_LENGTH - usedspace;3566
3567if (len >= freespace) {3568/* Fill the buffer completely and process it */3569memcpy(&context->buffer[usedspace], data, freespace);3570ADDINC128(context->bitcount, freespace << 3);3571len -= freespace;3572data += freespace;3573SHA512Transform(context->state.st64, context->buffer);3574} else {3575/* The buffer is not yet full */3576memcpy(&context->buffer[usedspace], data, len);3577ADDINC128(context->bitcount, len << 3);3578/* Clean up: */3579usedspace = freespace = 0;3580return;3581}3582}3583while (len >= SHA512_BLOCK_LENGTH) {3584/* Process as many complete blocks as we can */3585SHA512Transform(context->state.st64, data);3586ADDINC128(context->bitcount, SHA512_BLOCK_LENGTH << 3);3587len -= SHA512_BLOCK_LENGTH;3588data += SHA512_BLOCK_LENGTH;3589}3590if (len > 0) {3591/* There's left-overs, so save 'em */3592memcpy(context->buffer, data, len);3593ADDINC128(context->bitcount, len << 3);3594}3595/* Clean up: */3596usedspace = freespace = 0;3597}
3598
3599void
3600SHA512Pad(SHA2_CTX *context)3601{
3602unsigned int usedspace;3603
3604usedspace = (context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH;3605if (usedspace > 0) {3606/* Begin padding with a 1 bit: */3607context->buffer[usedspace++] = 0x80;3608
3609if (usedspace <= SHA512_SHORT_BLOCK_LENGTH) {3610/* Set-up for the last transform: */3611memset(&context->buffer[usedspace], 0, SHA512_SHORT_BLOCK_LENGTH - usedspace);3612} else {3613if (usedspace < SHA512_BLOCK_LENGTH) {3614memset(&context->buffer[usedspace], 0, SHA512_BLOCK_LENGTH - usedspace);3615}3616/* Do second-to-last transform: */3617SHA512Transform(context->state.st64, context->buffer);3618
3619/* And set-up for the last transform: */3620memset(context->buffer, 0, SHA512_BLOCK_LENGTH - 2);3621}3622} else {3623/* Prepare for final transform: */3624memset(context->buffer, 0, SHA512_SHORT_BLOCK_LENGTH);3625
3626/* Begin padding with a 1 bit: */3627*context->buffer = 0x80;3628}3629/* Store the length of input data (in bits) in big endian format: */3630BE_64_TO_8(&context->buffer[SHA512_SHORT_BLOCK_LENGTH],3631context->bitcount[1]);3632BE_64_TO_8(&context->buffer[SHA512_SHORT_BLOCK_LENGTH + 8],3633context->bitcount[0]);3634
3635/* Final transform: */3636SHA512Transform(context->state.st64, context->buffer);3637
3638/* Clean up: */3639usedspace = 0;3640}
3641
3642void
3643SHA512Final(uint8_t digest[SHA512_DIGEST_LENGTH], SHA2_CTX *context)3644{
3645SHA512Pad(context);3646
3647#if BYTE_ORDER == LITTLE_ENDIAN3648int i;3649
3650/* Convert TO host byte order */3651for (i = 0; i < 8; i++)3652BE_64_TO_8(digest + i * 8, context->state.st64[i]);3653#else3654memcpy(digest, context->state.st64, SHA512_DIGEST_LENGTH);3655#endif3656explicit_bzero(context, sizeof(*context));3657}
3658
3659/*** SHA-384: *********************************************************/
3660void
3661SHA384Init(SHA2_CTX *context)3662{
3663memcpy(context->state.st64, sha384_initial_hash_value,3664sizeof(sha384_initial_hash_value));3665memset(context->buffer, 0, sizeof(context->buffer));3666context->bitcount[0] = context->bitcount[1] = 0;3667}
3668
3669MAKE_CLONE(SHA384Transform, SHA512Transform);3670MAKE_CLONE(SHA384Update, SHA512Update);3671MAKE_CLONE(SHA384Pad, SHA512Pad);3672
3673/* Equivalent of MAKE_CLONE (which is a no-op) for SHA384 funcs */
3674void
3675SHA384Transform(uint64_t state[8], const uint8_t data[SHA512_BLOCK_LENGTH])3676{
3677SHA512Transform(state, data);3678}
3679
3680void
3681SHA384Update(SHA2_CTX *context, const uint8_t *data, size_t len)3682{
3683SHA512Update(context, data, len);3684}
3685
3686void
3687SHA384Pad(SHA2_CTX *context)3688{
3689SHA512Pad(context);3690}
3691
3692void
3693SHA384Final(uint8_t digest[SHA384_DIGEST_LENGTH], SHA2_CTX *context)3694{
3695SHA384Pad(context);3696
3697#if BYTE_ORDER == LITTLE_ENDIAN3698int i;3699
3700/* Convert TO host byte order */3701for (i = 0; i < 6; i++)3702BE_64_TO_8(digest + i * 8, context->state.st64[i]);3703#else3704memcpy(digest, context->state.st64, SHA384_DIGEST_LENGTH);3705#endif3706/* Zero out state data */3707explicit_bzero(context, sizeof(*context));3708}
3709
3710char *3711SHA256End(SHA2_CTX *ctx, char *buf)3712{
3713int i;3714uint8_t digest[SHA256_DIGEST_LENGTH];3715static const char hex[] = "0123456789abcdef";3716
3717if (buf == NULL && (buf = malloc(SHA256_DIGEST_STRING_LENGTH)) == NULL)3718return (NULL);3719
3720SHA256Final(digest, ctx);3721for (i = 0; i < SHA256_DIGEST_LENGTH; i++) {3722buf[i + i] = hex[digest[i] >> 4];3723buf[i + i + 1] = hex[digest[i] & 0x0f];3724}3725buf[i + i] = '\0';3726explicit_bzero(digest, sizeof(digest));3727return (buf);3728}
3729
3730char *3731SHA384End(SHA2_CTX *ctx, char *buf)3732{
3733int i;3734uint8_t digest[SHA384_DIGEST_LENGTH];3735static const char hex[] = "0123456789abcdef";3736
3737if (buf == NULL && (buf = malloc(SHA384_DIGEST_STRING_LENGTH)) == NULL)3738return (NULL);3739
3740SHA384Final(digest, ctx);3741for (i = 0; i < SHA384_DIGEST_LENGTH; i++) {3742buf[i + i] = hex[digest[i] >> 4];3743buf[i + i + 1] = hex[digest[i] & 0x0f];3744}3745buf[i + i] = '\0';3746explicit_bzero(digest, sizeof(digest));3747return (buf);3748}
3749
3750char *3751SHA512End(SHA2_CTX *ctx, char *buf)3752{
3753int i;3754uint8_t digest[SHA512_DIGEST_LENGTH];3755static const char hex[] = "0123456789abcdef";3756
3757if (buf == NULL && (buf = malloc(SHA512_DIGEST_STRING_LENGTH)) == NULL)3758return (NULL);3759
3760SHA512Final(digest, ctx);3761for (i = 0; i < SHA512_DIGEST_LENGTH; i++) {3762buf[i + i] = hex[digest[i] >> 4];3763buf[i + i + 1] = hex[digest[i] & 0x0f];3764}3765buf[i + i] = '\0';3766explicit_bzero(digest, sizeof(digest));3767return (buf);3768}
3769
3770char *3771SHA256FileChunk(const char *filename, char *buf, off_t off, off_t len)3772{
3773struct stat sb;3774u_char buffer[BUFSIZ];3775SHA2_CTX ctx;3776int fd, save_errno;3777ssize_t nr;3778
3779SHA256Init(&ctx);3780
3781if ((fd = open(filename, O_RDONLY)) == -1)3782return (NULL);3783if (len == 0) {3784if (fstat(fd, &sb) == -1) {3785save_errno = errno;3786close(fd);3787errno = save_errno;3788return (NULL);3789}3790len = sb.st_size;3791}3792if (off > 0 && lseek(fd, off, SEEK_SET) == -1) {3793save_errno = errno;3794close(fd);3795errno = save_errno;3796return (NULL);3797}3798
3799while ((nr = read(fd, buffer, MINIMUM(sizeof(buffer), (size_t)len))) > 0) {3800SHA256Update(&ctx, buffer, nr);3801if (len > 0 && (len -= nr) == 0)3802break;3803}3804
3805save_errno = errno;3806close(fd);3807errno = save_errno;3808return (nr == -1 ? NULL : SHA256End(&ctx, buf));3809}
3810
3811char *3812SHA256File(const char *filename, char *buf)3813{
3814return (SHA256FileChunk(filename, buf, 0, 0));3815}
3816
3817char *3818SHA384FileChunk(const char *filename, char *buf, off_t off, off_t len)3819{
3820struct stat sb;3821u_char buffer[BUFSIZ];3822SHA2_CTX ctx;3823int fd, save_errno;3824ssize_t nr;3825
3826SHA384Init(&ctx);3827
3828if ((fd = open(filename, O_RDONLY)) == -1)3829return (NULL);3830if (len == 0) {3831if (fstat(fd, &sb) == -1) {3832save_errno = errno;3833close(fd);3834errno = save_errno;3835return (NULL);3836}3837len = sb.st_size;3838}3839if (off > 0 && lseek(fd, off, SEEK_SET) == -1) {3840save_errno = errno;3841close(fd);3842errno = save_errno;3843return (NULL);3844}3845
3846while ((nr = read(fd, buffer, MINIMUM(sizeof(buffer), (size_t)len))) > 0) {3847SHA384Update(&ctx, buffer, nr);3848if (len > 0 && (len -= nr) == 0)3849break;3850}3851
3852save_errno = errno;3853close(fd);3854errno = save_errno;3855return (nr == -1 ? NULL : SHA384End(&ctx, buf));3856}
3857
3858char *3859SHA384File(const char *filename, char *buf)3860{
3861return (SHA384FileChunk(filename, buf, 0, 0));3862}
3863
3864char *3865SHA512FileChunk(const char *filename, char *buf, off_t off, off_t len)3866{
3867struct stat sb;3868u_char buffer[BUFSIZ];3869SHA2_CTX ctx;3870int fd, save_errno;3871ssize_t nr;3872
3873SHA512Init(&ctx);3874
3875if ((fd = open(filename, O_RDONLY)) == -1)3876return (NULL);3877if (len == 0) {3878if (fstat(fd, &sb) == -1) {3879save_errno = errno;3880close(fd);3881errno = save_errno;3882return (NULL);3883}3884len = sb.st_size;3885}3886if (off > 0 && lseek(fd, off, SEEK_SET) == -1) {3887save_errno = errno;3888close(fd);3889errno = save_errno;3890return (NULL);3891}3892
3893while ((nr = read(fd, buffer, MINIMUM(sizeof(buffer), (size_t)len))) > 0) {3894SHA512Update(&ctx, buffer, nr);3895if (len > 0 && (len -= nr) == 0)3896break;3897}3898
3899save_errno = errno;3900close(fd);3901errno = save_errno;3902return (nr == -1 ? NULL : SHA512End(&ctx, buf));3903}
3904
3905char *3906SHA512File(const char *filename, char *buf)3907{
3908return (SHA512FileChunk(filename, buf, 0, 0));3909}
3910
3911char *3912SHA256Data(const u_char *data, size_t len, char *buf)3913{
3914SHA2_CTX ctx;3915
3916SHA256Init(&ctx);3917SHA256Update(&ctx, data, len);3918return (SHA256End(&ctx, buf));3919}
3920
3921char *3922SHA384Data(const u_char *data, size_t len, char *buf)3923{
3924SHA2_CTX ctx;3925
3926SHA384Init(&ctx);3927SHA384Update(&ctx, data, len);3928return (SHA384End(&ctx, buf));3929}
3930
3931char *3932SHA512Data(const u_char *data, size_t len, char *buf)3933{
3934SHA2_CTX ctx;3935
3936SHA512Init(&ctx);3937SHA512Update(&ctx, data, len);3938return (SHA512End(&ctx, buf));3939}
3940#endif /* !HAVE_SHA2 */3941#if !HAVE_STRLCAT3942/*
3943* Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
3944*
3945* Permission to use, copy, modify, and distribute this software for any
3946* purpose with or without fee is hereby granted, provided that the above
3947* copyright notice and this permission notice appear in all copies.
3948*
3949* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
3950* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
3951* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
3952* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
3953* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
3954* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
3955* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
3956*/
3957
3958#include <sys/types.h>3959#include <string.h>3960
3961/*
3962* Appends src to string dst of size siz (unlike strncat, siz is the
3963* full size of dst, not space left). At most siz-1 characters
3964* will be copied. Always NUL terminates (unless siz <= strlen(dst)).
3965* Returns strlen(src) + MIN(siz, strlen(initial dst)).
3966* If retval >= siz, truncation occurred.
3967*/
3968size_t
3969strlcat(char *dst, const char *src, size_t siz)3970{
3971char *d = dst;3972const char *s = src;3973size_t n = siz;3974size_t dlen;3975
3976/* Find the end of dst and adjust bytes left but don't go past end */3977while (n-- != 0 && *d != '\0')3978d++;3979dlen = d - dst;3980n = siz - dlen;3981
3982if (n == 0)3983return(dlen + strlen(s));3984while (*s != '\0') {3985if (n != 1) {3986*d++ = *s;3987n--;3988}3989s++;3990}3991*d = '\0';3992
3993return(dlen + (s - src)); /* count does not include NUL */3994}
3995#endif /* !HAVE_STRLCAT */3996#if !HAVE_STRLCPY3997/*
3998* Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
3999*
4000* Permission to use, copy, modify, and distribute this software for any
4001* purpose with or without fee is hereby granted, provided that the above
4002* copyright notice and this permission notice appear in all copies.
4003*
4004* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
4005* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
4006* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
4007* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
4008* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
4009* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
4010* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
4011*/
4012
4013#include <sys/types.h>4014#include <string.h>4015
4016/*
4017* Copy src to string dst of size siz. At most siz-1 characters
4018* will be copied. Always NUL terminates (unless siz == 0).
4019* Returns strlen(src); if retval >= siz, truncation occurred.
4020*/
4021size_t
4022strlcpy(char *dst, const char *src, size_t siz)4023{
4024char *d = dst;4025const char *s = src;4026size_t n = siz;4027
4028/* Copy as many bytes as will fit */4029if (n != 0) {4030while (--n != 0) {4031if ((*d++ = *s++) == '\0')4032break;4033}4034}4035
4036/* Not enough room in dst, add NUL and traverse rest of src */4037if (n == 0) {4038if (siz != 0)4039*d = '\0'; /* NUL-terminate dst */4040while (*s++)4041;4042}4043
4044return(s - src - 1); /* count does not include NUL */4045}
4046#endif /* !HAVE_STRLCPY */4047#if !HAVE_STRNDUP4048/* $OpenBSD$ */
4049/*
4050* Copyright (c) 2010 Todd C. Miller <Todd.Miller@courtesan.com>
4051*
4052* Permission to use, copy, modify, and distribute this software for any
4053* purpose with or without fee is hereby granted, provided that the above
4054* copyright notice and this permission notice appear in all copies.
4055*
4056* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
4057* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
4058* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
4059* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
4060* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
4061* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
4062* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
4063*/
4064
4065#include <sys/types.h>4066
4067#include <stddef.h>4068#include <stdlib.h>4069#include <string.h>4070
4071char *4072strndup(const char *str, size_t maxlen)4073{
4074char *copy;4075size_t len;4076
4077len = strnlen(str, maxlen);4078copy = malloc(len + 1);4079if (copy != NULL) {4080(void)memcpy(copy, str, len);4081copy[len] = '\0';4082}4083
4084return copy;4085}
4086#endif /* !HAVE_STRNDUP */4087#if !HAVE_STRNLEN4088/* $OpenBSD$ */
4089
4090/*
4091* Copyright (c) 2010 Todd C. Miller <Todd.Miller@courtesan.com>
4092*
4093* Permission to use, copy, modify, and distribute this software for any
4094* purpose with or without fee is hereby granted, provided that the above
4095* copyright notice and this permission notice appear in all copies.
4096*
4097* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
4098* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
4099* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
4100* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
4101* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
4102* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
4103* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
4104*/
4105
4106#include <sys/types.h>4107#include <string.h>4108
4109size_t
4110strnlen(const char *str, size_t maxlen)4111{
4112const char *cp;4113
4114for (cp = str; maxlen != 0 && *cp != '\0'; cp++, maxlen--)4115;4116
4117return (size_t)(cp - str);4118}
4119#endif /* !HAVE_STRNLEN */4120#if !HAVE_STRTONUM4121/*
4122* Copyright (c) 2004 Ted Unangst and Todd Miller
4123* All rights reserved.
4124*
4125* Permission to use, copy, modify, and distribute this software for any
4126* purpose with or without fee is hereby granted, provided that the above
4127* copyright notice and this permission notice appear in all copies.
4128*
4129* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
4130* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
4131* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
4132* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
4133* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
4134* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
4135* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
4136*/
4137
4138#include <errno.h>4139#include <limits.h>4140#include <stdlib.h>4141
4142#define INVALID 14143#define TOOSMALL 24144#define TOOLARGE 34145
4146long long4147strtonum(const char *numstr, long long minval, long long maxval,4148const char **errstrp)4149{
4150long long ll = 0;4151int error = 0;4152char *ep;4153struct errval {4154const char *errstr;4155int err;4156} ev[4] = {4157{ NULL, 0 },4158{ "invalid", EINVAL },4159{ "too small", ERANGE },4160{ "too large", ERANGE },4161};4162
4163ev[0].err = errno;4164errno = 0;4165if (minval > maxval) {4166error = INVALID;4167} else {4168ll = strtoll(numstr, &ep, 10);4169if (numstr == ep || *ep != '\0')4170error = INVALID;4171else if ((ll == LLONG_MIN && errno == ERANGE) || ll < minval)4172error = TOOSMALL;4173else if ((ll == LLONG_MAX && errno == ERANGE) || ll > maxval)4174error = TOOLARGE;4175}4176if (errstrp != NULL)4177*errstrp = ev[error].errstr;4178errno = ev[error].err;4179if (error)4180ll = 0;4181
4182return (ll);4183}
4184#endif /* !HAVE_STRTONUM */4185