Index: head/lib/libc/gen/__xuname.c =================================================================== --- head/lib/libc/gen/__xuname.c (revision 335897) +++ head/lib/libc/gen/__xuname.c (revision 335898) @@ -1,148 +1,147 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1994 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. + * + * From: @(#)uname.c 8.1 (Berkeley) 1/4/94 */ -#if defined(LIBC_SCCS) && !defined(lint) -/*static char sccsid[] = "From: @(#)uname.c 8.1 (Berkeley) 1/4/94";*/ -#endif /* LIBC_SCCS and not lint */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include int __xuname(int namesize, void *namebuf) { int mib[2], rval; size_t len; char *p, *q; int oerrno; rval = 0; q = (char *)namebuf; mib[0] = CTL_KERN; if ((p = getenv("UNAME_s"))) strlcpy(q, p, namesize); else { mib[1] = KERN_OSTYPE; len = namesize; oerrno = errno; if (sysctl(mib, 2, q, &len, NULL, 0) == -1) { if (errno == ENOMEM) errno = oerrno; else rval = -1; } q[namesize - 1] = '\0'; } q += namesize; mib[1] = KERN_HOSTNAME; len = namesize; oerrno = errno; if (sysctl(mib, 2, q, &len, NULL, 0) == -1) { if (errno == ENOMEM) errno = oerrno; else rval = -1; } q[namesize - 1] = '\0'; q += namesize; if ((p = getenv("UNAME_r"))) strlcpy(q, p, namesize); else { mib[1] = KERN_OSRELEASE; len = namesize; oerrno = errno; if (sysctl(mib, 2, q, &len, NULL, 0) == -1) { if (errno == ENOMEM) errno = oerrno; else rval = -1; } q[namesize - 1] = '\0'; } q += namesize; if ((p = getenv("UNAME_v"))) strlcpy(q, p, namesize); else { /* * The version may have newlines in it, turn them into * spaces. */ mib[1] = KERN_VERSION; len = namesize; oerrno = errno; if (sysctl(mib, 2, q, &len, NULL, 0) == -1) { if (errno == ENOMEM) errno = oerrno; else rval = -1; } q[namesize - 1] = '\0'; for (p = q; len--; ++p) { if (*p == '\n' || *p == '\t') { if (len > 1) *p = ' '; else *p = '\0'; } } } q += namesize; if ((p = getenv("UNAME_m"))) strlcpy(q, p, namesize); else { mib[0] = CTL_HW; mib[1] = HW_MACHINE; len = namesize; oerrno = errno; if (sysctl(mib, 2, q, &len, NULL, 0) == -1) { if (errno == ENOMEM) errno = oerrno; else rval = -1; } q[namesize - 1] = '\0'; } return (rval); } Index: head/lib/libc/gen/alarm.c =================================================================== --- head/lib/libc/gen/alarm.c (revision 335897) +++ head/lib/libc/gen/alarm.c (revision 335898) @@ -1,58 +1,56 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1983, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)alarm.c 8.1 (Berkeley) 6/4/93"; -#endif /* LIBC_SCCS and not lint */ #include +__SCCSID("@(#)alarm.c 8.1 (Berkeley) 6/4/93"); __FBSDID("$FreeBSD$"); /* * Backwards compatible alarm. */ #include #include unsigned int alarm(unsigned int secs) { struct itimerval it, oitv; struct itimerval *itp = ⁢ timerclear(&itp->it_interval); itp->it_value.tv_sec = secs; itp->it_value.tv_usec = 0; if (setitimer(ITIMER_REAL, itp, &oitv) < 0) return (-1); if (oitv.it_value.tv_usec) oitv.it_value.tv_sec++; return (oitv.it_value.tv_sec); } Index: head/lib/libc/gen/assert.c =================================================================== --- head/lib/libc/gen/assert.c (revision 335897) +++ head/lib/libc/gen/assert.c (revision 335898) @@ -1,55 +1,53 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1992, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)assert.c 8.1 (Berkeley) 6/4/93"; -#endif /* LIBC_SCCS and not lint */ #include +__SCCSID("@(#)assert.c 8.1 (Berkeley) 6/4/93"); __FBSDID("$FreeBSD$"); #include #include #include void __assert(const char *func, const char *file, int line, const char *failedexpr) { if (func == NULL) (void)fprintf(stderr, "Assertion failed: (%s), file %s, line %d.\n", failedexpr, file, line); else (void)fprintf(stderr, "Assertion failed: (%s), function %s, file %s, line %d.\n", failedexpr, func, file, line); abort(); /* NOTREACHED */ } Index: head/lib/libc/gen/clock.c =================================================================== --- head/lib/libc/gen/clock.c (revision 335897) +++ head/lib/libc/gen/clock.c (revision 335898) @@ -1,57 +1,55 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1989, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)clock.c 8.1 (Berkeley) 6/4/93"; -#endif /* LIBC_SCCS and not lint */ #include +__SCCSID("@(#)clock.c 8.1 (Berkeley) 6/4/93"); __FBSDID("$FreeBSD$"); #include #include #include /* * Convert usec to clock ticks; could do (usec * CLOCKS_PER_SEC) / 1000000, * but this would overflow if we switch to nanosec. */ #define CONVTCK(r) ((r).tv_sec * CLOCKS_PER_SEC \ + (r).tv_usec / (1000000 / CLOCKS_PER_SEC)) clock_t clock(void) { struct rusage ru; if (getrusage(RUSAGE_SELF, &ru)) return ((clock_t) -1); return((clock_t)((CONVTCK(ru.ru_utime) + CONVTCK(ru.ru_stime)))); } Index: head/lib/libc/gen/closedir.c =================================================================== --- head/lib/libc/gen/closedir.c (revision 335897) +++ head/lib/libc/gen/closedir.c (revision 335898) @@ -1,79 +1,77 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1983, 1993 * Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)closedir.c 8.1 (Berkeley) 6/10/93"; -#endif /* LIBC_SCCS and not lint */ #include +__SCCSID("@(#)closedir.c 8.1 (Berkeley) 6/10/93"); __FBSDID("$FreeBSD$"); #include "namespace.h" #include #include #include #include #include #include "un-namespace.h" #include "libc_private.h" #include "gen-private.h" #include "telldir.h" /* * close a directory. */ int fdclosedir(DIR *dirp) { int fd; if (__isthreaded) _pthread_mutex_lock(&dirp->dd_lock); fd = dirp->dd_fd; dirp->dd_fd = -1; dirp->dd_loc = 0; free((void *)dirp->dd_buf); free(dirp->dd_compat_de); _reclaim_telldir(dirp); if (__isthreaded) { _pthread_mutex_unlock(&dirp->dd_lock); _pthread_mutex_destroy(&dirp->dd_lock); } free((void *)dirp); return (fd); } int closedir(DIR *dirp) { return (_close(fdclosedir(dirp))); } Index: head/lib/libc/gen/confstr.c =================================================================== --- head/lib/libc/gen/confstr.c (revision 335897) +++ head/lib/libc/gen/confstr.c (revision 335898) @@ -1,123 +1,121 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)confstr.c 8.1 (Berkeley) 6/4/93"; -#endif /* LIBC_SCCS and not lint */ #include +__SCCSID("@(#)confstr.c 8.1 (Berkeley) 6/4/93"); __FBSDID("$FreeBSD$"); #include #include #include #include #include #include size_t confstr(int name, char *buf, size_t len) { const char *p; const char UPE[] = "unsupported programming environment"; switch (name) { case _CS_PATH: p = _PATH_STDPATH; goto docopy; /* * POSIX/SUS ``Programming Environments'' stuff * * We don't support more than one programming environment * on any platform (yet), so we just return the empty * string for the environment we are compiled for, * and the string "unsupported programming environment" * for anything else. (The Standard says that if these * values are used on a system which does not support * this environment -- determined via sysconf() -- then * the value we return is unspecified. So, we return * something which will cause obvious breakage.) */ case _CS_POSIX_V6_ILP32_OFF32_CFLAGS: case _CS_POSIX_V6_ILP32_OFF32_LDFLAGS: case _CS_POSIX_V6_ILP32_OFF32_LIBS: case _CS_POSIX_V6_LPBIG_OFFBIG_CFLAGS: case _CS_POSIX_V6_LPBIG_OFFBIG_LDFLAGS: case _CS_POSIX_V6_LPBIG_OFFBIG_LIBS: /* * These two environments are never supported. */ p = UPE; goto docopy; case _CS_POSIX_V6_ILP32_OFFBIG_CFLAGS: case _CS_POSIX_V6_ILP32_OFFBIG_LDFLAGS: case _CS_POSIX_V6_ILP32_OFFBIG_LIBS: if (sizeof(long) * CHAR_BIT == 32 && sizeof(off_t) > sizeof(long)) p = ""; else p = UPE; goto docopy; case _CS_POSIX_V6_LP64_OFF64_CFLAGS: case _CS_POSIX_V6_LP64_OFF64_LDFLAGS: case _CS_POSIX_V6_LP64_OFF64_LIBS: if (sizeof(long) * CHAR_BIT >= 64 && sizeof(void *) * CHAR_BIT >= 64 && sizeof(int) * CHAR_BIT >= 32 && sizeof(off_t) >= sizeof(long)) p = ""; else p = UPE; goto docopy; case _CS_POSIX_V6_WIDTH_RESTRICTED_ENVS: /* XXX - should have more complete coverage */ if (sizeof(long) * CHAR_BIT >= 64) p = "_POSIX_V6_LP64_OFF64"; else p = "_POSIX_V6_ILP32_OFFBIG"; goto docopy; docopy: if (len != 0 && buf != NULL) strlcpy(buf, p, len); return (strlen(p) + 1); default: errno = EINVAL; return (0); } /* NOTREACHED */ } Index: head/lib/libc/gen/crypt.c =================================================================== --- head/lib/libc/gen/crypt.c (revision 335897) +++ head/lib/libc/gen/crypt.c (revision 335898) @@ -1,90 +1,87 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1989 The Regents of the University of California. * All rights reserved. * * This code is derived from software contributed to Berkeley by * Tom Truscott. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ -#if defined(LIBC_SCCS) && !defined(lint) -/* from static char sccsid[] = "@(#)crypt.c 5.11 (Berkeley) 6/25/91"; */ -#endif /* LIBC_SCCS and not lint */ - #include +__SCCSID("@(#)crypt.c 5.11 (Berkeley) 6/25/91"); __FBSDID("$FreeBSD$"); #include #include #include /* * UNIX password, and DES, encryption. * * since this is non-exportable, this is just a dummy. if you want real * encryption, make sure you've got libcrypt.a around. */ /* ARGSUSED */ int __freebsd11_des_setkey(const char *key __unused) { fprintf(stderr, "WARNING! des_setkey(3) not present in the system!\n"); return (0); } /* ARGSUSED */ int __freebsd11_des_cipher(const char *in, char *out, long salt __unused, int num_iter __unused) { fprintf(stderr, "WARNING! des_cipher(3) not present in the system!\n"); bcopy(in, out, 8); return (0); } /* ARGSUSED */ int __freebsd11_setkey(const char *key __unused) { fprintf(stderr, "WARNING! setkey(3) not present in the system!\n"); return (0); } /* ARGSUSED */ int __freebsd11_encrypt(char *block __unused, int flag __unused) { fprintf(stderr, "WARNING! encrypt(3) not present in the system!\n"); return (0); } __sym_compat(des_setkey, __freebsd11_des_setkey, FBSD_1.0); __sym_compat(des_cipher, __freebsd11_des_cipher, FBSD_1.0); __sym_compat(setkey, __freebsd11_setkey, FBSD_1.0); __sym_compat(encrypt, __freebsd11_encrypt, FBSD_1.0); Index: head/lib/libc/gen/daemon.c =================================================================== --- head/lib/libc/gen/daemon.c (revision 335897) +++ head/lib/libc/gen/daemon.c (revision 335898) @@ -1,121 +1,119 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1990, 1993 The Regents of the University of California. * Copyright (c) 2017 Mariusz Zaborski * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)daemon.c 8.1 (Berkeley) 6/4/93"; -#endif /* LIBC_SCCS and not lint */ #include +__SCCSID("@(#)daemon.c 8.1 (Berkeley) 6/4/93"); __FBSDID("$FreeBSD$"); #include "namespace.h" #include #include #include #include #include #include #include "un-namespace.h" #include "libc_private.h" int daemonfd(int chdirfd, int nullfd) { struct sigaction osa, sa; pid_t newgrp; int oerrno; int osa_ok; /* A SIGHUP may be thrown when the parent exits below. */ sigemptyset(&sa.sa_mask); sa.sa_handler = SIG_IGN; sa.sa_flags = 0; osa_ok = __libc_sigaction(SIGHUP, &sa, &osa); switch (fork()) { case -1: return (-1); case 0: break; default: /* * A fine point: _exit(0), not exit(0), to avoid triggering * atexit(3) processing */ _exit(0); } newgrp = setsid(); oerrno = errno; if (osa_ok != -1) __libc_sigaction(SIGHUP, &osa, NULL); if (newgrp == -1) { errno = oerrno; return (-1); } if (chdirfd != -1) (void)fchdir(chdirfd); if (nullfd != -1) { (void)_dup2(nullfd, STDIN_FILENO); (void)_dup2(nullfd, STDOUT_FILENO); (void)_dup2(nullfd, STDERR_FILENO); } return (0); } int daemon(int nochdir, int noclose) { int chdirfd, nullfd, ret; if (!noclose) nullfd = _open(_PATH_DEVNULL, O_RDWR, 0); else nullfd = -1; if (!nochdir) chdirfd = _open("/", O_EXEC); else chdirfd = -1; ret = daemonfd(chdirfd, nullfd); if (chdirfd != -1) _close(chdirfd); if (nullfd > 2) _close(nullfd); return (ret); } Index: head/lib/libc/gen/devname.c =================================================================== --- head/lib/libc/gen/devname.c (revision 335897) +++ head/lib/libc/gen/devname.c (revision 335898) @@ -1,77 +1,75 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1989, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)devname.c 8.2 (Berkeley) 4/29/95"; -#endif /* LIBC_SCCS and not lint */ #include +__SCCSID("@(#)devname.c 8.2 (Berkeley) 4/29/95"); __FBSDID("$FreeBSD$"); #include #include #include #include #include #include #include char * devname_r(dev_t dev, mode_t type, char *buf, int len) { int i; size_t j; if (dev == NODEV || !(S_ISCHR(type) || S_ISBLK(dev))) { strlcpy(buf, "#NODEV", len); return (buf); } if (S_ISCHR(type)) { j = len; i = sysctlbyname("kern.devname", buf, &j, &dev, sizeof (dev)); if (i == 0) return (buf); } /* Finally just format it */ snprintf(buf, len, "#%c:%#jx", S_ISCHR(type) ? 'C' : 'B', (uintmax_t)dev); return (buf); } char * devname(dev_t dev, mode_t type) { static char buf[SPECNAMELEN + 1]; return (devname_r(dev, type, buf, sizeof(buf))); } Index: head/lib/libc/gen/disklabel.c =================================================================== --- head/lib/libc/gen/disklabel.c (revision 335897) +++ head/lib/libc/gen/disklabel.c (revision 335898) @@ -1,168 +1,166 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1983, 1987, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)disklabel.c 8.2 (Berkeley) 5/3/95"; -#endif /* LIBC_SCCS and not lint */ #include +__SCCSID("@(#)disklabel.c 8.2 (Berkeley) 5/3/95"); __FBSDID("$FreeBSD$"); #include #define DKTYPENAMES #define FSTYPENAMES #include #include #include #include #include #include #include static int gettype(char *t, const char **names) { const char **nm; for (nm = names; *nm; nm++) if (strcasecmp(t, *nm) == 0) return (nm - names); if (isdigit((unsigned char)*t)) return (atoi(t)); return (0); } struct disklabel * getdiskbyname(const char *name) { static struct disklabel disk; struct disklabel *dp = &disk; struct partition *pp; char *buf; char *db_array[2] = { _PATH_DISKTAB, 0 }; char *cp, *cq; /* can't be register */ char p, max, psize[3], pbsize[3], pfsize[3], poffset[3], ptype[3]; u_int32_t *dx; if (cgetent(&buf, db_array, (char *) name) < 0) return NULL; bzero((char *)&disk, sizeof(disk)); /* * typename */ cq = dp->d_typename; cp = buf; while (cq < dp->d_typename + sizeof(dp->d_typename) - 1 && (*cq = *cp) && *cq != '|' && *cq != ':') cq++, cp++; *cq = '\0'; if (cgetstr(buf, "ty", &cq) > 0) { if (strcmp(cq, "removable") == 0) dp->d_flags |= D_REMOVABLE; else if (cq && strcmp(cq, "simulated") == 0) dp->d_flags |= D_RAMDISK; free(cq); } if (cgetcap(buf, "sf", ':') != NULL) dp->d_flags |= D_BADSECT; #define getnumdflt(field, dname, dflt) \ { long f; (field) = (cgetnum(buf, dname, &f) == -1) ? (dflt) : f; } getnumdflt(dp->d_secsize, "se", DEV_BSIZE); getnumdflt(dp->d_ntracks, "nt", 0); getnumdflt(dp->d_nsectors, "ns", 0); getnumdflt(dp->d_ncylinders, "nc", 0); if (cgetstr(buf, "dt", &cq) > 0) { dp->d_type = gettype(cq, dktypenames); free(cq); } else getnumdflt(dp->d_type, "dt", 0); getnumdflt(dp->d_secpercyl, "sc", dp->d_nsectors * dp->d_ntracks); getnumdflt(dp->d_secperunit, "su", dp->d_secpercyl * dp->d_ncylinders); getnumdflt(dp->d_rpm, "rm", 3600); getnumdflt(dp->d_interleave, "il", 1); getnumdflt(dp->d_trackskew, "sk", 0); getnumdflt(dp->d_cylskew, "cs", 0); getnumdflt(dp->d_headswitch, "hs", 0); getnumdflt(dp->d_trkseek, "ts", 0); getnumdflt(dp->d_bbsize, "bs", BBSIZE); getnumdflt(dp->d_sbsize, "sb", 0); strcpy(psize, "px"); strcpy(pbsize, "bx"); strcpy(pfsize, "fx"); strcpy(poffset, "ox"); strcpy(ptype, "tx"); max = 'a' - 1; pp = &dp->d_partitions[0]; for (p = 'a'; p < 'a' + MAXPARTITIONS; p++, pp++) { long l; psize[1] = pbsize[1] = pfsize[1] = poffset[1] = ptype[1] = p; if (cgetnum(buf, psize, &l) == -1) pp->p_size = 0; else { pp->p_size = l; cgetnum(buf, poffset, &l); pp->p_offset = l; getnumdflt(pp->p_fsize, pfsize, 0); if (pp->p_fsize) { long bsize; if (cgetnum(buf, pbsize, &bsize) == 0) pp->p_frag = bsize / pp->p_fsize; else pp->p_frag = 8; } getnumdflt(pp->p_fstype, ptype, 0); if (pp->p_fstype == 0) if (cgetstr(buf, ptype, &cq) >= 0) { pp->p_fstype = gettype(cq, fstypenames); free(cq); } max = p; } } dp->d_npartitions = max + 1 - 'a'; (void)strcpy(psize, "dx"); dx = dp->d_drivedata; for (p = '0'; p < '0' + NDDATA; p++, dx++) { psize[1] = p; getnumdflt(*dx, psize, 0); } dp->d_magic = DISKMAGIC; dp->d_magic2 = DISKMAGIC; free(buf); return (dp); } Index: head/lib/libc/gen/err.c =================================================================== --- head/lib/libc/gen/err.c (revision 335897) +++ head/lib/libc/gen/err.c (revision 335898) @@ -1,194 +1,192 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)err.c 8.1 (Berkeley) 6/4/93"; -#endif /* LIBC_SCCS and not lint */ #include +__SCCSID("@(#)err.c 8.1 (Berkeley) 6/4/93"); __FBSDID("$FreeBSD$"); #include "namespace.h" #include #include #include #include #include #include #include "un-namespace.h" #include "libc_private.h" static FILE *err_file; /* file to use for error output */ static void (*err_exit)(int); /* * This is declared to take a `void *' so that the caller is not required * to include first. However, it is really a `FILE *', and the * manual page documents it as such. */ void err_set_file(void *fp) { if (fp) err_file = fp; else err_file = stderr; } void err_set_exit(void (*ef)(int)) { err_exit = ef; } __weak_reference(_err, err); void _err(int eval, const char *fmt, ...) { va_list ap; va_start(ap, fmt); verrc(eval, errno, fmt, ap); va_end(ap); } void verr(int eval, const char *fmt, va_list ap) { verrc(eval, errno, fmt, ap); } void errc(int eval, int code, const char *fmt, ...) { va_list ap; va_start(ap, fmt); verrc(eval, code, fmt, ap); va_end(ap); } void verrc(int eval, int code, const char *fmt, va_list ap) { if (err_file == NULL) err_set_file(NULL); fprintf(err_file, "%s: ", _getprogname()); if (fmt != NULL) { vfprintf(err_file, fmt, ap); fprintf(err_file, ": "); } fprintf(err_file, "%s\n", strerror(code)); if (err_exit) err_exit(eval); exit(eval); } void errx(int eval, const char *fmt, ...) { va_list ap; va_start(ap, fmt); verrx(eval, fmt, ap); va_end(ap); } void verrx(int eval, const char *fmt, va_list ap) { if (err_file == NULL) err_set_file(NULL); fprintf(err_file, "%s: ", _getprogname()); if (fmt != NULL) vfprintf(err_file, fmt, ap); fprintf(err_file, "\n"); if (err_exit) err_exit(eval); exit(eval); } __weak_reference(_warn, warn); void _warn(const char *fmt, ...) { va_list ap; va_start(ap, fmt); vwarnc(errno, fmt, ap); va_end(ap); } void vwarn(const char *fmt, va_list ap) { vwarnc(errno, fmt, ap); } void warnc(int code, const char *fmt, ...) { va_list ap; va_start(ap, fmt); vwarnc(code, fmt, ap); va_end(ap); } void vwarnc(int code, const char *fmt, va_list ap) { if (err_file == NULL) err_set_file(NULL); fprintf(err_file, "%s: ", _getprogname()); if (fmt != NULL) { vfprintf(err_file, fmt, ap); fprintf(err_file, ": "); } fprintf(err_file, "%s\n", strerror(code)); } void warnx(const char *fmt, ...) { va_list ap; va_start(ap, fmt); vwarnx(fmt, ap); va_end(ap); } void vwarnx(const char *fmt, va_list ap) { if (err_file == NULL) err_set_file(NULL); fprintf(err_file, "%s: ", _getprogname()); if (fmt != NULL) vfprintf(err_file, fmt, ap); fprintf(err_file, "\n"); } Index: head/lib/libc/gen/errlst.c =================================================================== --- head/lib/libc/gen/errlst.c (revision 335897) +++ head/lib/libc/gen/errlst.c (revision 335898) @@ -1,166 +1,164 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1982, 1985, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)errlst.c 8.2 (Berkeley) 11/16/93"; -#endif /* LIBC_SCCS and not lint */ #include +__SCCSID("@(#)errlst.c 8.2 (Berkeley) 11/16/93"); __FBSDID("$FreeBSD$"); #include #include "errlst.h" const char *const sys_errlist[] = { "No error: 0", /* 0 - ENOERROR */ "Operation not permitted", /* 1 - EPERM */ "No such file or directory", /* 2 - ENOENT */ "No such process", /* 3 - ESRCH */ "Interrupted system call", /* 4 - EINTR */ "Input/output error", /* 5 - EIO */ "Device not configured", /* 6 - ENXIO */ "Argument list too long", /* 7 - E2BIG */ "Exec format error", /* 8 - ENOEXEC */ "Bad file descriptor", /* 9 - EBADF */ "No child processes", /* 10 - ECHILD */ "Resource deadlock avoided", /* 11 - EDEADLK */ "Cannot allocate memory", /* 12 - ENOMEM */ "Permission denied", /* 13 - EACCES */ "Bad address", /* 14 - EFAULT */ "Block device required", /* 15 - ENOTBLK */ "Device busy", /* 16 - EBUSY */ "File exists", /* 17 - EEXIST */ "Cross-device link", /* 18 - EXDEV */ "Operation not supported by device", /* 19 - ENODEV */ "Not a directory", /* 20 - ENOTDIR */ "Is a directory", /* 21 - EISDIR */ "Invalid argument", /* 22 - EINVAL */ "Too many open files in system", /* 23 - ENFILE */ "Too many open files", /* 24 - EMFILE */ "Inappropriate ioctl for device", /* 25 - ENOTTY */ "Text file busy", /* 26 - ETXTBSY */ "File too large", /* 27 - EFBIG */ "No space left on device", /* 28 - ENOSPC */ "Illegal seek", /* 29 - ESPIPE */ "Read-only file system", /* 30 - EROFS */ "Too many links", /* 31 - EMLINK */ "Broken pipe", /* 32 - EPIPE */ /* math software */ "Numerical argument out of domain", /* 33 - EDOM */ "Result too large", /* 34 - ERANGE */ /* non-blocking and interrupt i/o */ "Resource temporarily unavailable", /* 35 - EAGAIN */ /* 35 - EWOULDBLOCK */ "Operation now in progress", /* 36 - EINPROGRESS */ "Operation already in progress", /* 37 - EALREADY */ /* ipc/network software -- argument errors */ "Socket operation on non-socket", /* 38 - ENOTSOCK */ "Destination address required", /* 39 - EDESTADDRREQ */ "Message too long", /* 40 - EMSGSIZE */ "Protocol wrong type for socket", /* 41 - EPROTOTYPE */ "Protocol not available", /* 42 - ENOPROTOOPT */ "Protocol not supported", /* 43 - EPROTONOSUPPORT */ "Socket type not supported", /* 44 - ESOCKTNOSUPPORT */ "Operation not supported", /* 45 - EOPNOTSUPP */ "Protocol family not supported", /* 46 - EPFNOSUPPORT */ /* 47 - EAFNOSUPPORT */ "Address family not supported by protocol family", "Address already in use", /* 48 - EADDRINUSE */ "Can't assign requested address", /* 49 - EADDRNOTAVAIL */ /* ipc/network software -- operational errors */ "Network is down", /* 50 - ENETDOWN */ "Network is unreachable", /* 51 - ENETUNREACH */ "Network dropped connection on reset", /* 52 - ENETRESET */ "Software caused connection abort", /* 53 - ECONNABORTED */ "Connection reset by peer", /* 54 - ECONNRESET */ "No buffer space available", /* 55 - ENOBUFS */ "Socket is already connected", /* 56 - EISCONN */ "Socket is not connected", /* 57 - ENOTCONN */ "Can't send after socket shutdown", /* 58 - ESHUTDOWN */ "Too many references: can't splice", /* 59 - ETOOMANYREFS */ "Operation timed out", /* 60 - ETIMEDOUT */ "Connection refused", /* 61 - ECONNREFUSED */ "Too many levels of symbolic links", /* 62 - ELOOP */ "File name too long", /* 63 - ENAMETOOLONG */ /* should be rearranged */ "Host is down", /* 64 - EHOSTDOWN */ "No route to host", /* 65 - EHOSTUNREACH */ "Directory not empty", /* 66 - ENOTEMPTY */ /* quotas & mush */ "Too many processes", /* 67 - EPROCLIM */ "Too many users", /* 68 - EUSERS */ "Disc quota exceeded", /* 69 - EDQUOT */ /* Network File System */ "Stale NFS file handle", /* 70 - ESTALE */ "Too many levels of remote in path", /* 71 - EREMOTE */ "RPC struct is bad", /* 72 - EBADRPC */ "RPC version wrong", /* 73 - ERPCMISMATCH */ "RPC prog. not avail", /* 74 - EPROGUNAVAIL */ "Program version wrong", /* 75 - EPROGMISMATCH */ "Bad procedure for program", /* 76 - EPROCUNAVAIL */ "No locks available", /* 77 - ENOLCK */ "Function not implemented", /* 78 - ENOSYS */ "Inappropriate file type or format", /* 79 - EFTYPE */ "Authentication error", /* 80 - EAUTH */ "Need authenticator", /* 81 - ENEEDAUTH */ "Identifier removed", /* 82 - EIDRM */ "No message of desired type", /* 83 - ENOMSG */ "Value too large to be stored in data type", /* 84 - EOVERFLOW */ "Operation canceled", /* 85 - ECANCELED */ "Illegal byte sequence", /* 86 - EILSEQ */ "Attribute not found", /* 87 - ENOATTR */ /* General */ "Programming error", /* 88 - EDOOFUS */ "Bad message", /* 89 - EBADMSG */ "Multihop attempted", /* 90 - EMULTIHOP */ "Link has been severed", /* 91 - ENOLINK */ "Protocol error", /* 92 - EPROTO */ "Capabilities insufficient", /* 93 - ENOTCAPABLE */ "Not permitted in capability mode", /* 94 - ECAPMODE */ "State not recoverable", /* 95 - ENOTRECOVERABLE */ "Previous owner died", /* 96 - EOWNERDEAD */ }; const int sys_nerr = sizeof(sys_errlist) / sizeof(sys_errlist[0]); #ifdef PIC __strong_reference(sys_errlist, __hidden_sys_errlist); __strong_reference(sys_nerr, __hidden_sys_nerr); #endif Index: head/lib/libc/gen/exec.c =================================================================== --- head/lib/libc/gen/exec.c (revision 335897) +++ head/lib/libc/gen/exec.c (revision 335898) @@ -1,283 +1,281 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1991, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)exec.c 8.1 (Berkeley) 6/4/93"; -#endif /* LIBC_SCCS and not lint */ #include +__SCCSID("@(#)exec.c 8.1 (Berkeley) 6/4/93"); __FBSDID("$FreeBSD$"); #include "namespace.h" #include #include #include #include #include #include #include #include #include #include "un-namespace.h" #include "libc_private.h" extern char **environ; int execl(const char *name, const char *arg, ...) { va_list ap; const char **argv; int n; va_start(ap, arg); n = 1; while (va_arg(ap, char *) != NULL) n++; va_end(ap); argv = alloca((n + 1) * sizeof(*argv)); if (argv == NULL) { errno = ENOMEM; return (-1); } va_start(ap, arg); n = 1; argv[0] = arg; while ((argv[n] = va_arg(ap, char *)) != NULL) n++; va_end(ap); return (_execve(name, __DECONST(char **, argv), environ)); } int execle(const char *name, const char *arg, ...) { va_list ap; const char **argv; char **envp; int n; va_start(ap, arg); n = 1; while (va_arg(ap, char *) != NULL) n++; va_end(ap); argv = alloca((n + 1) * sizeof(*argv)); if (argv == NULL) { errno = ENOMEM; return (-1); } va_start(ap, arg); n = 1; argv[0] = arg; while ((argv[n] = va_arg(ap, char *)) != NULL) n++; envp = va_arg(ap, char **); va_end(ap); return (_execve(name, __DECONST(char **, argv), envp)); } int execlp(const char *name, const char *arg, ...) { va_list ap; const char **argv; int n; va_start(ap, arg); n = 1; while (va_arg(ap, char *) != NULL) n++; va_end(ap); argv = alloca((n + 1) * sizeof(*argv)); if (argv == NULL) { errno = ENOMEM; return (-1); } va_start(ap, arg); n = 1; argv[0] = arg; while ((argv[n] = va_arg(ap, char *)) != NULL) n++; va_end(ap); return (execvp(name, __DECONST(char **, argv))); } int execv(const char *name, char * const *argv) { (void)_execve(name, argv, environ); return (-1); } int execvp(const char *name, char * const *argv) { return (_execvpe(name, argv, environ)); } static int execvPe(const char *name, const char *path, char * const *argv, char * const *envp) { const char **memp; size_t cnt, lp, ln; int eacces, save_errno; char *cur, buf[MAXPATHLEN]; const char *p, *bp; struct stat sb; eacces = 0; /* If it's an absolute or relative path name, it's easy. */ if (strchr(name, '/')) { bp = name; cur = NULL; goto retry; } bp = buf; /* If it's an empty path name, fail in the usual POSIX way. */ if (*name == '\0') { errno = ENOENT; return (-1); } cur = alloca(strlen(path) + 1); if (cur == NULL) { errno = ENOMEM; return (-1); } strcpy(cur, path); while ((p = strsep(&cur, ":")) != NULL) { /* * It's a SHELL path -- double, leading and trailing colons * mean the current directory. */ if (*p == '\0') { p = "."; lp = 1; } else lp = strlen(p); ln = strlen(name); /* * If the path is too long complain. This is a possible * security issue; given a way to make the path too long * the user may execute the wrong program. */ if (lp + ln + 2 > sizeof(buf)) { (void)_write(STDERR_FILENO, "execvP: ", 8); (void)_write(STDERR_FILENO, p, lp); (void)_write(STDERR_FILENO, ": path too long\n", 16); continue; } bcopy(p, buf, lp); buf[lp] = '/'; bcopy(name, buf + lp + 1, ln); buf[lp + ln + 1] = '\0'; retry: (void)_execve(bp, argv, envp); switch (errno) { case E2BIG: goto done; case ELOOP: case ENAMETOOLONG: case ENOENT: break; case ENOEXEC: for (cnt = 0; argv[cnt]; ++cnt) ; memp = alloca((cnt + 2) * sizeof(char *)); if (memp == NULL) { /* errno = ENOMEM; XXX override ENOEXEC? */ goto done; } memp[0] = "sh"; memp[1] = bp; bcopy(argv + 1, memp + 2, cnt * sizeof(char *)); (void)_execve(_PATH_BSHELL, __DECONST(char **, memp), envp); goto done; case ENOMEM: goto done; case ENOTDIR: break; case ETXTBSY: /* * We used to retry here, but sh(1) doesn't. */ goto done; default: /* * EACCES may be for an inaccessible directory or * a non-executable file. Call stat() to decide * which. This also handles ambiguities for EFAULT * and EIO, and undocumented errors like ESTALE. * We hope that the race for a stat() is unimportant. */ save_errno = errno; if (stat(bp, &sb) != 0) break; if (save_errno == EACCES) { eacces = 1; continue; } errno = save_errno; goto done; } } if (eacces) errno = EACCES; else errno = ENOENT; done: return (-1); } int execvP(const char *name, const char *path, char * const argv[]) { return execvPe(name, path, argv, environ); } int _execvpe(const char *name, char * const argv[], char * const envp[]) { const char *path; /* Get the path we're searching. */ if ((path = getenv("PATH")) == NULL) path = _PATH_DEFPATH; return (execvPe(name, path, argv, envp)); } Index: head/lib/libc/gen/fnmatch.c =================================================================== --- head/lib/libc/gen/fnmatch.c (revision 335897) +++ head/lib/libc/gen/fnmatch.c (revision 335898) @@ -1,312 +1,310 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1989, 1993, 1994 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Guido van Rossum. * * Copyright (c) 2011 The FreeBSD Foundation * All rights reserved. * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)fnmatch.c 8.2 (Berkeley) 4/16/94"; -#endif /* LIBC_SCCS and not lint */ #include +__SCCSID("@(#)fnmatch.c 8.2 (Berkeley) 4/16/94"); __FBSDID("$FreeBSD$"); /* * Function fnmatch() as specified in POSIX 1003.2-1992, section B.6. * Compares a filename or pathname to a pattern. */ /* * Some notes on multibyte character support: * 1. Patterns with illegal byte sequences match nothing. * 2. Illegal byte sequences in the "string" argument are handled by treating * them as single-byte characters with a value of the first byte of the * sequence cast to wchar_t. * 3. Multibyte conversion state objects (mbstate_t) are passed around and * used for most, but not all, conversions. Further work will be required * to support state-dependent encodings. */ #include #include #include #include #include #include "collate.h" #define EOS '\0' #define RANGE_MATCH 1 #define RANGE_NOMATCH 0 #define RANGE_ERROR (-1) static int rangematch(const char *, wchar_t, int, char **, mbstate_t *); static int fnmatch1(const char *, const char *, const char *, int, mbstate_t, mbstate_t); int fnmatch(const char *pattern, const char *string, int flags) { static const mbstate_t initial; return (fnmatch1(pattern, string, string, flags, initial, initial)); } static int fnmatch1(const char *pattern, const char *string, const char *stringstart, int flags, mbstate_t patmbs, mbstate_t strmbs) { const char *bt_pattern, *bt_string; mbstate_t bt_patmbs, bt_strmbs; char *newp; char c; wchar_t pc, sc; size_t pclen, sclen; bt_pattern = bt_string = NULL; for (;;) { pclen = mbrtowc(&pc, pattern, MB_LEN_MAX, &patmbs); if (pclen == (size_t)-1 || pclen == (size_t)-2) return (FNM_NOMATCH); pattern += pclen; sclen = mbrtowc(&sc, string, MB_LEN_MAX, &strmbs); if (sclen == (size_t)-1 || sclen == (size_t)-2) { sc = (unsigned char)*string; sclen = 1; memset(&strmbs, 0, sizeof(strmbs)); } switch (pc) { case EOS: if ((flags & FNM_LEADING_DIR) && sc == '/') return (0); if (sc == EOS) return (0); goto backtrack; case '?': if (sc == EOS) return (FNM_NOMATCH); if (sc == '/' && (flags & FNM_PATHNAME)) goto backtrack; if (sc == '.' && (flags & FNM_PERIOD) && (string == stringstart || ((flags & FNM_PATHNAME) && *(string - 1) == '/'))) goto backtrack; string += sclen; break; case '*': c = *pattern; /* Collapse multiple stars. */ while (c == '*') c = *++pattern; if (sc == '.' && (flags & FNM_PERIOD) && (string == stringstart || ((flags & FNM_PATHNAME) && *(string - 1) == '/'))) goto backtrack; /* Optimize for pattern with * at end or before /. */ if (c == EOS) if (flags & FNM_PATHNAME) return ((flags & FNM_LEADING_DIR) || strchr(string, '/') == NULL ? 0 : FNM_NOMATCH); else return (0); else if (c == '/' && flags & FNM_PATHNAME) { if ((string = strchr(string, '/')) == NULL) return (FNM_NOMATCH); break; } /* * First try the shortest match for the '*' that * could work. We can forget any earlier '*' since * there is no way having it match more characters * can help us, given that we are already here. */ bt_pattern = pattern, bt_patmbs = patmbs; bt_string = string, bt_strmbs = strmbs; break; case '[': if (sc == EOS) return (FNM_NOMATCH); if (sc == '/' && (flags & FNM_PATHNAME)) goto backtrack; if (sc == '.' && (flags & FNM_PERIOD) && (string == stringstart || ((flags & FNM_PATHNAME) && *(string - 1) == '/'))) goto backtrack; switch (rangematch(pattern, sc, flags, &newp, &patmbs)) { case RANGE_ERROR: goto norm; case RANGE_MATCH: pattern = newp; break; case RANGE_NOMATCH: goto backtrack; } string += sclen; break; case '\\': if (!(flags & FNM_NOESCAPE)) { pclen = mbrtowc(&pc, pattern, MB_LEN_MAX, &patmbs); if (pclen == 0 || pclen == (size_t)-1 || pclen == (size_t)-2) return (FNM_NOMATCH); pattern += pclen; } /* FALLTHROUGH */ default: norm: string += sclen; if (pc == sc) ; else if ((flags & FNM_CASEFOLD) && (towlower(pc) == towlower(sc))) ; else { backtrack: /* * If we have a mismatch (other than hitting * the end of the string), go back to the last * '*' seen and have it match one additional * character. */ if (bt_pattern == NULL) return (FNM_NOMATCH); sclen = mbrtowc(&sc, bt_string, MB_LEN_MAX, &bt_strmbs); if (sclen == (size_t)-1 || sclen == (size_t)-2) { sc = (unsigned char)*bt_string; sclen = 1; memset(&bt_strmbs, 0, sizeof(bt_strmbs)); } if (sc == EOS) return (FNM_NOMATCH); if (sc == '/' && flags & FNM_PATHNAME) return (FNM_NOMATCH); bt_string += sclen; pattern = bt_pattern, patmbs = bt_patmbs; string = bt_string, strmbs = bt_strmbs; } break; } } /* NOTREACHED */ } static int rangematch(const char *pattern, wchar_t test, int flags, char **newp, mbstate_t *patmbs) { int negate, ok; wchar_t c, c2; size_t pclen; const char *origpat; struct xlocale_collate *table = (struct xlocale_collate*)__get_locale()->components[XLC_COLLATE]; /* * A bracket expression starting with an unquoted circumflex * character produces unspecified results (IEEE 1003.2-1992, * 3.13.2). This implementation treats it like '!', for * consistency with the regular expression syntax. * J.T. Conklin (conklin@ngai.kaleida.com) */ if ((negate = (*pattern == '!' || *pattern == '^'))) ++pattern; if (flags & FNM_CASEFOLD) test = towlower(test); /* * A right bracket shall lose its special meaning and represent * itself in a bracket expression if it occurs first in the list. * -- POSIX.2 2.8.3.2 */ ok = 0; origpat = pattern; for (;;) { if (*pattern == ']' && pattern > origpat) { pattern++; break; } else if (*pattern == '\0') { return (RANGE_ERROR); } else if (*pattern == '/' && (flags & FNM_PATHNAME)) { return (RANGE_NOMATCH); } else if (*pattern == '\\' && !(flags & FNM_NOESCAPE)) pattern++; pclen = mbrtowc(&c, pattern, MB_LEN_MAX, patmbs); if (pclen == (size_t)-1 || pclen == (size_t)-2) return (RANGE_NOMATCH); pattern += pclen; if (flags & FNM_CASEFOLD) c = towlower(c); if (*pattern == '-' && *(pattern + 1) != EOS && *(pattern + 1) != ']') { if (*++pattern == '\\' && !(flags & FNM_NOESCAPE)) if (*pattern != EOS) pattern++; pclen = mbrtowc(&c2, pattern, MB_LEN_MAX, patmbs); if (pclen == (size_t)-1 || pclen == (size_t)-2) return (RANGE_NOMATCH); pattern += pclen; if (c2 == EOS) return (RANGE_ERROR); if (flags & FNM_CASEFOLD) c2 = towlower(c2); if (table->__collate_load_error ? c <= test && test <= c2 : __wcollate_range_cmp(c, test) <= 0 && __wcollate_range_cmp(test, c2) <= 0 ) ok = 1; } else if (c == test) ok = 1; } *newp = (char *)pattern; return (ok == negate ? RANGE_NOMATCH : RANGE_MATCH); } Index: head/lib/libc/gen/fstab.c =================================================================== --- head/lib/libc/gen/fstab.c (revision 335897) +++ head/lib/libc/gen/fstab.c (revision 335898) @@ -1,304 +1,302 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1980, 1988, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)fstab.c 8.1 (Berkeley) 6/4/93"; -#endif /* LIBC_SCCS and not lint */ #include +__SCCSID("@(#)fstab.c 8.1 (Berkeley) 6/4/93"); __FBSDID("$FreeBSD$"); #include "namespace.h" #include #include #include #include #include #include #include #include #include #include #include #include "un-namespace.h" static FILE *_fs_fp; static struct fstab _fs_fstab; static int LineNo = 0; static char *path_fstab; static char fstab_path[PATH_MAX]; static int fsp_set = 0; static void error(int); static void fixfsfile(void); static int fstabscan(void); void setfstab(const char *file) { if (file == NULL) { path_fstab = _PATH_FSTAB; } else { strncpy(fstab_path, file, PATH_MAX); fstab_path[PATH_MAX - 1] = '\0'; path_fstab = fstab_path; } fsp_set = 1; return; } const char * getfstab(void) { if (fsp_set) return (path_fstab); else return (_PATH_FSTAB); } static void fixfsfile(void) { static char buf[sizeof(_PATH_DEV) + MNAMELEN]; struct stat sb; struct statfs sf; if (_fs_fstab.fs_file != NULL && strcmp(_fs_fstab.fs_file, "/") != 0) return; if (statfs("/", &sf) != 0) return; if (sf.f_mntfromname[0] == '/') buf[0] = '\0'; else strcpy(buf, _PATH_DEV); strcat(buf, sf.f_mntfromname); if (stat(buf, &sb) != 0 || (!S_ISBLK(sb.st_mode) && !S_ISCHR(sb.st_mode))) return; _fs_fstab.fs_spec = buf; } static int fstabscan(void) { char *cp, *p; #define MAXLINELENGTH 1024 static char line[MAXLINELENGTH]; char subline[MAXLINELENGTH]; int typexx; for (;;) { if (!(p = fgets(line, sizeof(line), _fs_fp))) return (0); /* OLD_STYLE_FSTAB */ ++LineNo; if (*line == '#' || *line == '\n') continue; if (!strpbrk(p, " \t")) { _fs_fstab.fs_spec = strsep(&p, ":\n"); _fs_fstab.fs_file = strsep(&p, ":\n"); fixfsfile(); _fs_fstab.fs_type = strsep(&p, ":\n"); if (_fs_fstab.fs_type) { if (!strcmp(_fs_fstab.fs_type, FSTAB_XX)) continue; _fs_fstab.fs_mntops = _fs_fstab.fs_type; _fs_fstab.fs_vfstype = strcmp(_fs_fstab.fs_type, FSTAB_SW) ? "ufs" : "swap"; if ((cp = strsep(&p, ":\n")) != NULL) { _fs_fstab.fs_freq = atoi(cp); if ((cp = strsep(&p, ":\n")) != NULL) { _fs_fstab.fs_passno = atoi(cp); return (1); } } } goto bad; } /* OLD_STYLE_FSTAB */ while ((cp = strsep(&p, " \t\n")) != NULL && *cp == '\0') ; _fs_fstab.fs_spec = cp; if (_fs_fstab.fs_spec == NULL || *_fs_fstab.fs_spec == '#') continue; if (strunvis(_fs_fstab.fs_spec, _fs_fstab.fs_spec) < 0) goto bad; while ((cp = strsep(&p, " \t\n")) != NULL && *cp == '\0') ; _fs_fstab.fs_file = cp; if (_fs_fstab.fs_file == NULL) goto bad; if (strunvis(_fs_fstab.fs_file, _fs_fstab.fs_file) < 0) goto bad; fixfsfile(); while ((cp = strsep(&p, " \t\n")) != NULL && *cp == '\0') ; _fs_fstab.fs_vfstype = cp; while ((cp = strsep(&p, " \t\n")) != NULL && *cp == '\0') ; _fs_fstab.fs_mntops = cp; if (_fs_fstab.fs_mntops == NULL) goto bad; _fs_fstab.fs_freq = 0; _fs_fstab.fs_passno = 0; while ((cp = strsep(&p, " \t\n")) != NULL && *cp == '\0') ; if (cp != NULL) { _fs_fstab.fs_freq = atoi(cp); while ((cp = strsep(&p, " \t\n")) != NULL && *cp == '\0') ; if (cp != NULL) _fs_fstab.fs_passno = atoi(cp); } (void)strlcpy(subline, _fs_fstab.fs_mntops, sizeof(subline)); p = subline; for (typexx = 0, cp = strsep(&p, ","); cp; cp = strsep(&p, ",")) { if (strlen(cp) != 2) continue; if (!strcmp(cp, FSTAB_RW)) { _fs_fstab.fs_type = FSTAB_RW; break; } if (!strcmp(cp, FSTAB_RQ)) { _fs_fstab.fs_type = FSTAB_RQ; break; } if (!strcmp(cp, FSTAB_RO)) { _fs_fstab.fs_type = FSTAB_RO; break; } if (!strcmp(cp, FSTAB_SW)) { _fs_fstab.fs_type = FSTAB_SW; break; } if (!strcmp(cp, FSTAB_XX)) { _fs_fstab.fs_type = FSTAB_XX; typexx++; break; } } if (typexx) continue; if (cp != NULL) return (1); bad: /* no way to distinguish between EOF and syntax error */ error(EFTYPE); } /* NOTREACHED */ } struct fstab * getfsent(void) { if ((!_fs_fp && !setfsent()) || !fstabscan()) return (NULL); return (&_fs_fstab); } struct fstab * getfsspec(const char *name) { if (setfsent()) while (fstabscan()) if (!strcmp(_fs_fstab.fs_spec, name)) return (&_fs_fstab); return (NULL); } struct fstab * getfsfile(const char *name) { if (setfsent()) while (fstabscan()) if (!strcmp(_fs_fstab.fs_file, name)) return (&_fs_fstab); return (NULL); } int setfsent(void) { if (_fs_fp) { rewind(_fs_fp); LineNo = 0; return (1); } if (fsp_set == 0) { if (issetugid()) setfstab(NULL); else setfstab(getenv("PATH_FSTAB")); } if ((_fs_fp = fopen(path_fstab, "re")) != NULL) { LineNo = 0; return (1); } error(errno); return (0); } void endfsent(void) { if (_fs_fp) { (void)fclose(_fs_fp); _fs_fp = NULL; } fsp_set = 0; } static void error(int err) { char *p; char num[30]; (void)_write(STDERR_FILENO, "fstab: ", 7); (void)_write(STDERR_FILENO, path_fstab, strlen(path_fstab)); (void)_write(STDERR_FILENO, ":", 1); sprintf(num, "%d: ", LineNo); (void)_write(STDERR_FILENO, num, strlen(num)); p = strerror(err); (void)_write(STDERR_FILENO, p, strlen(p)); (void)_write(STDERR_FILENO, "\n", 1); } Index: head/lib/libc/gen/fts-compat.c =================================================================== --- head/lib/libc/gen/fts-compat.c (revision 335897) +++ head/lib/libc/gen/fts-compat.c (revision 335898) @@ -1,1221 +1,1216 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1990, 1993, 1994 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $OpenBSD: fts.c,v 1.22 1999/10/03 19:22:22 millert Exp $ + * From: @(#)fts.c 8.6 (Berkeley) 8/14/94 + * From: $OpenBSD: fts.c,v 1.22 1999/10/03 19:22:22 millert Exp $ */ - -#if 0 -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)fts.c 8.6 (Berkeley) 8/14/94"; -#endif /* LIBC_SCCS and not lint */ -#endif #include __FBSDID("$FreeBSD$"); #include "namespace.h" #include #define _WANT_FREEBSD11_STATFS #include #define _WANT_FREEBSD11_STAT #include #define _WANT_FREEBSD11_DIRENT #include #include #include #include #include #include #include "gen-compat.h" #include "fts-compat.h" #include "un-namespace.h" #include "gen-private.h" FTSENT *__fts_children_44bsd(FTS *, int); int __fts_close_44bsd(FTS *); void *__fts_get_clientptr_44bsd(FTS *); FTS *__fts_get_stream_44bsd(FTSENT *); FTS *__fts_open_44bsd(char * const *, int, int (*)(const FTSENT * const *, const FTSENT * const *)); FTSENT *__fts_read_44bsd(FTS *); int __fts_set_44bsd(FTS *, FTSENT *, int); void __fts_set_clientptr_44bsd(FTS *, void *); static FTSENT *fts_alloc(FTS *, char *, int); static FTSENT *fts_build(FTS *, int); static void fts_lfree(FTSENT *); static void fts_load(FTS *, FTSENT *); static size_t fts_maxarglen(char * const *); static void fts_padjust(FTS *, FTSENT *); static int fts_palloc(FTS *, size_t); static FTSENT *fts_sort(FTS *, FTSENT *, int); static u_short fts_stat(FTS *, FTSENT *, int); static int fts_safe_changedir(FTS *, FTSENT *, int, char *); static int fts_ufslinks(FTS *, const FTSENT *); #define ISDOT(a) (a[0] == '.' && (!a[1] || (a[1] == '.' && !a[2]))) #define CLR(opt) (sp->fts_options &= ~(opt)) #define ISSET(opt) (sp->fts_options & (opt)) #define SET(opt) (sp->fts_options |= (opt)) #define FCHDIR(sp, fd) (!ISSET(FTS_NOCHDIR) && fchdir(fd)) /* fts_build flags */ #define BCHILD 1 /* fts_children */ #define BNAMES 2 /* fts_children, names only */ #define BREAD 3 /* fts_read */ /* * Internal representation of an FTS, including extra implementation * details. The FTS returned from fts_open points to this structure's * ftsp_fts member (and can be cast to an _fts_private as required) */ struct _fts_private { FTS ftsp_fts; struct freebsd11_statfs ftsp_statfs; uint32_t ftsp_dev; int ftsp_linksreliable; }; /* * The "FTS_NOSTAT" option can avoid a lot of calls to stat(2) if it * knows that a directory could not possibly have subdirectories. This * is decided by looking at the link count: a subdirectory would * increment its parent's link count by virtue of its own ".." entry. * This assumption only holds for UFS-like filesystems that implement * links and directories this way, so we must punt for others. */ static const char *ufslike_filesystems[] = { "ufs", "zfs", "nfs", "ext2fs", 0 }; FTS * __fts_open_44bsd(char * const *argv, int options, int (*compar)(const FTSENT * const *, const FTSENT * const *)) { struct _fts_private *priv; FTS *sp; FTSENT *p, *root; int nitems; FTSENT *parent, *tmp; int len; /* Options check. */ if (options & ~FTS_OPTIONMASK) { errno = EINVAL; return (NULL); } /* Allocate/initialize the stream. */ if ((priv = calloc(1, sizeof(*priv))) == NULL) return (NULL); sp = &priv->ftsp_fts; sp->fts_compar = compar; sp->fts_options = options; /* Logical walks turn on NOCHDIR; symbolic links are too hard. */ if (ISSET(FTS_LOGICAL)) SET(FTS_NOCHDIR); /* * Start out with 1K of path space, and enough, in any case, * to hold the user's paths. */ if (fts_palloc(sp, MAX(fts_maxarglen(argv), MAXPATHLEN))) goto mem1; /* Allocate/initialize root's parent. */ if ((parent = fts_alloc(sp, "", 0)) == NULL) goto mem2; parent->fts_level = FTS_ROOTPARENTLEVEL; /* Shush, GCC. */ tmp = NULL; /* Allocate/initialize root(s). */ for (root = NULL, nitems = 0; *argv != NULL; ++argv, ++nitems) { /* Don't allow zero-length paths. */ if ((len = strlen(*argv)) == 0) { errno = ENOENT; goto mem3; } p = fts_alloc(sp, *argv, len); p->fts_level = FTS_ROOTLEVEL; p->fts_parent = parent; p->fts_accpath = p->fts_name; p->fts_info = fts_stat(sp, p, ISSET(FTS_COMFOLLOW)); /* Command-line "." and ".." are real directories. */ if (p->fts_info == FTS_DOT) p->fts_info = FTS_D; /* * If comparison routine supplied, traverse in sorted * order; otherwise traverse in the order specified. */ if (compar) { p->fts_link = root; root = p; } else { p->fts_link = NULL; if (root == NULL) tmp = root = p; else { tmp->fts_link = p; tmp = p; } } } if (compar && nitems > 1) root = fts_sort(sp, root, nitems); /* * Allocate a dummy pointer and make fts_read think that we've just * finished the node before the root(s); set p->fts_info to FTS_INIT * so that everything about the "current" node is ignored. */ if ((sp->fts_cur = fts_alloc(sp, "", 0)) == NULL) goto mem3; sp->fts_cur->fts_link = root; sp->fts_cur->fts_info = FTS_INIT; /* * If using chdir(2), grab a file descriptor pointing to dot to ensure * that we can get back here; this could be avoided for some paths, * but almost certainly not worth the effort. Slashes, symbolic links, * and ".." are all fairly nasty problems. Note, if we can't get the * descriptor we run anyway, just more slowly. */ if (!ISSET(FTS_NOCHDIR) && (sp->fts_rfd = _open(".", O_RDONLY | O_CLOEXEC, 0)) < 0) SET(FTS_NOCHDIR); return (sp); mem3: fts_lfree(root); free(parent); mem2: free(sp->fts_path); mem1: free(sp); return (NULL); } static void fts_load(FTS *sp, FTSENT *p) { int len; char *cp; /* * Load the stream structure for the next traversal. Since we don't * actually enter the directory until after the preorder visit, set * the fts_accpath field specially so the chdir gets done to the right * place and the user can access the first node. From fts_open it's * known that the path will fit. */ len = p->fts_pathlen = p->fts_namelen; memmove(sp->fts_path, p->fts_name, len + 1); if ((cp = strrchr(p->fts_name, '/')) && (cp != p->fts_name || cp[1])) { len = strlen(++cp); memmove(p->fts_name, cp, len + 1); p->fts_namelen = len; } p->fts_accpath = p->fts_path = sp->fts_path; sp->fts_dev = p->fts_dev; } int __fts_close_44bsd(FTS *sp) { FTSENT *freep, *p; int saved_errno; /* * This still works if we haven't read anything -- the dummy structure * points to the root list, so we step through to the end of the root * list which has a valid parent pointer. */ if (sp->fts_cur) { for (p = sp->fts_cur; p->fts_level >= FTS_ROOTLEVEL;) { freep = p; p = p->fts_link != NULL ? p->fts_link : p->fts_parent; free(freep); } free(p); } /* Free up child linked list, sort array, path buffer. */ if (sp->fts_child) fts_lfree(sp->fts_child); if (sp->fts_array) free(sp->fts_array); free(sp->fts_path); /* Return to original directory, save errno if necessary. */ if (!ISSET(FTS_NOCHDIR)) { saved_errno = fchdir(sp->fts_rfd) ? errno : 0; (void)_close(sp->fts_rfd); /* Set errno and return. */ if (saved_errno != 0) { /* Free up the stream pointer. */ free(sp); errno = saved_errno; return (-1); } } /* Free up the stream pointer. */ free(sp); return (0); } /* * Special case of "/" at the end of the path so that slashes aren't * appended which would cause paths to be written as "....//foo". */ #define NAPPEND(p) \ (p->fts_path[p->fts_pathlen - 1] == '/' \ ? p->fts_pathlen - 1 : p->fts_pathlen) FTSENT * __fts_read_44bsd(FTS *sp) { FTSENT *p, *tmp; int instr; char *t; int saved_errno; /* If finished or unrecoverable error, return NULL. */ if (sp->fts_cur == NULL || ISSET(FTS_STOP)) return (NULL); /* Set current node pointer. */ p = sp->fts_cur; /* Save and zero out user instructions. */ instr = p->fts_instr; p->fts_instr = FTS_NOINSTR; /* Any type of file may be re-visited; re-stat and re-turn. */ if (instr == FTS_AGAIN) { p->fts_info = fts_stat(sp, p, 0); return (p); } /* * Following a symlink -- SLNONE test allows application to see * SLNONE and recover. If indirecting through a symlink, have * keep a pointer to current location. If unable to get that * pointer, follow fails. */ if (instr == FTS_FOLLOW && (p->fts_info == FTS_SL || p->fts_info == FTS_SLNONE)) { p->fts_info = fts_stat(sp, p, 1); if (p->fts_info == FTS_D && !ISSET(FTS_NOCHDIR)) { if ((p->fts_symfd = _open(".", O_RDONLY | O_CLOEXEC, 0)) < 0) { p->fts_errno = errno; p->fts_info = FTS_ERR; } else p->fts_flags |= FTS_SYMFOLLOW; } return (p); } /* Directory in pre-order. */ if (p->fts_info == FTS_D) { /* If skipped or crossed mount point, do post-order visit. */ if (instr == FTS_SKIP || (ISSET(FTS_XDEV) && p->fts_dev != sp->fts_dev)) { if (p->fts_flags & FTS_SYMFOLLOW) (void)_close(p->fts_symfd); if (sp->fts_child) { fts_lfree(sp->fts_child); sp->fts_child = NULL; } p->fts_info = FTS_DP; return (p); } /* Rebuild if only read the names and now traversing. */ if (sp->fts_child != NULL && ISSET(FTS_NAMEONLY)) { CLR(FTS_NAMEONLY); fts_lfree(sp->fts_child); sp->fts_child = NULL; } /* * Cd to the subdirectory. * * If have already read and now fail to chdir, whack the list * to make the names come out right, and set the parent errno * so the application will eventually get an error condition. * Set the FTS_DONTCHDIR flag so that when we logically change * directories back to the parent we don't do a chdir. * * If haven't read do so. If the read fails, fts_build sets * FTS_STOP or the fts_info field of the node. */ if (sp->fts_child != NULL) { if (fts_safe_changedir(sp, p, -1, p->fts_accpath)) { p->fts_errno = errno; p->fts_flags |= FTS_DONTCHDIR; for (p = sp->fts_child; p != NULL; p = p->fts_link) p->fts_accpath = p->fts_parent->fts_accpath; } } else if ((sp->fts_child = fts_build(sp, BREAD)) == NULL) { if (ISSET(FTS_STOP)) return (NULL); return (p); } p = sp->fts_child; sp->fts_child = NULL; goto name; } /* Move to the next node on this level. */ next: tmp = p; if ((p = p->fts_link) != NULL) { free(tmp); /* * If reached the top, return to the original directory (or * the root of the tree), and load the paths for the next root. */ if (p->fts_level == FTS_ROOTLEVEL) { if (FCHDIR(sp, sp->fts_rfd)) { SET(FTS_STOP); return (NULL); } fts_load(sp, p); return (sp->fts_cur = p); } /* * User may have called fts_set on the node. If skipped, * ignore. If followed, get a file descriptor so we can * get back if necessary. */ if (p->fts_instr == FTS_SKIP) goto next; if (p->fts_instr == FTS_FOLLOW) { p->fts_info = fts_stat(sp, p, 1); if (p->fts_info == FTS_D && !ISSET(FTS_NOCHDIR)) { if ((p->fts_symfd = _open(".", O_RDONLY | O_CLOEXEC, 0)) < 0) { p->fts_errno = errno; p->fts_info = FTS_ERR; } else p->fts_flags |= FTS_SYMFOLLOW; } p->fts_instr = FTS_NOINSTR; } name: t = sp->fts_path + NAPPEND(p->fts_parent); *t++ = '/'; memmove(t, p->fts_name, p->fts_namelen + 1); return (sp->fts_cur = p); } /* Move up to the parent node. */ p = tmp->fts_parent; free(tmp); if (p->fts_level == FTS_ROOTPARENTLEVEL) { /* * Done; free everything up and set errno to 0 so the user * can distinguish between error and EOF. */ free(p); errno = 0; return (sp->fts_cur = NULL); } /* NUL terminate the pathname. */ sp->fts_path[p->fts_pathlen] = '\0'; /* * Return to the parent directory. If at a root node or came through * a symlink, go back through the file descriptor. Otherwise, cd up * one directory. */ if (p->fts_level == FTS_ROOTLEVEL) { if (FCHDIR(sp, sp->fts_rfd)) { SET(FTS_STOP); return (NULL); } } else if (p->fts_flags & FTS_SYMFOLLOW) { if (FCHDIR(sp, p->fts_symfd)) { saved_errno = errno; (void)_close(p->fts_symfd); errno = saved_errno; SET(FTS_STOP); return (NULL); } (void)_close(p->fts_symfd); } else if (!(p->fts_flags & FTS_DONTCHDIR) && fts_safe_changedir(sp, p->fts_parent, -1, "..")) { SET(FTS_STOP); return (NULL); } p->fts_info = p->fts_errno ? FTS_ERR : FTS_DP; return (sp->fts_cur = p); } /* * Fts_set takes the stream as an argument although it's not used in this * implementation; it would be necessary if anyone wanted to add global * semantics to fts using fts_set. An error return is allowed for similar * reasons. */ /* ARGSUSED */ int __fts_set_44bsd(FTS *sp, FTSENT *p, int instr) { if (instr != 0 && instr != FTS_AGAIN && instr != FTS_FOLLOW && instr != FTS_NOINSTR && instr != FTS_SKIP) { errno = EINVAL; return (1); } p->fts_instr = instr; return (0); } FTSENT * __fts_children_44bsd(FTS *sp, int instr) { FTSENT *p; int fd; if (instr != 0 && instr != FTS_NAMEONLY) { errno = EINVAL; return (NULL); } /* Set current node pointer. */ p = sp->fts_cur; /* * Errno set to 0 so user can distinguish empty directory from * an error. */ errno = 0; /* Fatal errors stop here. */ if (ISSET(FTS_STOP)) return (NULL); /* Return logical hierarchy of user's arguments. */ if (p->fts_info == FTS_INIT) return (p->fts_link); /* * If not a directory being visited in pre-order, stop here. Could * allow FTS_DNR, assuming the user has fixed the problem, but the * same effect is available with FTS_AGAIN. */ if (p->fts_info != FTS_D /* && p->fts_info != FTS_DNR */) return (NULL); /* Free up any previous child list. */ if (sp->fts_child != NULL) fts_lfree(sp->fts_child); if (instr == FTS_NAMEONLY) { SET(FTS_NAMEONLY); instr = BNAMES; } else instr = BCHILD; /* * If using chdir on a relative path and called BEFORE fts_read does * its chdir to the root of a traversal, we can lose -- we need to * chdir into the subdirectory, and we don't know where the current * directory is, so we can't get back so that the upcoming chdir by * fts_read will work. */ if (p->fts_level != FTS_ROOTLEVEL || p->fts_accpath[0] == '/' || ISSET(FTS_NOCHDIR)) return (sp->fts_child = fts_build(sp, instr)); if ((fd = _open(".", O_RDONLY | O_CLOEXEC, 0)) < 0) return (NULL); sp->fts_child = fts_build(sp, instr); if (fchdir(fd)) { (void)_close(fd); return (NULL); } (void)_close(fd); return (sp->fts_child); } #ifndef fts_get_clientptr #error "fts_get_clientptr not defined" #endif void * (__fts_get_clientptr_44bsd)(FTS *sp) { return (fts_get_clientptr(sp)); } #ifndef fts_get_stream #error "fts_get_stream not defined" #endif FTS * (__fts_get_stream_44bsd)(FTSENT *p) { return (fts_get_stream(p)); } void __fts_set_clientptr_44bsd(FTS *sp, void *clientptr) { sp->fts_clientptr = clientptr; } /* * This is the tricky part -- do not casually change *anything* in here. The * idea is to build the linked list of entries that are used by fts_children * and fts_read. There are lots of special cases. * * The real slowdown in walking the tree is the stat calls. If FTS_NOSTAT is * set and it's a physical walk (so that symbolic links can't be directories), * we can do things quickly. First, if it's a 4.4BSD file system, the type * of the file is in the directory entry. Otherwise, we assume that the number * of subdirectories in a node is equal to the number of links to the parent. * The former skips all stat calls. The latter skips stat calls in any leaf * directories and for any files after the subdirectories in the directory have * been found, cutting the stat calls by about 2/3. */ static FTSENT * fts_build(FTS *sp, int type) { struct freebsd11_dirent *dp; FTSENT *p, *head; int nitems; FTSENT *cur, *tail; DIR *dirp; void *oldaddr; size_t dnamlen; int cderrno, descend, len, level, maxlen, nlinks, oflag, saved_errno, nostat, doadjust; char *cp; /* Set current node pointer. */ cur = sp->fts_cur; /* * Open the directory for reading. If this fails, we're done. * If being called from fts_read, set the fts_info field. */ #ifdef FTS_WHITEOUT if (ISSET(FTS_WHITEOUT)) oflag = DTF_NODUP | DTF_REWIND; else oflag = DTF_HIDEW | DTF_NODUP | DTF_REWIND; #else #define __opendir2(path, flag) opendir(path) #endif if ((dirp = __opendir2(cur->fts_accpath, oflag)) == NULL) { if (type == BREAD) { cur->fts_info = FTS_DNR; cur->fts_errno = errno; } return (NULL); } /* * Nlinks is the number of possible entries of type directory in the * directory if we're cheating on stat calls, 0 if we're not doing * any stat calls at all, -1 if we're doing stats on everything. */ if (type == BNAMES) { nlinks = 0; /* Be quiet about nostat, GCC. */ nostat = 0; } else if (ISSET(FTS_NOSTAT) && ISSET(FTS_PHYSICAL)) { if (fts_ufslinks(sp, cur)) nlinks = cur->fts_nlink - (ISSET(FTS_SEEDOT) ? 0 : 2); else nlinks = -1; nostat = 1; } else { nlinks = -1; nostat = 0; } #ifdef notdef (void)printf("nlinks == %d (cur: %d)\n", nlinks, cur->fts_nlink); (void)printf("NOSTAT %d PHYSICAL %d SEEDOT %d\n", ISSET(FTS_NOSTAT), ISSET(FTS_PHYSICAL), ISSET(FTS_SEEDOT)); #endif /* * If we're going to need to stat anything or we want to descend * and stay in the directory, chdir. If this fails we keep going, * but set a flag so we don't chdir after the post-order visit. * We won't be able to stat anything, but we can still return the * names themselves. Note, that since fts_read won't be able to * chdir into the directory, it will have to return different path * names than before, i.e. "a/b" instead of "b". Since the node * has already been visited in pre-order, have to wait until the * post-order visit to return the error. There is a special case * here, if there was nothing to stat then it's not an error to * not be able to stat. This is all fairly nasty. If a program * needed sorted entries or stat information, they had better be * checking FTS_NS on the returned nodes. */ cderrno = 0; if (nlinks || type == BREAD) { if (fts_safe_changedir(sp, cur, _dirfd(dirp), NULL)) { if (nlinks && type == BREAD) cur->fts_errno = errno; cur->fts_flags |= FTS_DONTCHDIR; descend = 0; cderrno = errno; } else descend = 1; } else descend = 0; /* * Figure out the max file name length that can be stored in the * current path -- the inner loop allocates more path as necessary. * We really wouldn't have to do the maxlen calculations here, we * could do them in fts_read before returning the path, but it's a * lot easier here since the length is part of the dirent structure. * * If not changing directories set a pointer so that can just append * each new name into the path. */ len = NAPPEND(cur); if (ISSET(FTS_NOCHDIR)) { cp = sp->fts_path + len; *cp++ = '/'; } else { /* GCC, you're too verbose. */ cp = NULL; } len++; maxlen = sp->fts_pathlen - len; level = cur->fts_level + 1; /* Read the directory, attaching each entry to the `link' pointer. */ doadjust = 0; for (head = tail = NULL, nitems = 0; dirp && (dp = freebsd11_readdir(dirp));) { dnamlen = dp->d_namlen; if (!ISSET(FTS_SEEDOT) && ISDOT(dp->d_name)) continue; if ((p = fts_alloc(sp, dp->d_name, (int)dnamlen)) == NULL) goto mem1; if (dnamlen >= maxlen) { /* include space for NUL */ oldaddr = sp->fts_path; if (fts_palloc(sp, dnamlen + len + 1)) { /* * No more memory for path or structures. Save * errno, free up the current structure and the * structures already allocated. */ mem1: saved_errno = errno; if (p) free(p); fts_lfree(head); (void)closedir(dirp); cur->fts_info = FTS_ERR; SET(FTS_STOP); errno = saved_errno; return (NULL); } /* Did realloc() change the pointer? */ if (oldaddr != sp->fts_path) { doadjust = 1; if (ISSET(FTS_NOCHDIR)) cp = sp->fts_path + len; } maxlen = sp->fts_pathlen - len; } if (len + dnamlen >= USHRT_MAX) { /* * In an FTSENT, fts_pathlen is a u_short so it is * possible to wraparound here. If we do, free up * the current structure and the structures already * allocated, then error out with ENAMETOOLONG. */ free(p); fts_lfree(head); (void)closedir(dirp); cur->fts_info = FTS_ERR; SET(FTS_STOP); errno = ENAMETOOLONG; return (NULL); } p->fts_level = level; p->fts_parent = sp->fts_cur; p->fts_pathlen = len + dnamlen; #ifdef FTS_WHITEOUT if (dp->d_type == DT_WHT) p->fts_flags |= FTS_ISW; #endif if (cderrno) { if (nlinks) { p->fts_info = FTS_NS; p->fts_errno = cderrno; } else p->fts_info = FTS_NSOK; p->fts_accpath = cur->fts_accpath; } else if (nlinks == 0 #ifdef DT_DIR || (nostat && dp->d_type != DT_DIR && dp->d_type != DT_UNKNOWN) #endif ) { p->fts_accpath = ISSET(FTS_NOCHDIR) ? p->fts_path : p->fts_name; p->fts_info = FTS_NSOK; } else { /* Build a file name for fts_stat to stat. */ if (ISSET(FTS_NOCHDIR)) { p->fts_accpath = p->fts_path; memmove(cp, p->fts_name, p->fts_namelen + 1); } else p->fts_accpath = p->fts_name; /* Stat it. */ p->fts_info = fts_stat(sp, p, 0); /* Decrement link count if applicable. */ if (nlinks > 0 && (p->fts_info == FTS_D || p->fts_info == FTS_DC || p->fts_info == FTS_DOT)) --nlinks; } /* We walk in directory order so "ls -f" doesn't get upset. */ p->fts_link = NULL; if (head == NULL) head = tail = p; else { tail->fts_link = p; tail = p; } ++nitems; } if (dirp) (void)closedir(dirp); /* * If realloc() changed the address of the path, adjust the * addresses for the rest of the tree and the dir list. */ if (doadjust) fts_padjust(sp, head); /* * If not changing directories, reset the path back to original * state. */ if (ISSET(FTS_NOCHDIR)) { if (len == sp->fts_pathlen || nitems == 0) --cp; *cp = '\0'; } /* * If descended after called from fts_children or after called from * fts_read and nothing found, get back. At the root level we use * the saved fd; if one of fts_open()'s arguments is a relative path * to an empty directory, we wind up here with no other way back. If * can't get back, we're done. */ if (descend && (type == BCHILD || !nitems) && (cur->fts_level == FTS_ROOTLEVEL ? FCHDIR(sp, sp->fts_rfd) : fts_safe_changedir(sp, cur->fts_parent, -1, ".."))) { cur->fts_info = FTS_ERR; SET(FTS_STOP); return (NULL); } /* If didn't find anything, return NULL. */ if (!nitems) { if (type == BREAD) cur->fts_info = FTS_DP; return (NULL); } /* Sort the entries. */ if (sp->fts_compar && nitems > 1) head = fts_sort(sp, head, nitems); return (head); } static u_short fts_stat(FTS *sp, FTSENT *p, int follow) { FTSENT *t; uint32_t dev; uint32_t ino; struct freebsd11_stat *sbp, sb; int saved_errno; /* If user needs stat info, stat buffer already allocated. */ sbp = ISSET(FTS_NOSTAT) ? &sb : p->fts_statp; #ifdef FTS_WHITEOUT /* Check for whiteout. */ if (p->fts_flags & FTS_ISW) { if (sbp != &sb) { memset(sbp, '\0', sizeof(*sbp)); sbp->st_mode = S_IFWHT; } return (FTS_W); } #endif /* * If doing a logical walk, or application requested FTS_FOLLOW, do * a stat(2). If that fails, check for a non-existent symlink. If * fail, set the errno from the stat call. */ if (ISSET(FTS_LOGICAL) || follow) { if (freebsd11_stat(p->fts_accpath, sbp)) { saved_errno = errno; if (!freebsd11_lstat(p->fts_accpath, sbp)) { errno = 0; return (FTS_SLNONE); } p->fts_errno = saved_errno; goto err; } } else if (freebsd11_lstat(p->fts_accpath, sbp)) { p->fts_errno = errno; err: memset(sbp, 0, sizeof(*sbp)); return (FTS_NS); } if (S_ISDIR(sbp->st_mode)) { /* * Set the device/inode. Used to find cycles and check for * crossing mount points. Also remember the link count, used * in fts_build to limit the number of stat calls. It is * understood that these fields are only referenced if fts_info * is set to FTS_D. */ dev = p->fts_dev = sbp->st_dev; ino = p->fts_ino = sbp->st_ino; p->fts_nlink = sbp->st_nlink; if (ISDOT(p->fts_name)) return (FTS_DOT); /* * Cycle detection is done by brute force when the directory * is first encountered. If the tree gets deep enough or the * number of symbolic links to directories is high enough, * something faster might be worthwhile. */ for (t = p->fts_parent; t->fts_level >= FTS_ROOTLEVEL; t = t->fts_parent) if (ino == t->fts_ino && dev == t->fts_dev) { p->fts_cycle = t; return (FTS_DC); } return (FTS_D); } if (S_ISLNK(sbp->st_mode)) return (FTS_SL); if (S_ISREG(sbp->st_mode)) return (FTS_F); return (FTS_DEFAULT); } /* * The comparison function takes pointers to pointers to FTSENT structures. * Qsort wants a comparison function that takes pointers to void. * (Both with appropriate levels of const-poisoning, of course!) * Use a trampoline function to deal with the difference. */ static int fts_compar(const void *a, const void *b) { FTS *parent; parent = (*(const FTSENT * const *)a)->fts_fts; return (*parent->fts_compar)(a, b); } static FTSENT * fts_sort(FTS *sp, FTSENT *head, int nitems) { FTSENT **ap, *p; /* * Construct an array of pointers to the structures and call qsort(3). * Reassemble the array in the order returned by qsort. If unable to * sort for memory reasons, return the directory entries in their * current order. Allocate enough space for the current needs plus * 40 so don't realloc one entry at a time. */ if (nitems > sp->fts_nitems) { sp->fts_nitems = nitems + 40; if ((sp->fts_array = reallocf(sp->fts_array, sp->fts_nitems * sizeof(FTSENT *))) == NULL) { sp->fts_nitems = 0; return (head); } } for (ap = sp->fts_array, p = head; p; p = p->fts_link) *ap++ = p; qsort(sp->fts_array, nitems, sizeof(FTSENT *), fts_compar); for (head = *(ap = sp->fts_array); --nitems; ++ap) ap[0]->fts_link = ap[1]; ap[0]->fts_link = NULL; return (head); } static FTSENT * fts_alloc(FTS *sp, char *name, int namelen) { FTSENT *p; size_t len; struct ftsent_withstat { FTSENT ent; struct freebsd11_stat statbuf; }; /* * The file name is a variable length array and no stat structure is * necessary if the user has set the nostat bit. Allocate the FTSENT * structure, the file name and the stat structure in one chunk, but * be careful that the stat structure is reasonably aligned. */ if (ISSET(FTS_NOSTAT)) len = sizeof(FTSENT) + namelen + 1; else len = sizeof(struct ftsent_withstat) + namelen + 1; if ((p = malloc(len)) == NULL) return (NULL); if (ISSET(FTS_NOSTAT)) { p->fts_name = (char *)(p + 1); p->fts_statp = NULL; } else { p->fts_name = (char *)((struct ftsent_withstat *)p + 1); p->fts_statp = &((struct ftsent_withstat *)p)->statbuf; } /* Copy the name and guarantee NUL termination. */ memcpy(p->fts_name, name, namelen); p->fts_name[namelen] = '\0'; p->fts_namelen = namelen; p->fts_path = sp->fts_path; p->fts_errno = 0; p->fts_flags = 0; p->fts_instr = FTS_NOINSTR; p->fts_number = 0; p->fts_pointer = NULL; p->fts_fts = sp; return (p); } static void fts_lfree(FTSENT *head) { FTSENT *p; /* Free a linked list of structures. */ while ((p = head)) { head = head->fts_link; free(p); } } /* * Allow essentially unlimited paths; find, rm, ls should all work on any tree. * Most systems will allow creation of paths much longer than MAXPATHLEN, even * though the kernel won't resolve them. Add the size (not just what's needed) * plus 256 bytes so don't realloc the path 2 bytes at a time. */ static int fts_palloc(FTS *sp, size_t more) { sp->fts_pathlen += more + 256; /* * Check for possible wraparound. In an FTS, fts_pathlen is * a signed int but in an FTSENT it is an unsigned short. * We limit fts_pathlen to USHRT_MAX to be safe in both cases. */ if (sp->fts_pathlen < 0 || sp->fts_pathlen >= USHRT_MAX) { if (sp->fts_path) free(sp->fts_path); sp->fts_path = NULL; errno = ENAMETOOLONG; return (1); } sp->fts_path = reallocf(sp->fts_path, sp->fts_pathlen); return (sp->fts_path == NULL); } /* * When the path is realloc'd, have to fix all of the pointers in structures * already returned. */ static void fts_padjust(FTS *sp, FTSENT *head) { FTSENT *p; char *addr = sp->fts_path; #define ADJUST(p) do { \ if ((p)->fts_accpath != (p)->fts_name) { \ (p)->fts_accpath = \ (char *)addr + ((p)->fts_accpath - (p)->fts_path); \ } \ (p)->fts_path = addr; \ } while (0) /* Adjust the current set of children. */ for (p = sp->fts_child; p; p = p->fts_link) ADJUST(p); /* Adjust the rest of the tree, including the current level. */ for (p = head; p->fts_level >= FTS_ROOTLEVEL;) { ADJUST(p); p = p->fts_link ? p->fts_link : p->fts_parent; } } static size_t fts_maxarglen(char * const *argv) { size_t len, max; for (max = 0; *argv; ++argv) if ((len = strlen(*argv)) > max) max = len; return (max + 1); } /* * Change to dir specified by fd or p->fts_accpath without getting * tricked by someone changing the world out from underneath us. * Assumes p->fts_dev and p->fts_ino are filled in. */ static int fts_safe_changedir(FTS *sp, FTSENT *p, int fd, char *path) { int ret, oerrno, newfd; struct freebsd11_stat sb; newfd = fd; if (ISSET(FTS_NOCHDIR)) return (0); if (fd < 0 && (newfd = _open(path, O_RDONLY | O_CLOEXEC, 0)) < 0) return (-1); if (freebsd11_fstat(newfd, &sb)) { ret = -1; goto bail; } if (p->fts_dev != sb.st_dev || p->fts_ino != sb.st_ino) { errno = ENOENT; /* disinformation */ ret = -1; goto bail; } ret = fchdir(newfd); bail: oerrno = errno; if (fd < 0) (void)_close(newfd); errno = oerrno; return (ret); } /* * Check if the filesystem for "ent" has UFS-style links. */ static int fts_ufslinks(FTS *sp, const FTSENT *ent) { struct _fts_private *priv; const char **cpp; priv = (struct _fts_private *)sp; /* * If this node's device is different from the previous, grab * the filesystem information, and decide on the reliability * of the link information from this filesystem for stat(2) * avoidance. */ if (priv->ftsp_dev != ent->fts_dev) { if (freebsd11_statfs(ent->fts_path, &priv->ftsp_statfs) != -1) { priv->ftsp_dev = ent->fts_dev; priv->ftsp_linksreliable = 0; for (cpp = ufslike_filesystems; *cpp; cpp++) { if (strcmp(priv->ftsp_statfs.f_fstypename, *cpp) == 0) { priv->ftsp_linksreliable = 1; break; } } } else { priv->ftsp_linksreliable = 0; } } return (priv->ftsp_linksreliable); } __sym_compat(fts_open, __fts_open_44bsd, FBSD_1.0); __sym_compat(fts_close, __fts_close_44bsd, FBSD_1.0); __sym_compat(fts_read, __fts_read_44bsd, FBSD_1.0); __sym_compat(fts_set, __fts_set_44bsd, FBSD_1.0); __sym_compat(fts_children, __fts_children_44bsd, FBSD_1.0); __sym_compat(fts_get_clientptr, __fts_get_clientptr_44bsd, FBSD_1.0); __sym_compat(fts_get_stream, __fts_get_stream_44bsd, FBSD_1.0); __sym_compat(fts_set_clientptr, __fts_set_clientptr_44bsd, FBSD_1.0); Index: head/lib/libc/gen/fts-compat11.c =================================================================== --- head/lib/libc/gen/fts-compat11.c (revision 335897) +++ head/lib/libc/gen/fts-compat11.c (revision 335898) @@ -1,1199 +1,1194 @@ /*- * Copyright (c) 1990, 1993, 1994 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * from: $OpenBSD: fts.c,v 1.22 1999/10/03 19:22:22 millert Exp $ + * From: @(#)fts.c 8.6 (Berkeley) 8/14/94 + * From: $OpenBSD: fts.c,v 1.22 1999/10/03 19:22:22 millert Exp $ */ - -#if 0 -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)fts.c 8.6 (Berkeley) 8/14/94"; -#endif /* LIBC_SCCS and not lint */ -#endif #include __FBSDID("$FreeBSD$"); #include "namespace.h" #include #define _WANT_FREEBSD11_STATFS #include #define _WANT_FREEBSD11_STAT #include #define _WANT_FREEBSD11_DIRENT #include #include #include #include #include #include #include #include "gen-compat.h" #include "fts-compat11.h" #include "un-namespace.h" #include "gen-private.h" static FTSENT11 *fts_alloc(FTS11 *, char *, size_t); static FTSENT11 *fts_build(FTS11 *, int); static void fts_lfree(FTSENT11 *); static void fts_load(FTS11 *, FTSENT11 *); static size_t fts_maxarglen(char * const *); static void fts_padjust(FTS11 *, FTSENT11 *); static int fts_palloc(FTS11 *, size_t); static FTSENT11 *fts_sort(FTS11 *, FTSENT11 *, size_t); static int fts_stat(FTS11 *, FTSENT11 *, int, int); static int fts_safe_changedir(FTS11 *, FTSENT11 *, int, char *); static int fts_ufslinks(FTS11 *, const FTSENT11 *); #define ISDOT(a) (a[0] == '.' && (!a[1] || (a[1] == '.' && !a[2]))) #define CLR(opt) (sp->fts_options &= ~(opt)) #define ISSET(opt) (sp->fts_options & (opt)) #define SET(opt) (sp->fts_options |= (opt)) #define FCHDIR(sp, fd) (!ISSET(FTS_NOCHDIR) && fchdir(fd)) /* fts_build flags */ #define BCHILD 1 /* fts_children */ #define BNAMES 2 /* fts_children, names only */ #define BREAD 3 /* fts_read */ /* * Internal representation of an FTS, including extra implementation * details. The FTS returned from fts_open points to this structure's * ftsp_fts member (and can be cast to an _fts_private as required) */ struct _fts_private11 { FTS11 ftsp_fts; struct freebsd11_statfs ftsp_statfs; uint32_t ftsp_dev; int ftsp_linksreliable; }; /* * The "FTS_NOSTAT" option can avoid a lot of calls to stat(2) if it * knows that a directory could not possibly have subdirectories. This * is decided by looking at the link count: a subdirectory would * increment its parent's link count by virtue of its own ".." entry. * This assumption only holds for UFS-like filesystems that implement * links and directories this way, so we must punt for others. */ static const char *ufslike_filesystems[] = { "ufs", "zfs", "nfs", "ext2fs", 0 }; FTS11 * freebsd11_fts_open(char * const *argv, int options, int (*compar)(const FTSENT11 * const *, const FTSENT11 * const *)) { struct _fts_private11 *priv; FTS11 *sp; FTSENT11 *p, *root; FTSENT11 *parent, *tmp; size_t len, nitems; /* Options check. */ if (options & ~FTS_OPTIONMASK) { errno = EINVAL; return (NULL); } /* fts_open() requires at least one path */ if (*argv == NULL) { errno = EINVAL; return (NULL); } /* Allocate/initialize the stream. */ if ((priv = calloc(1, sizeof(*priv))) == NULL) return (NULL); sp = &priv->ftsp_fts; sp->fts_compar = compar; sp->fts_options = options; /* Logical walks turn on NOCHDIR; symbolic links are too hard. */ if (ISSET(FTS_LOGICAL)) SET(FTS_NOCHDIR); /* * Start out with 1K of path space, and enough, in any case, * to hold the user's paths. */ if (fts_palloc(sp, MAX(fts_maxarglen(argv), MAXPATHLEN))) goto mem1; /* Allocate/initialize root's parent. */ if ((parent = fts_alloc(sp, "", 0)) == NULL) goto mem2; parent->fts_level = FTS_ROOTPARENTLEVEL; /* Shush, GCC. */ tmp = NULL; /* Allocate/initialize root(s). */ for (root = NULL, nitems = 0; *argv != NULL; ++argv, ++nitems) { len = strlen(*argv); p = fts_alloc(sp, *argv, len); p->fts_level = FTS_ROOTLEVEL; p->fts_parent = parent; p->fts_accpath = p->fts_name; p->fts_info = fts_stat(sp, p, ISSET(FTS_COMFOLLOW), -1); /* Command-line "." and ".." are real directories. */ if (p->fts_info == FTS_DOT) p->fts_info = FTS_D; /* * If comparison routine supplied, traverse in sorted * order; otherwise traverse in the order specified. */ if (compar) { p->fts_link = root; root = p; } else { p->fts_link = NULL; if (root == NULL) tmp = root = p; else { tmp->fts_link = p; tmp = p; } } } if (compar && nitems > 1) root = fts_sort(sp, root, nitems); /* * Allocate a dummy pointer and make fts_read think that we've just * finished the node before the root(s); set p->fts_info to FTS_INIT * so that everything about the "current" node is ignored. */ if ((sp->fts_cur = fts_alloc(sp, "", 0)) == NULL) goto mem3; sp->fts_cur->fts_link = root; sp->fts_cur->fts_info = FTS_INIT; /* * If using chdir(2), grab a file descriptor pointing to dot to ensure * that we can get back here; this could be avoided for some paths, * but almost certainly not worth the effort. Slashes, symbolic links, * and ".." are all fairly nasty problems. Note, if we can't get the * descriptor we run anyway, just more slowly. */ if (!ISSET(FTS_NOCHDIR) && (sp->fts_rfd = _open(".", O_RDONLY | O_CLOEXEC, 0)) < 0) SET(FTS_NOCHDIR); return (sp); mem3: fts_lfree(root); free(parent); mem2: free(sp->fts_path); mem1: free(sp); return (NULL); } static void fts_load(FTS11 *sp, FTSENT11 *p) { size_t len; char *cp; /* * Load the stream structure for the next traversal. Since we don't * actually enter the directory until after the preorder visit, set * the fts_accpath field specially so the chdir gets done to the right * place and the user can access the first node. From fts_open it's * known that the path will fit. */ len = p->fts_pathlen = p->fts_namelen; memmove(sp->fts_path, p->fts_name, len + 1); if ((cp = strrchr(p->fts_name, '/')) && (cp != p->fts_name || cp[1])) { len = strlen(++cp); memmove(p->fts_name, cp, len + 1); p->fts_namelen = len; } p->fts_accpath = p->fts_path = sp->fts_path; sp->fts_dev = p->fts_dev; } int freebsd11_fts_close(FTS11 *sp) { FTSENT11 *freep, *p; int saved_errno; /* * This still works if we haven't read anything -- the dummy structure * points to the root list, so we step through to the end of the root * list which has a valid parent pointer. */ if (sp->fts_cur) { for (p = sp->fts_cur; p->fts_level >= FTS_ROOTLEVEL;) { freep = p; p = p->fts_link != NULL ? p->fts_link : p->fts_parent; free(freep); } free(p); } /* Free up child linked list, sort array, path buffer. */ if (sp->fts_child) fts_lfree(sp->fts_child); if (sp->fts_array) free(sp->fts_array); free(sp->fts_path); /* Return to original directory, save errno if necessary. */ if (!ISSET(FTS_NOCHDIR)) { saved_errno = fchdir(sp->fts_rfd) ? errno : 0; (void)_close(sp->fts_rfd); /* Set errno and return. */ if (saved_errno != 0) { /* Free up the stream pointer. */ free(sp); errno = saved_errno; return (-1); } } /* Free up the stream pointer. */ free(sp); return (0); } /* * Special case of "/" at the end of the path so that slashes aren't * appended which would cause paths to be written as "....//foo". */ #define NAPPEND(p) \ (p->fts_path[p->fts_pathlen - 1] == '/' \ ? p->fts_pathlen - 1 : p->fts_pathlen) FTSENT11 * freebsd11_fts_read(FTS11 *sp) { FTSENT11 *p, *tmp; int instr; char *t; int saved_errno; /* If finished or unrecoverable error, return NULL. */ if (sp->fts_cur == NULL || ISSET(FTS_STOP)) return (NULL); /* Set current node pointer. */ p = sp->fts_cur; /* Save and zero out user instructions. */ instr = p->fts_instr; p->fts_instr = FTS_NOINSTR; /* Any type of file may be re-visited; re-stat and re-turn. */ if (instr == FTS_AGAIN) { p->fts_info = fts_stat(sp, p, 0, -1); return (p); } /* * Following a symlink -- SLNONE test allows application to see * SLNONE and recover. If indirecting through a symlink, have * keep a pointer to current location. If unable to get that * pointer, follow fails. */ if (instr == FTS_FOLLOW && (p->fts_info == FTS_SL || p->fts_info == FTS_SLNONE)) { p->fts_info = fts_stat(sp, p, 1, -1); if (p->fts_info == FTS_D && !ISSET(FTS_NOCHDIR)) { if ((p->fts_symfd = _open(".", O_RDONLY | O_CLOEXEC, 0)) < 0) { p->fts_errno = errno; p->fts_info = FTS_ERR; } else p->fts_flags |= FTS_SYMFOLLOW; } return (p); } /* Directory in pre-order. */ if (p->fts_info == FTS_D) { /* If skipped or crossed mount point, do post-order visit. */ if (instr == FTS_SKIP || (ISSET(FTS_XDEV) && p->fts_dev != sp->fts_dev)) { if (p->fts_flags & FTS_SYMFOLLOW) (void)_close(p->fts_symfd); if (sp->fts_child) { fts_lfree(sp->fts_child); sp->fts_child = NULL; } p->fts_info = FTS_DP; return (p); } /* Rebuild if only read the names and now traversing. */ if (sp->fts_child != NULL && ISSET(FTS_NAMEONLY)) { CLR(FTS_NAMEONLY); fts_lfree(sp->fts_child); sp->fts_child = NULL; } /* * Cd to the subdirectory. * * If have already read and now fail to chdir, whack the list * to make the names come out right, and set the parent errno * so the application will eventually get an error condition. * Set the FTS_DONTCHDIR flag so that when we logically change * directories back to the parent we don't do a chdir. * * If haven't read do so. If the read fails, fts_build sets * FTS_STOP or the fts_info field of the node. */ if (sp->fts_child != NULL) { if (fts_safe_changedir(sp, p, -1, p->fts_accpath)) { p->fts_errno = errno; p->fts_flags |= FTS_DONTCHDIR; for (p = sp->fts_child; p != NULL; p = p->fts_link) p->fts_accpath = p->fts_parent->fts_accpath; } } else if ((sp->fts_child = fts_build(sp, BREAD)) == NULL) { if (ISSET(FTS_STOP)) return (NULL); return (p); } p = sp->fts_child; sp->fts_child = NULL; goto name; } /* Move to the next node on this level. */ next: tmp = p; if ((p = p->fts_link) != NULL) { /* * If reached the top, return to the original directory (or * the root of the tree), and load the paths for the next root. */ if (p->fts_level == FTS_ROOTLEVEL) { if (FCHDIR(sp, sp->fts_rfd)) { SET(FTS_STOP); return (NULL); } free(tmp); fts_load(sp, p); return (sp->fts_cur = p); } /* * User may have called fts_set on the node. If skipped, * ignore. If followed, get a file descriptor so we can * get back if necessary. */ if (p->fts_instr == FTS_SKIP) { free(tmp); goto next; } if (p->fts_instr == FTS_FOLLOW) { p->fts_info = fts_stat(sp, p, 1, -1); if (p->fts_info == FTS_D && !ISSET(FTS_NOCHDIR)) { if ((p->fts_symfd = _open(".", O_RDONLY | O_CLOEXEC, 0)) < 0) { p->fts_errno = errno; p->fts_info = FTS_ERR; } else p->fts_flags |= FTS_SYMFOLLOW; } p->fts_instr = FTS_NOINSTR; } free(tmp); name: t = sp->fts_path + NAPPEND(p->fts_parent); *t++ = '/'; memmove(t, p->fts_name, p->fts_namelen + 1); return (sp->fts_cur = p); } /* Move up to the parent node. */ p = tmp->fts_parent; if (p->fts_level == FTS_ROOTPARENTLEVEL) { /* * Done; free everything up and set errno to 0 so the user * can distinguish between error and EOF. */ free(tmp); free(p); errno = 0; return (sp->fts_cur = NULL); } /* NUL terminate the pathname. */ sp->fts_path[p->fts_pathlen] = '\0'; /* * Return to the parent directory. If at a root node or came through * a symlink, go back through the file descriptor. Otherwise, cd up * one directory. */ if (p->fts_level == FTS_ROOTLEVEL) { if (FCHDIR(sp, sp->fts_rfd)) { SET(FTS_STOP); return (NULL); } } else if (p->fts_flags & FTS_SYMFOLLOW) { if (FCHDIR(sp, p->fts_symfd)) { saved_errno = errno; (void)_close(p->fts_symfd); errno = saved_errno; SET(FTS_STOP); return (NULL); } (void)_close(p->fts_symfd); } else if (!(p->fts_flags & FTS_DONTCHDIR) && fts_safe_changedir(sp, p->fts_parent, -1, "..")) { SET(FTS_STOP); return (NULL); } free(tmp); p->fts_info = p->fts_errno ? FTS_ERR : FTS_DP; return (sp->fts_cur = p); } /* * Fts_set takes the stream as an argument although it's not used in this * implementation; it would be necessary if anyone wanted to add global * semantics to fts using fts_set. An error return is allowed for similar * reasons. */ /* ARGSUSED */ int freebsd11_fts_set(FTS11 *sp, FTSENT11 *p, int instr) { if (instr != 0 && instr != FTS_AGAIN && instr != FTS_FOLLOW && instr != FTS_NOINSTR && instr != FTS_SKIP) { errno = EINVAL; return (1); } p->fts_instr = instr; return (0); } FTSENT11 * freebsd11_fts_children(FTS11 *sp, int instr) { FTSENT11 *p; int fd, rc, serrno; if (instr != 0 && instr != FTS_NAMEONLY) { errno = EINVAL; return (NULL); } /* Set current node pointer. */ p = sp->fts_cur; /* * Errno set to 0 so user can distinguish empty directory from * an error. */ errno = 0; /* Fatal errors stop here. */ if (ISSET(FTS_STOP)) return (NULL); /* Return logical hierarchy of user's arguments. */ if (p->fts_info == FTS_INIT) return (p->fts_link); /* * If not a directory being visited in pre-order, stop here. Could * allow FTS_DNR, assuming the user has fixed the problem, but the * same effect is available with FTS_AGAIN. */ if (p->fts_info != FTS_D /* && p->fts_info != FTS_DNR */) return (NULL); /* Free up any previous child list. */ if (sp->fts_child != NULL) fts_lfree(sp->fts_child); if (instr == FTS_NAMEONLY) { SET(FTS_NAMEONLY); instr = BNAMES; } else instr = BCHILD; /* * If using chdir on a relative path and called BEFORE fts_read does * its chdir to the root of a traversal, we can lose -- we need to * chdir into the subdirectory, and we don't know where the current * directory is, so we can't get back so that the upcoming chdir by * fts_read will work. */ if (p->fts_level != FTS_ROOTLEVEL || p->fts_accpath[0] == '/' || ISSET(FTS_NOCHDIR)) return (sp->fts_child = fts_build(sp, instr)); if ((fd = _open(".", O_RDONLY | O_CLOEXEC, 0)) < 0) return (NULL); sp->fts_child = fts_build(sp, instr); serrno = (sp->fts_child == NULL) ? errno : 0; rc = fchdir(fd); if (rc < 0 && serrno == 0) serrno = errno; (void)_close(fd); errno = serrno; if (rc < 0) return (NULL); return (sp->fts_child); } #ifndef freebsd11_fts_get_clientptr #error "freebsd11_fts_get_clientptr not defined" #endif void * (freebsd11_fts_get_clientptr)(FTS11 *sp) { return (freebsd11_fts_get_clientptr(sp)); } #ifndef freebsd11_fts_get_stream #error "freebsd11_fts_get_stream not defined" #endif FTS11 * (freebsd11_fts_get_stream)(FTSENT11 *p) { return (freebsd11_fts_get_stream(p)); } void freebsd11_fts_set_clientptr(FTS11 *sp, void *clientptr) { sp->fts_clientptr = clientptr; } /* * This is the tricky part -- do not casually change *anything* in here. The * idea is to build the linked list of entries that are used by fts_children * and fts_read. There are lots of special cases. * * The real slowdown in walking the tree is the stat calls. If FTS_NOSTAT is * set and it's a physical walk (so that symbolic links can't be directories), * we can do things quickly. First, if it's a 4.4BSD file system, the type * of the file is in the directory entry. Otherwise, we assume that the number * of subdirectories in a node is equal to the number of links to the parent. * The former skips all stat calls. The latter skips stat calls in any leaf * directories and for any files after the subdirectories in the directory have * been found, cutting the stat calls by about 2/3. */ static FTSENT11 * fts_build(FTS11 *sp, int type) { struct freebsd11_dirent *dp; FTSENT11 *p, *head; FTSENT11 *cur, *tail; DIR *dirp; void *oldaddr; char *cp; int cderrno, descend, oflag, saved_errno, nostat, doadjust; long level; long nlinks; /* has to be signed because -1 is a magic value */ size_t dnamlen, len, maxlen, nitems; /* Set current node pointer. */ cur = sp->fts_cur; /* * Open the directory for reading. If this fails, we're done. * If being called from fts_read, set the fts_info field. */ #ifdef FTS_WHITEOUT if (ISSET(FTS_WHITEOUT)) oflag = DTF_NODUP | DTF_REWIND; else oflag = DTF_HIDEW | DTF_NODUP | DTF_REWIND; #else #define __opendir2(path, flag) opendir(path) #endif if ((dirp = __opendir2(cur->fts_accpath, oflag)) == NULL) { if (type == BREAD) { cur->fts_info = FTS_DNR; cur->fts_errno = errno; } return (NULL); } /* * Nlinks is the number of possible entries of type directory in the * directory if we're cheating on stat calls, 0 if we're not doing * any stat calls at all, -1 if we're doing stats on everything. */ if (type == BNAMES) { nlinks = 0; /* Be quiet about nostat, GCC. */ nostat = 0; } else if (ISSET(FTS_NOSTAT) && ISSET(FTS_PHYSICAL)) { if (fts_ufslinks(sp, cur)) nlinks = cur->fts_nlink - (ISSET(FTS_SEEDOT) ? 0 : 2); else nlinks = -1; nostat = 1; } else { nlinks = -1; nostat = 0; } #ifdef notdef (void)printf("nlinks == %d (cur: %d)\n", nlinks, cur->fts_nlink); (void)printf("NOSTAT %d PHYSICAL %d SEEDOT %d\n", ISSET(FTS_NOSTAT), ISSET(FTS_PHYSICAL), ISSET(FTS_SEEDOT)); #endif /* * If we're going to need to stat anything or we want to descend * and stay in the directory, chdir. If this fails we keep going, * but set a flag so we don't chdir after the post-order visit. * We won't be able to stat anything, but we can still return the * names themselves. Note, that since fts_read won't be able to * chdir into the directory, it will have to return different path * names than before, i.e. "a/b" instead of "b". Since the node * has already been visited in pre-order, have to wait until the * post-order visit to return the error. There is a special case * here, if there was nothing to stat then it's not an error to * not be able to stat. This is all fairly nasty. If a program * needed sorted entries or stat information, they had better be * checking FTS_NS on the returned nodes. */ cderrno = 0; if (nlinks || type == BREAD) { if (fts_safe_changedir(sp, cur, _dirfd(dirp), NULL)) { if (nlinks && type == BREAD) cur->fts_errno = errno; cur->fts_flags |= FTS_DONTCHDIR; descend = 0; cderrno = errno; } else descend = 1; } else descend = 0; /* * Figure out the max file name length that can be stored in the * current path -- the inner loop allocates more path as necessary. * We really wouldn't have to do the maxlen calculations here, we * could do them in fts_read before returning the path, but it's a * lot easier here since the length is part of the dirent structure. * * If not changing directories set a pointer so that can just append * each new name into the path. */ len = NAPPEND(cur); if (ISSET(FTS_NOCHDIR)) { cp = sp->fts_path + len; *cp++ = '/'; } else { /* GCC, you're too verbose. */ cp = NULL; } len++; maxlen = sp->fts_pathlen - len; level = cur->fts_level + 1; /* Read the directory, attaching each entry to the `link' pointer. */ doadjust = 0; for (head = tail = NULL, nitems = 0; dirp && (dp = freebsd11_readdir(dirp));) { dnamlen = dp->d_namlen; if (!ISSET(FTS_SEEDOT) && ISDOT(dp->d_name)) continue; if ((p = fts_alloc(sp, dp->d_name, dnamlen)) == NULL) goto mem1; if (dnamlen >= maxlen) { /* include space for NUL */ oldaddr = sp->fts_path; if (fts_palloc(sp, dnamlen + len + 1)) { /* * No more memory for path or structures. Save * errno, free up the current structure and the * structures already allocated. */ mem1: saved_errno = errno; if (p) free(p); fts_lfree(head); (void)closedir(dirp); cur->fts_info = FTS_ERR; SET(FTS_STOP); errno = saved_errno; return (NULL); } /* Did realloc() change the pointer? */ if (oldaddr != sp->fts_path) { doadjust = 1; if (ISSET(FTS_NOCHDIR)) cp = sp->fts_path + len; } maxlen = sp->fts_pathlen - len; } p->fts_level = level; p->fts_parent = sp->fts_cur; p->fts_pathlen = len + dnamlen; #ifdef FTS_WHITEOUT if (dp->d_type == DT_WHT) p->fts_flags |= FTS_ISW; #endif if (cderrno) { if (nlinks) { p->fts_info = FTS_NS; p->fts_errno = cderrno; } else p->fts_info = FTS_NSOK; p->fts_accpath = cur->fts_accpath; } else if (nlinks == 0 #ifdef DT_DIR || (nostat && dp->d_type != DT_DIR && dp->d_type != DT_UNKNOWN) #endif ) { p->fts_accpath = ISSET(FTS_NOCHDIR) ? p->fts_path : p->fts_name; p->fts_info = FTS_NSOK; } else { /* Build a file name for fts_stat to stat. */ if (ISSET(FTS_NOCHDIR)) { p->fts_accpath = p->fts_path; memmove(cp, p->fts_name, p->fts_namelen + 1); p->fts_info = fts_stat(sp, p, 0, _dirfd(dirp)); } else { p->fts_accpath = p->fts_name; p->fts_info = fts_stat(sp, p, 0, -1); } /* Decrement link count if applicable. */ if (nlinks > 0 && (p->fts_info == FTS_D || p->fts_info == FTS_DC || p->fts_info == FTS_DOT)) --nlinks; } /* We walk in directory order so "ls -f" doesn't get upset. */ p->fts_link = NULL; if (head == NULL) head = tail = p; else { tail->fts_link = p; tail = p; } ++nitems; } if (dirp) (void)closedir(dirp); /* * If realloc() changed the address of the path, adjust the * addresses for the rest of the tree and the dir list. */ if (doadjust) fts_padjust(sp, head); /* * If not changing directories, reset the path back to original * state. */ if (ISSET(FTS_NOCHDIR)) sp->fts_path[cur->fts_pathlen] = '\0'; /* * If descended after called from fts_children or after called from * fts_read and nothing found, get back. At the root level we use * the saved fd; if one of fts_open()'s arguments is a relative path * to an empty directory, we wind up here with no other way back. If * can't get back, we're done. */ if (descend && (type == BCHILD || !nitems) && (cur->fts_level == FTS_ROOTLEVEL ? FCHDIR(sp, sp->fts_rfd) : fts_safe_changedir(sp, cur->fts_parent, -1, ".."))) { fts_lfree(head); cur->fts_info = FTS_ERR; SET(FTS_STOP); return (NULL); } /* If didn't find anything, return NULL. */ if (!nitems) { if (type == BREAD) cur->fts_info = FTS_DP; return (NULL); } /* Sort the entries. */ if (sp->fts_compar && nitems > 1) head = fts_sort(sp, head, nitems); return (head); } static int fts_stat(FTS11 *sp, FTSENT11 *p, int follow, int dfd) { FTSENT11 *t; uint32_t dev; uint32_t ino; struct freebsd11_stat *sbp, sb; int saved_errno; const char *path; if (dfd == -1) path = p->fts_accpath, dfd = AT_FDCWD; else path = p->fts_name; /* If user needs stat info, stat buffer already allocated. */ sbp = ISSET(FTS_NOSTAT) ? &sb : p->fts_statp; #ifdef FTS_WHITEOUT /* Check for whiteout. */ if (p->fts_flags & FTS_ISW) { if (sbp != &sb) { memset(sbp, '\0', sizeof(*sbp)); sbp->st_mode = S_IFWHT; } return (FTS_W); } #endif /* * If doing a logical walk, or application requested FTS_FOLLOW, do * a stat(2). If that fails, check for a non-existent symlink. If * fail, set the errno from the stat call. */ if (ISSET(FTS_LOGICAL) || follow) { if (freebsd11_fstatat(dfd, path, sbp, 0)) { saved_errno = errno; if (freebsd11_fstatat(dfd, path, sbp, AT_SYMLINK_NOFOLLOW)) { p->fts_errno = saved_errno; goto err; } errno = 0; if (S_ISLNK(sbp->st_mode)) return (FTS_SLNONE); } } else if (freebsd11_fstatat(dfd, path, sbp, AT_SYMLINK_NOFOLLOW)) { p->fts_errno = errno; err: memset(sbp, 0, sizeof(*sbp)); return (FTS_NS); } if (S_ISDIR(sbp->st_mode)) { /* * Set the device/inode. Used to find cycles and check for * crossing mount points. Also remember the link count, used * in fts_build to limit the number of stat calls. It is * understood that these fields are only referenced if fts_info * is set to FTS_D. */ dev = p->fts_dev = sbp->st_dev; ino = p->fts_ino = sbp->st_ino; p->fts_nlink = sbp->st_nlink; if (ISDOT(p->fts_name)) return (FTS_DOT); /* * Cycle detection is done by brute force when the directory * is first encountered. If the tree gets deep enough or the * number of symbolic links to directories is high enough, * something faster might be worthwhile. */ for (t = p->fts_parent; t->fts_level >= FTS_ROOTLEVEL; t = t->fts_parent) if (ino == t->fts_ino && dev == t->fts_dev) { p->fts_cycle = t; return (FTS_DC); } return (FTS_D); } if (S_ISLNK(sbp->st_mode)) return (FTS_SL); if (S_ISREG(sbp->st_mode)) return (FTS_F); return (FTS_DEFAULT); } /* * The comparison function takes pointers to pointers to FTSENT structures. * Qsort wants a comparison function that takes pointers to void. * (Both with appropriate levels of const-poisoning, of course!) * Use a trampoline function to deal with the difference. */ static int fts_compar(const void *a, const void *b) { FTS11 *parent; parent = (*(const FTSENT11 * const *)a)->fts_fts; return (*parent->fts_compar)(a, b); } static FTSENT11 * fts_sort(FTS11 *sp, FTSENT11 *head, size_t nitems) { FTSENT11 **ap, *p; /* * Construct an array of pointers to the structures and call qsort(3). * Reassemble the array in the order returned by qsort. If unable to * sort for memory reasons, return the directory entries in their * current order. Allocate enough space for the current needs plus * 40 so don't realloc one entry at a time. */ if (nitems > sp->fts_nitems) { sp->fts_nitems = nitems + 40; if ((sp->fts_array = reallocf(sp->fts_array, sp->fts_nitems * sizeof(FTSENT11 *))) == NULL) { sp->fts_nitems = 0; return (head); } } for (ap = sp->fts_array, p = head; p; p = p->fts_link) *ap++ = p; qsort(sp->fts_array, nitems, sizeof(FTSENT11 *), fts_compar); for (head = *(ap = sp->fts_array); --nitems; ++ap) ap[0]->fts_link = ap[1]; ap[0]->fts_link = NULL; return (head); } static FTSENT11 * fts_alloc(FTS11 *sp, char *name, size_t namelen) { FTSENT11 *p; size_t len; struct ftsent11_withstat { FTSENT11 ent; struct freebsd11_stat statbuf; }; /* * The file name is a variable length array and no stat structure is * necessary if the user has set the nostat bit. Allocate the FTSENT * structure, the file name and the stat structure in one chunk, but * be careful that the stat structure is reasonably aligned. */ if (ISSET(FTS_NOSTAT)) len = sizeof(FTSENT11) + namelen + 1; else len = sizeof(struct ftsent11_withstat) + namelen + 1; if ((p = malloc(len)) == NULL) return (NULL); if (ISSET(FTS_NOSTAT)) { p->fts_name = (char *)(p + 1); p->fts_statp = NULL; } else { p->fts_name = (char *)((struct ftsent11_withstat *)p + 1); p->fts_statp = &((struct ftsent11_withstat *)p)->statbuf; } /* Copy the name and guarantee NUL termination. */ memcpy(p->fts_name, name, namelen); p->fts_name[namelen] = '\0'; p->fts_namelen = namelen; p->fts_path = sp->fts_path; p->fts_errno = 0; p->fts_flags = 0; p->fts_instr = FTS_NOINSTR; p->fts_number = 0; p->fts_pointer = NULL; p->fts_fts = sp; return (p); } static void fts_lfree(FTSENT11 *head) { FTSENT11 *p; /* Free a linked list of structures. */ while ((p = head)) { head = head->fts_link; free(p); } } /* * Allow essentially unlimited paths; find, rm, ls should all work on any tree. * Most systems will allow creation of paths much longer than MAXPATHLEN, even * though the kernel won't resolve them. Add the size (not just what's needed) * plus 256 bytes so don't realloc the path 2 bytes at a time. */ static int fts_palloc(FTS11 *sp, size_t more) { sp->fts_pathlen += more + 256; sp->fts_path = reallocf(sp->fts_path, sp->fts_pathlen); return (sp->fts_path == NULL); } /* * When the path is realloc'd, have to fix all of the pointers in structures * already returned. */ static void fts_padjust(FTS11 *sp, FTSENT11 *head) { FTSENT11 *p; char *addr = sp->fts_path; #define ADJUST(p) do { \ if ((p)->fts_accpath != (p)->fts_name) { \ (p)->fts_accpath = \ (char *)addr + ((p)->fts_accpath - (p)->fts_path); \ } \ (p)->fts_path = addr; \ } while (0) /* Adjust the current set of children. */ for (p = sp->fts_child; p; p = p->fts_link) ADJUST(p); /* Adjust the rest of the tree, including the current level. */ for (p = head; p->fts_level >= FTS_ROOTLEVEL;) { ADJUST(p); p = p->fts_link ? p->fts_link : p->fts_parent; } } static size_t fts_maxarglen(char * const *argv) { size_t len, max; for (max = 0; *argv; ++argv) if ((len = strlen(*argv)) > max) max = len; return (max + 1); } /* * Change to dir specified by fd or p->fts_accpath without getting * tricked by someone changing the world out from underneath us. * Assumes p->fts_dev and p->fts_ino are filled in. */ static int fts_safe_changedir(FTS11 *sp, FTSENT11 *p, int fd, char *path) { int ret, oerrno, newfd; struct freebsd11_stat sb; newfd = fd; if (ISSET(FTS_NOCHDIR)) return (0); if (fd < 0 && (newfd = _open(path, O_RDONLY | O_DIRECTORY | O_CLOEXEC, 0)) < 0) return (-1); if (freebsd11_fstat(newfd, &sb)) { ret = -1; goto bail; } if (p->fts_dev != sb.st_dev || p->fts_ino != sb.st_ino) { errno = ENOENT; /* disinformation */ ret = -1; goto bail; } ret = fchdir(newfd); bail: oerrno = errno; if (fd < 0) (void)_close(newfd); errno = oerrno; return (ret); } /* * Check if the filesystem for "ent" has UFS-style links. */ static int fts_ufslinks(FTS11 *sp, const FTSENT11 *ent) { struct _fts_private11 *priv; const char **cpp; priv = (struct _fts_private11 *)sp; /* * If this node's device is different from the previous, grab * the filesystem information, and decide on the reliability * of the link information from this filesystem for stat(2) * avoidance. */ if (priv->ftsp_dev != ent->fts_dev) { if (freebsd11_statfs(ent->fts_path, &priv->ftsp_statfs) != -1) { priv->ftsp_dev = ent->fts_dev; priv->ftsp_linksreliable = 0; for (cpp = ufslike_filesystems; *cpp; cpp++) { if (strcmp(priv->ftsp_statfs.f_fstypename, *cpp) == 0) { priv->ftsp_linksreliable = 1; break; } } } else { priv->ftsp_linksreliable = 0; } } return (priv->ftsp_linksreliable); } __sym_compat(fts_open, freebsd11_fts_open, FBSD_1.1); __sym_compat(fts_close, freebsd11_fts_close, FBSD_1.1); __sym_compat(fts_read, freebsd11_fts_read, FBSD_1.1); __sym_compat(fts_set, freebsd11_fts_set, FBSD_1.1); __sym_compat(fts_children, freebsd11_fts_children, FBSD_1.1); __sym_compat(fts_get_clientptr, freebsd11_fts_get_clientptr, FBSD_1.1); __sym_compat(fts_get_stream, freebsd11_fts_get_stream, FBSD_1.1); __sym_compat(fts_set_clientptr, freebsd11_fts_set_clientptr, FBSD_1.1); Index: head/lib/libc/gen/fts.c =================================================================== --- head/lib/libc/gen/fts.c (revision 335897) +++ head/lib/libc/gen/fts.c (revision 335898) @@ -1,1185 +1,1180 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1990, 1993, 1994 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $OpenBSD: fts.c,v 1.22 1999/10/03 19:22:22 millert Exp $ */ -#if 0 -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)fts.c 8.6 (Berkeley) 8/14/94"; -#endif /* LIBC_SCCS and not lint */ -#endif - #include +__SCCSID("@(#)fts.c 8.6 (Berkeley) 8/14/94"); __FBSDID("$FreeBSD$"); #include "namespace.h" #include #include #include #include #include #include #include #include #include #include #include "un-namespace.h" #include "gen-private.h" static FTSENT *fts_alloc(FTS *, char *, size_t); static FTSENT *fts_build(FTS *, int); static void fts_lfree(FTSENT *); static void fts_load(FTS *, FTSENT *); static size_t fts_maxarglen(char * const *); static void fts_padjust(FTS *, FTSENT *); static int fts_palloc(FTS *, size_t); static FTSENT *fts_sort(FTS *, FTSENT *, size_t); static int fts_stat(FTS *, FTSENT *, int, int); static int fts_safe_changedir(FTS *, FTSENT *, int, char *); static int fts_ufslinks(FTS *, const FTSENT *); #define ISDOT(a) (a[0] == '.' && (!a[1] || (a[1] == '.' && !a[2]))) #define CLR(opt) (sp->fts_options &= ~(opt)) #define ISSET(opt) (sp->fts_options & (opt)) #define SET(opt) (sp->fts_options |= (opt)) #define FCHDIR(sp, fd) (!ISSET(FTS_NOCHDIR) && fchdir(fd)) /* fts_build flags */ #define BCHILD 1 /* fts_children */ #define BNAMES 2 /* fts_children, names only */ #define BREAD 3 /* fts_read */ /* * Internal representation of an FTS, including extra implementation * details. The FTS returned from fts_open points to this structure's * ftsp_fts member (and can be cast to an _fts_private as required) */ struct _fts_private { FTS ftsp_fts; struct statfs ftsp_statfs; dev_t ftsp_dev; int ftsp_linksreliable; }; /* * The "FTS_NOSTAT" option can avoid a lot of calls to stat(2) if it * knows that a directory could not possibly have subdirectories. This * is decided by looking at the link count: a subdirectory would * increment its parent's link count by virtue of its own ".." entry. * This assumption only holds for UFS-like filesystems that implement * links and directories this way, so we must punt for others. */ static const char *ufslike_filesystems[] = { "ufs", "zfs", "nfs", "ext2fs", 0 }; FTS * fts_open(char * const *argv, int options, int (*compar)(const FTSENT * const *, const FTSENT * const *)) { struct _fts_private *priv; FTS *sp; FTSENT *p, *root; FTSENT *parent, *tmp; size_t len, nitems; /* Options check. */ if (options & ~FTS_OPTIONMASK) { errno = EINVAL; return (NULL); } /* fts_open() requires at least one path */ if (*argv == NULL) { errno = EINVAL; return (NULL); } /* Allocate/initialize the stream. */ if ((priv = calloc(1, sizeof(*priv))) == NULL) return (NULL); sp = &priv->ftsp_fts; sp->fts_compar = compar; sp->fts_options = options; /* Logical walks turn on NOCHDIR; symbolic links are too hard. */ if (ISSET(FTS_LOGICAL)) SET(FTS_NOCHDIR); /* * Start out with 1K of path space, and enough, in any case, * to hold the user's paths. */ if (fts_palloc(sp, MAX(fts_maxarglen(argv), MAXPATHLEN))) goto mem1; /* Allocate/initialize root's parent. */ if ((parent = fts_alloc(sp, "", 0)) == NULL) goto mem2; parent->fts_level = FTS_ROOTPARENTLEVEL; /* Shush, GCC. */ tmp = NULL; /* Allocate/initialize root(s). */ for (root = NULL, nitems = 0; *argv != NULL; ++argv, ++nitems) { len = strlen(*argv); p = fts_alloc(sp, *argv, len); p->fts_level = FTS_ROOTLEVEL; p->fts_parent = parent; p->fts_accpath = p->fts_name; p->fts_info = fts_stat(sp, p, ISSET(FTS_COMFOLLOW), -1); /* Command-line "." and ".." are real directories. */ if (p->fts_info == FTS_DOT) p->fts_info = FTS_D; /* * If comparison routine supplied, traverse in sorted * order; otherwise traverse in the order specified. */ if (compar) { p->fts_link = root; root = p; } else { p->fts_link = NULL; if (root == NULL) tmp = root = p; else { tmp->fts_link = p; tmp = p; } } } if (compar && nitems > 1) root = fts_sort(sp, root, nitems); /* * Allocate a dummy pointer and make fts_read think that we've just * finished the node before the root(s); set p->fts_info to FTS_INIT * so that everything about the "current" node is ignored. */ if ((sp->fts_cur = fts_alloc(sp, "", 0)) == NULL) goto mem3; sp->fts_cur->fts_link = root; sp->fts_cur->fts_info = FTS_INIT; /* * If using chdir(2), grab a file descriptor pointing to dot to ensure * that we can get back here; this could be avoided for some paths, * but almost certainly not worth the effort. Slashes, symbolic links, * and ".." are all fairly nasty problems. Note, if we can't get the * descriptor we run anyway, just more slowly. */ if (!ISSET(FTS_NOCHDIR) && (sp->fts_rfd = _open(".", O_RDONLY | O_CLOEXEC, 0)) < 0) SET(FTS_NOCHDIR); return (sp); mem3: fts_lfree(root); free(parent); mem2: free(sp->fts_path); mem1: free(sp); return (NULL); } static void fts_load(FTS *sp, FTSENT *p) { size_t len; char *cp; /* * Load the stream structure for the next traversal. Since we don't * actually enter the directory until after the preorder visit, set * the fts_accpath field specially so the chdir gets done to the right * place and the user can access the first node. From fts_open it's * known that the path will fit. */ len = p->fts_pathlen = p->fts_namelen; memmove(sp->fts_path, p->fts_name, len + 1); if ((cp = strrchr(p->fts_name, '/')) && (cp != p->fts_name || cp[1])) { len = strlen(++cp); memmove(p->fts_name, cp, len + 1); p->fts_namelen = len; } p->fts_accpath = p->fts_path = sp->fts_path; sp->fts_dev = p->fts_dev; } int fts_close(FTS *sp) { FTSENT *freep, *p; int saved_errno; /* * This still works if we haven't read anything -- the dummy structure * points to the root list, so we step through to the end of the root * list which has a valid parent pointer. */ if (sp->fts_cur) { for (p = sp->fts_cur; p->fts_level >= FTS_ROOTLEVEL;) { freep = p; p = p->fts_link != NULL ? p->fts_link : p->fts_parent; free(freep); } free(p); } /* Free up child linked list, sort array, path buffer. */ if (sp->fts_child) fts_lfree(sp->fts_child); if (sp->fts_array) free(sp->fts_array); free(sp->fts_path); /* Return to original directory, save errno if necessary. */ if (!ISSET(FTS_NOCHDIR)) { saved_errno = fchdir(sp->fts_rfd) ? errno : 0; (void)_close(sp->fts_rfd); /* Set errno and return. */ if (saved_errno != 0) { /* Free up the stream pointer. */ free(sp); errno = saved_errno; return (-1); } } /* Free up the stream pointer. */ free(sp); return (0); } /* * Special case of "/" at the end of the path so that slashes aren't * appended which would cause paths to be written as "....//foo". */ #define NAPPEND(p) \ (p->fts_path[p->fts_pathlen - 1] == '/' \ ? p->fts_pathlen - 1 : p->fts_pathlen) FTSENT * fts_read(FTS *sp) { FTSENT *p, *tmp; int instr; char *t; int saved_errno; /* If finished or unrecoverable error, return NULL. */ if (sp->fts_cur == NULL || ISSET(FTS_STOP)) return (NULL); /* Set current node pointer. */ p = sp->fts_cur; /* Save and zero out user instructions. */ instr = p->fts_instr; p->fts_instr = FTS_NOINSTR; /* Any type of file may be re-visited; re-stat and re-turn. */ if (instr == FTS_AGAIN) { p->fts_info = fts_stat(sp, p, 0, -1); return (p); } /* * Following a symlink -- SLNONE test allows application to see * SLNONE and recover. If indirecting through a symlink, have * keep a pointer to current location. If unable to get that * pointer, follow fails. */ if (instr == FTS_FOLLOW && (p->fts_info == FTS_SL || p->fts_info == FTS_SLNONE)) { p->fts_info = fts_stat(sp, p, 1, -1); if (p->fts_info == FTS_D && !ISSET(FTS_NOCHDIR)) { if ((p->fts_symfd = _open(".", O_RDONLY | O_CLOEXEC, 0)) < 0) { p->fts_errno = errno; p->fts_info = FTS_ERR; } else p->fts_flags |= FTS_SYMFOLLOW; } return (p); } /* Directory in pre-order. */ if (p->fts_info == FTS_D) { /* If skipped or crossed mount point, do post-order visit. */ if (instr == FTS_SKIP || (ISSET(FTS_XDEV) && p->fts_dev != sp->fts_dev)) { if (p->fts_flags & FTS_SYMFOLLOW) (void)_close(p->fts_symfd); if (sp->fts_child) { fts_lfree(sp->fts_child); sp->fts_child = NULL; } p->fts_info = FTS_DP; return (p); } /* Rebuild if only read the names and now traversing. */ if (sp->fts_child != NULL && ISSET(FTS_NAMEONLY)) { CLR(FTS_NAMEONLY); fts_lfree(sp->fts_child); sp->fts_child = NULL; } /* * Cd to the subdirectory. * * If have already read and now fail to chdir, whack the list * to make the names come out right, and set the parent errno * so the application will eventually get an error condition. * Set the FTS_DONTCHDIR flag so that when we logically change * directories back to the parent we don't do a chdir. * * If haven't read do so. If the read fails, fts_build sets * FTS_STOP or the fts_info field of the node. */ if (sp->fts_child != NULL) { if (fts_safe_changedir(sp, p, -1, p->fts_accpath)) { p->fts_errno = errno; p->fts_flags |= FTS_DONTCHDIR; for (p = sp->fts_child; p != NULL; p = p->fts_link) p->fts_accpath = p->fts_parent->fts_accpath; } } else if ((sp->fts_child = fts_build(sp, BREAD)) == NULL) { if (ISSET(FTS_STOP)) return (NULL); return (p); } p = sp->fts_child; sp->fts_child = NULL; goto name; } /* Move to the next node on this level. */ next: tmp = p; if ((p = p->fts_link) != NULL) { /* * If reached the top, return to the original directory (or * the root of the tree), and load the paths for the next root. */ if (p->fts_level == FTS_ROOTLEVEL) { if (FCHDIR(sp, sp->fts_rfd)) { SET(FTS_STOP); return (NULL); } free(tmp); fts_load(sp, p); return (sp->fts_cur = p); } /* * User may have called fts_set on the node. If skipped, * ignore. If followed, get a file descriptor so we can * get back if necessary. */ if (p->fts_instr == FTS_SKIP) { free(tmp); goto next; } if (p->fts_instr == FTS_FOLLOW) { p->fts_info = fts_stat(sp, p, 1, -1); if (p->fts_info == FTS_D && !ISSET(FTS_NOCHDIR)) { if ((p->fts_symfd = _open(".", O_RDONLY | O_CLOEXEC, 0)) < 0) { p->fts_errno = errno; p->fts_info = FTS_ERR; } else p->fts_flags |= FTS_SYMFOLLOW; } p->fts_instr = FTS_NOINSTR; } free(tmp); name: t = sp->fts_path + NAPPEND(p->fts_parent); *t++ = '/'; memmove(t, p->fts_name, p->fts_namelen + 1); return (sp->fts_cur = p); } /* Move up to the parent node. */ p = tmp->fts_parent; if (p->fts_level == FTS_ROOTPARENTLEVEL) { /* * Done; free everything up and set errno to 0 so the user * can distinguish between error and EOF. */ free(tmp); free(p); errno = 0; return (sp->fts_cur = NULL); } /* NUL terminate the pathname. */ sp->fts_path[p->fts_pathlen] = '\0'; /* * Return to the parent directory. If at a root node or came through * a symlink, go back through the file descriptor. Otherwise, cd up * one directory. */ if (p->fts_level == FTS_ROOTLEVEL) { if (FCHDIR(sp, sp->fts_rfd)) { SET(FTS_STOP); return (NULL); } } else if (p->fts_flags & FTS_SYMFOLLOW) { if (FCHDIR(sp, p->fts_symfd)) { saved_errno = errno; (void)_close(p->fts_symfd); errno = saved_errno; SET(FTS_STOP); return (NULL); } (void)_close(p->fts_symfd); } else if (!(p->fts_flags & FTS_DONTCHDIR) && fts_safe_changedir(sp, p->fts_parent, -1, "..")) { SET(FTS_STOP); return (NULL); } free(tmp); p->fts_info = p->fts_errno ? FTS_ERR : FTS_DP; return (sp->fts_cur = p); } /* * Fts_set takes the stream as an argument although it's not used in this * implementation; it would be necessary if anyone wanted to add global * semantics to fts using fts_set. An error return is allowed for similar * reasons. */ /* ARGSUSED */ int fts_set(FTS *sp, FTSENT *p, int instr) { if (instr != 0 && instr != FTS_AGAIN && instr != FTS_FOLLOW && instr != FTS_NOINSTR && instr != FTS_SKIP) { errno = EINVAL; return (1); } p->fts_instr = instr; return (0); } FTSENT * fts_children(FTS *sp, int instr) { FTSENT *p; int fd, rc, serrno; if (instr != 0 && instr != FTS_NAMEONLY) { errno = EINVAL; return (NULL); } /* Set current node pointer. */ p = sp->fts_cur; /* * Errno set to 0 so user can distinguish empty directory from * an error. */ errno = 0; /* Fatal errors stop here. */ if (ISSET(FTS_STOP)) return (NULL); /* Return logical hierarchy of user's arguments. */ if (p->fts_info == FTS_INIT) return (p->fts_link); /* * If not a directory being visited in pre-order, stop here. Could * allow FTS_DNR, assuming the user has fixed the problem, but the * same effect is available with FTS_AGAIN. */ if (p->fts_info != FTS_D /* && p->fts_info != FTS_DNR */) return (NULL); /* Free up any previous child list. */ if (sp->fts_child != NULL) fts_lfree(sp->fts_child); if (instr == FTS_NAMEONLY) { SET(FTS_NAMEONLY); instr = BNAMES; } else instr = BCHILD; /* * If using chdir on a relative path and called BEFORE fts_read does * its chdir to the root of a traversal, we can lose -- we need to * chdir into the subdirectory, and we don't know where the current * directory is, so we can't get back so that the upcoming chdir by * fts_read will work. */ if (p->fts_level != FTS_ROOTLEVEL || p->fts_accpath[0] == '/' || ISSET(FTS_NOCHDIR)) return (sp->fts_child = fts_build(sp, instr)); if ((fd = _open(".", O_RDONLY | O_CLOEXEC, 0)) < 0) return (NULL); sp->fts_child = fts_build(sp, instr); serrno = (sp->fts_child == NULL) ? errno : 0; rc = fchdir(fd); if (rc < 0 && serrno == 0) serrno = errno; (void)_close(fd); errno = serrno; if (rc < 0) return (NULL); return (sp->fts_child); } #ifndef fts_get_clientptr #error "fts_get_clientptr not defined" #endif void * (fts_get_clientptr)(FTS *sp) { return (fts_get_clientptr(sp)); } #ifndef fts_get_stream #error "fts_get_stream not defined" #endif FTS * (fts_get_stream)(FTSENT *p) { return (fts_get_stream(p)); } void fts_set_clientptr(FTS *sp, void *clientptr) { sp->fts_clientptr = clientptr; } /* * This is the tricky part -- do not casually change *anything* in here. The * idea is to build the linked list of entries that are used by fts_children * and fts_read. There are lots of special cases. * * The real slowdown in walking the tree is the stat calls. If FTS_NOSTAT is * set and it's a physical walk (so that symbolic links can't be directories), * we can do things quickly. First, if it's a 4.4BSD file system, the type * of the file is in the directory entry. Otherwise, we assume that the number * of subdirectories in a node is equal to the number of links to the parent. * The former skips all stat calls. The latter skips stat calls in any leaf * directories and for any files after the subdirectories in the directory have * been found, cutting the stat calls by about 2/3. */ static FTSENT * fts_build(FTS *sp, int type) { struct dirent *dp; FTSENT *p, *head; FTSENT *cur, *tail; DIR *dirp; void *oldaddr; char *cp; int cderrno, descend, oflag, saved_errno, nostat, doadjust; long level; long nlinks; /* has to be signed because -1 is a magic value */ size_t dnamlen, len, maxlen, nitems; /* Set current node pointer. */ cur = sp->fts_cur; /* * Open the directory for reading. If this fails, we're done. * If being called from fts_read, set the fts_info field. */ #ifdef FTS_WHITEOUT if (ISSET(FTS_WHITEOUT)) oflag = DTF_NODUP | DTF_REWIND; else oflag = DTF_HIDEW | DTF_NODUP | DTF_REWIND; #else #define __opendir2(path, flag) opendir(path) #endif if ((dirp = __opendir2(cur->fts_accpath, oflag)) == NULL) { if (type == BREAD) { cur->fts_info = FTS_DNR; cur->fts_errno = errno; } return (NULL); } /* * Nlinks is the number of possible entries of type directory in the * directory if we're cheating on stat calls, 0 if we're not doing * any stat calls at all, -1 if we're doing stats on everything. */ if (type == BNAMES) { nlinks = 0; /* Be quiet about nostat, GCC. */ nostat = 0; } else if (ISSET(FTS_NOSTAT) && ISSET(FTS_PHYSICAL)) { if (fts_ufslinks(sp, cur)) nlinks = cur->fts_nlink - (ISSET(FTS_SEEDOT) ? 0 : 2); else nlinks = -1; nostat = 1; } else { nlinks = -1; nostat = 0; } #ifdef notdef (void)printf("nlinks == %d (cur: %d)\n", nlinks, cur->fts_nlink); (void)printf("NOSTAT %d PHYSICAL %d SEEDOT %d\n", ISSET(FTS_NOSTAT), ISSET(FTS_PHYSICAL), ISSET(FTS_SEEDOT)); #endif /* * If we're going to need to stat anything or we want to descend * and stay in the directory, chdir. If this fails we keep going, * but set a flag so we don't chdir after the post-order visit. * We won't be able to stat anything, but we can still return the * names themselves. Note, that since fts_read won't be able to * chdir into the directory, it will have to return different path * names than before, i.e. "a/b" instead of "b". Since the node * has already been visited in pre-order, have to wait until the * post-order visit to return the error. There is a special case * here, if there was nothing to stat then it's not an error to * not be able to stat. This is all fairly nasty. If a program * needed sorted entries or stat information, they had better be * checking FTS_NS on the returned nodes. */ cderrno = 0; if (nlinks || type == BREAD) { if (fts_safe_changedir(sp, cur, _dirfd(dirp), NULL)) { if (nlinks && type == BREAD) cur->fts_errno = errno; cur->fts_flags |= FTS_DONTCHDIR; descend = 0; cderrno = errno; } else descend = 1; } else descend = 0; /* * Figure out the max file name length that can be stored in the * current path -- the inner loop allocates more path as necessary. * We really wouldn't have to do the maxlen calculations here, we * could do them in fts_read before returning the path, but it's a * lot easier here since the length is part of the dirent structure. * * If not changing directories set a pointer so that can just append * each new name into the path. */ len = NAPPEND(cur); if (ISSET(FTS_NOCHDIR)) { cp = sp->fts_path + len; *cp++ = '/'; } else { /* GCC, you're too verbose. */ cp = NULL; } len++; maxlen = sp->fts_pathlen - len; level = cur->fts_level + 1; /* Read the directory, attaching each entry to the `link' pointer. */ doadjust = 0; for (head = tail = NULL, nitems = 0; dirp && (dp = readdir(dirp));) { dnamlen = dp->d_namlen; if (!ISSET(FTS_SEEDOT) && ISDOT(dp->d_name)) continue; if ((p = fts_alloc(sp, dp->d_name, dnamlen)) == NULL) goto mem1; if (dnamlen >= maxlen) { /* include space for NUL */ oldaddr = sp->fts_path; if (fts_palloc(sp, dnamlen + len + 1)) { /* * No more memory for path or structures. Save * errno, free up the current structure and the * structures already allocated. */ mem1: saved_errno = errno; if (p) free(p); fts_lfree(head); (void)closedir(dirp); cur->fts_info = FTS_ERR; SET(FTS_STOP); errno = saved_errno; return (NULL); } /* Did realloc() change the pointer? */ if (oldaddr != sp->fts_path) { doadjust = 1; if (ISSET(FTS_NOCHDIR)) cp = sp->fts_path + len; } maxlen = sp->fts_pathlen - len; } p->fts_level = level; p->fts_parent = sp->fts_cur; p->fts_pathlen = len + dnamlen; #ifdef FTS_WHITEOUT if (dp->d_type == DT_WHT) p->fts_flags |= FTS_ISW; #endif if (cderrno) { if (nlinks) { p->fts_info = FTS_NS; p->fts_errno = cderrno; } else p->fts_info = FTS_NSOK; p->fts_accpath = cur->fts_accpath; } else if (nlinks == 0 #ifdef DT_DIR || (nostat && dp->d_type != DT_DIR && dp->d_type != DT_UNKNOWN) #endif ) { p->fts_accpath = ISSET(FTS_NOCHDIR) ? p->fts_path : p->fts_name; p->fts_info = FTS_NSOK; } else { /* Build a file name for fts_stat to stat. */ if (ISSET(FTS_NOCHDIR)) { p->fts_accpath = p->fts_path; memmove(cp, p->fts_name, p->fts_namelen + 1); p->fts_info = fts_stat(sp, p, 0, _dirfd(dirp)); } else { p->fts_accpath = p->fts_name; p->fts_info = fts_stat(sp, p, 0, -1); } /* Decrement link count if applicable. */ if (nlinks > 0 && (p->fts_info == FTS_D || p->fts_info == FTS_DC || p->fts_info == FTS_DOT)) --nlinks; } /* We walk in directory order so "ls -f" doesn't get upset. */ p->fts_link = NULL; if (head == NULL) head = tail = p; else { tail->fts_link = p; tail = p; } ++nitems; } if (dirp) (void)closedir(dirp); /* * If realloc() changed the address of the path, adjust the * addresses for the rest of the tree and the dir list. */ if (doadjust) fts_padjust(sp, head); /* * If not changing directories, reset the path back to original * state. */ if (ISSET(FTS_NOCHDIR)) sp->fts_path[cur->fts_pathlen] = '\0'; /* * If descended after called from fts_children or after called from * fts_read and nothing found, get back. At the root level we use * the saved fd; if one of fts_open()'s arguments is a relative path * to an empty directory, we wind up here with no other way back. If * can't get back, we're done. */ if (descend && (type == BCHILD || !nitems) && (cur->fts_level == FTS_ROOTLEVEL ? FCHDIR(sp, sp->fts_rfd) : fts_safe_changedir(sp, cur->fts_parent, -1, ".."))) { fts_lfree(head); cur->fts_info = FTS_ERR; SET(FTS_STOP); return (NULL); } /* If didn't find anything, return NULL. */ if (!nitems) { if (type == BREAD) cur->fts_info = FTS_DP; return (NULL); } /* Sort the entries. */ if (sp->fts_compar && nitems > 1) head = fts_sort(sp, head, nitems); return (head); } static int fts_stat(FTS *sp, FTSENT *p, int follow, int dfd) { FTSENT *t; dev_t dev; ino_t ino; struct stat *sbp, sb; int saved_errno; const char *path; if (dfd == -1) path = p->fts_accpath, dfd = AT_FDCWD; else path = p->fts_name; /* If user needs stat info, stat buffer already allocated. */ sbp = ISSET(FTS_NOSTAT) ? &sb : p->fts_statp; #ifdef FTS_WHITEOUT /* Check for whiteout. */ if (p->fts_flags & FTS_ISW) { if (sbp != &sb) { memset(sbp, '\0', sizeof(*sbp)); sbp->st_mode = S_IFWHT; } return (FTS_W); } #endif /* * If doing a logical walk, or application requested FTS_FOLLOW, do * a stat(2). If that fails, check for a non-existent symlink. If * fail, set the errno from the stat call. */ if (ISSET(FTS_LOGICAL) || follow) { if (fstatat(dfd, path, sbp, 0)) { saved_errno = errno; if (fstatat(dfd, path, sbp, AT_SYMLINK_NOFOLLOW)) { p->fts_errno = saved_errno; goto err; } errno = 0; if (S_ISLNK(sbp->st_mode)) return (FTS_SLNONE); } } else if (fstatat(dfd, path, sbp, AT_SYMLINK_NOFOLLOW)) { p->fts_errno = errno; err: memset(sbp, 0, sizeof(struct stat)); return (FTS_NS); } if (S_ISDIR(sbp->st_mode)) { /* * Set the device/inode. Used to find cycles and check for * crossing mount points. Also remember the link count, used * in fts_build to limit the number of stat calls. It is * understood that these fields are only referenced if fts_info * is set to FTS_D. */ dev = p->fts_dev = sbp->st_dev; ino = p->fts_ino = sbp->st_ino; p->fts_nlink = sbp->st_nlink; if (ISDOT(p->fts_name)) return (FTS_DOT); /* * Cycle detection is done by brute force when the directory * is first encountered. If the tree gets deep enough or the * number of symbolic links to directories is high enough, * something faster might be worthwhile. */ for (t = p->fts_parent; t->fts_level >= FTS_ROOTLEVEL; t = t->fts_parent) if (ino == t->fts_ino && dev == t->fts_dev) { p->fts_cycle = t; return (FTS_DC); } return (FTS_D); } if (S_ISLNK(sbp->st_mode)) return (FTS_SL); if (S_ISREG(sbp->st_mode)) return (FTS_F); return (FTS_DEFAULT); } /* * The comparison function takes pointers to pointers to FTSENT structures. * Qsort wants a comparison function that takes pointers to void. * (Both with appropriate levels of const-poisoning, of course!) * Use a trampoline function to deal with the difference. */ static int fts_compar(const void *a, const void *b) { FTS *parent; parent = (*(const FTSENT * const *)a)->fts_fts; return (*parent->fts_compar)(a, b); } static FTSENT * fts_sort(FTS *sp, FTSENT *head, size_t nitems) { FTSENT **ap, *p; /* * Construct an array of pointers to the structures and call qsort(3). * Reassemble the array in the order returned by qsort. If unable to * sort for memory reasons, return the directory entries in their * current order. Allocate enough space for the current needs plus * 40 so don't realloc one entry at a time. */ if (nitems > sp->fts_nitems) { sp->fts_nitems = nitems + 40; if ((sp->fts_array = reallocf(sp->fts_array, sp->fts_nitems * sizeof(FTSENT *))) == NULL) { sp->fts_nitems = 0; return (head); } } for (ap = sp->fts_array, p = head; p; p = p->fts_link) *ap++ = p; qsort(sp->fts_array, nitems, sizeof(FTSENT *), fts_compar); for (head = *(ap = sp->fts_array); --nitems; ++ap) ap[0]->fts_link = ap[1]; ap[0]->fts_link = NULL; return (head); } static FTSENT * fts_alloc(FTS *sp, char *name, size_t namelen) { FTSENT *p; size_t len; struct ftsent_withstat { FTSENT ent; struct stat statbuf; }; /* * The file name is a variable length array and no stat structure is * necessary if the user has set the nostat bit. Allocate the FTSENT * structure, the file name and the stat structure in one chunk, but * be careful that the stat structure is reasonably aligned. */ if (ISSET(FTS_NOSTAT)) len = sizeof(FTSENT) + namelen + 1; else len = sizeof(struct ftsent_withstat) + namelen + 1; if ((p = malloc(len)) == NULL) return (NULL); if (ISSET(FTS_NOSTAT)) { p->fts_name = (char *)(p + 1); p->fts_statp = NULL; } else { p->fts_name = (char *)((struct ftsent_withstat *)p + 1); p->fts_statp = &((struct ftsent_withstat *)p)->statbuf; } /* Copy the name and guarantee NUL termination. */ memcpy(p->fts_name, name, namelen); p->fts_name[namelen] = '\0'; p->fts_namelen = namelen; p->fts_path = sp->fts_path; p->fts_errno = 0; p->fts_flags = 0; p->fts_instr = FTS_NOINSTR; p->fts_number = 0; p->fts_pointer = NULL; p->fts_fts = sp; return (p); } static void fts_lfree(FTSENT *head) { FTSENT *p; /* Free a linked list of structures. */ while ((p = head)) { head = head->fts_link; free(p); } } /* * Allow essentially unlimited paths; find, rm, ls should all work on any tree. * Most systems will allow creation of paths much longer than MAXPATHLEN, even * though the kernel won't resolve them. Add the size (not just what's needed) * plus 256 bytes so don't realloc the path 2 bytes at a time. */ static int fts_palloc(FTS *sp, size_t more) { sp->fts_pathlen += more + 256; sp->fts_path = reallocf(sp->fts_path, sp->fts_pathlen); return (sp->fts_path == NULL); } /* * When the path is realloc'd, have to fix all of the pointers in structures * already returned. */ static void fts_padjust(FTS *sp, FTSENT *head) { FTSENT *p; char *addr = sp->fts_path; #define ADJUST(p) do { \ if ((p)->fts_accpath != (p)->fts_name) { \ (p)->fts_accpath = \ (char *)addr + ((p)->fts_accpath - (p)->fts_path); \ } \ (p)->fts_path = addr; \ } while (0) /* Adjust the current set of children. */ for (p = sp->fts_child; p; p = p->fts_link) ADJUST(p); /* Adjust the rest of the tree, including the current level. */ for (p = head; p->fts_level >= FTS_ROOTLEVEL;) { ADJUST(p); p = p->fts_link ? p->fts_link : p->fts_parent; } } static size_t fts_maxarglen(char * const *argv) { size_t len, max; for (max = 0; *argv; ++argv) if ((len = strlen(*argv)) > max) max = len; return (max + 1); } /* * Change to dir specified by fd or p->fts_accpath without getting * tricked by someone changing the world out from underneath us. * Assumes p->fts_dev and p->fts_ino are filled in. */ static int fts_safe_changedir(FTS *sp, FTSENT *p, int fd, char *path) { int ret, oerrno, newfd; struct stat sb; newfd = fd; if (ISSET(FTS_NOCHDIR)) return (0); if (fd < 0 && (newfd = _open(path, O_RDONLY | O_DIRECTORY | O_CLOEXEC, 0)) < 0) return (-1); if (_fstat(newfd, &sb)) { ret = -1; goto bail; } if (p->fts_dev != sb.st_dev || p->fts_ino != sb.st_ino) { errno = ENOENT; /* disinformation */ ret = -1; goto bail; } ret = fchdir(newfd); bail: oerrno = errno; if (fd < 0) (void)_close(newfd); errno = oerrno; return (ret); } /* * Check if the filesystem for "ent" has UFS-style links. */ static int fts_ufslinks(FTS *sp, const FTSENT *ent) { struct _fts_private *priv; const char **cpp; priv = (struct _fts_private *)sp; /* * If this node's device is different from the previous, grab * the filesystem information, and decide on the reliability * of the link information from this filesystem for stat(2) * avoidance. */ if (priv->ftsp_dev != ent->fts_dev) { if (statfs(ent->fts_path, &priv->ftsp_statfs) != -1) { priv->ftsp_dev = ent->fts_dev; priv->ftsp_linksreliable = 0; for (cpp = ufslike_filesystems; *cpp; cpp++) { if (strcmp(priv->ftsp_statfs.f_fstypename, *cpp) == 0) { priv->ftsp_linksreliable = 1; break; } } } else { priv->ftsp_linksreliable = 0; } } return (priv->ftsp_linksreliable); } Index: head/lib/libc/gen/ftw-compat11.c =================================================================== --- head/lib/libc/gen/ftw-compat11.c (revision 335897) +++ head/lib/libc/gen/ftw-compat11.c (revision 335898) @@ -1,98 +1,98 @@ /* $OpenBSD: ftw.c,v 1.5 2005/08/08 08:05:34 espie Exp $ */ /* * Copyright (c) 2003, 2004 Todd C. Miller * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * Sponsored in part by the Defense Advanced Research Projects * Agency (DARPA) and Air Force Research Laboratory, Air Force * Materiel Command, USAF, under agreement number F39502-99-1-0512. * - * from: $FreeBSD$ + * From: FreeBSD: head/lib/libc/gen/ftw.c 239151 2012-08-09 15:11:38Z jilles */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include "fts-compat11.h" int freebsd11_ftw(const char *path, int (*fn)(const char *, const struct freebsd11_stat *, int), int nfds) { char * const paths[2] = { (char *)path, NULL }; FTSENT11 *cur; FTS11 *ftsp; int error = 0, fnflag, sverrno; /* XXX - nfds is currently unused */ if (nfds < 1) { errno = EINVAL; return (-1); } ftsp = freebsd11_fts_open(paths, FTS_LOGICAL | FTS_COMFOLLOW | FTS_NOCHDIR, NULL); if (ftsp == NULL) return (-1); while ((cur = freebsd11_fts_read(ftsp)) != NULL) { switch (cur->fts_info) { case FTS_D: fnflag = FTW_D; break; case FTS_DNR: fnflag = FTW_DNR; break; case FTS_DP: /* we only visit in preorder */ continue; case FTS_F: case FTS_DEFAULT: fnflag = FTW_F; break; case FTS_NS: case FTS_NSOK: case FTS_SLNONE: fnflag = FTW_NS; break; case FTS_SL: fnflag = FTW_SL; break; case FTS_DC: errno = ELOOP; /* FALLTHROUGH */ default: error = -1; goto done; } error = fn(cur->fts_path, cur->fts_statp, fnflag); if (error != 0) break; } done: sverrno = errno; if (freebsd11_fts_close(ftsp) != 0 && error == 0) error = -1; else errno = sverrno; return (error); } __sym_compat(ftw, freebsd11_ftw, FBSD_1.0); Index: head/lib/libc/gen/getbootfile.c =================================================================== --- head/lib/libc/gen/getbootfile.c (revision 335897) +++ head/lib/libc/gen/getbootfile.c (revision 335898) @@ -1,55 +1,54 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1989, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. + * + * From: @(#)gethostname.c 8.1 (Berkeley) 6/4/93 */ -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "From: @(#)gethostname.c 8.1 (Berkeley) 6/4/93"; -#endif /* LIBC_SCCS and not lint */ #include __FBSDID("$FreeBSD$"); #include #include #include const char * getbootfile(void) { static char name[MAXPATHLEN]; size_t size = sizeof name; int mib[2]; mib[0] = CTL_KERN; mib[1] = KERN_BOOTFILE; if (sysctl(mib, 2, name, &size, NULL, 0) == -1) return ("/boot/kernel/kernel"); return (name); } Index: head/lib/libc/gen/getbsize.c =================================================================== --- head/lib/libc/gen/getbsize.c (revision 335897) +++ head/lib/libc/gen/getbsize.c (revision 335898) @@ -1,106 +1,104 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1991, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)getbsize.c 8.1 (Berkeley) 6/4/93"; -#endif /* LIBC_SCCS and not lint */ #include +__SCCSID("@(#)getbsize.c 8.1 (Berkeley) 6/4/93"); __FBSDID("$FreeBSD$"); #include #include #include #include char * getbsize(int *headerlenp, long *blocksizep) { static char header[20]; long n, max, mul, blocksize; char *ep, *p; const char *form; #define KB (1024L) #define MB (1024L * 1024L) #define GB (1024L * 1024L * 1024L) #define MAXB GB /* No tera, peta, nor exa. */ form = ""; if ((p = getenv("BLOCKSIZE")) != NULL && *p != '\0') { if ((n = strtol(p, &ep, 10)) < 0) goto underflow; if (n == 0) n = 1; if (*ep && ep[1]) goto fmterr; switch (*ep) { case 'G': case 'g': form = "G"; max = MAXB / GB; mul = GB; break; case 'K': case 'k': form = "K"; max = MAXB / KB; mul = KB; break; case 'M': case 'm': form = "M"; max = MAXB / MB; mul = MB; break; case '\0': max = MAXB; mul = 1; break; default: fmterr: warnx("%s: unknown blocksize", p); n = 512; max = MAXB; mul = 1; break; } if (n > max) { warnx("maximum blocksize is %ldG", MAXB / GB); n = max; } if ((blocksize = n * mul) < 512) { underflow: warnx("minimum blocksize is 512"); form = ""; blocksize = n = 512; } } else blocksize = n = 512; (void)snprintf(header, sizeof(header), "%ld%s-blocks", n, form); *headerlenp = strlen(header); *blocksizep = blocksize; return (header); } Index: head/lib/libc/gen/getcap.c =================================================================== --- head/lib/libc/gen/getcap.c (revision 335897) +++ head/lib/libc/gen/getcap.c (revision 335898) @@ -1,1057 +1,1055 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1992, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Casey Leedom of Lawrence Livermore National Laboratory. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)getcap.c 8.3 (Berkeley) 3/25/94"; -#endif /* LIBC_SCCS and not lint */ #include +__SCCSID("@(#)getcap.c 8.3 (Berkeley) 3/25/94"); __FBSDID("$FreeBSD$"); #include "namespace.h" #include #include #include #include #include #include #include #include #include #include "un-namespace.h" #include #define BFRAG 1024 #define BSIZE 1024 #define ESC ('[' & 037) /* ASCII ESC */ #define MAX_RECURSION 32 /* maximum getent recursion */ #define SFRAG 100 /* cgetstr mallocs in SFRAG chunks */ #define RECOK (char)0 #define TCERR (char)1 #define SHADOW (char)2 static size_t topreclen; /* toprec length */ static char *toprec; /* Additional record specified by cgetset() */ static int gottoprec; /* Flag indicating retrieval of toprecord */ static int cdbget(DB *, char **, const char *); static int getent(char **, u_int *, char **, int, const char *, int, char *); static int nfcmp(char *, char *); /* * Cgetset() allows the addition of a user specified buffer to be added * to the database array, in effect "pushing" the buffer on top of the * virtual database. 0 is returned on success, -1 on failure. */ int cgetset(const char *ent) { if (ent == NULL) { if (toprec) free(toprec); toprec = NULL; topreclen = 0; return (0); } topreclen = strlen(ent); if ((toprec = malloc (topreclen + 1)) == NULL) { errno = ENOMEM; return (-1); } gottoprec = 0; (void)strcpy(toprec, ent); return (0); } /* * Cgetcap searches the capability record buf for the capability cap with * type `type'. A pointer to the value of cap is returned on success, NULL * if the requested capability couldn't be found. * * Specifying a type of ':' means that nothing should follow cap (:cap:). * In this case a pointer to the terminating ':' or NUL will be returned if * cap is found. * * If (cap, '@') or (cap, terminator, '@') is found before (cap, terminator) * return NULL. */ char * cgetcap(char *buf, const char *cap, int type) { char *bp; const char *cp; bp = buf; for (;;) { /* * Skip past the current capability field - it's either the * name field if this is the first time through the loop, or * the remainder of a field whose name failed to match cap. */ for (;;) if (*bp == '\0') return (NULL); else if (*bp++ == ':') break; /* * Try to match (cap, type) in buf. */ for (cp = cap; *cp == *bp && *bp != '\0'; cp++, bp++) continue; if (*cp != '\0') continue; if (*bp == '@') return (NULL); if (type == ':') { if (*bp != '\0' && *bp != ':') continue; return(bp); } if (*bp != type) continue; bp++; return (*bp == '@' ? NULL : bp); } /* NOTREACHED */ } /* * Cgetent extracts the capability record name from the NULL terminated file * array db_array and returns a pointer to a malloc'd copy of it in buf. * Buf must be retained through all subsequent calls to cgetcap, cgetnum, * cgetflag, and cgetstr, but may then be free'd. 0 is returned on success, * -1 if the requested record couldn't be found, -2 if a system error was * encountered (couldn't open/read a file, etc.), and -3 if a potential * reference loop is detected. */ int cgetent(char **buf, char **db_array, const char *name) { u_int dummy; return (getent(buf, &dummy, db_array, -1, name, 0, NULL)); } /* * Getent implements the functions of cgetent. If fd is non-negative, * *db_array has already been opened and fd is the open file descriptor. We * do this to save time and avoid using up file descriptors for tc= * recursions. * * Getent returns the same success/failure codes as cgetent. On success, a * pointer to a malloc'ed capability record with all tc= capabilities fully * expanded and its length (not including trailing ASCII NUL) are left in * *cap and *len. * * Basic algorithm: * + Allocate memory incrementally as needed in chunks of size BFRAG * for capability buffer. * + Recurse for each tc=name and interpolate result. Stop when all * names interpolated, a name can't be found, or depth exceeds * MAX_RECURSION. */ static int getent(char **cap, u_int *len, char **db_array, int fd, const char *name, int depth, char *nfield) { DB *capdbp; char *r_end, *rp, **db_p; int myfd, eof, foundit, retval; char *record, *cbuf; int tc_not_resolved; char pbuf[_POSIX_PATH_MAX]; /* * Return with ``loop detected'' error if we've recursed more than * MAX_RECURSION times. */ if (depth > MAX_RECURSION) return (-3); /* * Check if we have a top record from cgetset(). */ if (depth == 0 && toprec != NULL && cgetmatch(toprec, name) == 0) { if ((record = malloc (topreclen + BFRAG)) == NULL) { errno = ENOMEM; return (-2); } (void)strcpy(record, toprec); myfd = 0; db_p = db_array; rp = record + topreclen + 1; r_end = rp + BFRAG; goto tc_exp; } /* * Allocate first chunk of memory. */ if ((record = malloc(BFRAG)) == NULL) { errno = ENOMEM; return (-2); } r_end = record + BFRAG; foundit = 0; /* * Loop through database array until finding the record. */ for (db_p = db_array; *db_p != NULL; db_p++) { eof = 0; /* * Open database if not already open. */ if (fd >= 0) { (void)lseek(fd, (off_t)0, SEEK_SET); myfd = 0; } else { (void)snprintf(pbuf, sizeof(pbuf), "%s.db", *db_p); if ((capdbp = dbopen(pbuf, O_RDONLY, 0, DB_HASH, 0)) != NULL) { free(record); retval = cdbget(capdbp, &record, name); if (retval < 0) { /* no record available */ (void)capdbp->close(capdbp); return (retval); } /* save the data; close frees it */ cbuf = strdup(record); if (capdbp->close(capdbp) < 0) { free(cbuf); return (-2); } if (cbuf == NULL) { errno = ENOMEM; return (-2); } *len = strlen(cbuf); *cap = cbuf; return (retval); } else { fd = _open(*db_p, O_RDONLY | O_CLOEXEC, 0); if (fd < 0) continue; myfd = 1; } } /* * Find the requested capability record ... */ { char buf[BUFSIZ]; char *b_end, *bp; int c; /* * Loop invariants: * There is always room for one more character in record. * R_end always points just past end of record. * Rp always points just past last character in record. * B_end always points just past last character in buf. * Bp always points at next character in buf. */ b_end = buf; bp = buf; for (;;) { /* * Read in a line implementing (\, newline) * line continuation. */ rp = record; for (;;) { if (bp >= b_end) { int n; n = _read(fd, buf, sizeof(buf)); if (n <= 0) { if (myfd) (void)_close(fd); if (n < 0) { free(record); return (-2); } else { fd = -1; eof = 1; break; } } b_end = buf+n; bp = buf; } c = *bp++; if (c == '\n') { if (rp > record && *(rp-1) == '\\') { rp--; continue; } else break; } *rp++ = c; /* * Enforce loop invariant: if no room * left in record buffer, try to get * some more. */ if (rp >= r_end) { u_int pos; size_t newsize; pos = rp - record; newsize = r_end - record + BFRAG; record = reallocf(record, newsize); if (record == NULL) { errno = ENOMEM; if (myfd) (void)_close(fd); return (-2); } r_end = record + newsize; rp = record + pos; } } /* loop invariant let's us do this */ *rp++ = '\0'; /* * If encountered eof check next file. */ if (eof) break; /* * Toss blank lines and comments. */ if (*record == '\0' || *record == '#') continue; /* * See if this is the record we want ... */ if (cgetmatch(record, name) == 0) { if (nfield == NULL || !nfcmp(nfield, record)) { foundit = 1; break; /* found it! */ } } } } if (foundit) break; } if (!foundit) { free(record); return (-1); } /* * Got the capability record, but now we have to expand all tc=name * references in it ... */ tc_exp: { char *newicap, *s; int newilen; u_int ilen; int diff, iret, tclen; char *icap, *scan, *tc, *tcstart, *tcend; /* * Loop invariants: * There is room for one more character in record. * R_end points just past end of record. * Rp points just past last character in record. * Scan points at remainder of record that needs to be * scanned for tc=name constructs. */ scan = record; tc_not_resolved = 0; for (;;) { if ((tc = cgetcap(scan, "tc", '=')) == NULL) break; /* * Find end of tc=name and stomp on the trailing `:' * (if present) so we can use it to call ourselves. */ s = tc; for (;;) if (*s == '\0') break; else if (*s++ == ':') { *(s - 1) = '\0'; break; } tcstart = tc - 3; tclen = s - tcstart; tcend = s; iret = getent(&icap, &ilen, db_p, fd, tc, depth+1, NULL); newicap = icap; /* Put into a register. */ newilen = ilen; if (iret != 0) { /* an error */ if (iret < -1) { if (myfd) (void)_close(fd); free(record); return (iret); } if (iret == 1) tc_not_resolved = 1; /* couldn't resolve tc */ if (iret == -1) { *(s - 1) = ':'; scan = s - 1; tc_not_resolved = 1; continue; } } /* not interested in name field of tc'ed record */ s = newicap; for (;;) if (*s == '\0') break; else if (*s++ == ':') break; newilen -= s - newicap; newicap = s; /* make sure interpolated record is `:'-terminated */ s += newilen; if (*(s-1) != ':') { *s = ':'; /* overwrite NUL with : */ newilen++; } /* * Make sure there's enough room to insert the * new record. */ diff = newilen - tclen; if (diff >= r_end - rp) { u_int pos, tcpos, tcposend; size_t newsize; pos = rp - record; newsize = r_end - record + diff + BFRAG; tcpos = tcstart - record; tcposend = tcend - record; record = reallocf(record, newsize); if (record == NULL) { errno = ENOMEM; if (myfd) (void)_close(fd); free(icap); return (-2); } r_end = record + newsize; rp = record + pos; tcstart = record + tcpos; tcend = record + tcposend; } /* * Insert tc'ed record into our record. */ s = tcstart + newilen; bcopy(tcend, s, rp - tcend); bcopy(newicap, tcstart, newilen); rp += diff; free(icap); /* * Start scan on `:' so next cgetcap works properly * (cgetcap always skips first field). */ scan = s-1; } } /* * Close file (if we opened it), give back any extra memory, and * return capability, length and success. */ if (myfd) (void)_close(fd); *len = rp - record - 1; /* don't count NUL */ if (r_end > rp) if ((record = reallocf(record, (size_t)(rp - record))) == NULL) { errno = ENOMEM; return (-2); } *cap = record; if (tc_not_resolved) return (1); return (0); } static int cdbget(DB *capdbp, char **bp, const char *name) { DBT key, data; char *namebuf; namebuf = strdup(name); if (namebuf == NULL) return (-2); key.data = namebuf; key.size = strlen(namebuf); for (;;) { /* Get the reference. */ switch(capdbp->get(capdbp, &key, &data, 0)) { case -1: free(namebuf); return (-2); case 1: free(namebuf); return (-1); } /* If not an index to another record, leave. */ if (((char *)data.data)[0] != SHADOW) break; key.data = (char *)data.data + 1; key.size = data.size - 1; } *bp = (char *)data.data + 1; free(namebuf); return (((char *)(data.data))[0] == TCERR ? 1 : 0); } /* * Cgetmatch will return 0 if name is one of the names of the capability * record buf, -1 if not. */ int cgetmatch(const char *buf, const char *name) { const char *np, *bp; if (name == NULL || *name == '\0') return -1; /* * Start search at beginning of record. */ bp = buf; for (;;) { /* * Try to match a record name. */ np = name; for (;;) if (*np == '\0') if (*bp == '|' || *bp == ':' || *bp == '\0') return (0); else break; else if (*bp++ != *np++) break; /* * Match failed, skip to next name in record. */ bp--; /* a '|' or ':' may have stopped the match */ for (;;) if (*bp == '\0' || *bp == ':') return (-1); /* match failed totally */ else if (*bp++ == '|') break; /* found next name */ } } int cgetfirst(char **buf, char **db_array) { (void)cgetclose(); return (cgetnext(buf, db_array)); } static FILE *pfp; static int slash; static char **dbp; int cgetclose(void) { if (pfp != NULL) { (void)fclose(pfp); pfp = NULL; } dbp = NULL; gottoprec = 0; slash = 0; return(0); } /* * Cgetnext() gets either the first or next entry in the logical database * specified by db_array. It returns 0 upon completion of the database, 1 * upon returning an entry with more remaining, and -1 if an error occurs. */ int cgetnext(char **bp, char **db_array) { size_t len; int done, hadreaderr, savederrno, status; char *cp, *line, *rp, *np, buf[BSIZE], nbuf[BSIZE]; u_int dummy; if (dbp == NULL) dbp = db_array; if (pfp == NULL && (pfp = fopen(*dbp, "re")) == NULL) { (void)cgetclose(); return (-1); } for (;;) { if (toprec && !gottoprec) { gottoprec = 1; line = toprec; } else { line = fgetln(pfp, &len); if (line == NULL && pfp) { hadreaderr = ferror(pfp); if (hadreaderr) savederrno = errno; fclose(pfp); pfp = NULL; if (hadreaderr) { cgetclose(); errno = savederrno; return (-1); } else { if (*++dbp == NULL) { (void)cgetclose(); return (0); } else if ((pfp = fopen(*dbp, "re")) == NULL) { (void)cgetclose(); return (-1); } else continue; } } else line[len - 1] = '\0'; if (len == 1) { slash = 0; continue; } if (isspace((unsigned char)*line) || *line == ':' || *line == '#' || slash) { if (line[len - 2] == '\\') slash = 1; else slash = 0; continue; } if (line[len - 2] == '\\') slash = 1; else slash = 0; } /* * Line points to a name line. */ done = 0; np = nbuf; for (;;) { for (cp = line; *cp != '\0'; cp++) { if (*cp == ':') { *np++ = ':'; done = 1; break; } if (*cp == '\\') break; *np++ = *cp; } if (done) { *np = '\0'; break; } else { /* name field extends beyond the line */ line = fgetln(pfp, &len); if (line == NULL && pfp) { /* Name extends beyond the EOF! */ hadreaderr = ferror(pfp); if (hadreaderr) savederrno = errno; fclose(pfp); pfp = NULL; if (hadreaderr) { cgetclose(); errno = savederrno; return (-1); } else { cgetclose(); return (-1); } } else line[len - 1] = '\0'; } } rp = buf; for(cp = nbuf; *cp != '\0'; cp++) if (*cp == '|' || *cp == ':') break; else *rp++ = *cp; *rp = '\0'; /* * XXX * Last argument of getent here should be nbuf if we want true * sequential access in the case of duplicates. * With NULL, getent will return the first entry found * rather than the duplicate entry record. This is a * matter of semantics that should be resolved. */ status = getent(bp, &dummy, db_array, -1, buf, 0, NULL); if (status == -2 || status == -3) (void)cgetclose(); return (status + 1); } /* NOTREACHED */ } /* * Cgetstr retrieves the value of the string capability cap from the * capability record pointed to by buf. A pointer to a decoded, NUL * terminated, malloc'd copy of the string is returned in the char * * pointed to by str. The length of the string not including the trailing * NUL is returned on success, -1 if the requested string capability * couldn't be found, -2 if a system error was encountered (storage * allocation failure). */ int cgetstr(char *buf, const char *cap, char **str) { u_int m_room; char *bp, *mp; int len; char *mem; /* * Find string capability cap */ bp = cgetcap(buf, cap, '='); if (bp == NULL) return (-1); /* * Conversion / storage allocation loop ... Allocate memory in * chunks SFRAG in size. */ if ((mem = malloc(SFRAG)) == NULL) { errno = ENOMEM; return (-2); /* couldn't even allocate the first fragment */ } m_room = SFRAG; mp = mem; while (*bp != ':' && *bp != '\0') { /* * Loop invariants: * There is always room for one more character in mem. * Mp always points just past last character in mem. * Bp always points at next character in buf. */ if (*bp == '^') { bp++; if (*bp == ':' || *bp == '\0') break; /* drop unfinished escape */ if (*bp == '?') { *mp++ = '\177'; bp++; } else *mp++ = *bp++ & 037; } else if (*bp == '\\') { bp++; if (*bp == ':' || *bp == '\0') break; /* drop unfinished escape */ if ('0' <= *bp && *bp <= '7') { int n, i; n = 0; i = 3; /* maximum of three octal digits */ do { n = n * 8 + (*bp++ - '0'); } while (--i && '0' <= *bp && *bp <= '7'); *mp++ = n; } else switch (*bp++) { case 'b': case 'B': *mp++ = '\b'; break; case 't': case 'T': *mp++ = '\t'; break; case 'n': case 'N': *mp++ = '\n'; break; case 'f': case 'F': *mp++ = '\f'; break; case 'r': case 'R': *mp++ = '\r'; break; case 'e': case 'E': *mp++ = ESC; break; case 'c': case 'C': *mp++ = ':'; break; default: /* * Catches '\', '^', and * everything else. */ *mp++ = *(bp-1); break; } } else *mp++ = *bp++; m_room--; /* * Enforce loop invariant: if no room left in current * buffer, try to get some more. */ if (m_room == 0) { size_t size = mp - mem; if ((mem = reallocf(mem, size + SFRAG)) == NULL) return (-2); m_room = SFRAG; mp = mem + size; } } *mp++ = '\0'; /* loop invariant let's us do this */ m_room--; len = mp - mem - 1; /* * Give back any extra memory and return value and success. */ if (m_room != 0) if ((mem = reallocf(mem, (size_t)(mp - mem))) == NULL) return (-2); *str = mem; return (len); } /* * Cgetustr retrieves the value of the string capability cap from the * capability record pointed to by buf. The difference between cgetustr() * and cgetstr() is that cgetustr does not decode escapes but rather treats * all characters literally. A pointer to a NUL terminated malloc'd * copy of the string is returned in the char pointed to by str. The * length of the string not including the trailing NUL is returned on success, * -1 if the requested string capability couldn't be found, -2 if a system * error was encountered (storage allocation failure). */ int cgetustr(char *buf, const char *cap, char **str) { u_int m_room; char *bp, *mp; int len; char *mem; /* * Find string capability cap */ if ((bp = cgetcap(buf, cap, '=')) == NULL) return (-1); /* * Conversion / storage allocation loop ... Allocate memory in * chunks SFRAG in size. */ if ((mem = malloc(SFRAG)) == NULL) { errno = ENOMEM; return (-2); /* couldn't even allocate the first fragment */ } m_room = SFRAG; mp = mem; while (*bp != ':' && *bp != '\0') { /* * Loop invariants: * There is always room for one more character in mem. * Mp always points just past last character in mem. * Bp always points at next character in buf. */ *mp++ = *bp++; m_room--; /* * Enforce loop invariant: if no room left in current * buffer, try to get some more. */ if (m_room == 0) { size_t size = mp - mem; if ((mem = reallocf(mem, size + SFRAG)) == NULL) return (-2); m_room = SFRAG; mp = mem + size; } } *mp++ = '\0'; /* loop invariant let's us do this */ m_room--; len = mp - mem - 1; /* * Give back any extra memory and return value and success. */ if (m_room != 0) if ((mem = reallocf(mem, (size_t)(mp - mem))) == NULL) return (-2); *str = mem; return (len); } /* * Cgetnum retrieves the value of the numeric capability cap from the * capability record pointed to by buf. The numeric value is returned in * the long pointed to by num. 0 is returned on success, -1 if the requested * numeric capability couldn't be found. */ int cgetnum(char *buf, const char *cap, long *num) { long n; int base, digit; char *bp; /* * Find numeric capability cap */ bp = cgetcap(buf, cap, '#'); if (bp == NULL) return (-1); /* * Look at value and determine numeric base: * 0x... or 0X... hexadecimal, * else 0... octal, * else decimal. */ if (*bp == '0') { bp++; if (*bp == 'x' || *bp == 'X') { bp++; base = 16; } else base = 8; } else base = 10; /* * Conversion loop ... */ n = 0; for (;;) { if ('0' <= *bp && *bp <= '9') digit = *bp - '0'; else if ('a' <= *bp && *bp <= 'f') digit = 10 + *bp - 'a'; else if ('A' <= *bp && *bp <= 'F') digit = 10 + *bp - 'A'; else break; if (digit >= base) break; n = n * base + digit; bp++; } /* * Return value and success. */ *num = n; return (0); } /* * Compare name field of record. */ static int nfcmp(char *nf, char *rec) { char *cp, tmp; int ret; for (cp = rec; *cp != ':'; cp++) ; tmp = *(cp + 1); *(cp + 1) = '\0'; ret = strcmp(nf, rec); *(cp + 1) = tmp; return (ret); } Index: head/lib/libc/gen/getcwd.c =================================================================== --- head/lib/libc/gen/getcwd.c (revision 335897) +++ head/lib/libc/gen/getcwd.c (revision 335898) @@ -1,232 +1,230 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1989, 1991, 1993, 1995 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)getcwd.c 8.5 (Berkeley) 2/7/95"; -#endif /* LIBC_SCCS and not lint */ #include +__SCCSID("@(#)getcwd.c 8.5 (Berkeley) 2/7/95"); __FBSDID("$FreeBSD$"); #include "namespace.h" #include #include #include #include #include #include #include #include #include #include "un-namespace.h" #include "gen-private.h" #define ISDOT(dp) \ (dp->d_name[0] == '.' && (dp->d_name[1] == '\0' || \ (dp->d_name[1] == '.' && dp->d_name[2] == '\0'))) extern int __getcwd(char *, size_t); char * getcwd(char *pt, size_t size) { struct dirent *dp; DIR *dir = NULL; dev_t dev; ino_t ino; int first; char *bpt; struct stat s; dev_t root_dev; ino_t root_ino; size_t ptsize; int save_errno; char *ept, c; int fd; /* * If no buffer specified by the user, allocate one as necessary. * If a buffer is specified, the size has to be non-zero. The path * is built from the end of the buffer backwards. */ if (pt) { ptsize = 0; if (!size) { errno = EINVAL; return (NULL); } if (size == 1) { errno = ERANGE; return (NULL); } ept = pt + size; } else { if ((pt = malloc(ptsize = PATH_MAX)) == NULL) return (NULL); ept = pt + ptsize; } if (__getcwd(pt, ept - pt) == 0) { if (*pt != '/') { bpt = pt; ept = pt + strlen(pt) - 1; while (bpt < ept) { c = *bpt; *bpt++ = *ept; *ept-- = c; } } return (pt); } bpt = ept - 1; *bpt = '\0'; /* Save root values, so know when to stop. */ if (stat("/", &s)) goto err; root_dev = s.st_dev; root_ino = s.st_ino; errno = 0; /* XXX readdir has no error return. */ for (first = 1;; first = 0) { /* Stat the current level. */ if (dir != NULL ? _fstat(_dirfd(dir), &s) : lstat(".", &s)) goto err; /* Save current node values. */ ino = s.st_ino; dev = s.st_dev; /* Check for reaching root. */ if (root_dev == dev && root_ino == ino) { *--bpt = '/'; /* * It's unclear that it's a requirement to copy the * path to the beginning of the buffer, but it's always * been that way and stuff would probably break. */ bcopy(bpt, pt, ept - bpt); if (dir) (void) closedir(dir); return (pt); } /* Open and stat parent directory. */ fd = _openat(dir != NULL ? _dirfd(dir) : AT_FDCWD, "..", O_RDONLY | O_CLOEXEC); if (fd == -1) goto err; if (dir) (void) closedir(dir); if (!(dir = fdopendir(fd)) || _fstat(_dirfd(dir), &s)) { _close(fd); goto err; } /* * If it's a mount point, have to stat each element because * the inode number in the directory is for the entry in the * parent directory, not the inode number of the mounted file. */ save_errno = 0; if (s.st_dev == dev) { for (;;) { if (!(dp = readdir(dir))) goto notfound; if (dp->d_fileno == ino) break; } } else for (;;) { if (!(dp = readdir(dir))) goto notfound; if (ISDOT(dp)) continue; /* Save the first error for later. */ if (fstatat(_dirfd(dir), dp->d_name, &s, AT_SYMLINK_NOFOLLOW)) { if (!save_errno) save_errno = errno; errno = 0; continue; } if (s.st_dev == dev && s.st_ino == ino) break; } /* * Check for length of the current name, preceding slash, * leading slash. */ while (bpt - pt < dp->d_namlen + (first ? 1 : 2)) { size_t len, off; if (!ptsize) { errno = ERANGE; goto err; } off = bpt - pt; len = ept - bpt; if ((pt = reallocf(pt, ptsize *= 2)) == NULL) goto err; bpt = pt + off; ept = pt + ptsize; bcopy(bpt, ept - len, len); bpt = ept - len; } if (!first) *--bpt = '/'; bpt -= dp->d_namlen; bcopy(dp->d_name, bpt, dp->d_namlen); } notfound: /* * If readdir set errno, use it, not any saved error; otherwise, * didn't find the current directory in its parent directory, set * errno to ENOENT. */ if (!errno) errno = save_errno ? save_errno : ENOENT; /* FALLTHROUGH */ err: save_errno = errno; if (ptsize) free(pt); if (dir) (void) closedir(dir); errno = save_errno; return (NULL); } Index: head/lib/libc/gen/getdomainname.c =================================================================== --- head/lib/libc/gen/getdomainname.c (revision 335897) +++ head/lib/libc/gen/getdomainname.c (revision 335898) @@ -1,55 +1,53 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1989, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)gethostname.c 8.1 (Berkeley) 6/4/93"; -#endif /* LIBC_SCCS and not lint */ #include +__SCCSID("@(#)gethostname.c 8.1 (Berkeley) 6/4/93"); __FBSDID("$FreeBSD$"); #include #include #include int getdomainname(char *name, int namelen) { int mib[2]; size_t size; mib[0] = CTL_KERN; mib[1] = KERN_NISDOMAINNAME; size = namelen; if (sysctl(mib, 2, name, &size, NULL, 0) == -1) return (-1); return (0); } Index: head/lib/libc/gen/getgrouplist.c =================================================================== --- head/lib/libc/gen/getgrouplist.c (revision 335897) +++ head/lib/libc/gen/getgrouplist.c (revision 335898) @@ -1,54 +1,52 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1991, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)getgrouplist.c 8.2 (Berkeley) 12/8/94"; -#endif /* LIBC_SCCS and not lint */ #include +__SCCSID("@(#)getgrouplist.c 8.2 (Berkeley) 12/8/94"); __FBSDID("$FreeBSD$"); /* * get credential */ #include #include #include #include extern int __getgroupmembership(const char *, gid_t, gid_t *, int, int *); int getgrouplist(const char *uname, gid_t agroup, gid_t *groups, int *grpcnt) { return __getgroupmembership(uname, agroup, groups, *grpcnt, grpcnt); } Index: head/lib/libc/gen/gethostname.c =================================================================== --- head/lib/libc/gen/gethostname.c (revision 335897) +++ head/lib/libc/gen/gethostname.c (revision 335898) @@ -1,57 +1,55 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1989, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)gethostname.c 8.1 (Berkeley) 6/4/93"; -#endif /* LIBC_SCCS and not lint */ #include +__SCCSID("@(#)gethostname.c 8.1 (Berkeley) 6/4/93"); __FBSDID("$FreeBSD$"); #include #include #include #include int gethostname(char *name, size_t namelen) { int mib[2]; mib[0] = CTL_KERN; mib[1] = KERN_HOSTNAME; if (sysctl(mib, 2, name, &namelen, NULL, 0) == -1) { if (errno == ENOMEM) errno = ENAMETOOLONG; return (-1); } return (0); } Index: head/lib/libc/gen/getloadavg.c =================================================================== --- head/lib/libc/gen/getloadavg.c (revision 335897) +++ head/lib/libc/gen/getloadavg.c (revision 335898) @@ -1,69 +1,67 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1989, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)getloadavg.c 8.1 (Berkeley) 6/4/93"; -#endif /* LIBC_SCCS and not lint */ #include +__SCCSID("@(#)getloadavg.c 8.1 (Berkeley) 6/4/93"); __FBSDID("$FreeBSD$"); #include #include #include #include #include #include /* * getloadavg() -- Get system load averages. * * Put `nelem' samples into `loadavg' array. * Return number of samples retrieved, or -1 on error. */ int getloadavg(double loadavg[], int nelem) { struct loadavg loadinfo; int i, mib[2]; size_t size; mib[0] = CTL_VM; mib[1] = VM_LOADAVG; size = sizeof(loadinfo); if (sysctl(mib, 2, &loadinfo, &size, NULL, 0) < 0) return (-1); nelem = MIN(nelem, sizeof(loadinfo.ldavg) / sizeof(fixpt_t)); for (i = 0; i < nelem; i++) loadavg[i] = (double) loadinfo.ldavg[i] / loadinfo.fscale; return (nelem); } Index: head/lib/libc/gen/getlogin.c =================================================================== --- head/lib/libc/gen/getlogin.c (revision 335897) +++ head/lib/libc/gen/getlogin.c (revision 335898) @@ -1,79 +1,77 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1988, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)getlogin.c 8.1 (Berkeley) 6/4/93"; -#endif /* LIBC_SCCS and not lint */ #include +__SCCSID("@(#)getlogin.c 8.1 (Berkeley) 6/4/93"); __FBSDID("$FreeBSD$"); #include #include #include #include #include #include #include "namespace.h" #include #include "un-namespace.h" #include "libc_private.h" extern int _getlogin(char *, int); char * getlogin(void) { static char logname[MAXLOGNAME]; if (_getlogin(logname, sizeof(logname)) < 0) return (NULL); return (logname[0] != '\0' ? logname : NULL); } int getlogin_r(char *logname, int namelen) { char tmpname[MAXLOGNAME]; int len; if (namelen < 1) return (ERANGE); logname[0] = '\0'; if (_getlogin(tmpname, sizeof(tmpname)) < 0) return (errno); len = strlen(tmpname) + 1; if (len > namelen) return (ERANGE); strlcpy(logname, tmpname, len); return (0); } Index: head/lib/libc/gen/getmntinfo-compat11.c =================================================================== --- head/lib/libc/gen/getmntinfo-compat11.c (revision 335897) +++ head/lib/libc/gen/getmntinfo-compat11.c (revision 335898) @@ -1,72 +1,71 @@ /* * Copyright (c) 1989, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. + * + * From: @(#)getmntinfo.c 8.1 (Berkeley) 6/4/93 */ -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)getmntinfo.c 8.1 (Berkeley) 6/4/93"; -#endif /* LIBC_SCCS and not lint */ #include __FBSDID("$FreeBSD$"); #include #include #define _WANT_FREEBSD11_STATFS #include #include #include "gen-compat.h" /* * Return information about mounted filesystems. */ int freebsd11_getmntinfo(struct freebsd11_statfs **mntbufp, int flags) { static struct freebsd11_statfs *mntbuf; static int mntsize; static long bufsize; if (mntsize <= 0 && (mntsize = freebsd11_getfsstat(0, 0, MNT_NOWAIT)) < 0) return (0); if (bufsize > 0 && (mntsize = freebsd11_getfsstat(mntbuf, bufsize, flags)) < 0) return (0); while (bufsize <= mntsize * sizeof(struct freebsd11_statfs)) { if (mntbuf) free(mntbuf); bufsize = (mntsize + 1) * sizeof(struct freebsd11_statfs); if ((mntbuf = (struct freebsd11_statfs *)malloc(bufsize)) == 0) return (0); if ((mntsize = freebsd11_getfsstat(mntbuf, bufsize, flags)) < 0) return (0); } *mntbufp = mntbuf; return (mntsize); } __sym_compat(getmntinfo, freebsd11_getmntinfo, FBSD_1.0); Index: head/lib/libc/gen/getmntinfo.c =================================================================== --- head/lib/libc/gen/getmntinfo.c (revision 335897) +++ head/lib/libc/gen/getmntinfo.c (revision 335898) @@ -1,72 +1,70 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1989, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)getmntinfo.c 8.1 (Berkeley) 6/4/93"; -#endif /* LIBC_SCCS and not lint */ #include +__SCCSID("@(#)getmntinfo.c 8.1 (Berkeley) 6/4/93"); __FBSDID("$FreeBSD$"); #include #include #include #include #define MAX_TRIES 3 #define SCALING_FACTOR 2 /* * Return information about mounted filesystems. */ int getmntinfo(struct statfs **mntbufp, int mode) { static struct statfs *mntbuf; static int mntsize; static long bufsize; unsigned tries = 0; if (mntsize <= 0 && (mntsize = getfsstat(0, 0, MNT_NOWAIT)) < 0) return (0); if (bufsize > 0 && (mntsize = getfsstat(mntbuf, bufsize, mode)) < 0) return (0); while (tries++ < MAX_TRIES && bufsize <= mntsize * sizeof(*mntbuf)) { bufsize = (mntsize * SCALING_FACTOR) * sizeof(*mntbuf); if ((mntbuf = reallocf(mntbuf, bufsize)) == NULL) return (0); if ((mntsize = getfsstat(mntbuf, bufsize, mode)) < 0) return (0); } *mntbufp = mntbuf; if (mntsize > (bufsize / sizeof(*mntbuf))) return (bufsize / sizeof(*mntbuf)); return (mntsize); } Index: head/lib/libc/gen/getnetgrent.c =================================================================== --- head/lib/libc/gen/getnetgrent.c (revision 335897) +++ head/lib/libc/gen/getnetgrent.c (revision 335898) @@ -1,1018 +1,1016 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1992, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Rick Macklem at The University of Guelph. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)getnetgrent.c 8.2 (Berkeley) 4/27/95"; -#endif /* LIBC_SCCS and not lint */ #include +__SCCSID("@(#)getnetgrent.c 8.2 (Berkeley) 4/27/95"); __FBSDID("$FreeBSD$"); #include "namespace.h" #include #include #include #include #include #include #include #include #include #include #include "nss_tls.h" #ifdef YP /* * Notes: * We want to be able to use NIS netgroups properly while retaining * the ability to use a local /etc/netgroup file. Unfortunately, you * can't really do both at the same time - at least, not efficiently. * NetBSD deals with this problem by creating a netgroup database * using Berkeley DB (just like the password database) that allows * for lookups using netgroup, netgroup.byuser or netgroup.byhost * searches. This is a neat idea, but I don't have time to implement * something like that now. (I think ultimately it would be nice * if we DB-fied the group and netgroup stuff all in one shot, but * for now I'm satisfied just to have something that works well * without requiring massive code changes.) * * Therefore, to still permit the use of the local file and maintain * optimum NIS performance, we allow for the following conditions: * * - If /etc/netgroup does not exist and NIS is turned on, we use * NIS netgroups only. * * - If /etc/netgroup exists but is empty, we use NIS netgroups * only. * * - If /etc/netgroup exists and contains _only_ a '+', we use * NIS netgroups only. * * - If /etc/netgroup exists, contains locally defined netgroups * and a '+', we use a mixture of NIS and the local entries. * This method should return the same NIS data as just using * NIS alone, but it will be slower if the NIS netgroup database * is large (innetgr() in particular will suffer since extra * processing has to be done in order to determine memberships * using just the raw netgroup data). * * - If /etc/netgroup exists and contains only locally defined * netgroup entries, we use just those local entries and ignore * NIS (this is the original, pre-NIS behavior). */ #include #include #include #include #include #include static char *_netgr_yp_domain; int _use_only_yp; static int _netgr_yp_enabled; static int _yp_innetgr; #endif #ifndef _PATH_NETGROUP #define _PATH_NETGROUP "/etc/netgroup" #endif enum constants { NGRP_STORAGE_INITIAL = 1 << 10, /* 1 KByte */ NGRP_STORAGE_MAX = 1 << 20, /* 1 MByte */ }; static const ns_src defaultsrc[] = { { NSSRC_COMPAT, NS_SUCCESS }, { NULL, 0 }, }; /* * Static Variables and functions used by setnetgrent(), getnetgrent() and * endnetgrent(). * There are two linked lists: * - linelist is just used by setnetgrent() to parse the net group file via. * parse_netgrp() * - netgrp is the list of entries for the current netgroup */ struct linelist { struct linelist *l_next; /* Chain ptr. */ int l_parsed; /* Flag for cycles */ char *l_groupname; /* Name of netgroup */ char *l_line; /* Netgroup entrie(s) to be parsed */ }; struct netgrp { struct netgrp *ng_next; /* Chain ptr */ char *ng_str[3]; /* Field pointers, see below */ }; struct netgr_state { FILE *st_netf; struct linelist *st_linehead; struct netgrp *st_nextgrp; struct netgrp *st_gr; char *st_grname; }; #define NG_HOST 0 /* Host name */ #define NG_USER 1 /* User name */ #define NG_DOM 2 /* and Domain name */ static void netgr_endstate(void *); NSS_TLS_HANDLING(netgr); static int files_endnetgrent(void *, void *, va_list); static int files_getnetgrent_r(void *, void *, va_list); static int files_setnetgrent(void *, void *, va_list); static int compat_endnetgrent(void *, void *, va_list); static int compat_innetgr(void *, void *, va_list); static int compat_getnetgrent_r(void *, void *, va_list); static int compat_setnetgrent(void *, void *, va_list); static void _compat_clearstate(void); static int _getnetgrent_r(char **, char **, char **, char *, size_t, int *, struct netgr_state *); static int _innetgr_fallback(void *, void *, const char *, const char *, const char *, const char *); static int innetgr_fallback(void *, void *, va_list); static int parse_netgrp(const char *, struct netgr_state *, int); static struct linelist *read_for_group(const char *, struct netgr_state *, int); #define LINSIZ 1024 /* Length of netgroup file line */ static const ns_dtab getnetgrent_dtab[] = { NS_FILES_CB(files_getnetgrent_r, NULL) NS_COMPAT_CB(compat_getnetgrent_r, NULL) { NULL, NULL, NULL }, }; static const ns_dtab setnetgrent_dtab[] = { NS_FILES_CB(files_setnetgrent, NULL) NS_COMPAT_CB(compat_setnetgrent, NULL) { NULL, NULL, NULL }, }; static const ns_dtab endnetgrent_dtab[] = { NS_FILES_CB(files_endnetgrent, NULL) NS_COMPAT_CB(compat_endnetgrent, NULL) { NULL, NULL, NULL }, }; static struct netgr_state compat_state; static void netgr_endstate(void *arg) { struct linelist *lp, *olp; struct netgrp *gp, *ogp; struct netgr_state *st; st = (struct netgr_state *)arg; lp = st->st_linehead; while (lp != NULL) { olp = lp; lp = lp->l_next; free(olp->l_groupname); free(olp->l_line); free(olp); } st->st_linehead = NULL; if (st->st_grname != NULL) { free(st->st_grname); st->st_grname = NULL; } gp = st->st_gr; while (gp != NULL) { ogp = gp; gp = gp->ng_next; free(ogp->ng_str[NG_HOST]); free(ogp->ng_str[NG_USER]); free(ogp->ng_str[NG_DOM]); free(ogp); } st->st_gr = NULL; st->st_nextgrp = NULL; } static int files_getnetgrent_r(void *retval, void *mdata, va_list ap) { struct netgr_state *st; char **hostp, **userp, **domp, *buf; size_t bufsize; int *errnop; hostp = va_arg(ap, char **); userp = va_arg(ap, char **); domp = va_arg(ap, char **); buf = va_arg(ap, char *); bufsize = va_arg(ap, size_t); errnop = va_arg(ap, int *); if (netgr_getstate(&st) != 0) return (NS_UNAVAIL); return (_getnetgrent_r(hostp, userp, domp, buf, bufsize, errnop, st)); } static int files_setnetgrent(void *retval, void *mdata, va_list ap) { const ns_src src[] = { { NSSRC_FILES, NS_SUCCESS }, { NULL, 0 }, }; struct netgr_state *st; const char *group; int rv; group = va_arg(ap, const char *); if (group == NULL || group[0] == '\0') return (NS_RETURN); rv = netgr_getstate(&st); if (rv != 0) return (NS_UNAVAIL); if (st->st_gr == NULL || strcmp(group, st->st_grname) != 0) { (void)_nsdispatch(NULL, endnetgrent_dtab, NSDB_NETGROUP, "endnetgrent", src); if ((st->st_netf = fopen(_PATH_NETGROUP, "re")) != NULL) { if (parse_netgrp(group, st, 0) != 0) (void)_nsdispatch(NULL, endnetgrent_dtab, NSDB_NETGROUP, "endnetgrent", src); else st->st_grname = strdup(group); (void)fclose(st->st_netf); st->st_netf = NULL; } } st->st_nextgrp = st->st_gr; return (st->st_grname != NULL ? NS_SUCCESS : NS_NOTFOUND); } static int files_endnetgrent(void *retval, void *mdata, va_list ap) { struct netgr_state *st; if (netgr_getstate(&st) != 0) return (NS_UNAVAIL); netgr_endstate(st); return (NS_SUCCESS); } static int compat_getnetgrent_r(void *retval, void *mdata, va_list ap) { char **hostp, **userp, **domp, *buf; size_t bufsize; int *errnop; #ifdef YP _yp_innetgr = 0; #endif hostp = va_arg(ap, char **); userp = va_arg(ap, char **); domp = va_arg(ap, char **); buf = va_arg(ap, char *); bufsize = va_arg(ap, size_t); errnop = va_arg(ap, int *); return (_getnetgrent_r(hostp, userp, domp, buf, bufsize, errnop, &compat_state)); } /* * compat_setnetgrent() * Parse the netgroup file looking for the netgroup and build the list * of netgrp structures. Let parse_netgrp() and read_for_group() do * most of the work. */ static int compat_setnetgrent(void *retval, void *mdata, va_list ap) { FILE *netf; const char *group; #ifdef YP struct stat _yp_statp; char _yp_plus; #endif group = va_arg(ap, const char *); /* Sanity check */ if (group == NULL || !strlen(group)) return (NS_RETURN); if (compat_state.st_gr == NULL || strcmp(group, compat_state.st_grname) != 0) { _compat_clearstate(); #ifdef YP /* Presumed guilty until proven innocent. */ _use_only_yp = 0; /* * If /etc/netgroup doesn't exist or is empty, * use NIS exclusively. */ if (((stat(_PATH_NETGROUP, &_yp_statp) < 0) && errno == ENOENT) || _yp_statp.st_size == 0) _use_only_yp = _netgr_yp_enabled = 1; if ((netf = fopen(_PATH_NETGROUP,"re")) != NULL ||_use_only_yp){ compat_state.st_netf = netf; /* * Icky: grab the first character of the netgroup file * and turn on NIS if it's a '+'. rewind the stream * afterwards so we don't goof up read_for_group() later. */ if (netf) { fscanf(netf, "%c", &_yp_plus); rewind(netf); if (_yp_plus == '+') _use_only_yp = _netgr_yp_enabled = 1; } /* * If we were called specifically for an innetgr() * lookup and we're in NIS-only mode, short-circuit * parse_netgroup() and cut directly to the chase. */ if (_use_only_yp && _yp_innetgr) { /* dohw! */ if (netf != NULL) fclose(netf); return (NS_RETURN); } #else if ((netf = fopen(_PATH_NETGROUP, "re"))) { compat_state.st_netf = netf; #endif if (parse_netgrp(group, &compat_state, 1)) { _compat_clearstate(); } else { compat_state.st_grname = strdup(group); } if (netf) fclose(netf); } } compat_state.st_nextgrp = compat_state.st_gr; return (NS_SUCCESS); } static void _compat_clearstate(void) { #ifdef YP _netgr_yp_enabled = 0; #endif netgr_endstate(&compat_state); } /* * compat_endnetgrent() - cleanup */ static int compat_endnetgrent(void *retval, void *mdata, va_list ap) { _compat_clearstate(); return (NS_SUCCESS); } int _getnetgrent_r(char **hostp, char **userp, char **domp, char *buf, size_t bufsize, int *errnop, struct netgr_state *st) { char *p, *src; size_t len; int rv; #define COPY_NG_ELEM(dstp, i) do { \ src = st->st_nextgrp->ng_str[(i)]; \ if (src == NULL) \ src = ""; \ len = strlcpy(p, src, bufsize); \ if (len >= bufsize) { \ *errnop = ERANGE; \ return (NS_RETURN); \ } \ *(dstp) = p; \ p += len + 1; \ bufsize -= len + 1; \ } while (0) p = buf; if (st->st_nextgrp != NULL) { COPY_NG_ELEM(hostp, NG_HOST); COPY_NG_ELEM(userp, NG_USER); COPY_NG_ELEM(domp, NG_DOM); st->st_nextgrp = st->st_nextgrp->ng_next; rv = NS_SUCCESS; } else { rv = NS_NOTFOUND; } #undef COPY_NG_ELEM return (rv); } #ifdef YP static int _listmatch(const char *list, const char *group, int len) { const char *ptr = list; const char *cptr; int glen = strlen(group); /* skip possible leading whitespace */ while (isspace((unsigned char)*ptr)) ptr++; while (ptr < list + len) { cptr = ptr; while(*ptr != ',' && *ptr != '\0' && !isspace((unsigned char)*ptr)) ptr++; if (strncmp(cptr, group, glen) == 0 && glen == (ptr - cptr)) return (1); while (*ptr == ',' || isspace((unsigned char)*ptr)) ptr++; } return (0); } static int _revnetgr_lookup(char* lookupdom, char* map, const char* str, const char* dom, const char* group) { int y, rv, rot; char key[MAXHOSTNAMELEN]; char *result; int resultlen; for (rot = 0; ; rot++) { switch (rot) { case 0: snprintf(key, MAXHOSTNAMELEN, "%s.%s", str, dom ? dom : lookupdom); break; case 1: snprintf(key, MAXHOSTNAMELEN, "%s.*", str); break; case 2: snprintf(key, MAXHOSTNAMELEN, "*.%s", dom ? dom : lookupdom); break; case 3: snprintf(key, MAXHOSTNAMELEN, "*.*"); break; default: return (0); } y = yp_match(lookupdom, map, key, strlen(key), &result, &resultlen); if (y == 0) { rv = _listmatch(result, group, resultlen); free(result); if (rv) return (1); } else if (y != YPERR_KEY) { /* * If we get an error other than 'no * such key in map' then something is * wrong and we should stop the search. */ return (-1); } } } #endif /* * Search for a match in a netgroup. */ static int compat_innetgr(void *retval, void *mdata, va_list ap) { #ifdef YP const ns_src src[] = { { mdata, NS_SUCCESS }, { NULL, 0 }, }; #endif const char *group, *host, *user, *dom; group = va_arg(ap, const char *); host = va_arg(ap, const char *); user = va_arg(ap, const char *); dom = va_arg(ap, const char *); if (group == NULL || !strlen(group)) return (NS_RETURN); #ifdef YP _yp_innetgr = 1; (void)_nsdispatch(NULL, setnetgrent_dtab, NSDB_NETGROUP, "setnetgrent", src, group); _yp_innetgr = 0; /* * If we're in NIS-only mode, do the search using * NIS 'reverse netgroup' lookups. * * What happens with 'reverse netgroup' lookups: * * 1) try 'reverse netgroup' lookup * 1.a) if host is specified and user is null: * look in netgroup.byhost * (try host.domain, host.*, *.domain or *.*) * if found, return yes * 1.b) if user is specified and host is null: * look in netgroup.byuser * (try host.domain, host.*, *.domain or *.*) * if found, return yes * 1.c) if both host and user are specified, * don't do 'reverse netgroup' lookup. It won't work. * 1.d) if neither host ane user are specified (why?!?) * don't do 'reverse netgroup' lookup either. * 2) if domain is specified and 'reverse lookup' is done: * 'reverse lookup' was authoritative. bye bye. * 3) otherwise, too bad, try it the slow way. */ if (_use_only_yp && (host == NULL) != (user == NULL)) { int ret; if(yp_get_default_domain(&_netgr_yp_domain)) return (NS_NOTFOUND); ret = _revnetgr_lookup(_netgr_yp_domain, host?"netgroup.byhost":"netgroup.byuser", host?host:user, dom, group); if (ret == 1) { *(int *)retval = 1; return (NS_SUCCESS); } else if (ret == 0 && dom != NULL) { *(int *)retval = 0; return (NS_SUCCESS); } } #endif /* YP */ return (_innetgr_fallback(retval, mdata, group, host, user, dom)); } static int _innetgr_fallback(void *retval, void *mdata, const char *group, const char *host, const char *user, const char *dom) { const ns_src src[] = { { mdata, NS_SUCCESS }, { NULL, 0 }, }; char *h, *u, *d; char *buf; size_t bufsize; int rv, ret_errno; if (group == NULL || group[0] == '\0') return (NS_RETURN); bufsize = NGRP_STORAGE_INITIAL; buf = malloc(bufsize); if (buf == NULL) return (NS_UNAVAIL); *(int *)retval = 0; (void)_nsdispatch(NULL, setnetgrent_dtab, NSDB_NETGROUP, "setnetgrent", src, group); for (;;) { do { ret_errno = 0; rv = _nsdispatch(NULL, getnetgrent_dtab, NSDB_NETGROUP, "getnetgrent_r", src, &h, &u, &d, buf, bufsize, &ret_errno); if (rv != NS_SUCCESS && ret_errno == ERANGE) { bufsize *= 2; if (bufsize > NGRP_STORAGE_MAX || (buf = reallocf(buf, bufsize)) == NULL) goto out; } } while (rv != NS_SUCCESS && ret_errno == ERANGE); if (rv != NS_SUCCESS) { if (rv == NS_NOTFOUND && ret_errno == 0) rv = NS_SUCCESS; break; } if ((host == NULL || h == NULL || strcmp(host, h) == 0) && (user == NULL || u == NULL || strcmp(user, u) == 0) && (dom == NULL || d == NULL || strcmp(dom, d) == 0)) { *(int *)retval = 1; break; } } out: free(buf); (void)_nsdispatch(NULL, endnetgrent_dtab, NSDB_NETGROUP, "endnetgrent", src); return (rv); } static int innetgr_fallback(void *retval, void *mdata, va_list ap) { const char *group, *host, *user, *dom; group = va_arg(ap, const char *); host = va_arg(ap, const char *); user = va_arg(ap, const char *); dom = va_arg(ap, const char *); return (_innetgr_fallback(retval, mdata, group, host, user, dom)); } /* * Parse the netgroup file setting up the linked lists. */ static int parse_netgrp(const char *group, struct netgr_state *st, int niscompat) { struct netgrp *grp; struct linelist *lp = st->st_linehead; char **ng; char *epos, *gpos, *pos, *spos; int freepos, len, strpos; #ifdef DEBUG int fields; #endif /* * First, see if the line has already been read in. */ while (lp) { if (!strcmp(group, lp->l_groupname)) break; lp = lp->l_next; } if (lp == NULL && (lp = read_for_group(group, st, niscompat)) == NULL) return (1); if (lp->l_parsed) { #ifdef DEBUG /* * This error message is largely superflous since the * code handles the error condition sucessfully, and * spewing it out from inside libc can actually hose * certain programs. */ fprintf(stderr, "Cycle in netgroup %s\n", lp->l_groupname); #endif return (1); } else lp->l_parsed = 1; pos = lp->l_line; /* Watch for null pointer dereferences, dammit! */ while (pos != NULL && *pos != '\0') { if (*pos == '(') { grp = malloc(sizeof(*grp)); if (grp == NULL) return (1); ng = grp->ng_str; bzero(grp, sizeof(*grp)); pos++; gpos = strsep(&pos, ")"); #ifdef DEBUG fields = 0; #endif for (strpos = 0; strpos < 3; strpos++) { if ((spos = strsep(&gpos, ",")) == NULL) { /* * All other systems I've tested * return NULL for empty netgroup * fields. It's up to user programs * to handle the NULLs appropriately. */ ng[strpos] = NULL; continue; } #ifdef DEBUG fields++; #endif while (*spos == ' ' || *spos == '\t') spos++; if ((epos = strpbrk(spos, " \t"))) { *epos = '\0'; len = epos - spos; } else len = strlen(spos); if (len <= 0) continue; ng[strpos] = malloc(len + 1); if (ng[strpos] == NULL) { for (freepos = 0; freepos < strpos; freepos++) free(ng[freepos]); free(grp); return (1); } bcopy(spos, ng[strpos], len + 1); } grp->ng_next = st->st_gr; st->st_gr = grp; #ifdef DEBUG /* * Note: on other platforms, malformed netgroup * entries are not normally flagged. While we * can catch bad entries and report them, we should * stay silent by default for compatibility's sake. */ if (fields < 3) { fprintf(stderr, "Bad entry (%s%s%s%s%s) in netgroup \"%s\"\n", ng[NG_HOST] == NULL ? "" : ng[NG_HOST], ng[NG_USER] == NULL ? "" : ",", ng[NG_USER] == NULL ? "" : ng[NG_USER], ng[NG_DOM] == NULL ? "" : ",", ng[NG_DOM] == NULL ? "" : ng[NG_DOM], lp->l_groupname); } #endif } else { spos = strsep(&pos, ", \t"); if (parse_netgrp(spos, st, niscompat)) continue; } if (pos == NULL) break; while (*pos == ' ' || *pos == ',' || *pos == '\t') pos++; } return (0); } /* * Read the netgroup file and save lines until the line for the netgroup * is found. Return 1 if eof is encountered. */ static struct linelist * read_for_group(const char *group, struct netgr_state *st, int niscompat) { char *linep, *olinep, *pos, *spos; int len, olen; int cont; struct linelist *lp; char line[LINSIZ + 2]; FILE *netf; #ifdef YP char *result; int resultlen; linep = NULL; netf = st->st_netf; while ((_netgr_yp_enabled && niscompat) || fgets(line, LINSIZ, netf) != NULL) { if (_netgr_yp_enabled) { if(!_netgr_yp_domain) if(yp_get_default_domain(&_netgr_yp_domain)) continue; if (yp_match(_netgr_yp_domain, "netgroup", group, strlen(group), &result, &resultlen)) { free(result); if (_use_only_yp) return ((struct linelist *)0); else { _netgr_yp_enabled = 0; continue; } } if (strlen(result) == 0) { free(result); return (NULL); } snprintf(line, LINSIZ, "%s %s", group, result); free(result); } #else linep = NULL; while (fgets(line, LINSIZ, netf) != NULL) { #endif pos = (char *)&line; #ifdef YP if (niscompat && *pos == '+') { _netgr_yp_enabled = 1; continue; } #endif if (*pos == '#') continue; while (*pos == ' ' || *pos == '\t') pos++; spos = pos; while (*pos != ' ' && *pos != '\t' && *pos != '\n' && *pos != '\0') pos++; len = pos - spos; while (*pos == ' ' || *pos == '\t') pos++; if (*pos != '\n' && *pos != '\0') { lp = malloc(sizeof (*lp)); if (lp == NULL) return (NULL); lp->l_parsed = 0; lp->l_groupname = malloc(len + 1); if (lp->l_groupname == NULL) { free(lp); return (NULL); } bcopy(spos, lp->l_groupname, len); *(lp->l_groupname + len) = '\0'; len = strlen(pos); olen = 0; /* * Loop around handling line continuations. */ do { if (*(pos + len - 1) == '\n') len--; if (*(pos + len - 1) == '\\') { len--; cont = 1; } else cont = 0; if (len > 0) { linep = malloc(olen + len + 1); if (linep == NULL) { free(lp->l_groupname); free(lp); if (olen > 0) free(olinep); return (NULL); } if (olen > 0) { bcopy(olinep, linep, olen); free(olinep); } bcopy(pos, linep + olen, len); olen += len; *(linep + olen) = '\0'; olinep = linep; } if (cont) { if (fgets(line, LINSIZ, netf)) { pos = line; len = strlen(pos); } else cont = 0; } } while (cont); lp->l_line = linep; lp->l_next = st->st_linehead; st->st_linehead = lp; /* * If this is the one we wanted, we are done. */ if (!strcmp(lp->l_groupname, group)) return (lp); } } #ifdef YP /* * Yucky. The recursive nature of this whole mess might require * us to make more than one pass through the netgroup file. * This might be best left outside the #ifdef YP, but YP is * defined by default anyway, so I'll leave it like this * until I know better. */ rewind(netf); #endif return (NULL); } int getnetgrent_r(char **hostp, char **userp, char **domp, char *buf, size_t bufsize) { int rv, ret_errno; ret_errno = 0; rv = _nsdispatch(NULL, getnetgrent_dtab, NSDB_NETGROUP, "getnetgrent_r", defaultsrc, hostp, userp, domp, buf, bufsize, &ret_errno); if (rv == NS_SUCCESS) { return (1); } else { errno = ret_errno; return (0); } } int getnetgrent(char **hostp, char **userp, char **domp) { static char *ngrp_storage; static size_t ngrp_storage_size; int ret_errno, rv; if (ngrp_storage == NULL) { ngrp_storage_size = NGRP_STORAGE_INITIAL; ngrp_storage = malloc(ngrp_storage_size); if (ngrp_storage == NULL) return (0); } do { ret_errno = 0; rv = _nsdispatch(NULL, getnetgrent_dtab, NSDB_NETGROUP, "getnetgrent_r", defaultsrc, hostp, userp, domp, ngrp_storage, ngrp_storage_size, &ret_errno); if (rv != NS_SUCCESS && ret_errno == ERANGE) { ngrp_storage_size *= 2; if (ngrp_storage_size > NGRP_STORAGE_MAX) { free(ngrp_storage); ngrp_storage = NULL; errno = ERANGE; return (0); } ngrp_storage = reallocf(ngrp_storage, ngrp_storage_size); if (ngrp_storage == NULL) return (0); } } while (rv != NS_SUCCESS && ret_errno == ERANGE); if (rv == NS_SUCCESS) { return (1); } else { errno = ret_errno; return (0); } } void setnetgrent(const char *netgroup) { (void)_nsdispatch(NULL, setnetgrent_dtab, NSDB_NETGROUP, "setnetgrent", defaultsrc, netgroup); } void endnetgrent(void) { (void)_nsdispatch(NULL, endnetgrent_dtab, NSDB_NETGROUP, "endnetgrent", defaultsrc); } int innetgr(const char *netgroup, const char *host, const char *user, const char *domain) { static const ns_dtab dtab[] = { NS_COMPAT_CB(compat_innetgr, NULL) NS_FALLBACK_CB(innetgr_fallback) { NULL, NULL, NULL }, }; int result, rv; rv = _nsdispatch(&result, dtab, NSDB_NETGROUP, "innetgr", defaultsrc, netgroup, host, user, domain); return (rv == NS_SUCCESS ? result : 0); } Index: head/lib/libc/gen/getosreldate.c =================================================================== --- head/lib/libc/gen/getosreldate.c (revision 335897) +++ head/lib/libc/gen/getosreldate.c (revision 335898) @@ -1,63 +1,61 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1989, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)gethostid.c 8.1 (Berkeley) 6/2/93"; -#endif /* LIBC_SCCS and not lint */ #include +__SCCSID("@(#)gethostid.c 8.1 (Berkeley) 6/2/93"); __FBSDID("$FreeBSD$"); #include #include #include #include int getosreldate(void) { int mib[2]; size_t size; int value; char *temp; if ((temp = getenv("OSVERSION"))) { value = atoi(temp); return (value); } mib[0] = CTL_KERN; mib[1] = KERN_OSRELDATE; size = sizeof value; if (sysctl(mib, 2, &value, &size, NULL, 0) == -1) return (-1); return (value); } Index: head/lib/libc/gen/getpagesize.c =================================================================== --- head/lib/libc/gen/getpagesize.c (revision 335897) +++ head/lib/libc/gen/getpagesize.c (revision 335898) @@ -1,77 +1,75 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1989, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)getpagesize.c 8.1 (Berkeley) 6/4/93"; -#endif /* LIBC_SCCS and not lint */ #include +__SCCSID("@(#)getpagesize.c 8.1 (Berkeley) 6/4/93"); __FBSDID("$FreeBSD$"); #include #include #include #include #include #include "libc_private.h" /* * This is unlikely to change over the running time of any * program, so we cache the result to save some syscalls. * * NB: This function may be called from malloc(3) at initialization * NB: so must not result in a malloc(3) related call! */ int getpagesize(void) { int mib[2]; static int value; size_t size; int error; if (value != 0) return (value); error = _elf_aux_info(AT_PAGESZ, &value, sizeof(value)); if (error == 0 && value != 0) return (value); mib[0] = CTL_HW; mib[1] = HW_PAGESIZE; size = sizeof value; if (sysctl(mib, nitems(mib), &value, &size, NULL, 0) == -1) return (PAGE_SIZE); return (value); } Index: head/lib/libc/gen/getttyent.c =================================================================== --- head/lib/libc/gen/getttyent.c (revision 335897) +++ head/lib/libc/gen/getttyent.c (revision 335898) @@ -1,318 +1,316 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1989, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)getttyent.c 8.1 (Berkeley) 6/4/93"; -#endif /* LIBC_SCCS and not lint */ #include +__SCCSID("@(#)getttyent.c 8.1 (Berkeley) 6/4/93"); __FBSDID("$FreeBSD$"); #include #include #include #include #include #include #include #include static char zapchar; static FILE *tf; static size_t lbsize; static char *line; #define MALLOCCHUNK 100 static char *skip(char *); static char *value(char *); struct ttyent * getttynam(const char *tty) { struct ttyent *t; if (strncmp(tty, "/dev/", 5) == 0) tty += 5; setttyent(); while ( (t = getttyent()) ) if (!strcmp(tty, t->ty_name)) break; endttyent(); return (t); } static int auto_tty_status(const char *ty_name) { size_t len; char *buf, *cons, *nextcons; int rv; rv = TTY_IFCONSOLE; /* Check if this is an enabled kernel console line */ buf = NULL; if (sysctlbyname("kern.console", NULL, &len, NULL, 0) == -1) return (rv); /* Errors mean don't enable */ buf = malloc(len); if (sysctlbyname("kern.console", buf, &len, NULL, 0) == -1) goto done; if ((cons = strchr(buf, '/')) == NULL) goto done; *cons = '\0'; nextcons = buf; while ((cons = strsep(&nextcons, ",")) != NULL && strlen(cons) != 0) { if (strcmp(cons, ty_name) == 0) { rv |= TTY_ON; break; } } done: free(buf); return (rv); } static int auto_exists_status(const char *ty_name) { struct stat sb; char *dev; int rv; rv = TTY_IFEXISTS; if (*ty_name == '/') asprintf(&dev, "%s", ty_name); else asprintf(&dev, "/dev/%s", ty_name); if (dev != NULL && stat(dev, &sb) == 0) rv |= TTY_ON; free(dev); return (rv); } struct ttyent * getttyent(void) { static struct ttyent tty; char *p; int c; size_t i; if (!tf && !setttyent()) return (NULL); for (;;) { if (!fgets(p = line, lbsize, tf)) return (NULL); /* extend buffer if line was too big, and retry */ while (!strchr(p, '\n') && !feof(tf)) { i = strlen(p); lbsize += MALLOCCHUNK; if ((p = realloc(line, lbsize)) == NULL) { (void)endttyent(); return (NULL); } line = p; if (!fgets(&line[i], lbsize - i, tf)) return (NULL); } while (isspace((unsigned char)*p)) ++p; if (*p && *p != '#') break; } #define scmp(e) !strncmp(p, e, sizeof(e) - 1) && isspace((unsigned char)p[sizeof(e) - 1]) #define vcmp(e) !strncmp(p, e, sizeof(e) - 1) && p[sizeof(e) - 1] == '=' zapchar = 0; tty.ty_name = p; tty.ty_status = 0; tty.ty_window = NULL; tty.ty_group = _TTYS_NOGROUP; p = skip(p); if (!*(tty.ty_getty = p)) tty.ty_getty = tty.ty_type = NULL; else { p = skip(p); if (!*(tty.ty_type = p)) tty.ty_type = NULL; else { /* compatibility kludge: handle network/dialup specially */ if (scmp(_TTYS_DIALUP)) tty.ty_status |= TTY_DIALUP; else if (scmp(_TTYS_NETWORK)) tty.ty_status |= TTY_NETWORK; p = skip(p); } } for (; *p; p = skip(p)) { if (scmp(_TTYS_OFF)) tty.ty_status &= ~TTY_ON; else if (scmp(_TTYS_ON)) tty.ty_status |= TTY_ON; else if (scmp(_TTYS_ONIFCONSOLE)) tty.ty_status |= auto_tty_status(tty.ty_name); else if (scmp(_TTYS_ONIFEXISTS)) tty.ty_status |= auto_exists_status(tty.ty_name); else if (scmp(_TTYS_SECURE)) tty.ty_status |= TTY_SECURE; else if (scmp(_TTYS_INSECURE)) tty.ty_status &= ~TTY_SECURE; else if (scmp(_TTYS_DIALUP)) tty.ty_status |= TTY_DIALUP; else if (scmp(_TTYS_NETWORK)) tty.ty_status |= TTY_NETWORK; else if (vcmp(_TTYS_WINDOW)) tty.ty_window = value(p); else if (vcmp(_TTYS_GROUP)) tty.ty_group = value(p); else break; } if (zapchar == '#' || *p == '#') while ((c = *++p) == ' ' || c == '\t') ; tty.ty_comment = p; if (*p == 0) tty.ty_comment = 0; if ((p = strchr(p, '\n'))) *p = '\0'; return (&tty); } #define QUOTED 1 /* * Skip over the current field, removing quotes, and return a pointer to * the next field. */ static char * skip(char *p) { char *t; int c, q; for (q = 0, t = p; (c = *p) != '\0'; p++) { if (c == '"') { q ^= QUOTED; /* obscure, but nice */ continue; } if (q == QUOTED && *p == '\\' && *(p+1) == '"') p++; *t++ = *p; if (q == QUOTED) continue; if (c == '#') { zapchar = c; *p = 0; break; } if (c == '\t' || c == ' ' || c == '\n') { zapchar = c; *p++ = 0; while ((c = *p) == '\t' || c == ' ' || c == '\n') p++; break; } } *--t = '\0'; return (p); } static char * value(char *p) { return ((p = strchr(p, '=')) ? ++p : NULL); } int setttyent(void) { if (line == NULL) { if ((line = malloc(MALLOCCHUNK)) == NULL) return (0); lbsize = MALLOCCHUNK; } if (tf) { rewind(tf); return (1); } else if ( (tf = fopen(_PATH_TTYS, "re")) ) return (1); return (0); } int endttyent(void) { int rval; /* * NB: Don't free `line' because getttynam() * may still be referencing it */ if (tf) { rval = (fclose(tf) != EOF); tf = NULL; return (rval); } return (1); } static int isttystat(const char *tty, int flag) { struct ttyent *t; return ((t = getttynam(tty)) == NULL) ? 0 : !!(t->ty_status & flag); } int isdialuptty(const char *tty) { return isttystat(tty, TTY_DIALUP); } int isnettty(const char *tty) { return isttystat(tty, TTY_NETWORK); } Index: head/lib/libc/gen/getusershell.c =================================================================== --- head/lib/libc/gen/getusershell.c (revision 335897) +++ head/lib/libc/gen/getusershell.c (revision 335898) @@ -1,262 +1,260 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1985, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)getusershell.c 8.1 (Berkeley) 6/4/93"; -#endif /* LIBC_SCCS and not lint */ -/* $NetBSD: getusershell.c,v 1.17 1999/01/25 01:09:34 lukem Exp $ */ #include +__SCCSID("@(#)getusershell.c 8.1 (Berkeley) 6/4/93"); +__RCSID("$NetBSD: getusershell.c,v 1.17 1999/01/25 01:09:34 lukem Exp $"); __FBSDID("$FreeBSD$"); #include "namespace.h" #include #include #include #include #include #include #include #include #include #include #include #ifdef HESIOD #include #endif #ifdef YP #include #include #include #endif #include "un-namespace.h" static const char *const *curshell; static StringList *sl; static const char *const *initshells(void); /* * Get a list of shells from "shells" nsswitch database */ char * getusershell(void) { char *ret; if (curshell == NULL) curshell = initshells(); /*LINTED*/ ret = (char *)*curshell; if (ret != NULL) curshell++; return (ret); } void endusershell(void) { if (sl) { sl_free(sl, 1); sl = NULL; } curshell = NULL; } void setusershell(void) { curshell = initshells(); } static int _local_initshells(void *, void *, va_list); /*ARGSUSED*/ static int _local_initshells(void *rv, void *cb_data, va_list ap) { char *sp, *cp; FILE *fp; char line[MAXPATHLEN + 2]; if (sl) sl_free(sl, 1); sl = sl_init(); if ((fp = fopen(_PATH_SHELLS, "re")) == NULL) return NS_UNAVAIL; while (fgets(line, MAXPATHLEN + 1, fp) != NULL) { cp = line; while (*cp != '#' && *cp != '/' && *cp != '\0') cp++; if (*cp == '#' || *cp == '\0') continue; sp = cp; while (!isspace(*cp) && *cp != '#' && *cp != '\0') cp++; *cp = '\0'; sl_add(sl, strdup(sp)); } (void)fclose(fp); return NS_SUCCESS; } #ifdef HESIOD static int _dns_initshells(void *, void *, va_list); /*ARGSUSED*/ static int _dns_initshells(void *rv, void *cb_data, va_list ap) { char shellname[] = "shells-XXXXX"; int hsindex, hpi, r; char **hp; void *context; if (sl) sl_free(sl, 1); sl = sl_init(); r = NS_UNAVAIL; if (hesiod_init(&context) == -1) return (r); for (hsindex = 0; ; hsindex++) { snprintf(shellname, sizeof(shellname)-1, "shells-%d", hsindex); hp = hesiod_resolve(context, shellname, "shells"); if (hp == NULL) { if (errno == ENOENT) { if (hsindex == 0) r = NS_NOTFOUND; else r = NS_SUCCESS; } break; } else { for (hpi = 0; hp[hpi]; hpi++) sl_add(sl, hp[hpi]); free(hp); } } hesiod_end(context); return (r); } #endif /* HESIOD */ #ifdef YP static int _nis_initshells(void *, void *, va_list); /*ARGSUSED*/ static int _nis_initshells(void *rv, void *cb_data, va_list ap) { static char *ypdomain; char *key, *data; char *lastkey; int keylen, datalen; int r; if (sl) sl_free(sl, 1); sl = sl_init(); if (ypdomain == NULL) { switch (yp_get_default_domain(&ypdomain)) { case 0: break; case YPERR_RESRC: return NS_TRYAGAIN; default: return NS_UNAVAIL; } } /* * `key' and `data' point to strings dynamically allocated by * the yp_... functions. * `data' is directly put into the stringlist of shells. */ key = data = NULL; if (yp_first(ypdomain, "shells", &key, &keylen, &data, &datalen)) return NS_UNAVAIL; do { data[datalen] = '\0'; /* clear trailing \n */ sl_add(sl, data); lastkey = key; r = yp_next(ypdomain, "shells", lastkey, keylen, &key, &keylen, &data, &datalen); free(lastkey); } while (r == 0); if (r == YPERR_NOMORE) { /* * `data' and `key' ought to be NULL - do not try to free them. */ return NS_SUCCESS; } return NS_UNAVAIL; } #endif /* YP */ static const char *const * initshells(void) { static const ns_dtab dtab[] = { NS_FILES_CB(_local_initshells, NULL) NS_DNS_CB(_dns_initshells, NULL) NS_NIS_CB(_nis_initshells, NULL) { 0 } }; if (sl) sl_free(sl, 1); sl = sl_init(); if (_nsdispatch(NULL, dtab, NSDB_SHELLS, "initshells", __nsdefaultsrc) != NS_SUCCESS) { if (sl) sl_free(sl, 1); sl = sl_init(); /* * Local shells should NOT be added here. They should be * added in /etc/shells. */ sl_add(sl, strdup(_PATH_BSHELL)); sl_add(sl, strdup(_PATH_CSHELL)); } sl_add(sl, NULL); return (const char *const *)(sl->sl_str); } Index: head/lib/libc/gen/getvfsbyname.c =================================================================== --- head/lib/libc/gen/getvfsbyname.c (revision 335897) +++ head/lib/libc/gen/getvfsbyname.c (revision 335898) @@ -1,76 +1,74 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1995 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)kvm_getvfsbyname.c 8.1 (Berkeley) 4/3/95"; -#endif /* LIBC_SCCS and not lint */ #include +__SCCSID("@(#)kvm_getvfsbyname.c 8.1 (Berkeley) 4/3/95"); __FBSDID("$FreeBSD$"); #include #include #include #include #include #include /* * Given a filesystem name, determine if it is resident in the kernel, * and if it is resident, return its xvfsconf structure. */ int getvfsbyname(const char *fsname, struct xvfsconf *vfcp) { struct xvfsconf *xvfsp; size_t buflen; int cnt, i; if (sysctlbyname("vfs.conflist", NULL, &buflen, NULL, 0) < 0) return (-1); xvfsp = malloc(buflen); if (xvfsp == NULL) return (-1); if (sysctlbyname("vfs.conflist", xvfsp, &buflen, NULL, 0) < 0) { free(xvfsp); return (-1); } cnt = buflen / sizeof(struct xvfsconf); for (i = 0; i < cnt; i++) { if (strcmp(fsname, xvfsp[i].vfc_name) == 0) { memcpy(vfcp, xvfsp + i, sizeof(struct xvfsconf)); free(xvfsp); return (0); } } free(xvfsp); errno = ENOENT; return (-1); } Index: head/lib/libc/gen/glob-compat11.c =================================================================== --- head/lib/libc/gen/glob-compat11.c (revision 335897) +++ head/lib/libc/gen/glob-compat11.c (revision 335898) @@ -1,1093 +1,1091 @@ /* * Copyright (c) 1989, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Guido van Rossum. * * Copyright (c) 2011 The FreeBSD Foundation * All rights reserved. * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * from: $FreeBSD$ + * From: @(#)glob.c 8.3 (Berkeley) 10/13/93 + * From: FreeBSD: head/lib/libc/gen/glob.c 317913 2017-05-07 19:52:56Z jilles */ -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)glob.c 8.3 (Berkeley) 10/13/93"; -#endif /* LIBC_SCCS and not lint */ #include __FBSDID("$FreeBSD$"); #include #define _WANT_FREEBSD11_STAT #include #include #define _WANT_FREEBSD11_DIRENT #include #include #include #include #include #include #include #include #include #include #include #include "collate.h" #include "gen-compat.h" #include "glob-compat11.h" /* * glob(3) expansion limits. Stop the expansion if any of these limits * is reached. This caps the runtime in the face of DoS attacks. See * also CVE-2010-2632 */ #define GLOB_LIMIT_BRACE 128 /* number of brace calls */ #define GLOB_LIMIT_PATH 65536 /* number of path elements */ #define GLOB_LIMIT_READDIR 16384 /* number of readdirs */ #define GLOB_LIMIT_STAT 1024 /* number of stat system calls */ #define GLOB_LIMIT_STRING ARG_MAX /* maximum total size for paths */ struct glob_limit { size_t l_brace_cnt; size_t l_path_lim; size_t l_readdir_cnt; size_t l_stat_cnt; size_t l_string_cnt; }; #define DOT L'.' #define EOS L'\0' #define LBRACKET L'[' #define NOT L'!' #define QUESTION L'?' #define QUOTE L'\\' #define RANGE L'-' #define RBRACKET L']' #define SEP L'/' #define STAR L'*' #define TILDE L'~' #define LBRACE L'{' #define RBRACE L'}' #define COMMA L',' #define M_QUOTE 0x8000000000ULL #define M_PROTECT 0x4000000000ULL #define M_MASK 0xffffffffffULL #define M_CHAR 0x00ffffffffULL typedef uint_fast64_t Char; #define CHAR(c) ((Char)((c)&M_CHAR)) #define META(c) ((Char)((c)|M_QUOTE)) #define UNPROT(c) ((c) & ~M_PROTECT) #define M_ALL META(L'*') #define M_END META(L']') #define M_NOT META(L'!') #define M_ONE META(L'?') #define M_RNG META(L'-') #define M_SET META(L'[') #define ismeta(c) (((c)&M_QUOTE) != 0) #ifdef DEBUG #define isprot(c) (((c)&M_PROTECT) != 0) #endif static int compare(const void *, const void *); static int g_Ctoc(const Char *, char *, size_t); static int g_lstat(Char *, struct freebsd11_stat *, glob11_t *); static DIR *g_opendir(Char *, glob11_t *); static const Char *g_strchr(const Char *, wchar_t); #ifdef notdef static Char *g_strcat(Char *, const Char *); #endif static int g_stat(Char *, struct freebsd11_stat *, glob11_t *); static int glob0(const Char *, glob11_t *, struct glob_limit *, const char *); static int glob1(Char *, glob11_t *, struct glob_limit *); static int glob2(Char *, Char *, Char *, Char *, glob11_t *, struct glob_limit *); static int glob3(Char *, Char *, Char *, Char *, Char *, glob11_t *, struct glob_limit *); static int globextend(const Char *, glob11_t *, struct glob_limit *, const char *); static const Char * globtilde(const Char *, Char *, size_t, glob11_t *); static int globexp0(const Char *, glob11_t *, struct glob_limit *, const char *); static int globexp1(const Char *, glob11_t *, struct glob_limit *); static int globexp2(const Char *, const Char *, glob11_t *, struct glob_limit *); static int globfinal(glob11_t *, struct glob_limit *, size_t, const char *); static int match(Char *, Char *, Char *); static int err_nomatch(glob11_t *, struct glob_limit *, const char *); static int err_aborted(glob11_t *, int, char *); #ifdef DEBUG static void qprintf(const char *, Char *); #endif int freebsd11_glob(const char * __restrict pattern, int flags, int (*errfunc)(const char *, int), glob11_t * __restrict pglob) { struct glob_limit limit = { 0, 0, 0, 0, 0 }; const char *patnext; Char *bufnext, *bufend, patbuf[MAXPATHLEN], prot; mbstate_t mbs; wchar_t wc; size_t clen; int too_long; patnext = pattern; if (!(flags & GLOB_APPEND)) { pglob->gl_pathc = 0; pglob->gl_pathv = NULL; if (!(flags & GLOB_DOOFFS)) pglob->gl_offs = 0; } if (flags & GLOB_LIMIT) { limit.l_path_lim = pglob->gl_matchc; if (limit.l_path_lim == 0) limit.l_path_lim = GLOB_LIMIT_PATH; } pglob->gl_flags = flags & ~GLOB_MAGCHAR; pglob->gl_errfunc = errfunc; pglob->gl_matchc = 0; bufnext = patbuf; bufend = bufnext + MAXPATHLEN - 1; too_long = 1; if (flags & GLOB_NOESCAPE) { memset(&mbs, 0, sizeof(mbs)); while (bufnext <= bufend) { clen = mbrtowc(&wc, patnext, MB_LEN_MAX, &mbs); if (clen == (size_t)-1 || clen == (size_t)-2) return (err_nomatch(pglob, &limit, pattern)); else if (clen == 0) { too_long = 0; break; } *bufnext++ = wc; patnext += clen; } } else { /* Protect the quoted characters. */ memset(&mbs, 0, sizeof(mbs)); while (bufnext <= bufend) { if (*patnext == '\\') { if (*++patnext == '\0') { *bufnext++ = QUOTE; continue; } prot = M_PROTECT; } else prot = 0; clen = mbrtowc(&wc, patnext, MB_LEN_MAX, &mbs); if (clen == (size_t)-1 || clen == (size_t)-2) return (err_nomatch(pglob, &limit, pattern)); else if (clen == 0) { too_long = 0; break; } *bufnext++ = wc | prot; patnext += clen; } } if (too_long) return (err_nomatch(pglob, &limit, pattern)); *bufnext = EOS; if (flags & GLOB_BRACE) return (globexp0(patbuf, pglob, &limit, pattern)); else return (glob0(patbuf, pglob, &limit, pattern)); } static int globexp0(const Char *pattern, glob11_t *pglob, struct glob_limit *limit, const char *origpat) { int rv; size_t oldpathc; /* Protect a single {}, for find(1), like csh */ if (pattern[0] == LBRACE && pattern[1] == RBRACE && pattern[2] == EOS) { if ((pglob->gl_flags & GLOB_LIMIT) && limit->l_brace_cnt++ >= GLOB_LIMIT_BRACE) { errno = E2BIG; return (GLOB_NOSPACE); } return (glob0(pattern, pglob, limit, origpat)); } oldpathc = pglob->gl_pathc; if ((rv = globexp1(pattern, pglob, limit)) != 0) return rv; return (globfinal(pglob, limit, oldpathc, origpat)); } /* * Expand recursively a glob {} pattern. When there is no more expansion * invoke the standard globbing routine to glob the rest of the magic * characters */ static int globexp1(const Char *pattern, glob11_t *pglob, struct glob_limit *limit) { const Char* ptr; if ((ptr = g_strchr(pattern, LBRACE)) != NULL) { if ((pglob->gl_flags & GLOB_LIMIT) && limit->l_brace_cnt++ >= GLOB_LIMIT_BRACE) { errno = E2BIG; return (GLOB_NOSPACE); } return (globexp2(ptr, pattern, pglob, limit)); } return (glob0(pattern, pglob, limit, NULL)); } /* * Recursive brace globbing helper. Tries to expand a single brace. * If it succeeds then it invokes globexp1 with the new pattern. * If it fails then it tries to glob the rest of the pattern and returns. */ static int globexp2(const Char *ptr, const Char *pattern, glob11_t *pglob, struct glob_limit *limit) { int i, rv; Char *lm, *ls; const Char *pe, *pm, *pm1, *pl; Char patbuf[MAXPATHLEN]; /* copy part up to the brace */ for (lm = patbuf, pm = pattern; pm != ptr; *lm++ = *pm++) continue; *lm = EOS; ls = lm; /* Find the balanced brace */ for (i = 0, pe = ++ptr; *pe != EOS; pe++) if (*pe == LBRACKET) { /* Ignore everything between [] */ for (pm = pe++; *pe != RBRACKET && *pe != EOS; pe++) continue; if (*pe == EOS) { /* * We could not find a matching RBRACKET. * Ignore and just look for RBRACE */ pe = pm; } } else if (*pe == LBRACE) i++; else if (*pe == RBRACE) { if (i == 0) break; i--; } /* Non matching braces; just glob the pattern */ if (i != 0 || *pe == EOS) return (glob0(pattern, pglob, limit, NULL)); for (i = 0, pl = pm = ptr; pm <= pe; pm++) switch (*pm) { case LBRACKET: /* Ignore everything between [] */ for (pm1 = pm++; *pm != RBRACKET && *pm != EOS; pm++) continue; if (*pm == EOS) { /* * We could not find a matching RBRACKET. * Ignore and just look for RBRACE */ pm = pm1; } break; case LBRACE: i++; break; case RBRACE: if (i) { i--; break; } /* FALLTHROUGH */ case COMMA: if (i && *pm == COMMA) break; else { /* Append the current string */ for (lm = ls; (pl < pm); *lm++ = *pl++) continue; /* * Append the rest of the pattern after the * closing brace */ for (pl = pe + 1; (*lm++ = *pl++) != EOS;) continue; /* Expand the current pattern */ #ifdef DEBUG qprintf("globexp2:", patbuf); #endif rv = globexp1(patbuf, pglob, limit); if (rv) return (rv); /* move after the comma, to the next string */ pl = pm + 1; } break; default: break; } return (0); } /* * expand tilde from the passwd file. */ static const Char * globtilde(const Char *pattern, Char *patbuf, size_t patbuf_len, glob11_t *pglob) { struct passwd *pwd; char *h, *sc; const Char *p; Char *b, *eb; wchar_t wc; wchar_t wbuf[MAXPATHLEN]; wchar_t *wbufend, *dc; size_t clen; mbstate_t mbs; int too_long; if (*pattern != TILDE || !(pglob->gl_flags & GLOB_TILDE)) return (pattern); /* * Copy up to the end of the string or / */ eb = &patbuf[patbuf_len - 1]; for (p = pattern + 1, b = patbuf; b < eb && *p != EOS && UNPROT(*p) != SEP; *b++ = *p++) continue; if (*p != EOS && UNPROT(*p) != SEP) return (NULL); *b = EOS; h = NULL; if (patbuf[0] == EOS) { /* * handle a plain ~ or ~/ by expanding $HOME first (iff * we're not running setuid or setgid) and then trying * the password file */ if (issetugid() != 0 || (h = getenv("HOME")) == NULL) { if (((h = getlogin()) != NULL && (pwd = getpwnam(h)) != NULL) || (pwd = getpwuid(getuid())) != NULL) h = pwd->pw_dir; else return (pattern); } } else { /* * Expand a ~user */ if (g_Ctoc(patbuf, (char *)wbuf, sizeof(wbuf))) return (NULL); if ((pwd = getpwnam((char *)wbuf)) == NULL) return (pattern); else h = pwd->pw_dir; } /* Copy the home directory */ dc = wbuf; sc = h; wbufend = wbuf + MAXPATHLEN - 1; too_long = 1; memset(&mbs, 0, sizeof(mbs)); while (dc <= wbufend) { clen = mbrtowc(&wc, sc, MB_LEN_MAX, &mbs); if (clen == (size_t)-1 || clen == (size_t)-2) { /* XXX See initial comment #2. */ wc = (unsigned char)*sc; clen = 1; memset(&mbs, 0, sizeof(mbs)); } if ((*dc++ = wc) == EOS) { too_long = 0; break; } sc += clen; } if (too_long) return (NULL); dc = wbuf; for (b = patbuf; b < eb && *dc != EOS; *b++ = *dc++ | M_PROTECT) continue; if (*dc != EOS) return (NULL); /* Append the rest of the pattern */ if (*p != EOS) { too_long = 1; while (b <= eb) { if ((*b++ = *p++) == EOS) { too_long = 0; break; } } if (too_long) return (NULL); } else *b = EOS; return (patbuf); } /* * The main glob() routine: compiles the pattern (optionally processing * quotes), calls glob1() to do the real pattern matching, and finally * sorts the list (unless unsorted operation is requested). Returns 0 * if things went well, nonzero if errors occurred. */ static int glob0(const Char *pattern, glob11_t *pglob, struct glob_limit *limit, const char *origpat) { const Char *qpatnext; int err; size_t oldpathc; Char *bufnext, c, patbuf[MAXPATHLEN]; qpatnext = globtilde(pattern, patbuf, MAXPATHLEN, pglob); if (qpatnext == NULL) { errno = E2BIG; return (GLOB_NOSPACE); } oldpathc = pglob->gl_pathc; bufnext = patbuf; /* We don't need to check for buffer overflow any more. */ while ((c = *qpatnext++) != EOS) { switch (c) { case LBRACKET: c = *qpatnext; if (c == NOT) ++qpatnext; if (*qpatnext == EOS || g_strchr(qpatnext+1, RBRACKET) == NULL) { *bufnext++ = LBRACKET; if (c == NOT) --qpatnext; break; } *bufnext++ = M_SET; if (c == NOT) *bufnext++ = M_NOT; c = *qpatnext++; do { *bufnext++ = CHAR(c); if (*qpatnext == RANGE && (c = qpatnext[1]) != RBRACKET) { *bufnext++ = M_RNG; *bufnext++ = CHAR(c); qpatnext += 2; } } while ((c = *qpatnext++) != RBRACKET); pglob->gl_flags |= GLOB_MAGCHAR; *bufnext++ = M_END; break; case QUESTION: pglob->gl_flags |= GLOB_MAGCHAR; *bufnext++ = M_ONE; break; case STAR: pglob->gl_flags |= GLOB_MAGCHAR; /* collapse adjacent stars to one, * to avoid exponential behavior */ if (bufnext == patbuf || bufnext[-1] != M_ALL) *bufnext++ = M_ALL; break; default: *bufnext++ = CHAR(c); break; } } *bufnext = EOS; #ifdef DEBUG qprintf("glob0:", patbuf); #endif if ((err = glob1(patbuf, pglob, limit)) != 0) return(err); if (origpat != NULL) return (globfinal(pglob, limit, oldpathc, origpat)); return (0); } static int globfinal(glob11_t *pglob, struct glob_limit *limit, size_t oldpathc, const char *origpat) { if (pglob->gl_pathc == oldpathc) return (err_nomatch(pglob, limit, origpat)); if (!(pglob->gl_flags & GLOB_NOSORT)) qsort(pglob->gl_pathv + pglob->gl_offs + oldpathc, pglob->gl_pathc - oldpathc, sizeof(char *), compare); return (0); } static int compare(const void *p, const void *q) { return (strcoll(*(char **)p, *(char **)q)); } static int glob1(Char *pattern, glob11_t *pglob, struct glob_limit *limit) { Char pathbuf[MAXPATHLEN]; /* A null pathname is invalid -- POSIX 1003.1 sect. 2.4. */ if (*pattern == EOS) return (0); return (glob2(pathbuf, pathbuf, pathbuf + MAXPATHLEN - 1, pattern, pglob, limit)); } /* * The functions glob2 and glob3 are mutually recursive; there is one level * of recursion for each segment in the pattern that contains one or more * meta characters. */ static int glob2(Char *pathbuf, Char *pathend, Char *pathend_last, Char *pattern, glob11_t *pglob, struct glob_limit *limit) { struct freebsd11_stat sb; Char *p, *q; int anymeta; /* * Loop over pattern segments until end of pattern or until * segment with meta character found. */ for (anymeta = 0;;) { if (*pattern == EOS) { /* End of pattern? */ *pathend = EOS; if (g_lstat(pathbuf, &sb, pglob)) return (0); if ((pglob->gl_flags & GLOB_LIMIT) && limit->l_stat_cnt++ >= GLOB_LIMIT_STAT) { errno = E2BIG; return (GLOB_NOSPACE); } if ((pglob->gl_flags & GLOB_MARK) && UNPROT(pathend[-1]) != SEP && (S_ISDIR(sb.st_mode) || (S_ISLNK(sb.st_mode) && g_stat(pathbuf, &sb, pglob) == 0 && S_ISDIR(sb.st_mode)))) { if (pathend + 1 > pathend_last) { errno = E2BIG; return (GLOB_NOSPACE); } *pathend++ = SEP; *pathend = EOS; } ++pglob->gl_matchc; return (globextend(pathbuf, pglob, limit, NULL)); } /* Find end of next segment, copy tentatively to pathend. */ q = pathend; p = pattern; while (*p != EOS && UNPROT(*p) != SEP) { if (ismeta(*p)) anymeta = 1; if (q + 1 > pathend_last) { errno = E2BIG; return (GLOB_NOSPACE); } *q++ = *p++; } if (!anymeta) { /* No expansion, do next segment. */ pathend = q; pattern = p; while (UNPROT(*pattern) == SEP) { if (pathend + 1 > pathend_last) { errno = E2BIG; return (GLOB_NOSPACE); } *pathend++ = *pattern++; } } else /* Need expansion, recurse. */ return (glob3(pathbuf, pathend, pathend_last, pattern, p, pglob, limit)); } /* NOTREACHED */ } static int glob3(Char *pathbuf, Char *pathend, Char *pathend_last, Char *pattern, Char *restpattern, glob11_t *pglob, struct glob_limit *limit) { struct freebsd11_dirent *dp; DIR *dirp; int err, too_long, saverrno, saverrno2; char buf[MAXPATHLEN + MB_LEN_MAX - 1]; struct freebsd11_dirent *(*readdirfunc)(DIR *); if (pathend > pathend_last) { errno = E2BIG; return (GLOB_NOSPACE); } *pathend = EOS; if (pglob->gl_errfunc != NULL && g_Ctoc(pathbuf, buf, sizeof(buf))) { errno = E2BIG; return (GLOB_NOSPACE); } saverrno = errno; errno = 0; if ((dirp = g_opendir(pathbuf, pglob)) == NULL) { if (errno == ENOENT || errno == ENOTDIR) return (0); err = err_aborted(pglob, errno, buf); if (errno == 0) errno = saverrno; return (err); } err = 0; /* pglob->gl_readdir takes a void *, fix this manually */ if (pglob->gl_flags & GLOB_ALTDIRFUNC) readdirfunc = (struct freebsd11_dirent *(*)(DIR *))pglob->gl_readdir; else readdirfunc = freebsd11_readdir; errno = 0; /* Search directory for matching names. */ while ((dp = (*readdirfunc)(dirp)) != NULL) { char *sc; Char *dc; wchar_t wc; size_t clen; mbstate_t mbs; if ((pglob->gl_flags & GLOB_LIMIT) && limit->l_readdir_cnt++ >= GLOB_LIMIT_READDIR) { errno = E2BIG; err = GLOB_NOSPACE; break; } /* Initial DOT must be matched literally. */ if (dp->d_name[0] == '.' && UNPROT(*pattern) != DOT) { errno = 0; continue; } memset(&mbs, 0, sizeof(mbs)); dc = pathend; sc = dp->d_name; too_long = 1; while (dc <= pathend_last) { clen = mbrtowc(&wc, sc, MB_LEN_MAX, &mbs); if (clen == (size_t)-1 || clen == (size_t)-2) { /* XXX See initial comment #2. */ wc = (unsigned char)*sc; clen = 1; memset(&mbs, 0, sizeof(mbs)); } if ((*dc++ = wc) == EOS) { too_long = 0; break; } sc += clen; } if (too_long && (err = err_aborted(pglob, ENAMETOOLONG, buf))) { errno = ENAMETOOLONG; break; } if (too_long || !match(pathend, pattern, restpattern)) { *pathend = EOS; errno = 0; continue; } if (errno == 0) errno = saverrno; err = glob2(pathbuf, --dc, pathend_last, restpattern, pglob, limit); if (err) break; errno = 0; } saverrno2 = errno; if (pglob->gl_flags & GLOB_ALTDIRFUNC) (*pglob->gl_closedir)(dirp); else closedir(dirp); errno = saverrno2; if (err) return (err); if (dp == NULL && errno != 0 && (err = err_aborted(pglob, errno, buf))) return (err); if (errno == 0) errno = saverrno; return (0); } /* * Extend the gl_pathv member of a glob11_t structure to accommodate a new item, * add the new item, and update gl_pathc. * * This assumes the BSD realloc, which only copies the block when its size * crosses a power-of-two boundary; for v7 realloc, this would cause quadratic * behavior. * * Return 0 if new item added, error code if memory couldn't be allocated. * * Invariant of the glob11_t structure: * Either gl_pathc is zero and gl_pathv is NULL; or gl_pathc > 0 and * gl_pathv points to (gl_offs + gl_pathc + 1) items. */ static int globextend(const Char *path, glob11_t *pglob, struct glob_limit *limit, const char *origpat) { char **pathv; size_t i, newn, len; char *copy; const Char *p; if ((pglob->gl_flags & GLOB_LIMIT) && pglob->gl_matchc > limit->l_path_lim) { errno = E2BIG; return (GLOB_NOSPACE); } newn = 2 + pglob->gl_pathc + pglob->gl_offs; /* reallocarray(NULL, newn, size) is equivalent to malloc(newn*size). */ pathv = reallocarray(pglob->gl_pathv, newn, sizeof(*pathv)); if (pathv == NULL) return (GLOB_NOSPACE); if (pglob->gl_pathv == NULL && pglob->gl_offs > 0) { /* first time around -- clear initial gl_offs items */ pathv += pglob->gl_offs; for (i = pglob->gl_offs + 1; --i > 0; ) *--pathv = NULL; } pglob->gl_pathv = pathv; if (origpat != NULL) copy = strdup(origpat); else { for (p = path; *p++ != EOS;) continue; len = MB_CUR_MAX * (size_t)(p - path); /* XXX overallocation */ if ((copy = malloc(len)) != NULL) { if (g_Ctoc(path, copy, len)) { free(copy); errno = E2BIG; return (GLOB_NOSPACE); } } } if (copy != NULL) { limit->l_string_cnt += strlen(copy) + 1; if ((pglob->gl_flags & GLOB_LIMIT) && limit->l_string_cnt >= GLOB_LIMIT_STRING) { free(copy); errno = E2BIG; return (GLOB_NOSPACE); } pathv[pglob->gl_offs + pglob->gl_pathc++] = copy; } pathv[pglob->gl_offs + pglob->gl_pathc] = NULL; return (copy == NULL ? GLOB_NOSPACE : 0); } /* * pattern matching function for filenames. */ static int match(Char *name, Char *pat, Char *patend) { int ok, negate_range; Char c, k, *nextp, *nextn; struct xlocale_collate *table = (struct xlocale_collate*)__get_locale()->components[XLC_COLLATE]; nextn = NULL; nextp = NULL; while (1) { while (pat < patend) { c = *pat++; switch (c & M_MASK) { case M_ALL: if (pat == patend) return (1); if (*name == EOS) return (0); nextn = name + 1; nextp = pat - 1; break; case M_ONE: if (*name++ == EOS) goto fail; break; case M_SET: ok = 0; if ((k = *name++) == EOS) goto fail; negate_range = ((*pat & M_MASK) == M_NOT); if (negate_range != 0) ++pat; while (((c = *pat++) & M_MASK) != M_END) if ((*pat & M_MASK) == M_RNG) { if (table->__collate_load_error ? CHAR(c) <= CHAR(k) && CHAR(k) <= CHAR(pat[1]) : __wcollate_range_cmp(CHAR(c), CHAR(k)) <= 0 && __wcollate_range_cmp(CHAR(k), CHAR(pat[1])) <= 0) ok = 1; pat += 2; } else if (c == k) ok = 1; if (ok == negate_range) goto fail; break; default: if (*name++ != c) goto fail; break; } } if (*name == EOS) return (1); fail: if (nextn == NULL) break; pat = nextp; name = nextn; } return (0); } /* Free allocated data belonging to a glob11_t structure. */ void freebsd11_globfree(glob11_t *pglob) { size_t i; char **pp; if (pglob->gl_pathv != NULL) { pp = pglob->gl_pathv + pglob->gl_offs; for (i = pglob->gl_pathc; i--; ++pp) if (*pp) free(*pp); free(pglob->gl_pathv); pglob->gl_pathv = NULL; } } static DIR * g_opendir(Char *str, glob11_t *pglob) { char buf[MAXPATHLEN + MB_LEN_MAX - 1]; if (*str == EOS) strcpy(buf, "."); else { if (g_Ctoc(str, buf, sizeof(buf))) { errno = ENAMETOOLONG; return (NULL); } } if (pglob->gl_flags & GLOB_ALTDIRFUNC) return ((*pglob->gl_opendir)(buf)); return (opendir(buf)); } static int g_lstat(Char *fn, struct freebsd11_stat *sb, glob11_t *pglob) { char buf[MAXPATHLEN + MB_LEN_MAX - 1]; if (g_Ctoc(fn, buf, sizeof(buf))) { errno = ENAMETOOLONG; return (-1); } if (pglob->gl_flags & GLOB_ALTDIRFUNC) return((*pglob->gl_lstat)(buf, sb)); return (freebsd11_lstat(buf, sb)); } static int g_stat(Char *fn, struct freebsd11_stat *sb, glob11_t *pglob) { char buf[MAXPATHLEN + MB_LEN_MAX - 1]; if (g_Ctoc(fn, buf, sizeof(buf))) { errno = ENAMETOOLONG; return (-1); } if (pglob->gl_flags & GLOB_ALTDIRFUNC) return ((*pglob->gl_stat)(buf, sb)); return (freebsd11_stat(buf, sb)); } static const Char * g_strchr(const Char *str, wchar_t ch) { do { if (*str == ch) return (str); } while (*str++); return (NULL); } static int g_Ctoc(const Char *str, char *buf, size_t len) { mbstate_t mbs; size_t clen; memset(&mbs, 0, sizeof(mbs)); while (len >= MB_CUR_MAX) { clen = wcrtomb(buf, CHAR(*str), &mbs); if (clen == (size_t)-1) { /* XXX See initial comment #2. */ *buf = (char)CHAR(*str); clen = 1; memset(&mbs, 0, sizeof(mbs)); } if (CHAR(*str) == EOS) return (0); str++; buf += clen; len -= clen; } return (1); } static int err_nomatch(glob11_t *pglob, struct glob_limit *limit, const char *origpat) { /* * If there was no match we are going to append the origpat * if GLOB_NOCHECK was specified or if GLOB_NOMAGIC was specified * and the origpat did not contain any magic characters * GLOB_NOMAGIC is there just for compatibility with csh. */ if ((pglob->gl_flags & GLOB_NOCHECK) || ((pglob->gl_flags & GLOB_NOMAGIC) && !(pglob->gl_flags & GLOB_MAGCHAR))) return (globextend(NULL, pglob, limit, origpat)); return (GLOB_NOMATCH); } static int err_aborted(glob11_t *pglob, int err, char *buf) { if ((pglob->gl_errfunc != NULL && pglob->gl_errfunc(buf, err)) || (pglob->gl_flags & GLOB_ERR)) return (GLOB_ABORTED); return (0); } #ifdef DEBUG static void qprintf(const char *str, Char *s) { Char *p; (void)printf("%s\n", str); if (s != NULL) { for (p = s; *p != EOS; p++) (void)printf("%c", (char)CHAR(*p)); (void)printf("\n"); for (p = s; *p != EOS; p++) (void)printf("%c", (isprot(*p) ? '\\' : ' ')); (void)printf("\n"); for (p = s; *p != EOS; p++) (void)printf("%c", (ismeta(*p) ? '_' : ' ')); (void)printf("\n"); } } #endif __sym_compat(glob, freebsd11_glob, FBSD_1.0); __sym_compat(globfree, freebsd11_globfree, FBSD_1.0); Index: head/lib/libc/gen/glob.c =================================================================== --- head/lib/libc/gen/glob.c (revision 335897) +++ head/lib/libc/gen/glob.c (revision 335898) @@ -1,1121 +1,1119 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1989, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Guido van Rossum. * * Copyright (c) 2011 The FreeBSD Foundation * All rights reserved. * Portions of this software were developed by David Chisnall * under sponsorship from the FreeBSD Foundation. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)glob.c 8.3 (Berkeley) 10/13/93"; -#endif /* LIBC_SCCS and not lint */ #include +__SCCSID("@(#)glob.c 8.3 (Berkeley) 10/13/93"); __FBSDID("$FreeBSD$"); /* * glob(3) -- a superset of the one defined in POSIX 1003.2. * * The [!...] convention to negate a range is supported (SysV, Posix, ksh). * * Optional extra services, controlled by flags not defined by POSIX: * * GLOB_QUOTE: * Escaping convention: \ inhibits any special meaning the following * character might have (except \ at end of string is retained). * GLOB_MAGCHAR: * Set in gl_flags if pattern contained a globbing character. * GLOB_NOMAGIC: * Same as GLOB_NOCHECK, but it will only append pattern if it did * not contain any magic characters. [Used in csh style globbing] * GLOB_ALTDIRFUNC: * Use alternately specified directory access functions. * GLOB_TILDE: * expand ~user/foo to the /home/dir/of/user/foo * GLOB_BRACE: * expand {1,2}{a,b} to 1a 1b 2a 2b * gl_matchc: * Number of matches in the current invocation of glob. */ /* * Some notes on multibyte character support: * 1. Patterns with illegal byte sequences match nothing - even if * GLOB_NOCHECK is specified. * 2. Illegal byte sequences in filenames are handled by treating them as * single-byte characters with a values of such bytes of the sequence * cast to wchar_t. * 3. State-dependent encodings are not currently supported. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "collate.h" /* * glob(3) expansion limits. Stop the expansion if any of these limits * is reached. This caps the runtime in the face of DoS attacks. See * also CVE-2010-2632 */ #define GLOB_LIMIT_BRACE 128 /* number of brace calls */ #define GLOB_LIMIT_PATH 65536 /* number of path elements */ #define GLOB_LIMIT_READDIR 16384 /* number of readdirs */ #define GLOB_LIMIT_STAT 1024 /* number of stat system calls */ #define GLOB_LIMIT_STRING ARG_MAX /* maximum total size for paths */ struct glob_limit { size_t l_brace_cnt; size_t l_path_lim; size_t l_readdir_cnt; size_t l_stat_cnt; size_t l_string_cnt; }; #define DOT L'.' #define EOS L'\0' #define LBRACKET L'[' #define NOT L'!' #define QUESTION L'?' #define QUOTE L'\\' #define RANGE L'-' #define RBRACKET L']' #define SEP L'/' #define STAR L'*' #define TILDE L'~' #define LBRACE L'{' #define RBRACE L'}' #define COMMA L',' #define M_QUOTE 0x8000000000ULL #define M_PROTECT 0x4000000000ULL #define M_MASK 0xffffffffffULL #define M_CHAR 0x00ffffffffULL typedef uint_fast64_t Char; #define CHAR(c) ((Char)((c)&M_CHAR)) #define META(c) ((Char)((c)|M_QUOTE)) #define UNPROT(c) ((c) & ~M_PROTECT) #define M_ALL META(L'*') #define M_END META(L']') #define M_NOT META(L'!') #define M_ONE META(L'?') #define M_RNG META(L'-') #define M_SET META(L'[') #define ismeta(c) (((c)&M_QUOTE) != 0) #ifdef DEBUG #define isprot(c) (((c)&M_PROTECT) != 0) #endif static int compare(const void *, const void *); static int g_Ctoc(const Char *, char *, size_t); static int g_lstat(Char *, struct stat *, glob_t *); static DIR *g_opendir(Char *, glob_t *); static const Char *g_strchr(const Char *, wchar_t); #ifdef notdef static Char *g_strcat(Char *, const Char *); #endif static int g_stat(Char *, struct stat *, glob_t *); static int glob0(const Char *, glob_t *, struct glob_limit *, const char *); static int glob1(Char *, glob_t *, struct glob_limit *); static int glob2(Char *, Char *, Char *, Char *, glob_t *, struct glob_limit *); static int glob3(Char *, Char *, Char *, Char *, Char *, glob_t *, struct glob_limit *); static int globextend(const Char *, glob_t *, struct glob_limit *, const char *); static const Char * globtilde(const Char *, Char *, size_t, glob_t *); static int globexp0(const Char *, glob_t *, struct glob_limit *, const char *); static int globexp1(const Char *, glob_t *, struct glob_limit *); static int globexp2(const Char *, const Char *, glob_t *, struct glob_limit *); static int globfinal(glob_t *, struct glob_limit *, size_t, const char *); static int match(Char *, Char *, Char *); static int err_nomatch(glob_t *, struct glob_limit *, const char *); static int err_aborted(glob_t *, int, char *); #ifdef DEBUG static void qprintf(const char *, Char *); #endif int glob(const char * __restrict pattern, int flags, int (*errfunc)(const char *, int), glob_t * __restrict pglob) { struct glob_limit limit = { 0, 0, 0, 0, 0 }; const char *patnext; Char *bufnext, *bufend, patbuf[MAXPATHLEN], prot; mbstate_t mbs; wchar_t wc; size_t clen; int too_long; patnext = pattern; if (!(flags & GLOB_APPEND)) { pglob->gl_pathc = 0; pglob->gl_pathv = NULL; if (!(flags & GLOB_DOOFFS)) pglob->gl_offs = 0; } if (flags & GLOB_LIMIT) { limit.l_path_lim = pglob->gl_matchc; if (limit.l_path_lim == 0) limit.l_path_lim = GLOB_LIMIT_PATH; } pglob->gl_flags = flags & ~GLOB_MAGCHAR; pglob->gl_errfunc = errfunc; pglob->gl_matchc = 0; bufnext = patbuf; bufend = bufnext + MAXPATHLEN - 1; too_long = 1; if (flags & GLOB_NOESCAPE) { memset(&mbs, 0, sizeof(mbs)); while (bufnext <= bufend) { clen = mbrtowc(&wc, patnext, MB_LEN_MAX, &mbs); if (clen == (size_t)-1 || clen == (size_t)-2) return (err_nomatch(pglob, &limit, pattern)); else if (clen == 0) { too_long = 0; break; } *bufnext++ = wc; patnext += clen; } } else { /* Protect the quoted characters. */ memset(&mbs, 0, sizeof(mbs)); while (bufnext <= bufend) { if (*patnext == '\\') { if (*++patnext == '\0') { *bufnext++ = QUOTE; continue; } prot = M_PROTECT; } else prot = 0; clen = mbrtowc(&wc, patnext, MB_LEN_MAX, &mbs); if (clen == (size_t)-1 || clen == (size_t)-2) return (err_nomatch(pglob, &limit, pattern)); else if (clen == 0) { too_long = 0; break; } *bufnext++ = wc | prot; patnext += clen; } } if (too_long) return (err_nomatch(pglob, &limit, pattern)); *bufnext = EOS; if (flags & GLOB_BRACE) return (globexp0(patbuf, pglob, &limit, pattern)); else return (glob0(patbuf, pglob, &limit, pattern)); } static int globexp0(const Char *pattern, glob_t *pglob, struct glob_limit *limit, const char *origpat) { int rv; size_t oldpathc; /* Protect a single {}, for find(1), like csh */ if (pattern[0] == LBRACE && pattern[1] == RBRACE && pattern[2] == EOS) { if ((pglob->gl_flags & GLOB_LIMIT) && limit->l_brace_cnt++ >= GLOB_LIMIT_BRACE) { errno = E2BIG; return (GLOB_NOSPACE); } return (glob0(pattern, pglob, limit, origpat)); } oldpathc = pglob->gl_pathc; if ((rv = globexp1(pattern, pglob, limit)) != 0) return rv; return (globfinal(pglob, limit, oldpathc, origpat)); } /* * Expand recursively a glob {} pattern. When there is no more expansion * invoke the standard globbing routine to glob the rest of the magic * characters */ static int globexp1(const Char *pattern, glob_t *pglob, struct glob_limit *limit) { const Char* ptr; if ((ptr = g_strchr(pattern, LBRACE)) != NULL) { if ((pglob->gl_flags & GLOB_LIMIT) && limit->l_brace_cnt++ >= GLOB_LIMIT_BRACE) { errno = E2BIG; return (GLOB_NOSPACE); } return (globexp2(ptr, pattern, pglob, limit)); } return (glob0(pattern, pglob, limit, NULL)); } /* * Recursive brace globbing helper. Tries to expand a single brace. * If it succeeds then it invokes globexp1 with the new pattern. * If it fails then it tries to glob the rest of the pattern and returns. */ static int globexp2(const Char *ptr, const Char *pattern, glob_t *pglob, struct glob_limit *limit) { int i, rv; Char *lm, *ls; const Char *pe, *pm, *pm1, *pl; Char patbuf[MAXPATHLEN]; /* copy part up to the brace */ for (lm = patbuf, pm = pattern; pm != ptr; *lm++ = *pm++) continue; *lm = EOS; ls = lm; /* Find the balanced brace */ for (i = 0, pe = ++ptr; *pe != EOS; pe++) if (*pe == LBRACKET) { /* Ignore everything between [] */ for (pm = pe++; *pe != RBRACKET && *pe != EOS; pe++) continue; if (*pe == EOS) { /* * We could not find a matching RBRACKET. * Ignore and just look for RBRACE */ pe = pm; } } else if (*pe == LBRACE) i++; else if (*pe == RBRACE) { if (i == 0) break; i--; } /* Non matching braces; just glob the pattern */ if (i != 0 || *pe == EOS) return (glob0(pattern, pglob, limit, NULL)); for (i = 0, pl = pm = ptr; pm <= pe; pm++) switch (*pm) { case LBRACKET: /* Ignore everything between [] */ for (pm1 = pm++; *pm != RBRACKET && *pm != EOS; pm++) continue; if (*pm == EOS) { /* * We could not find a matching RBRACKET. * Ignore and just look for RBRACE */ pm = pm1; } break; case LBRACE: i++; break; case RBRACE: if (i) { i--; break; } /* FALLTHROUGH */ case COMMA: if (i && *pm == COMMA) break; else { /* Append the current string */ for (lm = ls; (pl < pm); *lm++ = *pl++) continue; /* * Append the rest of the pattern after the * closing brace */ for (pl = pe + 1; (*lm++ = *pl++) != EOS;) continue; /* Expand the current pattern */ #ifdef DEBUG qprintf("globexp2:", patbuf); #endif rv = globexp1(patbuf, pglob, limit); if (rv) return (rv); /* move after the comma, to the next string */ pl = pm + 1; } break; default: break; } return (0); } /* * expand tilde from the passwd file. */ static const Char * globtilde(const Char *pattern, Char *patbuf, size_t patbuf_len, glob_t *pglob) { struct passwd *pwd; char *h, *sc; const Char *p; Char *b, *eb; wchar_t wc; wchar_t wbuf[MAXPATHLEN]; wchar_t *wbufend, *dc; size_t clen; mbstate_t mbs; int too_long; if (*pattern != TILDE || !(pglob->gl_flags & GLOB_TILDE)) return (pattern); /* * Copy up to the end of the string or / */ eb = &patbuf[patbuf_len - 1]; for (p = pattern + 1, b = patbuf; b < eb && *p != EOS && UNPROT(*p) != SEP; *b++ = *p++) continue; if (*p != EOS && UNPROT(*p) != SEP) return (NULL); *b = EOS; h = NULL; if (patbuf[0] == EOS) { /* * handle a plain ~ or ~/ by expanding $HOME first (iff * we're not running setuid or setgid) and then trying * the password file */ if (issetugid() != 0 || (h = getenv("HOME")) == NULL) { if (((h = getlogin()) != NULL && (pwd = getpwnam(h)) != NULL) || (pwd = getpwuid(getuid())) != NULL) h = pwd->pw_dir; else return (pattern); } } else { /* * Expand a ~user */ if (g_Ctoc(patbuf, (char *)wbuf, sizeof(wbuf))) return (NULL); if ((pwd = getpwnam((char *)wbuf)) == NULL) return (pattern); else h = pwd->pw_dir; } /* Copy the home directory */ dc = wbuf; sc = h; wbufend = wbuf + MAXPATHLEN - 1; too_long = 1; memset(&mbs, 0, sizeof(mbs)); while (dc <= wbufend) { clen = mbrtowc(&wc, sc, MB_LEN_MAX, &mbs); if (clen == (size_t)-1 || clen == (size_t)-2) { /* XXX See initial comment #2. */ wc = (unsigned char)*sc; clen = 1; memset(&mbs, 0, sizeof(mbs)); } if ((*dc++ = wc) == EOS) { too_long = 0; break; } sc += clen; } if (too_long) return (NULL); dc = wbuf; for (b = patbuf; b < eb && *dc != EOS; *b++ = *dc++ | M_PROTECT) continue; if (*dc != EOS) return (NULL); /* Append the rest of the pattern */ if (*p != EOS) { too_long = 1; while (b <= eb) { if ((*b++ = *p++) == EOS) { too_long = 0; break; } } if (too_long) return (NULL); } else *b = EOS; return (patbuf); } /* * The main glob() routine: compiles the pattern (optionally processing * quotes), calls glob1() to do the real pattern matching, and finally * sorts the list (unless unsorted operation is requested). Returns 0 * if things went well, nonzero if errors occurred. */ static int glob0(const Char *pattern, glob_t *pglob, struct glob_limit *limit, const char *origpat) { const Char *qpatnext; int err; size_t oldpathc; Char *bufnext, c, patbuf[MAXPATHLEN]; qpatnext = globtilde(pattern, patbuf, MAXPATHLEN, pglob); if (qpatnext == NULL) { errno = E2BIG; return (GLOB_NOSPACE); } oldpathc = pglob->gl_pathc; bufnext = patbuf; /* We don't need to check for buffer overflow any more. */ while ((c = *qpatnext++) != EOS) { switch (c) { case LBRACKET: c = *qpatnext; if (c == NOT) ++qpatnext; if (*qpatnext == EOS || g_strchr(qpatnext+1, RBRACKET) == NULL) { *bufnext++ = LBRACKET; if (c == NOT) --qpatnext; break; } *bufnext++ = M_SET; if (c == NOT) *bufnext++ = M_NOT; c = *qpatnext++; do { *bufnext++ = CHAR(c); if (*qpatnext == RANGE && (c = qpatnext[1]) != RBRACKET) { *bufnext++ = M_RNG; *bufnext++ = CHAR(c); qpatnext += 2; } } while ((c = *qpatnext++) != RBRACKET); pglob->gl_flags |= GLOB_MAGCHAR; *bufnext++ = M_END; break; case QUESTION: pglob->gl_flags |= GLOB_MAGCHAR; *bufnext++ = M_ONE; break; case STAR: pglob->gl_flags |= GLOB_MAGCHAR; /* collapse adjacent stars to one, * to ensure "**" at the end continues to match the * empty string */ if (bufnext == patbuf || bufnext[-1] != M_ALL) *bufnext++ = M_ALL; break; default: *bufnext++ = CHAR(c); break; } } *bufnext = EOS; #ifdef DEBUG qprintf("glob0:", patbuf); #endif if ((err = glob1(patbuf, pglob, limit)) != 0) return(err); if (origpat != NULL) return (globfinal(pglob, limit, oldpathc, origpat)); return (0); } static int globfinal(glob_t *pglob, struct glob_limit *limit, size_t oldpathc, const char *origpat) { if (pglob->gl_pathc == oldpathc) return (err_nomatch(pglob, limit, origpat)); if (!(pglob->gl_flags & GLOB_NOSORT)) qsort(pglob->gl_pathv + pglob->gl_offs + oldpathc, pglob->gl_pathc - oldpathc, sizeof(char *), compare); return (0); } static int compare(const void *p, const void *q) { return (strcoll(*(char **)p, *(char **)q)); } static int glob1(Char *pattern, glob_t *pglob, struct glob_limit *limit) { Char pathbuf[MAXPATHLEN]; /* A null pathname is invalid -- POSIX 1003.1 sect. 2.4. */ if (*pattern == EOS) return (0); return (glob2(pathbuf, pathbuf, pathbuf + MAXPATHLEN - 1, pattern, pglob, limit)); } /* * The functions glob2 and glob3 are mutually recursive; there is one level * of recursion for each segment in the pattern that contains one or more * meta characters. */ static int glob2(Char *pathbuf, Char *pathend, Char *pathend_last, Char *pattern, glob_t *pglob, struct glob_limit *limit) { struct stat sb; Char *p, *q; int anymeta; /* * Loop over pattern segments until end of pattern or until * segment with meta character found. */ for (anymeta = 0;;) { if (*pattern == EOS) { /* End of pattern? */ *pathend = EOS; if (g_lstat(pathbuf, &sb, pglob)) return (0); if ((pglob->gl_flags & GLOB_LIMIT) && limit->l_stat_cnt++ >= GLOB_LIMIT_STAT) { errno = E2BIG; return (GLOB_NOSPACE); } if ((pglob->gl_flags & GLOB_MARK) && UNPROT(pathend[-1]) != SEP && (S_ISDIR(sb.st_mode) || (S_ISLNK(sb.st_mode) && g_stat(pathbuf, &sb, pglob) == 0 && S_ISDIR(sb.st_mode)))) { if (pathend + 1 > pathend_last) { errno = E2BIG; return (GLOB_NOSPACE); } *pathend++ = SEP; *pathend = EOS; } ++pglob->gl_matchc; return (globextend(pathbuf, pglob, limit, NULL)); } /* Find end of next segment, copy tentatively to pathend. */ q = pathend; p = pattern; while (*p != EOS && UNPROT(*p) != SEP) { if (ismeta(*p)) anymeta = 1; if (q + 1 > pathend_last) { errno = E2BIG; return (GLOB_NOSPACE); } *q++ = *p++; } if (!anymeta) { /* No expansion, do next segment. */ pathend = q; pattern = p; while (UNPROT(*pattern) == SEP) { if (pathend + 1 > pathend_last) { errno = E2BIG; return (GLOB_NOSPACE); } *pathend++ = *pattern++; } } else /* Need expansion, recurse. */ return (glob3(pathbuf, pathend, pathend_last, pattern, p, pglob, limit)); } /* NOTREACHED */ } static int glob3(Char *pathbuf, Char *pathend, Char *pathend_last, Char *pattern, Char *restpattern, glob_t *pglob, struct glob_limit *limit) { struct dirent *dp; DIR *dirp; int err, too_long, saverrno, saverrno2; char buf[MAXPATHLEN + MB_LEN_MAX - 1]; struct dirent *(*readdirfunc)(DIR *); if (pathend > pathend_last) { errno = E2BIG; return (GLOB_NOSPACE); } *pathend = EOS; if (pglob->gl_errfunc != NULL && g_Ctoc(pathbuf, buf, sizeof(buf))) { errno = E2BIG; return (GLOB_NOSPACE); } saverrno = errno; errno = 0; if ((dirp = g_opendir(pathbuf, pglob)) == NULL) { if (errno == ENOENT || errno == ENOTDIR) return (0); err = err_aborted(pglob, errno, buf); if (errno == 0) errno = saverrno; return (err); } err = 0; /* pglob->gl_readdir takes a void *, fix this manually */ if (pglob->gl_flags & GLOB_ALTDIRFUNC) readdirfunc = (struct dirent *(*)(DIR *))pglob->gl_readdir; else readdirfunc = readdir; errno = 0; /* Search directory for matching names. */ while ((dp = (*readdirfunc)(dirp)) != NULL) { char *sc; Char *dc; wchar_t wc; size_t clen; mbstate_t mbs; if ((pglob->gl_flags & GLOB_LIMIT) && limit->l_readdir_cnt++ >= GLOB_LIMIT_READDIR) { errno = E2BIG; err = GLOB_NOSPACE; break; } /* Initial DOT must be matched literally. */ if (dp->d_name[0] == '.' && UNPROT(*pattern) != DOT) { errno = 0; continue; } memset(&mbs, 0, sizeof(mbs)); dc = pathend; sc = dp->d_name; too_long = 1; while (dc <= pathend_last) { clen = mbrtowc(&wc, sc, MB_LEN_MAX, &mbs); if (clen == (size_t)-1 || clen == (size_t)-2) { /* XXX See initial comment #2. */ wc = (unsigned char)*sc; clen = 1; memset(&mbs, 0, sizeof(mbs)); } if ((*dc++ = wc) == EOS) { too_long = 0; break; } sc += clen; } if (too_long && (err = err_aborted(pglob, ENAMETOOLONG, buf))) { errno = ENAMETOOLONG; break; } if (too_long || !match(pathend, pattern, restpattern)) { *pathend = EOS; errno = 0; continue; } if (errno == 0) errno = saverrno; err = glob2(pathbuf, --dc, pathend_last, restpattern, pglob, limit); if (err) break; errno = 0; } saverrno2 = errno; if (pglob->gl_flags & GLOB_ALTDIRFUNC) (*pglob->gl_closedir)(dirp); else closedir(dirp); errno = saverrno2; if (err) return (err); if (dp == NULL && errno != 0 && (err = err_aborted(pglob, errno, buf))) return (err); if (errno == 0) errno = saverrno; return (0); } /* * Extend the gl_pathv member of a glob_t structure to accommodate a new item, * add the new item, and update gl_pathc. * * This assumes the BSD realloc, which only copies the block when its size * crosses a power-of-two boundary; for v7 realloc, this would cause quadratic * behavior. * * Return 0 if new item added, error code if memory couldn't be allocated. * * Invariant of the glob_t structure: * Either gl_pathc is zero and gl_pathv is NULL; or gl_pathc > 0 and * gl_pathv points to (gl_offs + gl_pathc + 1) items. */ static int globextend(const Char *path, glob_t *pglob, struct glob_limit *limit, const char *origpat) { char **pathv; size_t i, newn, len; char *copy; const Char *p; if ((pglob->gl_flags & GLOB_LIMIT) && pglob->gl_matchc > limit->l_path_lim) { errno = E2BIG; return (GLOB_NOSPACE); } newn = 2 + pglob->gl_pathc + pglob->gl_offs; /* reallocarray(NULL, newn, size) is equivalent to malloc(newn*size). */ pathv = reallocarray(pglob->gl_pathv, newn, sizeof(*pathv)); if (pathv == NULL) return (GLOB_NOSPACE); if (pglob->gl_pathv == NULL && pglob->gl_offs > 0) { /* first time around -- clear initial gl_offs items */ pathv += pglob->gl_offs; for (i = pglob->gl_offs + 1; --i > 0; ) *--pathv = NULL; } pglob->gl_pathv = pathv; if (origpat != NULL) copy = strdup(origpat); else { for (p = path; *p++ != EOS;) continue; len = MB_CUR_MAX * (size_t)(p - path); /* XXX overallocation */ if ((copy = malloc(len)) != NULL) { if (g_Ctoc(path, copy, len)) { free(copy); errno = E2BIG; return (GLOB_NOSPACE); } } } if (copy != NULL) { limit->l_string_cnt += strlen(copy) + 1; if ((pglob->gl_flags & GLOB_LIMIT) && limit->l_string_cnt >= GLOB_LIMIT_STRING) { free(copy); errno = E2BIG; return (GLOB_NOSPACE); } pathv[pglob->gl_offs + pglob->gl_pathc++] = copy; } pathv[pglob->gl_offs + pglob->gl_pathc] = NULL; return (copy == NULL ? GLOB_NOSPACE : 0); } /* * pattern matching function for filenames. */ static int match(Char *name, Char *pat, Char *patend) { int ok, negate_range; Char c, k, *nextp, *nextn; struct xlocale_collate *table = (struct xlocale_collate*)__get_locale()->components[XLC_COLLATE]; nextn = NULL; nextp = NULL; while (1) { while (pat < patend) { c = *pat++; switch (c & M_MASK) { case M_ALL: if (pat == patend) return (1); if (*name == EOS) return (0); nextn = name + 1; nextp = pat - 1; break; case M_ONE: if (*name++ == EOS) goto fail; break; case M_SET: ok = 0; if ((k = *name++) == EOS) goto fail; negate_range = ((*pat & M_MASK) == M_NOT); if (negate_range != 0) ++pat; while (((c = *pat++) & M_MASK) != M_END) if ((*pat & M_MASK) == M_RNG) { if (table->__collate_load_error ? CHAR(c) <= CHAR(k) && CHAR(k) <= CHAR(pat[1]) : __wcollate_range_cmp(CHAR(c), CHAR(k)) <= 0 && __wcollate_range_cmp(CHAR(k), CHAR(pat[1])) <= 0) ok = 1; pat += 2; } else if (c == k) ok = 1; if (ok == negate_range) goto fail; break; default: if (*name++ != c) goto fail; break; } } if (*name == EOS) return (1); fail: if (nextn == NULL) break; pat = nextp; name = nextn; } return (0); } /* Free allocated data belonging to a glob_t structure. */ void globfree(glob_t *pglob) { size_t i; char **pp; if (pglob->gl_pathv != NULL) { pp = pglob->gl_pathv + pglob->gl_offs; for (i = pglob->gl_pathc; i--; ++pp) if (*pp) free(*pp); free(pglob->gl_pathv); pglob->gl_pathv = NULL; } } static DIR * g_opendir(Char *str, glob_t *pglob) { char buf[MAXPATHLEN + MB_LEN_MAX - 1]; if (*str == EOS) strcpy(buf, "."); else { if (g_Ctoc(str, buf, sizeof(buf))) { errno = ENAMETOOLONG; return (NULL); } } if (pglob->gl_flags & GLOB_ALTDIRFUNC) return ((*pglob->gl_opendir)(buf)); return (opendir(buf)); } static int g_lstat(Char *fn, struct stat *sb, glob_t *pglob) { char buf[MAXPATHLEN + MB_LEN_MAX - 1]; if (g_Ctoc(fn, buf, sizeof(buf))) { errno = ENAMETOOLONG; return (-1); } if (pglob->gl_flags & GLOB_ALTDIRFUNC) return((*pglob->gl_lstat)(buf, sb)); return (lstat(buf, sb)); } static int g_stat(Char *fn, struct stat *sb, glob_t *pglob) { char buf[MAXPATHLEN + MB_LEN_MAX - 1]; if (g_Ctoc(fn, buf, sizeof(buf))) { errno = ENAMETOOLONG; return (-1); } if (pglob->gl_flags & GLOB_ALTDIRFUNC) return ((*pglob->gl_stat)(buf, sb)); return (stat(buf, sb)); } static const Char * g_strchr(const Char *str, wchar_t ch) { do { if (*str == ch) return (str); } while (*str++); return (NULL); } static int g_Ctoc(const Char *str, char *buf, size_t len) { mbstate_t mbs; size_t clen; memset(&mbs, 0, sizeof(mbs)); while (len >= MB_CUR_MAX) { clen = wcrtomb(buf, CHAR(*str), &mbs); if (clen == (size_t)-1) { /* XXX See initial comment #2. */ *buf = (char)CHAR(*str); clen = 1; memset(&mbs, 0, sizeof(mbs)); } if (CHAR(*str) == EOS) return (0); str++; buf += clen; len -= clen; } return (1); } static int err_nomatch(glob_t *pglob, struct glob_limit *limit, const char *origpat) { /* * If there was no match we are going to append the origpat * if GLOB_NOCHECK was specified or if GLOB_NOMAGIC was specified * and the origpat did not contain any magic characters * GLOB_NOMAGIC is there just for compatibility with csh. */ if ((pglob->gl_flags & GLOB_NOCHECK) || ((pglob->gl_flags & GLOB_NOMAGIC) && !(pglob->gl_flags & GLOB_MAGCHAR))) return (globextend(NULL, pglob, limit, origpat)); return (GLOB_NOMATCH); } static int err_aborted(glob_t *pglob, int err, char *buf) { if ((pglob->gl_errfunc != NULL && pglob->gl_errfunc(buf, err)) || (pglob->gl_flags & GLOB_ERR)) return (GLOB_ABORTED); return (0); } #ifdef DEBUG static void qprintf(const char *str, Char *s) { Char *p; (void)printf("%s\n", str); if (s != NULL) { for (p = s; *p != EOS; p++) (void)printf("%c", (char)CHAR(*p)); (void)printf("\n"); for (p = s; *p != EOS; p++) (void)printf("%c", (isprot(*p) ? '\\' : ' ')); (void)printf("\n"); for (p = s; *p != EOS; p++) (void)printf("%c", (ismeta(*p) ? '_' : ' ')); (void)printf("\n"); } } #endif Index: head/lib/libc/gen/initgroups.c =================================================================== --- head/lib/libc/gen/initgroups.c (revision 335897) +++ head/lib/libc/gen/initgroups.c (revision 335898) @@ -1,68 +1,66 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1983, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)initgroups.c 8.1 (Berkeley) 6/4/93"; -#endif #include +__SCCSID("@(#)initgroups.c 8.1 (Berkeley) 6/4/93"); __FBSDID("$FreeBSD$"); #include #include "namespace.h" #include #include "un-namespace.h" #include #include #include #include int initgroups(const char *uname, gid_t agroup) { int ngroups, ret; long ngroups_max; gid_t *groups; /* * Provide space for one group more than possible to allow * setgroups to fail and set errno. */ ngroups_max = sysconf(_SC_NGROUPS_MAX) + 2; if ((groups = malloc(sizeof(*groups) * ngroups_max)) == NULL) return (ENOMEM); ngroups = (int)ngroups_max; getgrouplist(uname, agroup, groups, &ngroups); ret = setgroups(ngroups, groups); free(groups); return (ret); } Index: head/lib/libc/gen/isatty.c =================================================================== --- head/lib/libc/gen/isatty.c (revision 335897) +++ head/lib/libc/gen/isatty.c (revision 335898) @@ -1,49 +1,47 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1988, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)isatty.c 8.1 (Berkeley) 6/4/93"; -#endif /* LIBC_SCCS and not lint */ #include +__SCCSID("@(#)isatty.c 8.1 (Berkeley) 6/4/93"); __FBSDID("$FreeBSD$"); #include #include int isatty(int fd) { int retval; struct termios t; retval = (tcgetattr(fd, &t) != -1); return(retval); } Index: head/lib/libc/gen/nftw-compat11.c =================================================================== --- head/lib/libc/gen/nftw-compat11.c (revision 335897) +++ head/lib/libc/gen/nftw-compat11.c (revision 335898) @@ -1,115 +1,115 @@ /* * Copyright (c) 2003, 2004 Todd C. Miller * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * Sponsored in part by the Defense Advanced Research Projects * Agency (DARPA) and Air Force Research Laboratory, Air Force * Materiel Command, USAF, under agreement number F39502-99-1-0512. * - * from: $OpenBSD: nftw.c,v 1.7 2006/03/31 19:41:44 millert Exp $ - * from: $FreeBSD$ + * From: $OpenBSD: nftw.c,v 1.7 2006/03/31 19:41:44 millert Exp $ + * From: FreeBSD: head/lib/libc/gen/nftw.c 239160 2012-08-09 22:05:40Z jilles */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include "fts-compat11.h" int freebsd11_nftw(const char *path, int (*fn)(const char *, const struct freebsd11_stat *, int, struct FTW *), int nfds, int ftwflags) { char * const paths[2] = { (char *)path, NULL }; struct FTW ftw; FTSENT11 *cur; FTS11 *ftsp; int error = 0, ftsflags, fnflag, postorder, sverrno; /* XXX - nfds is currently unused */ if (nfds < 1) { errno = EINVAL; return (-1); } ftsflags = FTS_COMFOLLOW; if (!(ftwflags & FTW_CHDIR)) ftsflags |= FTS_NOCHDIR; if (ftwflags & FTW_MOUNT) ftsflags |= FTS_XDEV; if (ftwflags & FTW_PHYS) ftsflags |= FTS_PHYSICAL; else ftsflags |= FTS_LOGICAL; postorder = (ftwflags & FTW_DEPTH) != 0; ftsp = freebsd11_fts_open(paths, ftsflags, NULL); if (ftsp == NULL) return (-1); while ((cur = freebsd11_fts_read(ftsp)) != NULL) { switch (cur->fts_info) { case FTS_D: if (postorder) continue; fnflag = FTW_D; break; case FTS_DC: continue; case FTS_DNR: fnflag = FTW_DNR; break; case FTS_DP: if (!postorder) continue; fnflag = FTW_DP; break; case FTS_F: case FTS_DEFAULT: fnflag = FTW_F; break; case FTS_NS: case FTS_NSOK: fnflag = FTW_NS; break; case FTS_SL: fnflag = FTW_SL; break; case FTS_SLNONE: fnflag = FTW_SLN; break; default: error = -1; goto done; } ftw.base = cur->fts_pathlen - cur->fts_namelen; ftw.level = cur->fts_level; error = fn(cur->fts_path, cur->fts_statp, fnflag, &ftw); if (error != 0) break; } done: sverrno = errno; if (freebsd11_fts_close(ftsp) != 0 && error == 0) error = -1; else errno = sverrno; return (error); } __sym_compat(nftw, freebsd11_nftw, FBSD_1.0); Index: head/lib/libc/gen/nice.c =================================================================== --- head/lib/libc/gen/nice.c (revision 335897) +++ head/lib/libc/gen/nice.c (revision 335898) @@ -1,64 +1,62 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1983, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)nice.c 8.1 (Berkeley) 6/4/93"; -#endif /* LIBC_SCCS and not lint */ #include +__SCCSID("@(#)nice.c 8.1 (Berkeley) 6/4/93"); __FBSDID("$FreeBSD$"); #include #include #include #include #include /* * Backwards compatible nice. */ int nice(int incr) { int saverrno, prio; saverrno = errno; errno = 0; prio = getpriority(PRIO_PROCESS, 0); if (prio == -1 && errno != 0) return (-1); if (setpriority(PRIO_PROCESS, 0, prio + incr) == -1) { if (errno == EACCES) errno = EPERM; return (-1); } errno = saverrno; return (0); } Index: head/lib/libc/gen/nlist.c =================================================================== --- head/lib/libc/gen/nlist.c (revision 335897) +++ head/lib/libc/gen/nlist.c (revision 335898) @@ -1,406 +1,404 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1989, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)nlist.c 8.1 (Berkeley) 6/4/93"; -#endif /* LIBC_SCCS and not lint */ #include +__SCCSID("@(#)nlist.c 8.1 (Berkeley) 6/4/93"); __FBSDID("$FreeBSD$"); #include "namespace.h" #include #include #include #include #include #include #include #include #include #include #include "un-namespace.h" /* i386 is the only current FreeBSD architecture that used a.out format. */ #ifdef __i386__ #define _NLIST_DO_AOUT #endif #define _NLIST_DO_ELF #ifdef _NLIST_DO_ELF #include #include #endif int __fdnlist(int, struct nlist *); int __aout_fdnlist(int, struct nlist *); int __elf_fdnlist(int, struct nlist *); int __elf_is_okay__(Elf_Ehdr *); int nlist(const char *name, struct nlist *list) { int fd, n; fd = _open(name, O_RDONLY | O_CLOEXEC, 0); if (fd < 0) return (-1); n = __fdnlist(fd, list); (void)_close(fd); return (n); } static struct nlist_handlers { int (*fn)(int fd, struct nlist *list); } nlist_fn[] = { #ifdef _NLIST_DO_AOUT { __aout_fdnlist }, #endif #ifdef _NLIST_DO_ELF { __elf_fdnlist }, #endif }; int __fdnlist(int fd, struct nlist *list) { int n = -1; unsigned int i; for (i = 0; i < nitems(nlist_fn); i++) { n = (nlist_fn[i].fn)(fd, list); if (n != -1) break; } return (n); } #define ISLAST(p) (p->n_un.n_name == 0 || p->n_un.n_name[0] == 0) #ifdef _NLIST_DO_AOUT int __aout_fdnlist(int fd, struct nlist *list) { struct nlist *p, *symtab; caddr_t strtab, a_out_mmap; off_t stroff, symoff; u_long symsize; int nent; struct exec * exec; struct stat st; /* check that file is at least as large as struct exec! */ if ((_fstat(fd, &st) < 0) || (st.st_size < sizeof(struct exec))) return (-1); /* Check for files too large to mmap. */ if (st.st_size > SIZE_T_MAX) { errno = EFBIG; return (-1); } /* * Map the whole a.out file into our address space. * We then find the string table withing this area. * We do not just mmap the string table, as it probably * does not start at a page boundary - we save ourselves a * lot of nastiness by mmapping the whole file. * * This gives us an easy way to randomly access all the strings, * without making the memory allocation permanent as with * malloc/free (i.e., munmap will return it to the system). */ a_out_mmap = mmap(NULL, (size_t)st.st_size, PROT_READ, MAP_PRIVATE, fd, (off_t)0); if (a_out_mmap == MAP_FAILED) return (-1); exec = (struct exec *)a_out_mmap; if (N_BADMAG(*exec)) { munmap(a_out_mmap, (size_t)st.st_size); return (-1); } symoff = N_SYMOFF(*exec); symsize = exec->a_syms; stroff = symoff + symsize; /* find the string table in our mmapped area */ strtab = a_out_mmap + stroff; symtab = (struct nlist *)(a_out_mmap + symoff); /* * clean out any left-over information for all valid entries. * Type and value defined to be 0 if not found; historical * versions cleared other and desc as well. Also figure out * the largest string length so don't read any more of the * string table than we have to. * * XXX clearing anything other than n_type and n_value violates * the semantics given in the man page. */ nent = 0; for (p = list; !ISLAST(p); ++p) { p->n_type = 0; p->n_other = 0; p->n_desc = 0; p->n_value = 0; ++nent; } while (symsize > 0) { int soff; symsize-= sizeof(struct nlist); soff = symtab->n_un.n_strx; if (soff != 0 && (symtab->n_type & N_STAB) == 0) for (p = list; !ISLAST(p); p++) if (!strcmp(&strtab[soff], p->n_un.n_name)) { p->n_value = symtab->n_value; p->n_type = symtab->n_type; p->n_desc = symtab->n_desc; p->n_other = symtab->n_other; if (--nent <= 0) break; } symtab++; } munmap(a_out_mmap, (size_t)st.st_size); return (nent); } #endif #ifdef _NLIST_DO_ELF static void elf_sym_to_nlist(struct nlist *, Elf_Sym *, Elf_Shdr *, int); /* * __elf_is_okay__ - Determine if ehdr really * is ELF and valid for the target platform. * * WARNING: This is NOT an ELF ABI function and * as such its use should be restricted. */ int __elf_is_okay__(Elf_Ehdr *ehdr) { int retval = 0; /* * We need to check magic, class size, endianess, * and version before we look at the rest of the * Elf_Ehdr structure. These few elements are * represented in a machine independant fashion. */ if (IS_ELF(*ehdr) && ehdr->e_ident[EI_CLASS] == ELF_TARG_CLASS && ehdr->e_ident[EI_DATA] == ELF_TARG_DATA && ehdr->e_ident[EI_VERSION] == ELF_TARG_VER) { /* Now check the machine dependant header */ if (ehdr->e_machine == ELF_TARG_MACH && ehdr->e_version == ELF_TARG_VER) retval = 1; } return retval; } int __elf_fdnlist(int fd, struct nlist *list) { struct nlist *p; Elf_Off symoff = 0, symstroff = 0; Elf_Size symsize = 0, symstrsize = 0; Elf_Ssize cc, i; int nent = -1; int errsave; Elf_Sym sbuf[1024]; Elf_Sym *s; Elf_Ehdr ehdr; char *strtab = NULL; Elf_Shdr *shdr = NULL; Elf_Size shdr_size; void *base; struct stat st; /* Make sure obj is OK */ if (lseek(fd, (off_t)0, SEEK_SET) == -1 || _read(fd, &ehdr, sizeof(Elf_Ehdr)) != sizeof(Elf_Ehdr) || !__elf_is_okay__(&ehdr) || _fstat(fd, &st) < 0) return (-1); /* calculate section header table size */ shdr_size = ehdr.e_shentsize * ehdr.e_shnum; /* Make sure it's not too big to mmap */ if (shdr_size > SIZE_T_MAX) { errno = EFBIG; return (-1); } /* mmap section header table */ base = mmap(NULL, (size_t)shdr_size, PROT_READ, MAP_PRIVATE, fd, (off_t)ehdr.e_shoff); if (base == MAP_FAILED) return (-1); shdr = (Elf_Shdr *)base; /* * Find the symbol table entry and it's corresponding * string table entry. Version 1.1 of the ABI states * that there is only one symbol table but that this * could change in the future. */ for (i = 0; i < ehdr.e_shnum; i++) { if (shdr[i].sh_type == SHT_SYMTAB) { symoff = shdr[i].sh_offset; symsize = shdr[i].sh_size; symstroff = shdr[shdr[i].sh_link].sh_offset; symstrsize = shdr[shdr[i].sh_link].sh_size; break; } } /* Check for files too large to mmap. */ if (symstrsize > SIZE_T_MAX) { errno = EFBIG; goto done; } /* * Map string table into our address space. This gives us * an easy way to randomly access all the strings, without * making the memory allocation permanent as with malloc/free * (i.e., munmap will return it to the system). */ base = mmap(NULL, (size_t)symstrsize, PROT_READ, MAP_PRIVATE, fd, (off_t)symstroff); if (base == MAP_FAILED) goto done; strtab = (char *)base; /* * clean out any left-over information for all valid entries. * Type and value defined to be 0 if not found; historical * versions cleared other and desc as well. Also figure out * the largest string length so don't read any more of the * string table than we have to. * * XXX clearing anything other than n_type and n_value violates * the semantics given in the man page. */ nent = 0; for (p = list; !ISLAST(p); ++p) { p->n_type = 0; p->n_other = 0; p->n_desc = 0; p->n_value = 0; ++nent; } /* Don't process any further if object is stripped. */ if (symoff == 0) goto done; if (lseek(fd, (off_t) symoff, SEEK_SET) == -1) { nent = -1; goto done; } while (symsize > 0 && nent > 0) { cc = MIN(symsize, sizeof(sbuf)); if (_read(fd, sbuf, cc) != cc) break; symsize -= cc; for (s = sbuf; cc > 0 && nent > 0; ++s, cc -= sizeof(*s)) { char *name; struct nlist *p; name = strtab + s->st_name; if (name[0] == '\0') continue; for (p = list; !ISLAST(p); p++) { if ((p->n_un.n_name[0] == '_' && strcmp(name, p->n_un.n_name+1) == 0) || strcmp(name, p->n_un.n_name) == 0) { elf_sym_to_nlist(p, s, shdr, ehdr.e_shnum); if (--nent <= 0) break; } } } } done: errsave = errno; if (strtab != NULL) munmap(strtab, symstrsize); if (shdr != NULL) munmap(shdr, shdr_size); errno = errsave; return (nent); } /* * Convert an Elf_Sym into an nlist structure. This fills in only the * n_value and n_type members. */ static void elf_sym_to_nlist(struct nlist *nl, Elf_Sym *s, Elf_Shdr *shdr, int shnum) { nl->n_value = s->st_value; switch (s->st_shndx) { case SHN_UNDEF: case SHN_COMMON: nl->n_type = N_UNDF; break; case SHN_ABS: nl->n_type = ELF_ST_TYPE(s->st_info) == STT_FILE ? N_FN : N_ABS; break; default: if (s->st_shndx >= shnum) nl->n_type = N_UNDF; else { Elf_Shdr *sh = shdr + s->st_shndx; nl->n_type = sh->sh_type == SHT_PROGBITS ? (sh->sh_flags & SHF_WRITE ? N_DATA : N_TEXT) : (sh->sh_type == SHT_NOBITS ? N_BSS : N_UNDF); } break; } if (ELF_ST_BIND(s->st_info) == STB_GLOBAL || ELF_ST_BIND(s->st_info) == STB_WEAK) nl->n_type |= N_EXT; } #endif /* _NLIST_DO_ELF */ Index: head/lib/libc/gen/opendir.c =================================================================== --- head/lib/libc/gen/opendir.c (revision 335897) +++ head/lib/libc/gen/opendir.c (revision 335898) @@ -1,363 +1,361 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1983, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)opendir.c 8.8 (Berkeley) 5/1/95"; -#endif /* LIBC_SCCS and not lint */ #include +__SCCSID("@(#)opendir.c 8.8 (Berkeley) 5/1/95"); __FBSDID("$FreeBSD$"); #include "namespace.h" #include #include #include #include #include #include #include #include #include #include "un-namespace.h" #include "gen-private.h" #include "telldir.h" static DIR * __opendir_common(int, int, bool); /* * Open a directory. */ DIR * opendir(const char *name) { return (__opendir2(name, DTF_HIDEW|DTF_NODUP)); } /* * Open a directory with existing file descriptor. */ DIR * fdopendir(int fd) { if (_fcntl(fd, F_SETFD, FD_CLOEXEC) == -1) return (NULL); return (__opendir_common(fd, DTF_HIDEW|DTF_NODUP, true)); } DIR * __opendir2(const char *name, int flags) { int fd; DIR *dir; int saved_errno; if ((flags & (__DTF_READALL | __DTF_SKIPREAD)) != 0) return (NULL); if ((fd = _open(name, O_RDONLY | O_NONBLOCK | O_DIRECTORY | O_CLOEXEC)) == -1) return (NULL); dir = __opendir_common(fd, flags, false); if (dir == NULL) { saved_errno = errno; _close(fd); errno = saved_errno; } return (dir); } static int opendir_compar(const void *p1, const void *p2) { return (strcmp((*(const struct dirent **)p1)->d_name, (*(const struct dirent **)p2)->d_name)); } /* * For a directory at the top of a unionfs stack, the entire directory's * contents are read and cached locally until the next call to rewinddir(). * For the fdopendir() case, the initial seek position must be preserved. * For rewinddir(), the full directory should always be re-read from the * beginning. * * If an error occurs, the existing buffer and state of 'dirp' is left * unchanged. */ bool _filldir(DIR *dirp, bool use_current_pos) { struct dirent **dpv; char *buf, *ddptr, *ddeptr; off_t pos; int fd2, incr, len, n, saved_errno, space; len = 0; space = 0; buf = NULL; ddptr = NULL; /* * Use the system page size if that is a multiple of DIRBLKSIZ. * Hopefully this can be a big win someday by allowing page * trades to user space to be done by _getdirentries(). */ incr = getpagesize(); if ((incr % DIRBLKSIZ) != 0) incr = DIRBLKSIZ; /* * The strategy here is to read all the directory * entries into a buffer, sort the buffer, and * remove duplicate entries by setting the inode * number to zero. * * We reopen the directory because _getdirentries() * on a MNT_UNION mount modifies the open directory, * making it refer to the lower directory after the * upper directory's entries are exhausted. * This would otherwise break software that uses * the directory descriptor for fchdir or *at * functions, such as fts.c. */ if ((fd2 = _openat(dirp->dd_fd, ".", O_RDONLY | O_CLOEXEC)) == -1) return (false); if (use_current_pos) { pos = lseek(dirp->dd_fd, 0, SEEK_CUR); if (pos == -1 || lseek(fd2, pos, SEEK_SET) == -1) { saved_errno = errno; _close(fd2); errno = saved_errno; return (false); } } do { /* * Always make at least DIRBLKSIZ bytes * available to _getdirentries */ if (space < DIRBLKSIZ) { space += incr; len += incr; buf = reallocf(buf, len); if (buf == NULL) { saved_errno = errno; _close(fd2); errno = saved_errno; return (false); } ddptr = buf + (len - space); } n = _getdirentries(fd2, ddptr, space, &dirp->dd_seek); if (n > 0) { ddptr += n; space -= n; } if (n < 0) { saved_errno = errno; _close(fd2); errno = saved_errno; return (false); } } while (n > 0); _close(fd2); ddeptr = ddptr; /* * There is now a buffer full of (possibly) duplicate * names. */ dirp->dd_buf = buf; /* * Go round this loop twice... * * Scan through the buffer, counting entries. * On the second pass, save pointers to each one. * Then sort the pointers and remove duplicate names. */ for (dpv = NULL;;) { n = 0; ddptr = buf; while (ddptr < ddeptr) { struct dirent *dp; dp = (struct dirent *) ddptr; if ((long)dp & 03L) break; if ((dp->d_reclen <= 0) || (dp->d_reclen > (ddeptr + 1 - ddptr))) break; ddptr += dp->d_reclen; if (dp->d_fileno) { if (dpv) dpv[n] = dp; n++; } } if (dpv) { struct dirent *xp; /* * This sort must be stable. */ mergesort(dpv, n, sizeof(*dpv), opendir_compar); dpv[n] = NULL; xp = NULL; /* * Scan through the buffer in sort order, * zapping the inode number of any * duplicate names. */ for (n = 0; dpv[n]; n++) { struct dirent *dp = dpv[n]; if ((xp == NULL) || strcmp(dp->d_name, xp->d_name)) { xp = dp; } else { dp->d_fileno = 0; } if (dp->d_type == DT_WHT && (dirp->dd_flags & DTF_HIDEW)) dp->d_fileno = 0; } free(dpv); break; } else { dpv = malloc((n+1) * sizeof(struct dirent *)); if (dpv == NULL) break; } } dirp->dd_len = len; dirp->dd_size = ddptr - dirp->dd_buf; return (true); } /* * Common routine for opendir(3), __opendir2(3) and fdopendir(3). */ static DIR * __opendir_common(int fd, int flags, bool use_current_pos) { DIR *dirp; int incr; int saved_errno; int unionstack; if ((dirp = malloc(sizeof(DIR) + sizeof(struct _telldir))) == NULL) return (NULL); dirp->dd_buf = NULL; dirp->dd_fd = fd; dirp->dd_flags = flags; dirp->dd_loc = 0; dirp->dd_lock = NULL; dirp->dd_td = (struct _telldir *)((char *)dirp + sizeof(DIR)); LIST_INIT(&dirp->dd_td->td_locq); dirp->dd_td->td_loccnt = 0; dirp->dd_compat_de = NULL; /* * Use the system page size if that is a multiple of DIRBLKSIZ. * Hopefully this can be a big win someday by allowing page * trades to user space to be done by _getdirentries(). */ incr = getpagesize(); if ((incr % DIRBLKSIZ) != 0) incr = DIRBLKSIZ; /* * Determine whether this directory is the top of a union stack. */ if (flags & DTF_NODUP) { struct statfs sfb; if (_fstatfs(fd, &sfb) < 0) goto fail; unionstack = !strcmp(sfb.f_fstypename, "unionfs") || (sfb.f_flags & MNT_UNION); } else { unionstack = 0; } if (unionstack) { if (!_filldir(dirp, use_current_pos)) goto fail; dirp->dd_flags |= __DTF_READALL; } else { dirp->dd_len = incr; dirp->dd_buf = malloc(dirp->dd_len); if (dirp->dd_buf == NULL) goto fail; if (use_current_pos) { /* * Read the first batch of directory entries * to prime dd_seek. This also checks if the * fd passed to fdopendir() is a directory. */ dirp->dd_size = _getdirentries(dirp->dd_fd, dirp->dd_buf, dirp->dd_len, &dirp->dd_seek); if (dirp->dd_size < 0) { if (errno == EINVAL) errno = ENOTDIR; goto fail; } dirp->dd_flags |= __DTF_SKIPREAD; } else { dirp->dd_size = 0; dirp->dd_seek = 0; } } return (dirp); fail: saved_errno = errno; free(dirp->dd_buf); free(dirp); errno = saved_errno; return (NULL); } Index: head/lib/libc/gen/pause.c =================================================================== --- head/lib/libc/gen/pause.c (revision 335897) +++ head/lib/libc/gen/pause.c (revision 335898) @@ -1,59 +1,57 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1983, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)pause.c 8.1 (Berkeley) 6/4/93"; -#endif /* LIBC_SCCS and not lint */ #include +__SCCSID("@(#)pause.c 8.1 (Berkeley) 6/4/93"); __FBSDID("$FreeBSD$"); #include #include #include "libc_private.h" int __pause(void); /* * Backwards compatible pause. */ int __pause(void) { sigset_t oset; if (sigprocmask(SIG_BLOCK, NULL, &oset) == -1) return (-1); return (sigsuspend(&oset)); } __weak_reference(__pause, pause); __weak_reference(__pause, _pause); Index: head/lib/libc/gen/popen.c =================================================================== --- head/lib/libc/gen/popen.c (revision 335897) +++ head/lib/libc/gen/popen.c (revision 335898) @@ -1,231 +1,229 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1988, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software written by Ken Arnold and * published in UNIX Review, Vol. 6, No. 8. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)popen.c 8.3 (Berkeley) 5/3/95"; -#endif /* LIBC_SCCS and not lint */ #include +__SCCSID("@(#)popen.c 8.3 (Berkeley) 5/3/95"); __FBSDID("$FreeBSD$"); #include "namespace.h" #include #include #include #include #include #include #include #include #include #include #include #include #include "un-namespace.h" #include "libc_private.h" extern char **environ; struct pid { SLIST_ENTRY(pid) next; FILE *fp; pid_t pid; }; static SLIST_HEAD(, pid) pidlist = SLIST_HEAD_INITIALIZER(pidlist); static pthread_mutex_t pidlist_mutex = PTHREAD_MUTEX_INITIALIZER; #define THREAD_LOCK() if (__isthreaded) _pthread_mutex_lock(&pidlist_mutex) #define THREAD_UNLOCK() if (__isthreaded) _pthread_mutex_unlock(&pidlist_mutex) FILE * popen(const char *command, const char *type) { struct pid *cur; FILE *iop; int pdes[2], pid, twoway, cloexec; int pdes_unused_in_parent; char *argv[4]; struct pid *p; cloexec = strchr(type, 'e') != NULL; /* * Lite2 introduced two-way popen() pipes using _socketpair(). * FreeBSD's pipe() is bidirectional, so we use that. */ if (strchr(type, '+')) { twoway = 1; type = "r+"; } else { twoway = 0; if ((*type != 'r' && *type != 'w') || (type[1] && (type[1] != 'e' || type[2]))) return (NULL); } if (pipe2(pdes, O_CLOEXEC) < 0) return (NULL); if ((cur = malloc(sizeof(struct pid))) == NULL) { (void)_close(pdes[0]); (void)_close(pdes[1]); return (NULL); } if (*type == 'r') { iop = fdopen(pdes[0], type); pdes_unused_in_parent = pdes[1]; } else { iop = fdopen(pdes[1], type); pdes_unused_in_parent = pdes[0]; } if (iop == NULL) { (void)_close(pdes[0]); (void)_close(pdes[1]); free(cur); return (NULL); } argv[0] = "sh"; argv[1] = "-c"; argv[2] = (char *)command; argv[3] = NULL; THREAD_LOCK(); switch (pid = vfork()) { case -1: /* Error. */ THREAD_UNLOCK(); /* * The _close() closes the unused end of pdes[], while * the fclose() closes the used end of pdes[], *and* cleans * up iop. */ (void)_close(pdes_unused_in_parent); free(cur); (void)fclose(iop); return (NULL); /* NOTREACHED */ case 0: /* Child. */ if (*type == 'r') { /* * The _dup2() to STDIN_FILENO is repeated to avoid * writing to pdes[1], which might corrupt the * parent's copy. This isn't good enough in * general, since the _exit() is no return, so * the compiler is free to corrupt all the local * variables. */ if (pdes[1] != STDOUT_FILENO) { (void)_dup2(pdes[1], STDOUT_FILENO); if (twoway) (void)_dup2(STDOUT_FILENO, STDIN_FILENO); } else if (twoway && (pdes[1] != STDIN_FILENO)) { (void)_dup2(pdes[1], STDIN_FILENO); (void)_fcntl(pdes[1], F_SETFD, 0); } else (void)_fcntl(pdes[1], F_SETFD, 0); } else { if (pdes[0] != STDIN_FILENO) { (void)_dup2(pdes[0], STDIN_FILENO); } else (void)_fcntl(pdes[0], F_SETFD, 0); } SLIST_FOREACH(p, &pidlist, next) (void)_close(fileno(p->fp)); _execve(_PATH_BSHELL, argv, environ); _exit(127); /* NOTREACHED */ } THREAD_UNLOCK(); /* Parent. */ (void)_close(pdes_unused_in_parent); /* Link into list of file descriptors. */ cur->fp = iop; cur->pid = pid; THREAD_LOCK(); SLIST_INSERT_HEAD(&pidlist, cur, next); THREAD_UNLOCK(); /* * To guard against undesired fd passing with concurrent calls, * only clear the close-on-exec flag after linking the file into * the list which will cause an explicit close. */ if (!cloexec) (void)_fcntl(*type == 'r' ? pdes[0] : pdes[1], F_SETFD, 0); return (iop); } /* * pclose -- * Pclose returns -1 if stream is not associated with a `popened' command, * if already `pclosed', or waitpid returns an error. */ int pclose(FILE *iop) { struct pid *cur, *last = NULL; int pstat; pid_t pid; /* * Find the appropriate file pointer and remove it from the list. */ THREAD_LOCK(); SLIST_FOREACH(cur, &pidlist, next) { if (cur->fp == iop) break; last = cur; } if (cur == NULL) { THREAD_UNLOCK(); return (-1); } if (last == NULL) SLIST_REMOVE_HEAD(&pidlist, next); else SLIST_REMOVE_AFTER(last, next); THREAD_UNLOCK(); (void)fclose(iop); do { pid = _wait4(cur->pid, &pstat, 0, (struct rusage *)0); } while (pid == -1 && errno == EINTR); free(cur); return (pid == -1 ? -1 : pstat); } Index: head/lib/libc/gen/psignal.c =================================================================== --- head/lib/libc/gen/psignal.c (revision 335897) +++ head/lib/libc/gen/psignal.c (revision 335898) @@ -1,63 +1,61 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1983, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)psignal.c 8.1 (Berkeley) 6/4/93"; -#endif /* LIBC_SCCS and not lint */ #include +__SCCSID("@(#)psignal.c 8.1 (Berkeley) 6/4/93"); __FBSDID("$FreeBSD$"); /* * Print the name of the signal indicated * along with the supplied message. */ #include "namespace.h" #include #include #include #include "un-namespace.h" void psignal(int sig, const char *s) { const char *c; if (sig >= 0 && sig < NSIG) c = sys_siglist[sig]; else c = "Unknown signal"; if (s != NULL && *s != '\0') { (void)_write(STDERR_FILENO, s, strlen(s)); (void)_write(STDERR_FILENO, ": ", 2); } (void)_write(STDERR_FILENO, c, strlen(c)); (void)_write(STDERR_FILENO, "\n", 1); } Index: head/lib/libc/gen/pw_scan.c =================================================================== --- head/lib/libc/gen/pw_scan.c (revision 335897) +++ head/lib/libc/gen/pw_scan.c (revision 335898) @@ -1,212 +1,210 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1990, 1993, 1994 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)pw_scan.c 8.3 (Berkeley) 4/2/94"; -#endif /* LIBC_SCCS and not lint */ #include +__SCCSID("@(#)pw_scan.c 8.3 (Berkeley) 4/2/94"); __FBSDID("$FreeBSD$"); /* * This module is used to "verify" password entries by chpass(1) and * pwd_mkdb(8). */ #include #include #include #include #include #include #include #include "pw_scan.h" /* * Some software assumes that IDs are short. We should emit warnings * for id's which cannot be stored in a short, but we are more liberal * by default, warning for IDs greater than USHRT_MAX. * * If pw_big_ids_warning is -1 on entry to pw_scan(), it will be set based * on the existence of PW_SCAN_BIG_IDS in the environment. * * It is believed all baseline system software that can not handle the * normal ID sizes is now gone so pw_big_ids_warning is disabled for now. * But the code has been left in place in case end-users want to re-enable * it and/or for the next time the ID sizes get bigger but pieces of the * system lag behind. */ static int pw_big_ids_warning = 0; int __pw_scan(char *bp, struct passwd *pw, int flags) { uid_t id; int root; char *ep, *p, *sh; unsigned long temp; if (pw_big_ids_warning == -1) pw_big_ids_warning = getenv("PW_SCAN_BIG_IDS") == NULL ? 1 : 0; pw->pw_fields = 0; if (!(pw->pw_name = strsep(&bp, ":"))) /* login */ goto fmt; root = !strcmp(pw->pw_name, "root"); if (pw->pw_name[0] && (pw->pw_name[0] != '+' || pw->pw_name[1] == '\0')) pw->pw_fields |= _PWF_NAME; if (!(pw->pw_passwd = strsep(&bp, ":"))) /* passwd */ goto fmt; if (pw->pw_passwd[0]) pw->pw_fields |= _PWF_PASSWD; if (!(p = strsep(&bp, ":"))) /* uid */ goto fmt; if (p[0]) pw->pw_fields |= _PWF_UID; else { if (pw->pw_name[0] != '+' && pw->pw_name[0] != '-') { if (flags & _PWSCAN_WARN) warnx("no uid for user %s", pw->pw_name); return (0); } } errno = 0; temp = strtoul(p, &ep, 10); if ((temp == ULONG_MAX && errno == ERANGE) || temp > UID_MAX) { if (flags & _PWSCAN_WARN) warnx("%s > max uid value (%u)", p, UID_MAX); return (0); } id = temp; if (*ep != '\0') { if (flags & _PWSCAN_WARN) warnx("%s uid is incorrect", p); return (0); } if (root && id) { if (flags & _PWSCAN_WARN) warnx("root uid should be 0"); return (0); } if (flags & _PWSCAN_WARN && pw_big_ids_warning && id > USHRT_MAX) { warnx("%s > recommended max uid value (%u)", p, USHRT_MAX); /*return (0);*/ /* THIS SHOULD NOT BE FATAL! */ } pw->pw_uid = id; if (!(p = strsep(&bp, ":"))) /* gid */ goto fmt; if (p[0]) pw->pw_fields |= _PWF_GID; else { if (pw->pw_name[0] != '+' && pw->pw_name[0] != '-') { if (flags & _PWSCAN_WARN) warnx("no gid for user %s", pw->pw_name); return (0); } } errno = 0; temp = strtoul(p, &ep, 10); if ((temp == ULONG_MAX && errno == ERANGE) || temp > GID_MAX) { if (flags & _PWSCAN_WARN) warnx("%s > max gid value (%u)", p, GID_MAX); return (0); } id = temp; if (*ep != '\0') { if (flags & _PWSCAN_WARN) warnx("%s gid is incorrect", p); return (0); } if (flags & _PWSCAN_WARN && pw_big_ids_warning && id > USHRT_MAX) { warnx("%s > recommended max gid value (%u)", p, USHRT_MAX); /* return (0); This should not be fatal! */ } pw->pw_gid = id; if (flags & _PWSCAN_MASTER ) { if (!(pw->pw_class = strsep(&bp, ":"))) /* class */ goto fmt; if (pw->pw_class[0]) pw->pw_fields |= _PWF_CLASS; if (!(p = strsep(&bp, ":"))) /* change */ goto fmt; if (p[0]) pw->pw_fields |= _PWF_CHANGE; pw->pw_change = atol(p); if (!(p = strsep(&bp, ":"))) /* expire */ goto fmt; if (p[0]) pw->pw_fields |= _PWF_EXPIRE; pw->pw_expire = atol(p); } if (!(pw->pw_gecos = strsep(&bp, ":"))) /* gecos */ goto fmt; if (pw->pw_gecos[0]) pw->pw_fields |= _PWF_GECOS; if (!(pw->pw_dir = strsep(&bp, ":"))) /* directory */ goto fmt; if (pw->pw_dir[0]) pw->pw_fields |= _PWF_DIR; if (!(pw->pw_shell = strsep(&bp, ":"))) /* shell */ goto fmt; p = pw->pw_shell; if (root && *p) { /* empty == /bin/sh */ for (setusershell();;) { if (!(sh = getusershell())) { if (flags & _PWSCAN_WARN) warnx("warning, unknown root shell"); break; } if (!strcmp(p, sh)) break; } endusershell(); } if (p[0]) pw->pw_fields |= _PWF_SHELL; if ((p = strsep(&bp, ":"))) { /* too many */ fmt: if (flags & _PWSCAN_WARN) warnx("corrupted entry"); return (0); } return (1); } Index: head/lib/libc/gen/raise.c =================================================================== --- head/lib/libc/gen/raise.c (revision 335897) +++ head/lib/libc/gen/raise.c (revision 335898) @@ -1,55 +1,53 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)raise.c 8.1 (Berkeley) 6/4/93"; -#endif /* LIBC_SCCS and not lint */ #include +__SCCSID("@(#)raise.c 8.1 (Berkeley) 6/4/93"); __FBSDID("$FreeBSD$"); #include #include #include "libc_private.h" __weak_reference(__raise, raise); __weak_reference(__raise, _raise); int __raise(int); int __raise(int s) { long id; if (__sys_thr_self(&id) == -1) return (-1); return (__sys_thr_kill(id, s)); } Index: head/lib/libc/gen/readdir-compat11.c =================================================================== --- head/lib/libc/gen/readdir-compat11.c (revision 335897) +++ head/lib/libc/gen/readdir-compat11.c (revision 335898) @@ -1,120 +1,117 @@ /* * Copyright (c) 1983, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * from: - * $FreeBSD$ + * From: @(#)readdir.c 8.3 (Berkeley) 9/29/94 + * From: FreeBSD: head/lib/libc/gen/readdir.c 314436 2017-02-28 23:42:47Z imp */ -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)readdir.c 8.3 (Berkeley) 9/29/94"; -#endif /* LIBC_SCCS and not lint */ #include __FBSDID("$FreeBSD$"); #include "namespace.h" #include #define _WANT_FREEBSD11_DIRENT #include #include #include #include #include #include #include #include "un-namespace.h" #include "libc_private.h" #include "gen-private.h" #include "telldir.h" #include "gen-compat.h" static bool freebsd11_cvtdirent(struct freebsd11_dirent *dstdp, struct dirent *srcdp) { if (srcdp->d_namlen >= sizeof(dstdp->d_name)) return (false); dstdp->d_type = srcdp->d_type; dstdp->d_namlen = srcdp->d_namlen; dstdp->d_fileno = srcdp->d_fileno; /* truncate */ dstdp->d_reclen = FREEBSD11_DIRSIZ(dstdp); bcopy(srcdp->d_name, dstdp->d_name, dstdp->d_namlen); bzero(dstdp->d_name + dstdp->d_namlen, dstdp->d_reclen - offsetof(struct freebsd11_dirent, d_name) - dstdp->d_namlen); return (true); } struct freebsd11_dirent * freebsd11_readdir(DIR *dirp) { struct freebsd11_dirent *dstdp; struct dirent *dp; if (__isthreaded) _pthread_mutex_lock(&dirp->dd_lock); dp = _readdir_unlocked(dirp, RDU_SKIP); if (dp != NULL) { if (dirp->dd_compat_de == NULL) dirp->dd_compat_de = malloc(sizeof(struct freebsd11_dirent)); if (freebsd11_cvtdirent(dirp->dd_compat_de, dp)) dstdp = dirp->dd_compat_de; else dstdp = NULL; } else dstdp = NULL; if (__isthreaded) _pthread_mutex_unlock(&dirp->dd_lock); return (dstdp); } int freebsd11_readdir_r(DIR *dirp, struct freebsd11_dirent *entry, struct freebsd11_dirent **result) { struct dirent xentry, *xresult; int error; error = __readdir_r(dirp, &xentry, &xresult); if (error != 0) return (error); if (xresult != NULL) { if (freebsd11_cvtdirent(entry, &xentry)) *result = entry; else /* should not happen due to RDU_SHORT */ *result = NULL; } else *result = NULL; return (0); } __sym_compat(readdir, freebsd11_readdir, FBSD_1.0); __sym_compat(readdir_r, freebsd11_readdir_r, FBSD_1.0); Index: head/lib/libc/gen/readdir.c =================================================================== --- head/lib/libc/gen/readdir.c (revision 335897) +++ head/lib/libc/gen/readdir.c (revision 335898) @@ -1,139 +1,137 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1983, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)readdir.c 8.3 (Berkeley) 9/29/94"; -#endif /* LIBC_SCCS and not lint */ #include +__SCCSID("@(#)readdir.c 8.3 (Berkeley) 9/29/94"); __FBSDID("$FreeBSD$"); #include "namespace.h" #include #include #include #include #include #include "un-namespace.h" #include "libc_private.h" #include "gen-private.h" #include "telldir.h" /* * get next entry in a directory. */ struct dirent * _readdir_unlocked(DIR *dirp, int flags) { struct dirent *dp; long initial_seek; long initial_loc = 0; for (;;) { if (dirp->dd_loc >= dirp->dd_size) { if (dirp->dd_flags & __DTF_READALL) return (NULL); initial_loc = dirp->dd_loc; dirp->dd_flags &= ~__DTF_SKIPREAD; dirp->dd_loc = 0; } if (dirp->dd_loc == 0 && !(dirp->dd_flags & (__DTF_READALL | __DTF_SKIPREAD))) { initial_seek = dirp->dd_seek; dirp->dd_size = _getdirentries(dirp->dd_fd, dirp->dd_buf, dirp->dd_len, &dirp->dd_seek); if (dirp->dd_size <= 0) return (NULL); _fixtelldir(dirp, initial_seek, initial_loc); } dirp->dd_flags &= ~__DTF_SKIPREAD; dp = (struct dirent *)(dirp->dd_buf + dirp->dd_loc); if ((long)dp & 03L) /* bogus pointer check */ return (NULL); if (dp->d_reclen <= 0 || dp->d_reclen > dirp->dd_len + 1 - dirp->dd_loc) return (NULL); dirp->dd_loc += dp->d_reclen; if (dp->d_ino == 0 && (flags & RDU_SKIP) != 0) continue; if (dp->d_type == DT_WHT && (dirp->dd_flags & DTF_HIDEW)) continue; if (dp->d_namlen >= sizeof(dp->d_name) && (flags & RDU_SHORT) != 0) continue; return (dp); } } struct dirent * readdir(DIR *dirp) { struct dirent *dp; if (__isthreaded) _pthread_mutex_lock(&dirp->dd_lock); dp = _readdir_unlocked(dirp, RDU_SKIP); if (__isthreaded) _pthread_mutex_unlock(&dirp->dd_lock); return (dp); } int __readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result) { struct dirent *dp; int saved_errno; saved_errno = errno; errno = 0; if (__isthreaded) _pthread_mutex_lock(&dirp->dd_lock); dp = _readdir_unlocked(dirp, RDU_SKIP | RDU_SHORT); if (dp != NULL) memcpy(entry, dp, _GENERIC_DIRSIZ(dp)); if (__isthreaded) _pthread_mutex_unlock(&dirp->dd_lock); if (errno != 0) { if (dp == NULL) return (errno); } else errno = saved_errno; if (dp != NULL) *result = entry; else *result = NULL; return (0); } __strong_reference(__readdir_r, readdir_r); Index: head/lib/libc/gen/rewinddir.c =================================================================== --- head/lib/libc/gen/rewinddir.c (revision 335897) +++ head/lib/libc/gen/rewinddir.c (revision 335898) @@ -1,66 +1,64 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)rewinddir.c 8.1 (Berkeley) 6/8/93"; -#endif /* LIBC_SCCS and not lint */ #include +__SCCSID("@(#)rewinddir.c 8.1 (Berkeley) 6/8/93"); __FBSDID("$FreeBSD$"); #include "namespace.h" #include #include #include #include #include "un-namespace.h" #include "libc_private.h" #include "gen-private.h" #include "telldir.h" void rewinddir(DIR *dirp) { if (__isthreaded) _pthread_mutex_lock(&dirp->dd_lock); dirp->dd_flags &= ~__DTF_SKIPREAD; /* current contents are invalid */ if (dirp->dd_flags & __DTF_READALL) _filldir(dirp, false); else { (void) lseek(dirp->dd_fd, 0, SEEK_SET); dirp->dd_seek = 0; } dirp->dd_loc = 0; _reclaim_telldir(dirp); if (__isthreaded) _pthread_mutex_unlock(&dirp->dd_lock); } Index: head/lib/libc/gen/scandir-compat11.c =================================================================== --- head/lib/libc/gen/scandir-compat11.c (revision 335897) +++ head/lib/libc/gen/scandir-compat11.c (revision 335898) @@ -1,174 +1,171 @@ /* * Copyright (c) 1983, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * from: - * $FreeBSD$ + * From: @(#)scandir.c 8.3 (Berkeley) 1/2/94 + * From: FreeBSD: head/lib/libc/gen/scandir.c 317372 2017-04-24 14:56:41Z pfg */ -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)scandir.c 8.3 (Berkeley) 1/2/94"; -#endif /* LIBC_SCCS and not lint */ #include __FBSDID("$FreeBSD$"); /* * Scan the directory dirname calling select to make a list of selected * directory entries then sort using qsort and compare routine dcomp. * Returns the number of entries and a pointer to a list of pointers to * struct dirent (through namelist). Returns -1 if there were any errors. */ #include "namespace.h" #define _WANT_FREEBSD11_DIRENT #include #include #include #include "un-namespace.h" #include "gen-compat.h" #ifdef I_AM_SCANDIR_B #include "block_abi.h" #define SELECT(x) CALL_BLOCK(select, x) #ifndef __BLOCKS__ void qsort_b(void *, size_t, size_t, void*); #endif #else #define SELECT(x) select(x) #endif static int freebsd11_alphasort_thunk(void *thunk, const void *p1, const void *p2); int #ifdef I_AM_SCANDIR_B freebsd11_scandir_b(const char *dirname, struct freebsd11_dirent ***namelist, DECLARE_BLOCK(int, select, const struct freebsd11_dirent *), DECLARE_BLOCK(int, dcomp, const struct freebsd11_dirent **, const struct freebsd11_dirent **)) #else freebsd11_scandir(const char *dirname, struct freebsd11_dirent ***namelist, int (*select)(const struct freebsd11_dirent *), int (*dcomp)(const struct freebsd11_dirent **, const struct freebsd11_dirent **)) #endif { struct freebsd11_dirent *d, *p, **names = NULL; size_t arraysz, numitems; DIR *dirp; if ((dirp = opendir(dirname)) == NULL) return(-1); numitems = 0; arraysz = 32; /* initial estimate of the array size */ names = (struct freebsd11_dirent **)malloc( arraysz * sizeof(struct freebsd11_dirent *)); if (names == NULL) goto fail; while ((d = freebsd11_readdir(dirp)) != NULL) { if (select != NULL && !SELECT(d)) continue; /* just selected names */ /* * Make a minimum size copy of the data */ p = (struct freebsd11_dirent *)malloc(FREEBSD11_DIRSIZ(d)); if (p == NULL) goto fail; p->d_fileno = d->d_fileno; p->d_type = d->d_type; p->d_reclen = d->d_reclen; p->d_namlen = d->d_namlen; bcopy(d->d_name, p->d_name, p->d_namlen + 1); /* * Check to make sure the array has space left and * realloc the maximum size. */ if (numitems >= arraysz) { struct freebsd11_dirent **names2; names2 = reallocarray(names, arraysz, 2 * sizeof(struct freebsd11_dirent *)); if (names2 == NULL) { free(p); goto fail; } names = names2; arraysz *= 2; } names[numitems++] = p; } closedir(dirp); if (numitems && dcomp != NULL) #ifdef I_AM_SCANDIR_B qsort_b(names, numitems, sizeof(struct freebsd11_dirent *), (void*)dcomp); #else qsort_r(names, numitems, sizeof(struct freebsd11_dirent *), &dcomp, freebsd11_alphasort_thunk); #endif *namelist = names; return (numitems); fail: while (numitems > 0) free(names[--numitems]); free(names); closedir(dirp); return (-1); } /* * Alphabetic order comparison routine for those who want it. * POSIX 2008 requires that alphasort() uses strcoll(). */ int freebsd11_alphasort(const struct freebsd11_dirent **d1, const struct freebsd11_dirent **d2) { return (strcoll((*d1)->d_name, (*d2)->d_name)); } static int freebsd11_alphasort_thunk(void *thunk, const void *p1, const void *p2) { int (*dc)(const struct freebsd11_dirent **, const struct freebsd11_dirent **); dc = *(int (**)(const struct freebsd11_dirent **, const struct freebsd11_dirent **))thunk; return (dc((const struct freebsd11_dirent **)p1, (const struct freebsd11_dirent **)p2)); } __sym_compat(alphasort, freebsd11_alphasort, FBSD_1.0); __sym_compat(scandir, freebsd11_scandir, FBSD_1.0); __sym_compat(scandir_b, freebsd11_scandir_b, FBSD_1.4); Index: head/lib/libc/gen/scandir.c =================================================================== --- head/lib/libc/gen/scandir.c (revision 335897) +++ head/lib/libc/gen/scandir.c (revision 335898) @@ -1,157 +1,155 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1983, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)scandir.c 8.3 (Berkeley) 1/2/94"; -#endif /* LIBC_SCCS and not lint */ #include +__SCCSID("@(#)scandir.c 8.3 (Berkeley) 1/2/94"); __FBSDID("$FreeBSD$"); /* * Scan the directory dirname calling select to make a list of selected * directory entries then sort using qsort and compare routine dcomp. * Returns the number of entries and a pointer to a list of pointers to * struct dirent (through namelist). Returns -1 if there were any errors. */ #include "namespace.h" #include #include #include #include "un-namespace.h" #ifdef I_AM_SCANDIR_B #include "block_abi.h" #define SELECT(x) CALL_BLOCK(select, x) #ifndef __BLOCKS__ void qsort_b(void *, size_t, size_t, void*); #endif #else #define SELECT(x) select(x) #endif static int alphasort_thunk(void *thunk, const void *p1, const void *p2); int #ifdef I_AM_SCANDIR_B scandir_b(const char *dirname, struct dirent ***namelist, DECLARE_BLOCK(int, select, const struct dirent *), DECLARE_BLOCK(int, dcomp, const struct dirent **, const struct dirent **)) #else scandir(const char *dirname, struct dirent ***namelist, int (*select)(const struct dirent *), int (*dcomp)(const struct dirent **, const struct dirent **)) #endif { struct dirent *d, *p, **names = NULL; size_t arraysz, numitems; DIR *dirp; if ((dirp = opendir(dirname)) == NULL) return(-1); numitems = 0; arraysz = 32; /* initial estimate of the array size */ names = (struct dirent **)malloc(arraysz * sizeof(struct dirent *)); if (names == NULL) goto fail; while ((d = readdir(dirp)) != NULL) { if (select != NULL && !SELECT(d)) continue; /* just selected names */ /* * Make a minimum size copy of the data */ p = (struct dirent *)malloc(_GENERIC_DIRSIZ(d)); if (p == NULL) goto fail; p->d_fileno = d->d_fileno; p->d_type = d->d_type; p->d_reclen = d->d_reclen; p->d_namlen = d->d_namlen; bcopy(d->d_name, p->d_name, p->d_namlen + 1); /* * Check to make sure the array has space left and * realloc the maximum size. */ if (numitems >= arraysz) { struct dirent **names2; names2 = reallocarray(names, arraysz, 2 * sizeof(struct dirent *)); if (names2 == NULL) { free(p); goto fail; } names = names2; arraysz *= 2; } names[numitems++] = p; } closedir(dirp); if (numitems && dcomp != NULL) #ifdef I_AM_SCANDIR_B qsort_b(names, numitems, sizeof(struct dirent *), (void*)dcomp); #else qsort_r(names, numitems, sizeof(struct dirent *), &dcomp, alphasort_thunk); #endif *namelist = names; return (numitems); fail: while (numitems > 0) free(names[--numitems]); free(names); closedir(dirp); return (-1); } /* * Alphabetic order comparison routine for those who want it. * POSIX 2008 requires that alphasort() uses strcoll(). */ int alphasort(const struct dirent **d1, const struct dirent **d2) { return (strcoll((*d1)->d_name, (*d2)->d_name)); } static int alphasort_thunk(void *thunk, const void *p1, const void *p2) { int (*dc)(const struct dirent **, const struct dirent **); dc = *(int (**)(const struct dirent **, const struct dirent **))thunk; return (dc((const struct dirent **)p1, (const struct dirent **)p2)); } Index: head/lib/libc/gen/seekdir.c =================================================================== --- head/lib/libc/gen/seekdir.c (revision 335897) +++ head/lib/libc/gen/seekdir.c (revision 335898) @@ -1,60 +1,58 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1983, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)seekdir.c 8.1 (Berkeley) 6/4/93"; -#endif /* LIBC_SCCS and not lint */ #include +__SCCSID("@(#)seekdir.c 8.1 (Berkeley) 6/4/93"); __FBSDID("$FreeBSD$"); #include "namespace.h" #include #include #include #include "un-namespace.h" #include "libc_private.h" #include "gen-private.h" #include "telldir.h" /* * Seek to an entry in a directory. * _seekdir is in telldir.c so that it can share opaque data structures. */ void seekdir(DIR *dirp, long loc) { if (__isthreaded) _pthread_mutex_lock(&dirp->dd_lock); _seekdir(dirp, loc); if (__isthreaded) _pthread_mutex_unlock(&dirp->dd_lock); } Index: head/lib/libc/gen/setdomainname.c =================================================================== --- head/lib/libc/gen/setdomainname.c (revision 335897) +++ head/lib/libc/gen/setdomainname.c (revision 335898) @@ -1,53 +1,51 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1989, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)sethostname.c 8.1 (Berkeley) 6/4/93"; -#endif /* LIBC_SCCS and not lint */ #include +__SCCSID("@(#)sethostname.c 8.1 (Berkeley) 6/4/93"); __FBSDID("$FreeBSD$"); #include #include #include int setdomainname(const char *name, int namelen) { int mib[2]; mib[0] = CTL_KERN; mib[1] = KERN_NISDOMAINNAME; if (sysctl(mib, 2, NULL, NULL, (void *)name, namelen) == -1) return (-1); return (0); } Index: head/lib/libc/gen/sethostname.c =================================================================== --- head/lib/libc/gen/sethostname.c (revision 335897) +++ head/lib/libc/gen/sethostname.c (revision 335898) @@ -1,53 +1,51 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1989, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)sethostname.c 8.1 (Berkeley) 6/4/93"; -#endif /* LIBC_SCCS and not lint */ #include +__SCCSID("@(#)sethostname.c 8.1 (Berkeley) 6/4/93"); __FBSDID("$FreeBSD$"); #include #include #include int sethostname(const char *name, int namelen) { int mib[2]; mib[0] = CTL_KERN; mib[1] = KERN_HOSTNAME; if (sysctl(mib, 2, NULL, NULL, (void *)name, namelen) == -1) return (-1); return (0); } Index: head/lib/libc/gen/setjmperr.c =================================================================== --- head/lib/libc/gen/setjmperr.c (revision 335897) +++ head/lib/libc/gen/setjmperr.c (revision 335898) @@ -1,55 +1,53 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1980, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)setjmperr.c 8.1 (Berkeley) 6/4/93"; -#endif /* LIBC_SCCS and not lint */ #include +__SCCSID("@(#)setjmperr.c 8.1 (Berkeley) 6/4/93"); __FBSDID("$FreeBSD$"); /* * This routine is called from longjmp() when an error occurs. * Programs that wish to exit gracefully from this error may * write their own versions. * If this routine returns, the program is aborted. */ #include "namespace.h" #include #include #include "un-namespace.h" void longjmperror(void) { #define ERRMSG "longjmp botch.\n" (void)_write(STDERR_FILENO, ERRMSG, sizeof(ERRMSG) - 1); } Index: head/lib/libc/gen/setmode.c =================================================================== --- head/lib/libc/gen/setmode.c (revision 335897) +++ head/lib/libc/gen/setmode.c (revision 335898) @@ -1,487 +1,485 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1989, 1993, 1994 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Dave Borman at Cray Research, Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)setmode.c 8.2 (Berkeley) 3/25/94"; -#endif /* LIBC_SCCS and not lint */ #include +__SCCSID("@(#)setmode.c 8.2 (Berkeley) 3/25/94"); __FBSDID("$FreeBSD$"); #include "namespace.h" #include #include #include #include #include #include #include #include #include #include #ifdef SETMODE_DEBUG #include #endif #include "un-namespace.h" #include "libc_private.h" #define SET_LEN 6 /* initial # of bitcmd struct to malloc */ #define SET_LEN_INCR 4 /* # of bitcmd structs to add as needed */ typedef struct bitcmd { char cmd; char cmd2; mode_t bits; } BITCMD; #define CMD2_CLR 0x01 #define CMD2_SET 0x02 #define CMD2_GBITS 0x04 #define CMD2_OBITS 0x08 #define CMD2_UBITS 0x10 static mode_t getumask(void); static BITCMD *addcmd(BITCMD *, mode_t, mode_t, mode_t, mode_t); static void compress_mode(BITCMD *); #ifdef SETMODE_DEBUG static void dumpmode(BITCMD *); #endif /* * Given the old mode and an array of bitcmd structures, apply the operations * described in the bitcmd structures to the old mode, and return the new mode. * Note that there is no '=' command; a strict assignment is just a '-' (clear * bits) followed by a '+' (set bits). */ mode_t getmode(const void *bbox, mode_t omode) { const BITCMD *set; mode_t clrval, newmode, value; set = (const BITCMD *)bbox; newmode = omode; for (value = 0;; set++) switch(set->cmd) { /* * When copying the user, group or other bits around, we "know" * where the bits are in the mode so that we can do shifts to * copy them around. If we don't use shifts, it gets real * grundgy with lots of single bit checks and bit sets. */ case 'u': value = (newmode & S_IRWXU) >> 6; goto common; case 'g': value = (newmode & S_IRWXG) >> 3; goto common; case 'o': value = newmode & S_IRWXO; common: if (set->cmd2 & CMD2_CLR) { clrval = (set->cmd2 & CMD2_SET) ? S_IRWXO : value; if (set->cmd2 & CMD2_UBITS) newmode &= ~((clrval<<6) & set->bits); if (set->cmd2 & CMD2_GBITS) newmode &= ~((clrval<<3) & set->bits); if (set->cmd2 & CMD2_OBITS) newmode &= ~(clrval & set->bits); } if (set->cmd2 & CMD2_SET) { if (set->cmd2 & CMD2_UBITS) newmode |= (value<<6) & set->bits; if (set->cmd2 & CMD2_GBITS) newmode |= (value<<3) & set->bits; if (set->cmd2 & CMD2_OBITS) newmode |= value & set->bits; } break; case '+': newmode |= set->bits; break; case '-': newmode &= ~set->bits; break; case 'X': if (omode & (S_IFDIR|S_IXUSR|S_IXGRP|S_IXOTH)) newmode |= set->bits; break; case '\0': default: #ifdef SETMODE_DEBUG (void)printf("getmode:%04o -> %04o\n", omode, newmode); #endif return (newmode); } } #define ADDCMD(a, b, c, d) \ if (set >= endset) { \ BITCMD *newset; \ setlen += SET_LEN_INCR; \ newset = reallocarray(saveset, setlen, sizeof(BITCMD)); \ if (newset == NULL) \ goto out; \ set = newset + (set - saveset); \ saveset = newset; \ endset = newset + (setlen - 2); \ } \ set = addcmd(set, (mode_t)(a), (mode_t)(b), (mode_t)(c), (d)) #define STANDARD_BITS (S_ISUID|S_ISGID|S_IRWXU|S_IRWXG|S_IRWXO) void * setmode(const char *p) { int serrno; char op, *ep; BITCMD *set, *saveset, *endset; mode_t mask, perm, permXbits, who; long perml; int equalopdone; u_int setlen; if (!*p) { errno = EINVAL; return (NULL); } /* * Get a copy of the mask for the permissions that are mask relative. * Flip the bits, we want what's not set. */ mask = ~getumask(); setlen = SET_LEN + 2; if ((set = malloc(setlen * sizeof(BITCMD))) == NULL) return (NULL); saveset = set; endset = set + (setlen - 2); /* * If an absolute number, get it and return; disallow non-octal digits * or illegal bits. */ if (isdigit((unsigned char)*p)) { errno = 0; perml = strtol(p, &ep, 8); if (*ep) { errno = EINVAL; goto out; } if (errno == ERANGE && (perml == LONG_MAX || perml == LONG_MIN)) goto out; if (perml & ~(STANDARD_BITS|S_ISTXT)) { errno = EINVAL; goto out; } perm = (mode_t)perml; ADDCMD('=', (STANDARD_BITS|S_ISTXT), perm, mask); set->cmd = 0; return (saveset); } /* * Build list of structures to set/clear/copy bits as described by * each clause of the symbolic mode. */ equalopdone = 0; for (;;) { /* First, find out which bits might be modified. */ for (who = 0;; ++p) { switch (*p) { case 'a': who |= STANDARD_BITS; break; case 'u': who |= S_ISUID|S_IRWXU; break; case 'g': who |= S_ISGID|S_IRWXG; break; case 'o': who |= S_IRWXO; break; default: goto getop; } } getop: if ((op = *p++) != '+' && op != '-' && op != '=') { errno = EINVAL; goto out; } if (op == '=') equalopdone = 0; who &= ~S_ISTXT; for (perm = 0, permXbits = 0;; ++p) { switch (*p) { case 'r': perm |= S_IRUSR|S_IRGRP|S_IROTH; break; case 's': /* If only "other" bits ignore set-id. */ if (!who || who & ~S_IRWXO) perm |= S_ISUID|S_ISGID; break; case 't': /* If only "other" bits ignore sticky. */ if (!who || who & ~S_IRWXO) { who |= S_ISTXT; perm |= S_ISTXT; } break; case 'w': perm |= S_IWUSR|S_IWGRP|S_IWOTH; break; case 'X': permXbits = S_IXUSR|S_IXGRP|S_IXOTH; break; case 'x': perm |= S_IXUSR|S_IXGRP|S_IXOTH; break; case 'u': case 'g': case 'o': /* * When ever we hit 'u', 'g', or 'o', we have * to flush out any partial mode that we have, * and then do the copying of the mode bits. */ if (perm) { ADDCMD(op, who, perm, mask); perm = 0; } if (op == '=') equalopdone = 1; if (op == '+' && permXbits) { ADDCMD('X', who, permXbits, mask); permXbits = 0; } ADDCMD(*p, who, op, mask); break; default: /* * Add any permissions that we haven't already * done. */ if (perm || (op == '=' && !equalopdone)) { if (op == '=') equalopdone = 1; ADDCMD(op, who, perm, mask); perm = 0; } if (permXbits) { ADDCMD('X', who, permXbits, mask); permXbits = 0; } goto apply; } } apply: if (!*p) break; if (*p != ',') goto getop; ++p; } set->cmd = 0; #ifdef SETMODE_DEBUG (void)printf("Before compress_mode()\n"); dumpmode(saveset); #endif compress_mode(saveset); #ifdef SETMODE_DEBUG (void)printf("After compress_mode()\n"); dumpmode(saveset); #endif return (saveset); out: serrno = errno; free(saveset); errno = serrno; return NULL; } static mode_t getumask(void) { sigset_t sigset, sigoset; size_t len; mode_t mask; u_short smask; /* * First try requesting the umask without temporarily modifying it. * Note that this does not work if the sysctl * security.bsd.unprivileged_proc_debug is set to 0. */ len = sizeof(smask); if (sysctl((int[4]){ CTL_KERN, KERN_PROC, KERN_PROC_UMASK, 0 }, 4, &smask, &len, NULL, 0) == 0) return (smask); /* * Since it's possible that the caller is opening files inside a signal * handler, protect them as best we can. */ sigfillset(&sigset); (void)__libc_sigprocmask(SIG_BLOCK, &sigset, &sigoset); (void)umask(mask = umask(0)); (void)__libc_sigprocmask(SIG_SETMASK, &sigoset, NULL); return (mask); } static BITCMD * addcmd(BITCMD *set, mode_t op, mode_t who, mode_t oparg, mode_t mask) { switch (op) { case '=': set->cmd = '-'; set->bits = who ? who : STANDARD_BITS; set++; op = '+'; /* FALLTHROUGH */ case '+': case '-': case 'X': set->cmd = op; set->bits = (who ? who : mask) & oparg; break; case 'u': case 'g': case 'o': set->cmd = op; if (who) { set->cmd2 = ((who & S_IRUSR) ? CMD2_UBITS : 0) | ((who & S_IRGRP) ? CMD2_GBITS : 0) | ((who & S_IROTH) ? CMD2_OBITS : 0); set->bits = (mode_t)~0; } else { set->cmd2 = CMD2_UBITS | CMD2_GBITS | CMD2_OBITS; set->bits = mask; } if (oparg == '+') set->cmd2 |= CMD2_SET; else if (oparg == '-') set->cmd2 |= CMD2_CLR; else if (oparg == '=') set->cmd2 |= CMD2_SET|CMD2_CLR; break; } return (set + 1); } #ifdef SETMODE_DEBUG static void dumpmode(BITCMD *set) { for (; set->cmd; ++set) (void)printf("cmd: '%c' bits %04o%s%s%s%s%s%s\n", set->cmd, set->bits, set->cmd2 ? " cmd2:" : "", set->cmd2 & CMD2_CLR ? " CLR" : "", set->cmd2 & CMD2_SET ? " SET" : "", set->cmd2 & CMD2_UBITS ? " UBITS" : "", set->cmd2 & CMD2_GBITS ? " GBITS" : "", set->cmd2 & CMD2_OBITS ? " OBITS" : ""); } #endif /* * Given an array of bitcmd structures, compress by compacting consecutive * '+', '-' and 'X' commands into at most 3 commands, one of each. The 'u', * 'g' and 'o' commands continue to be separate. They could probably be * compacted, but it's not worth the effort. */ static void compress_mode(BITCMD *set) { BITCMD *nset; int setbits, clrbits, Xbits, op; for (nset = set;;) { /* Copy over any 'u', 'g' and 'o' commands. */ while ((op = nset->cmd) != '+' && op != '-' && op != 'X') { *set++ = *nset++; if (!op) return; } for (setbits = clrbits = Xbits = 0;; nset++) { if ((op = nset->cmd) == '-') { clrbits |= nset->bits; setbits &= ~nset->bits; Xbits &= ~nset->bits; } else if (op == '+') { setbits |= nset->bits; clrbits &= ~nset->bits; Xbits &= ~nset->bits; } else if (op == 'X') Xbits |= nset->bits & ~setbits; else break; } if (clrbits) { set->cmd = '-'; set->cmd2 = 0; set->bits = clrbits; set++; } if (setbits) { set->cmd = '+'; set->cmd2 = 0; set->bits = setbits; set++; } if (Xbits) { set->cmd = 'X'; set->cmd2 = 0; set->bits = Xbits; set++; } } } Index: head/lib/libc/gen/siginterrupt.c =================================================================== --- head/lib/libc/gen/siginterrupt.c (revision 335897) +++ head/lib/libc/gen/siginterrupt.c (revision 335898) @@ -1,64 +1,62 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1989, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)siginterrupt.c 8.1 (Berkeley) 6/4/93"; -#endif /* LIBC_SCCS and not lint */ #include +__SCCSID("@(#)siginterrupt.c 8.1 (Berkeley) 6/4/93"); __FBSDID("$FreeBSD$"); #include "namespace.h" #include #include "un-namespace.h" #include "libc_private.h" /* * Set signal state to prevent restart of system calls * after an instance of the indicated signal. */ int siginterrupt(int sig, int flag) { extern sigset_t _sigintr __hidden; struct sigaction sa; int ret; if ((ret = __libc_sigaction(sig, (struct sigaction *)0, &sa)) < 0) return (ret); if (flag) { sigaddset(&_sigintr, sig); sa.sa_flags &= ~SA_RESTART; } else { sigdelset(&_sigintr, sig); sa.sa_flags |= SA_RESTART; } return (__libc_sigaction(sig, &sa, (struct sigaction *)0)); } Index: head/lib/libc/gen/siglist.c =================================================================== --- head/lib/libc/gen/siglist.c (revision 335897) +++ head/lib/libc/gen/siglist.c (revision 335898) @@ -1,109 +1,107 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1983, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)siglist.c 8.1 (Berkeley) 6/4/93"; -#endif /* LIBC_SCCS and not lint */ #include +__SCCSID("@(#)siglist.c 8.1 (Berkeley) 6/4/93"); __FBSDID("$FreeBSD$"); #include const char *const sys_signame[NSIG] = { [0] = "Signal 0", [SIGHUP] = "HUP", [SIGINT] = "INT", [SIGQUIT] = "QUIT", [SIGILL] = "ILL", [SIGTRAP] = "TRAP", [SIGABRT] = "ABRT", [SIGEMT] = "EMT", [SIGFPE] = "FPE", [SIGKILL] = "KILL", [SIGBUS] = "BUS", [SIGSEGV] = "SEGV", [SIGSYS] = "SYS", [SIGPIPE] = "PIPE", [SIGALRM] = "ALRM", [SIGTERM] = "TERM", [SIGURG] = "URG", [SIGSTOP] = "STOP", [SIGTSTP] = "TSTP", [SIGCONT] = "CONT", [SIGCHLD] = "CHLD", [SIGTTIN] = "TTIN", [SIGTTOU] = "TTOU", [SIGIO] = "IO", [SIGXCPU] = "XCPU", [SIGXFSZ] = "XFSZ", [SIGVTALRM] = "VTALRM", [SIGPROF] = "PROF", [SIGWINCH] = "WINCH", [SIGINFO] = "INFO", [SIGUSR1] = "USR1", [SIGUSR2] = "USR2", }; const char *const sys_siglist[NSIG] = { [0] = "Signal 0", [SIGHUP] = "Hangup", [SIGINT] = "Interrupt", [SIGQUIT] = "Quit", [SIGILL] = "Illegal instruction", [SIGTRAP] = "Trace/BPT trap", [SIGABRT] = "Abort trap", [SIGEMT] = "EMT trap", [SIGFPE] = "Floating point exception", [SIGKILL] = "Killed", [SIGBUS] = "Bus error", [SIGSEGV] = "Segmentation fault", [SIGSYS] = "Bad system call", [SIGPIPE] = "Broken pipe", [SIGALRM] = "Alarm clock", [SIGTERM] = "Terminated", [SIGURG] = "Urgent I/O condition", [SIGSTOP] = "Suspended (signal)", [SIGTSTP] = "Suspended", [SIGCONT] = "Continued", [SIGCHLD] = "Child exited", [SIGTTIN] = "Stopped (tty input)", [SIGTTOU] = "Stopped (tty output)", [SIGIO] = "I/O possible", [SIGXCPU] = "Cputime limit exceeded", [SIGXFSZ] = "Filesize limit exceeded", [SIGVTALRM] = "Virtual timer expired", [SIGPROF] = "Profiling timer expired", [SIGWINCH] = "Window size changes", [SIGINFO] = "Information request", [SIGUSR1] = "User defined signal 1", [SIGUSR2] = "User defined signal 2", }; const int sys_nsig = sizeof(sys_siglist) / sizeof(sys_siglist[0]); Index: head/lib/libc/gen/signal.c =================================================================== --- head/lib/libc/gen/signal.c (revision 335897) +++ head/lib/libc/gen/signal.c (revision 335898) @@ -1,61 +1,59 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1985, 1989, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)signal.c 8.1 (Berkeley) 6/4/93"; -#endif /* LIBC_SCCS and not lint */ #include +__SCCSID("@(#)signal.c 8.1 (Berkeley) 6/4/93"); __FBSDID("$FreeBSD$"); /* * Almost backwards compatible signal. */ #include "namespace.h" #include #include "un-namespace.h" #include "libc_private.h" sigset_t _sigintr __hidden; /* shared with siginterrupt */ sig_t signal(int s, sig_t a) { struct sigaction sa, osa; sa.sa_handler = a; sigemptyset(&sa.sa_mask); sa.sa_flags = 0; if (!sigismember(&_sigintr, s)) sa.sa_flags |= SA_RESTART; if (__libc_sigaction(s, &sa, &osa) < 0) return (SIG_ERR); return (osa.sa_handler); } Index: head/lib/libc/gen/sigsetops.c =================================================================== --- head/lib/libc/gen/sigsetops.c (revision 335897) +++ head/lib/libc/gen/sigsetops.c (revision 335898) @@ -1,96 +1,92 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1989, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * @(#)sigsetops.c 8.1 (Berkeley) 6/4/93 */ -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)sigsetops.c 8.1 (Berkeley) 6/4/93"; -#endif /* LIBC_SCCS and not lint */ #include +__SCCSID("@(#)sigsetops.c 8.1 (Berkeley) 6/4/93"); __FBSDID("$FreeBSD$"); #include #include int sigaddset(sigset_t *set, int signo) { if (signo <= 0 || signo > _SIG_MAXSIG) { errno = EINVAL; return (-1); } set->__bits[_SIG_WORD(signo)] |= _SIG_BIT(signo); return (0); } int sigdelset(sigset_t *set, int signo) { if (signo <= 0 || signo > _SIG_MAXSIG) { errno = EINVAL; return (-1); } set->__bits[_SIG_WORD(signo)] &= ~_SIG_BIT(signo); return (0); } int sigemptyset(sigset_t *set) { int i; for (i = 0; i < _SIG_WORDS; i++) set->__bits[i] = 0; return (0); } int sigfillset(sigset_t *set) { int i; for (i = 0; i < _SIG_WORDS; i++) set->__bits[i] = ~0U; return (0); } int sigismember(const sigset_t *set, int signo) { if (signo <= 0 || signo > _SIG_MAXSIG) { errno = EINVAL; return (-1); } return ((set->__bits[_SIG_WORD(signo)] & _SIG_BIT(signo)) ? 1 : 0); } Index: head/lib/libc/gen/sleep.c =================================================================== --- head/lib/libc/gen/sleep.c (revision 335897) +++ head/lib/libc/gen/sleep.c (revision 335898) @@ -1,75 +1,73 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1989, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)sleep.c 8.1 (Berkeley) 6/4/93"; -#endif /* LIBC_SCCS and not lint */ #include +__SCCSID("@(#)sleep.c 8.1 (Berkeley) 6/4/93"); __FBSDID("$FreeBSD$"); #include "namespace.h" #include #include #include #include #include "un-namespace.h" #include "libc_private.h" unsigned int __sleep(unsigned int); unsigned int __sleep(unsigned int seconds) { struct timespec time_to_sleep; struct timespec time_remaining; /* * Avoid overflow when `seconds' is huge. This assumes that * the maximum value for a time_t is >= INT_MAX. */ if (seconds > INT_MAX) return (seconds - INT_MAX + __sleep(INT_MAX)); time_to_sleep.tv_sec = seconds; time_to_sleep.tv_nsec = 0; if (((int (*)(const struct timespec *, struct timespec *)) __libc_interposing[INTERPOS_nanosleep])( &time_to_sleep, &time_remaining) != -1) return (0); if (errno != EINTR) return (seconds); /* best guess */ return (time_remaining.tv_sec + (time_remaining.tv_nsec != 0)); /* round up */ } __weak_reference(__sleep, sleep); __weak_reference(__sleep, _sleep); Index: head/lib/libc/gen/stringlist.c =================================================================== --- head/lib/libc/gen/stringlist.c (revision 335897) +++ head/lib/libc/gen/stringlist.c (revision 335898) @@ -1,116 +1,114 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 1994 Christos Zoulas * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ -#if defined(LIBC_SCCS) && !defined(lint) -static char *rcsid = "$NetBSD: stringlist.c,v 1.2 1997/01/17 07:26:20 lukem Exp $"; -#endif /* LIBC_SCCS and not lint */ #include +__RCSID("$NetBSD: stringlist.c,v 1.2 1997/01/17 07:26:20 lukem Exp $"); __FBSDID("$FreeBSD$"); #include "namespace.h" #include #include #include #include #include #include "un-namespace.h" #define _SL_CHUNKSIZE 20 /* * sl_init(): Initialize a string list */ StringList * sl_init(void) { StringList *sl; sl = malloc(sizeof(StringList)); if (sl == NULL) _err(1, "stringlist: %m"); sl->sl_cur = 0; sl->sl_max = _SL_CHUNKSIZE; sl->sl_str = malloc(sl->sl_max * sizeof(char *)); if (sl->sl_str == NULL) _err(1, "stringlist: %m"); return sl; } /* * sl_add(): Add an item to the string list */ int sl_add(StringList *sl, char *name) { if (sl->sl_cur == sl->sl_max - 1) { sl->sl_max += _SL_CHUNKSIZE; sl->sl_str = reallocf(sl->sl_str, sl->sl_max * sizeof(char *)); if (sl->sl_str == NULL) return (-1); } sl->sl_str[sl->sl_cur++] = name; return (0); } /* * sl_free(): Free a stringlist */ void sl_free(StringList *sl, int all) { size_t i; if (sl == NULL) return; if (sl->sl_str) { if (all) for (i = 0; i < sl->sl_cur; i++) free(sl->sl_str[i]); free(sl->sl_str); } free(sl); } /* * sl_find(): Find a name in the string list */ char * sl_find(StringList *sl, const char *name) { size_t i; for (i = 0; i < sl->sl_cur; i++) if (strcmp(sl->sl_str[i], name) == 0) return sl->sl_str[i]; return NULL; } Index: head/lib/libc/gen/strtofflags.c =================================================================== --- head/lib/libc/gen/strtofflags.c (revision 335897) +++ head/lib/libc/gen/strtofflags.c (revision 335898) @@ -1,171 +1,169 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)stat_flags.c 8.1 (Berkeley) 5/31/93"; -#endif /* LIBC_SCCS and not lint */ #include +__SCCSID("@(#)stat_flags.c 8.1 (Berkeley) 5/31/93"); __FBSDID("$FreeBSD$"); #include #include #include #include #include #include #define longestflaglen 12 static struct { char name[longestflaglen + 1]; char invert; u_long flag; } const mapping[] = { /* shorter names per flag first, all prefixed by "no" */ { "nosappnd", 0, SF_APPEND }, { "nosappend", 0, SF_APPEND }, { "noarch", 0, SF_ARCHIVED }, { "noarchived", 0, SF_ARCHIVED }, { "noschg", 0, SF_IMMUTABLE }, { "noschange", 0, SF_IMMUTABLE }, { "nosimmutable", 0, SF_IMMUTABLE }, { "nosunlnk", 0, SF_NOUNLINK }, { "nosunlink", 0, SF_NOUNLINK }, #ifdef SF_SNAPSHOT { "nosnapshot", 0, SF_SNAPSHOT }, #endif { "nouappnd", 0, UF_APPEND }, { "nouappend", 0, UF_APPEND }, { "nouarch", 0, UF_ARCHIVE }, { "nouarchive", 0, UF_ARCHIVE }, { "nohidden", 0, UF_HIDDEN }, { "nouhidden", 0, UF_HIDDEN }, { "nouchg", 0, UF_IMMUTABLE }, { "nouchange", 0, UF_IMMUTABLE }, { "nouimmutable", 0, UF_IMMUTABLE }, { "nodump", 1, UF_NODUMP }, { "nouunlnk", 0, UF_NOUNLINK }, { "nouunlink", 0, UF_NOUNLINK }, { "nooffline", 0, UF_OFFLINE }, { "nouoffline", 0, UF_OFFLINE }, { "noopaque", 0, UF_OPAQUE }, { "nordonly", 0, UF_READONLY }, { "nourdonly", 0, UF_READONLY }, { "noreadonly", 0, UF_READONLY }, { "noureadonly", 0, UF_READONLY }, { "noreparse", 0, UF_REPARSE }, { "noureparse", 0, UF_REPARSE }, { "nosparse", 0, UF_SPARSE }, { "nousparse", 0, UF_SPARSE }, { "nosystem", 0, UF_SYSTEM }, { "nousystem", 0, UF_SYSTEM } }; #define nmappings (sizeof(mapping) / sizeof(mapping[0])) /* * fflagstostr -- * Convert file flags to a comma-separated string. If no flags * are set, return the empty string. */ char * fflagstostr(u_long flags) { char *string; const char *sp; char *dp; u_long setflags; u_int i; if ((string = (char *)malloc(nmappings * (longestflaglen + 1))) == NULL) return (NULL); setflags = flags; dp = string; for (i = 0; i < nmappings; i++) { if (setflags & mapping[i].flag) { if (dp > string) *dp++ = ','; for (sp = mapping[i].invert ? mapping[i].name : mapping[i].name + 2; *sp; *dp++ = *sp++) ; setflags &= ~mapping[i].flag; } } *dp = '\0'; return (string); } /* * strtofflags -- * Take string of arguments and return file flags. Return 0 on * success, 1 on failure. On failure, stringp is set to point * to the offending token. */ int strtofflags(char **stringp, u_long *setp, u_long *clrp) { char *string, *p; int i; if (setp) *setp = 0; if (clrp) *clrp = 0; string = *stringp; while ((p = strsep(&string, "\t ,")) != NULL) { *stringp = p; if (*p == '\0') continue; for (i = 0; i < nmappings; i++) { if (strcmp(p, mapping[i].name + 2) == 0) { if (mapping[i].invert) { if (clrp) *clrp |= mapping[i].flag; } else { if (setp) *setp |= mapping[i].flag; } break; } else if (strcmp(p, mapping[i].name) == 0) { if (mapping[i].invert) { if (setp) *setp |= mapping[i].flag; } else { if (clrp) *clrp |= mapping[i].flag; } break; } } if (i == nmappings) return 1; } return 0; } Index: head/lib/libc/gen/sysconf.c =================================================================== --- head/lib/libc/gen/sysconf.c (revision 335897) +++ head/lib/libc/gen/sysconf.c (revision 335898) @@ -1,623 +1,621 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Sean Eric Fagan of Cygnus Support. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)sysconf.c 8.2 (Berkeley) 3/20/94"; -#endif /* LIBC_SCCS and not lint */ #include +__SCCSID("@(#)sysconf.c 8.2 (Berkeley) 3/20/94"); __FBSDID("$FreeBSD$"); #include "namespace.h" #include #include #include #include #include #include #include #include #include #include /* we just need the limits */ #include #include #include #include "un-namespace.h" #include "../stdlib/atexit.h" #include "tzfile.h" /* from ../../../contrib/tzcode/stdtime */ #include "libc_private.h" #define _PATH_ZONEINFO TZDIR /* from tzfile.h */ /* * sysconf -- * get configurable system variables. * * XXX * POSIX 1003.1 (ISO/IEC 9945-1, 4.8.1.3) states that the variable values * not change during the lifetime of the calling process. This would seem * to require that any change to system limits kill all running processes. * A workaround might be to cache the values when they are first retrieved * and then simply return the cached value on subsequent calls. This is * less useful than returning up-to-date values, however. */ long sysconf(int name) { struct rlimit rl; size_t len; int mib[2], sverrno, value; long lvalue, defaultresult; const char *path; defaultresult = -1; switch (name) { case _SC_ARG_MAX: mib[0] = CTL_KERN; mib[1] = KERN_ARGMAX; break; case _SC_CHILD_MAX: if (getrlimit(RLIMIT_NPROC, &rl) != 0) return (-1); if (rl.rlim_cur == RLIM_INFINITY) return (-1); if (rl.rlim_cur > LONG_MAX) { errno = EOVERFLOW; return (-1); } return ((long)rl.rlim_cur); case _SC_CLK_TCK: return (CLK_TCK); case _SC_NGROUPS_MAX: mib[0] = CTL_KERN; mib[1] = KERN_NGROUPS; break; case _SC_OPEN_MAX: if (getrlimit(RLIMIT_NOFILE, &rl) != 0) return (-1); if (rl.rlim_cur == RLIM_INFINITY) return (-1); if (rl.rlim_cur > LONG_MAX) { errno = EOVERFLOW; return (-1); } return ((long)rl.rlim_cur); case _SC_STREAM_MAX: if (getrlimit(RLIMIT_NOFILE, &rl) != 0) return (-1); if (rl.rlim_cur == RLIM_INFINITY) return (-1); if (rl.rlim_cur > LONG_MAX) { errno = EOVERFLOW; return (-1); } /* * struct __sFILE currently has a limitation that * file descriptors must fit in a signed short. * This doesn't precisely capture the letter of POSIX * but approximates the spirit. */ if (rl.rlim_cur > SHRT_MAX) return (SHRT_MAX); return ((long)rl.rlim_cur); case _SC_JOB_CONTROL: return (_POSIX_JOB_CONTROL); case _SC_SAVED_IDS: /* XXX - must be 1 */ mib[0] = CTL_KERN; mib[1] = KERN_SAVED_IDS; goto yesno; case _SC_VERSION: mib[0] = CTL_KERN; mib[1] = KERN_POSIX1; break; case _SC_BC_BASE_MAX: return (BC_BASE_MAX); case _SC_BC_DIM_MAX: return (BC_DIM_MAX); case _SC_BC_SCALE_MAX: return (BC_SCALE_MAX); case _SC_BC_STRING_MAX: return (BC_STRING_MAX); case _SC_COLL_WEIGHTS_MAX: return (COLL_WEIGHTS_MAX); case _SC_EXPR_NEST_MAX: return (EXPR_NEST_MAX); case _SC_LINE_MAX: return (LINE_MAX); case _SC_RE_DUP_MAX: return (RE_DUP_MAX); case _SC_2_VERSION: /* * This is something of a lie, but it would be silly at * this point to try to deduce this from the contents * of the filesystem. */ return (_POSIX2_VERSION); case _SC_2_C_BIND: return (_POSIX2_C_BIND); case _SC_2_C_DEV: return (_POSIX2_C_DEV); case _SC_2_CHAR_TERM: return (_POSIX2_CHAR_TERM); case _SC_2_FORT_DEV: return (_POSIX2_FORT_DEV); case _SC_2_FORT_RUN: return (_POSIX2_FORT_RUN); case _SC_2_LOCALEDEF: return (_POSIX2_LOCALEDEF); case _SC_2_SW_DEV: return (_POSIX2_SW_DEV); case _SC_2_UPE: return (_POSIX2_UPE); case _SC_TZNAME_MAX: path = _PATH_ZONEINFO; do_NAME_MAX: sverrno = errno; errno = 0; lvalue = pathconf(path, _PC_NAME_MAX); if (lvalue == -1 && errno != 0) return (-1); errno = sverrno; return (lvalue); case _SC_ASYNCHRONOUS_IO: #if _POSIX_ASYNCHRONOUS_IO == 0 mib[0] = CTL_P1003_1B; mib[1] = CTL_P1003_1B_ASYNCHRONOUS_IO; break; #else return (_POSIX_ASYNCHRONOUS_IO); #endif case _SC_MAPPED_FILES: return (_POSIX_MAPPED_FILES); case _SC_MEMLOCK: return (_POSIX_MEMLOCK); case _SC_MEMLOCK_RANGE: return (_POSIX_MEMLOCK_RANGE); case _SC_MEMORY_PROTECTION: return (_POSIX_MEMORY_PROTECTION); case _SC_MESSAGE_PASSING: #if _POSIX_MESSAGE_PASSING == 0 mib[0] = CTL_P1003_1B; mib[1] = CTL_P1003_1B_MESSAGE_PASSING; goto yesno; #else return (_POSIX_MESSAGE_PASSING); #endif case _SC_PRIORITIZED_IO: #if _POSIX_PRIORITIZED_IO == 0 mib[0] = CTL_P1003_1B; mib[1] = CTL_P1003_1B_PRIORITIZED_IO; goto yesno; #else return (_POSIX_PRIORITIZED_IO); #endif case _SC_PRIORITY_SCHEDULING: #if _POSIX_PRIORITY_SCHEDULING == 0 mib[0] = CTL_P1003_1B; mib[1] = CTL_P1003_1B_PRIORITY_SCHEDULING; goto yesno; #else return (_POSIX_PRIORITY_SCHEDULING); #endif case _SC_REALTIME_SIGNALS: #if _POSIX_REALTIME_SIGNALS == 0 mib[0] = CTL_P1003_1B; mib[1] = CTL_P1003_1B_REALTIME_SIGNALS; goto yesno; #else return (_POSIX_REALTIME_SIGNALS); #endif case _SC_SEMAPHORES: #if _POSIX_SEMAPHORES == 0 mib[0] = CTL_P1003_1B; mib[1] = CTL_P1003_1B_SEMAPHORES; goto yesno; #else return (_POSIX_SEMAPHORES); #endif case _SC_FSYNC: return (_POSIX_FSYNC); case _SC_SHARED_MEMORY_OBJECTS: return (_POSIX_SHARED_MEMORY_OBJECTS); case _SC_SYNCHRONIZED_IO: #if _POSIX_SYNCHRONIZED_IO == 0 mib[0] = CTL_P1003_1B; mib[1] = CTL_P1003_1B_SYNCHRONIZED_IO; goto yesno; #else return (_POSIX_SYNCHRONIZED_IO); #endif case _SC_TIMERS: #if _POSIX_TIMERS == 0 mib[0] = CTL_P1003_1B; mib[1] = CTL_P1003_1B_TIMERS; goto yesno; #else return (_POSIX_TIMERS); #endif case _SC_AIO_LISTIO_MAX: mib[0] = CTL_P1003_1B; mib[1] = CTL_P1003_1B_AIO_LISTIO_MAX; break; case _SC_AIO_MAX: mib[0] = CTL_P1003_1B; mib[1] = CTL_P1003_1B_AIO_MAX; break; case _SC_AIO_PRIO_DELTA_MAX: mib[0] = CTL_P1003_1B; mib[1] = CTL_P1003_1B_AIO_PRIO_DELTA_MAX; break; case _SC_DELAYTIMER_MAX: mib[0] = CTL_P1003_1B; mib[1] = CTL_P1003_1B_DELAYTIMER_MAX; goto yesno; case _SC_MQ_OPEN_MAX: mib[0] = CTL_P1003_1B; mib[1] = CTL_P1003_1B_MQ_OPEN_MAX; goto yesno; case _SC_PAGESIZE: defaultresult = getpagesize(); mib[0] = CTL_P1003_1B; mib[1] = CTL_P1003_1B_PAGESIZE; goto yesno; case _SC_RTSIG_MAX: mib[0] = CTL_P1003_1B; mib[1] = CTL_P1003_1B_RTSIG_MAX; goto yesno; case _SC_SEM_NSEMS_MAX: return (-1); case _SC_SEM_VALUE_MAX: return (SEM_VALUE_MAX); case _SC_SIGQUEUE_MAX: mib[0] = CTL_P1003_1B; mib[1] = CTL_P1003_1B_SIGQUEUE_MAX; goto yesno; case _SC_TIMER_MAX: mib[0] = CTL_P1003_1B; mib[1] = CTL_P1003_1B_TIMER_MAX; yesno: len = sizeof(value); if (sysctl(mib, 2, &value, &len, NULL, 0) == -1) return (-1); if (value == 0) return (defaultresult); return ((long)value); case _SC_2_PBS: case _SC_2_PBS_ACCOUNTING: case _SC_2_PBS_CHECKPOINT: case _SC_2_PBS_LOCATE: case _SC_2_PBS_MESSAGE: case _SC_2_PBS_TRACK: #if _POSIX2_PBS == 0 #error "don't know how to determine _SC_2_PBS" /* * This probably requires digging through the filesystem * to see if the appropriate package has been installed. * Since we don't currently support this option at all, * it's not worth the effort to write the code now. * Figuring out which of the sub-options are supported * would be even more difficult, so it's probably easier * to always say ``no''. */ #else return (_POSIX2_PBS); #endif case _SC_ADVISORY_INFO: #if _POSIX_ADVISORY_INFO == 0 #error "_POSIX_ADVISORY_INFO" #else return (_POSIX_ADVISORY_INFO); #endif case _SC_BARRIERS: #if _POSIX_BARRIERS == 0 #error "_POSIX_BARRIERS" #else return (_POSIX_BARRIERS); #endif case _SC_CLOCK_SELECTION: #if _POSIX_CLOCK_SELECTION == 0 #error "_POSIX_CLOCK_SELECTION" #else return (_POSIX_CLOCK_SELECTION); #endif case _SC_CPUTIME: return (_POSIX_CPUTIME); #ifdef notdef case _SC_FILE_LOCKING: /* * XXX - The standard doesn't tell us how to define * _POSIX_FILE_LOCKING, so we can't answer this one. */ #endif /* * SUSv4tc1 says the following about _SC_GETGR_R_SIZE_MAX and * _SC_GETPW_R_SIZE_MAX: * Note that sysconf(_SC_GETGR_R_SIZE_MAX) may return -1 if * there is no hard limit on the size of the buffer needed to * store all the groups returned. */ case _SC_GETGR_R_SIZE_MAX: case _SC_GETPW_R_SIZE_MAX: return (-1); case _SC_HOST_NAME_MAX: return (MAXHOSTNAMELEN - 1); /* does not include \0 */ case _SC_LOGIN_NAME_MAX: return (MAXLOGNAME); case _SC_MONOTONIC_CLOCK: #if _POSIX_MONOTONIC_CLOCK == 0 #error "_POSIX_MONOTONIC_CLOCK" #else return (_POSIX_MONOTONIC_CLOCK); #endif #if _POSIX_MESSAGE_PASSING > -1 case _SC_MQ_PRIO_MAX: return (MQ_PRIO_MAX); #endif case _SC_READER_WRITER_LOCKS: return (_POSIX_READER_WRITER_LOCKS); case _SC_REGEXP: return (_POSIX_REGEXP); case _SC_SHELL: return (_POSIX_SHELL); case _SC_SPAWN: return (_POSIX_SPAWN); case _SC_SPIN_LOCKS: return (_POSIX_SPIN_LOCKS); case _SC_SPORADIC_SERVER: #if _POSIX_SPORADIC_SERVER == 0 #error "_POSIX_SPORADIC_SERVER" #else return (_POSIX_SPORADIC_SERVER); #endif case _SC_THREAD_ATTR_STACKADDR: return (_POSIX_THREAD_ATTR_STACKADDR); case _SC_THREAD_ATTR_STACKSIZE: return (_POSIX_THREAD_ATTR_STACKSIZE); case _SC_THREAD_CPUTIME: return (_POSIX_THREAD_CPUTIME); case _SC_THREAD_DESTRUCTOR_ITERATIONS: return (PTHREAD_DESTRUCTOR_ITERATIONS); case _SC_THREAD_KEYS_MAX: return (PTHREAD_KEYS_MAX); case _SC_THREAD_PRIO_INHERIT: return (_POSIX_THREAD_PRIO_INHERIT); case _SC_THREAD_PRIO_PROTECT: return (_POSIX_THREAD_PRIO_PROTECT); case _SC_THREAD_PRIORITY_SCHEDULING: return (_POSIX_THREAD_PRIORITY_SCHEDULING); case _SC_THREAD_PROCESS_SHARED: return (_POSIX_THREAD_PROCESS_SHARED); case _SC_THREAD_SAFE_FUNCTIONS: return (_POSIX_THREAD_SAFE_FUNCTIONS); case _SC_THREAD_STACK_MIN: return (PTHREAD_STACK_MIN); case _SC_THREAD_THREADS_MAX: return (PTHREAD_THREADS_MAX); /* XXX wrong type! */ case _SC_TIMEOUTS: return (_POSIX_TIMEOUTS); case _SC_THREADS: return (_POSIX_THREADS); case _SC_TRACE: #if _POSIX_TRACE == 0 #error "_POSIX_TRACE" /* While you're implementing this, also do the ones below. */ #else return (_POSIX_TRACE); #endif #if _POSIX_TRACE > -1 case _SC_TRACE_EVENT_FILTER: return (_POSIX_TRACE_EVENT_FILTER); case _SC_TRACE_INHERIT: return (_POSIX_TRACE_INHERIT); case _SC_TRACE_LOG: return (_POSIX_TRACE_LOG); #endif case _SC_TTY_NAME_MAX: path = _PATH_DEV; goto do_NAME_MAX; case _SC_TYPED_MEMORY_OBJECTS: #if _POSIX_TYPED_MEMORY_OBJECTS == 0 #error "_POSIX_TYPED_MEMORY_OBJECTS" #else return (_POSIX_TYPED_MEMORY_OBJECTS); #endif case _SC_V6_ILP32_OFF32: #if _V6_ILP32_OFF32 == 0 if (sizeof(int) * CHAR_BIT == 32 && sizeof(int) == sizeof(long) && sizeof(long) == sizeof(void *) && sizeof(void *) == sizeof(off_t)) return 1; else return -1; #else return (_V6_ILP32_OFF32); #endif case _SC_V6_ILP32_OFFBIG: #if _V6_ILP32_OFFBIG == 0 if (sizeof(int) * CHAR_BIT == 32 && sizeof(int) == sizeof(long) && sizeof(long) == sizeof(void *) && sizeof(off_t) * CHAR_BIT >= 64) return 1; else return -1; #else return (_V6_ILP32_OFFBIG); #endif case _SC_V6_LP64_OFF64: #if _V6_LP64_OFF64 == 0 if (sizeof(int) * CHAR_BIT == 32 && sizeof(long) * CHAR_BIT == 64 && sizeof(long) == sizeof(void *) && sizeof(void *) == sizeof(off_t)) return 1; else return -1; #else return (_V6_LP64_OFF64); #endif case _SC_V6_LPBIG_OFFBIG: #if _V6_LPBIG_OFFBIG == 0 if (sizeof(int) * CHAR_BIT >= 32 && sizeof(long) * CHAR_BIT >= 64 && sizeof(void *) * CHAR_BIT >= 64 && sizeof(off_t) * CHAR_BIT >= 64) return 1; else return -1; #else return (_V6_LPBIG_OFFBIG); #endif case _SC_ATEXIT_MAX: return (ATEXIT_SIZE); case _SC_IOV_MAX: mib[0] = CTL_KERN; mib[1] = KERN_IOV_MAX; break; case _SC_XOPEN_CRYPT: return (_XOPEN_CRYPT); case _SC_XOPEN_ENH_I18N: return (_XOPEN_ENH_I18N); case _SC_XOPEN_LEGACY: return (_XOPEN_LEGACY); case _SC_XOPEN_REALTIME: #if _XOPEN_REALTIME == 0 sverrno = errno; value = sysconf(_SC_ASYNCHRONOUS_IO) > 0 && sysconf(_SC_MEMLOCK) > 0 && sysconf(_SC_MEMLOCK_RANGE) > 0 && sysconf(_SC_MESSAGE_PASSING) > 0 && sysconf(_SC_PRIORITY_SCHEDULING) > 0 && sysconf(_SC_REALTIME_SIGNALS) > 0 && sysconf(_SC_SEMAPHORES) > 0 && sysconf(_SC_SHARED_MEMORY_OBJECTS) > 0 && sysconf(_SC_SYNCHRONIZED_IO) > 0 && sysconf(_SC_TIMERS) > 0; errno = sverrno; if (value) return (200112L); else return (-1); #else return (_XOPEN_REALTIME); #endif case _SC_XOPEN_REALTIME_THREADS: #if _XOPEN_REALTIME_THREADS == 0 #error "_XOPEN_REALTIME_THREADS" #else return (_XOPEN_REALTIME_THREADS); #endif case _SC_XOPEN_SHM: len = sizeof(lvalue); sverrno = errno; if (sysctlbyname("kern.ipc.shmmin", &lvalue, &len, NULL, 0) == -1) { errno = sverrno; return (-1); } errno = sverrno; return (1); case _SC_XOPEN_STREAMS: return (_XOPEN_STREAMS); case _SC_XOPEN_UNIX: return (_XOPEN_UNIX); #ifdef _XOPEN_VERSION case _SC_XOPEN_VERSION: return (_XOPEN_VERSION); #endif #ifdef _XOPEN_XCU_VERSION case _SC_XOPEN_XCU_VERSION: return (_XOPEN_XCU_VERSION); #endif case _SC_SYMLOOP_MAX: return (MAXSYMLINKS); case _SC_RAW_SOCKETS: return (_POSIX_RAW_SOCKETS); case _SC_IPV6: #if _POSIX_IPV6 == 0 sverrno = errno; value = _socket(PF_INET6, SOCK_DGRAM, 0); errno = sverrno; if (value >= 0) { _close(value); return (200112L); } else return (0); #else return (_POSIX_IPV6); #endif case _SC_NPROCESSORS_CONF: case _SC_NPROCESSORS_ONLN: if (_elf_aux_info(AT_NCPUS, &value, sizeof(value)) == 0) return ((long)value); mib[0] = CTL_HW; mib[1] = HW_NCPU; break; #ifdef _SC_PHYS_PAGES case _SC_PHYS_PAGES: len = sizeof(lvalue); if (sysctlbyname("hw.availpages", &lvalue, &len, NULL, 0) == -1) return (-1); return (lvalue); #endif #ifdef _SC_CPUSET_SIZE case _SC_CPUSET_SIZE: len = sizeof(value); if (sysctlbyname("kern.sched.cpusetsize", &value, &len, NULL, 0) == -1) return (-1); return ((long)value); #endif default: errno = EINVAL; return (-1); } len = sizeof(value); if (sysctl(mib, 2, &value, &len, NULL, 0) == -1) value = -1; return ((long)value); } Index: head/lib/libc/gen/sysctl.c =================================================================== --- head/lib/libc/gen/sysctl.c (revision 335897) +++ head/lib/libc/gen/sysctl.c (revision 335898) @@ -1,197 +1,195 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)sysctl.c 8.2 (Berkeley) 1/4/94"; -#endif /* LIBC_SCCS and not lint */ #include +__SCCSID("@(#)sysctl.c 8.2 (Berkeley) 1/4/94"); __FBSDID("$FreeBSD$"); #include #include #include #include #include #include #include #include extern int __sysctl(const int *name, u_int namelen, void *oldp, size_t *oldlenp, const void *newp, size_t newlen); int sysctl(const int *name, u_int namelen, void *oldp, size_t *oldlenp, const void *newp, size_t newlen) { int retval; size_t orig_oldlen; orig_oldlen = oldlenp ? *oldlenp : 0; retval = __sysctl(name, namelen, oldp, oldlenp, newp, newlen); /* * All valid names under CTL_USER have a dummy entry in the sysctl * tree (to support name lookups and enumerations) with an * empty/zero value, and the true value is supplied by this routine. * For all such names, __sysctl() is used solely to validate the * name. * * Return here unless there was a successful lookup for a CTL_USER * name. */ if (retval || name[0] != CTL_USER) return (retval); if (newp != NULL) { errno = EPERM; return (-1); } if (namelen != 2) { errno = EINVAL; return (-1); } switch (name[1]) { case USER_CS_PATH: if (oldp && orig_oldlen < sizeof(_PATH_STDPATH)) { errno = ENOMEM; return -1; } *oldlenp = sizeof(_PATH_STDPATH); if (oldp != NULL) memmove(oldp, _PATH_STDPATH, sizeof(_PATH_STDPATH)); return (0); } if (oldp && *oldlenp < sizeof(int)) { errno = ENOMEM; return (-1); } *oldlenp = sizeof(int); if (oldp == NULL) return (0); switch (name[1]) { case USER_BC_BASE_MAX: *(int *)oldp = BC_BASE_MAX; return (0); case USER_BC_DIM_MAX: *(int *)oldp = BC_DIM_MAX; return (0); case USER_BC_SCALE_MAX: *(int *)oldp = BC_SCALE_MAX; return (0); case USER_BC_STRING_MAX: *(int *)oldp = BC_STRING_MAX; return (0); case USER_COLL_WEIGHTS_MAX: *(int *)oldp = COLL_WEIGHTS_MAX; return (0); case USER_EXPR_NEST_MAX: *(int *)oldp = EXPR_NEST_MAX; return (0); case USER_LINE_MAX: *(int *)oldp = LINE_MAX; return (0); case USER_RE_DUP_MAX: *(int *)oldp = RE_DUP_MAX; return (0); case USER_POSIX2_VERSION: *(int *)oldp = _POSIX2_VERSION; return (0); case USER_POSIX2_C_BIND: #ifdef POSIX2_C_BIND *(int *)oldp = 1; #else *(int *)oldp = 0; #endif return (0); case USER_POSIX2_C_DEV: #ifdef POSIX2_C_DEV *(int *)oldp = 1; #else *(int *)oldp = 0; #endif return (0); case USER_POSIX2_CHAR_TERM: #ifdef POSIX2_CHAR_TERM *(int *)oldp = 1; #else *(int *)oldp = 0; #endif return (0); case USER_POSIX2_FORT_DEV: #ifdef POSIX2_FORT_DEV *(int *)oldp = 1; #else *(int *)oldp = 0; #endif return (0); case USER_POSIX2_FORT_RUN: #ifdef POSIX2_FORT_RUN *(int *)oldp = 1; #else *(int *)oldp = 0; #endif return (0); case USER_POSIX2_LOCALEDEF: #ifdef POSIX2_LOCALEDEF *(int *)oldp = 1; #else *(int *)oldp = 0; #endif return (0); case USER_POSIX2_SW_DEV: #ifdef POSIX2_SW_DEV *(int *)oldp = 1; #else *(int *)oldp = 0; #endif return (0); case USER_POSIX2_UPE: #ifdef POSIX2_UPE *(int *)oldp = 1; #else *(int *)oldp = 0; #endif return (0); case USER_STREAM_MAX: *(int *)oldp = FOPEN_MAX; return (0); case USER_TZNAME_MAX: *(int *)oldp = NAME_MAX; return (0); default: errno = EINVAL; return (-1); } /* NOTREACHED */ } Index: head/lib/libc/gen/syslog.c =================================================================== --- head/lib/libc/gen/syslog.c (revision 335897) +++ head/lib/libc/gen/syslog.c (revision 335898) @@ -1,488 +1,486 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1983, 1988, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)syslog.c 8.5 (Berkeley) 4/29/95"; -#endif /* LIBC_SCCS and not lint */ #include +__SCCSID("@(#)syslog.c 8.5 (Berkeley) 4/29/95"); __FBSDID("$FreeBSD$"); #include "namespace.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "un-namespace.h" #include "libc_private.h" static int LogFile = -1; /* fd for log */ static int status; /* connection status */ static int opened; /* have done openlog() */ static int LogStat = 0; /* status bits, set by openlog() */ static const char *LogTag = NULL; /* string to tag the entry with */ static int LogFacility = LOG_USER; /* default facility code */ static int LogMask = 0xff; /* mask of priorities to be logged */ static pthread_mutex_t syslog_mutex = PTHREAD_MUTEX_INITIALIZER; #define THREAD_LOCK() \ do { \ if (__isthreaded) _pthread_mutex_lock(&syslog_mutex); \ } while(0) #define THREAD_UNLOCK() \ do { \ if (__isthreaded) _pthread_mutex_unlock(&syslog_mutex); \ } while(0) static void disconnectlog(void); /* disconnect from syslogd */ static void connectlog(void); /* (re)connect to syslogd */ static void openlog_unlocked(const char *, int, int); enum { NOCONN = 0, CONNDEF, CONNPRIV, }; /* * Format of the magic cookie passed through the stdio hook */ struct bufcookie { char *base; /* start of buffer */ int left; }; /* * stdio write hook for writing to a static string buffer * XXX: Maybe one day, dynamically allocate it so that the line length * is `unlimited'. */ static int writehook(void *cookie, const char *buf, int len) { struct bufcookie *h; /* private `handle' */ h = (struct bufcookie *)cookie; if (len > h->left) { /* clip in case of wraparound */ len = h->left; } if (len > 0) { (void)memcpy(h->base, buf, len); /* `write' it. */ h->base += len; h->left -= len; } return len; } /* * syslog, vsyslog -- * print message on log file; output is intended for syslogd(8). */ void syslog(int pri, const char *fmt, ...) { va_list ap; va_start(ap, fmt); vsyslog(pri, fmt, ap); va_end(ap); } static void vsyslog1(int pri, const char *fmt, va_list ap) { struct timeval now; struct tm tm; char ch, *p; long tz_offset; int cnt, fd, saved_errno; char hostname[MAXHOSTNAMELEN], *stdp, tbuf[2048], fmt_cpy[1024], errstr[64], tz_sign; FILE *fp, *fmt_fp; struct bufcookie tbuf_cookie; struct bufcookie fmt_cookie; #define INTERNALLOG LOG_ERR|LOG_CONS|LOG_PERROR|LOG_PID /* Check for invalid bits. */ if (pri & ~(LOG_PRIMASK|LOG_FACMASK)) { syslog(INTERNALLOG, "syslog: unknown facility/priority: %x", pri); pri &= LOG_PRIMASK|LOG_FACMASK; } saved_errno = errno; /* Check priority against setlogmask values. */ if (!(LOG_MASK(LOG_PRI(pri)) & LogMask)) return; /* Set default facility if none specified. */ if ((pri & LOG_FACMASK) == 0) pri |= LogFacility; /* Create the primary stdio hook */ tbuf_cookie.base = tbuf; tbuf_cookie.left = sizeof(tbuf); fp = fwopen(&tbuf_cookie, writehook); if (fp == NULL) return; /* Build the message according to RFC 5424. Tag and version. */ (void)fprintf(fp, "<%d>1 ", pri); /* Timestamp similar to RFC 3339. */ if (gettimeofday(&now, NULL) == 0 && localtime_r(&now.tv_sec, &tm) != NULL) { if (tm.tm_gmtoff < 0) { tz_sign = '-'; tz_offset = -tm.tm_gmtoff; } else { tz_sign = '+'; tz_offset = tm.tm_gmtoff; } (void)fprintf(fp, "%04d-%02d-%02d" /* Date. */ "T%02d:%02d:%02d.%06ld" /* Time. */ "%c%02ld:%02ld ", /* Time zone offset. */ tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, now.tv_usec, tz_sign, tz_offset / 3600, (tz_offset % 3600) / 60); } else (void)fprintf(fp, "- "); /* Hostname. */ (void)gethostname(hostname, sizeof(hostname)); (void)fprintf(fp, "%s ", hostname); if (LogStat & LOG_PERROR) { /* Transfer to string buffer */ (void)fflush(fp); stdp = tbuf + (sizeof(tbuf) - tbuf_cookie.left); } /* * Application name, process ID, message ID and structured data. * Provide the process ID regardless of whether LOG_PID has been * specified, as it provides valuable information. Many * applications tend not to use this, even though they should. */ if (LogTag == NULL) LogTag = _getprogname(); (void)fprintf(fp, "%s %d - - ", LogTag == NULL ? "-" : LogTag, getpid()); /* Check to see if we can skip expanding the %m */ if (strstr(fmt, "%m")) { /* Create the second stdio hook */ fmt_cookie.base = fmt_cpy; fmt_cookie.left = sizeof(fmt_cpy) - 1; fmt_fp = fwopen(&fmt_cookie, writehook); if (fmt_fp == NULL) { fclose(fp); return; } /* * Substitute error message for %m. Be careful not to * molest an escaped percent "%%m". We want to pass it * on untouched as the format is later parsed by vfprintf. */ for ( ; (ch = *fmt); ++fmt) { if (ch == '%' && fmt[1] == 'm') { ++fmt; strerror_r(saved_errno, errstr, sizeof(errstr)); fputs(errstr, fmt_fp); } else if (ch == '%' && fmt[1] == '%') { ++fmt; fputc(ch, fmt_fp); fputc(ch, fmt_fp); } else { fputc(ch, fmt_fp); } } /* Null terminate if room */ fputc(0, fmt_fp); fclose(fmt_fp); /* Guarantee null termination */ fmt_cpy[sizeof(fmt_cpy) - 1] = '\0'; fmt = fmt_cpy; } (void)vfprintf(fp, fmt, ap); (void)fclose(fp); cnt = sizeof(tbuf) - tbuf_cookie.left; /* Remove a trailing newline */ if (tbuf[cnt - 1] == '\n') cnt--; /* Output to stderr if requested. */ if (LogStat & LOG_PERROR) { struct iovec iov[2]; struct iovec *v = iov; v->iov_base = stdp; v->iov_len = cnt - (stdp - tbuf); ++v; v->iov_base = "\n"; v->iov_len = 1; (void)_writev(STDERR_FILENO, iov, 2); } /* Get connected, output the message to the local logger. */ if (!opened) openlog_unlocked(LogTag, LogStat | LOG_NDELAY, 0); connectlog(); /* * If the send() fails, there are two likely scenarios: * 1) syslogd was restarted * 2) /var/run/log is out of socket buffer space, which * in most cases means local DoS. * If the error does not indicate a full buffer, we address * case #1 by attempting to reconnect to /var/run/log[priv] * and resending the message once. * * If we are working with a privileged socket, the retry * attempts end there, because we don't want to freeze a * critical application like su(1) or sshd(8). * * Otherwise, we address case #2 by repeatedly retrying the * send() to give syslogd a chance to empty its socket buffer. */ if (send(LogFile, tbuf, cnt, 0) < 0) { if (errno != ENOBUFS) { /* * Scenario 1: syslogd was restarted * reconnect and resend once */ disconnectlog(); connectlog(); if (send(LogFile, tbuf, cnt, 0) >= 0) return; /* * if the resend failed, fall through to * possible scenario 2 */ } while (errno == ENOBUFS) { /* * Scenario 2: out of socket buffer space * possible DoS, fail fast on a privileged * socket */ if (status == CONNPRIV) break; _usleep(1); if (send(LogFile, tbuf, cnt, 0) >= 0) return; } } else return; /* * Output the message to the console; try not to block * as a blocking console should not stop other processes. * Make sure the error reported is the one from the syslogd failure. */ if (LogStat & LOG_CONS && (fd = _open(_PATH_CONSOLE, O_WRONLY|O_NONBLOCK|O_CLOEXEC, 0)) >= 0) { struct iovec iov[2]; struct iovec *v = iov; p = strchr(tbuf, '>') + 3; v->iov_base = p; v->iov_len = cnt - (p - tbuf); ++v; v->iov_base = "\r\n"; v->iov_len = 2; (void)_writev(fd, iov, 2); (void)_close(fd); } } static void syslog_cancel_cleanup(void *arg __unused) { THREAD_UNLOCK(); } void vsyslog(int pri, const char *fmt, va_list ap) { THREAD_LOCK(); pthread_cleanup_push(syslog_cancel_cleanup, NULL); vsyslog1(pri, fmt, ap); pthread_cleanup_pop(1); } /* Should be called with mutex acquired */ static void disconnectlog(void) { /* * If the user closed the FD and opened another in the same slot, * that's their problem. They should close it before calling on * system services. */ if (LogFile != -1) { _close(LogFile); LogFile = -1; } status = NOCONN; /* retry connect */ } /* Should be called with mutex acquired */ static void connectlog(void) { struct sockaddr_un SyslogAddr; /* AF_UNIX address of local logger */ if (LogFile == -1) { if ((LogFile = _socket(AF_UNIX, SOCK_DGRAM | SOCK_CLOEXEC, 0)) == -1) return; } if (LogFile != -1 && status == NOCONN) { SyslogAddr.sun_len = sizeof(SyslogAddr); SyslogAddr.sun_family = AF_UNIX; /* * First try privileged socket. If no success, * then try default socket. */ (void)strncpy(SyslogAddr.sun_path, _PATH_LOG_PRIV, sizeof SyslogAddr.sun_path); if (_connect(LogFile, (struct sockaddr *)&SyslogAddr, sizeof(SyslogAddr)) != -1) status = CONNPRIV; if (status == NOCONN) { (void)strncpy(SyslogAddr.sun_path, _PATH_LOG, sizeof SyslogAddr.sun_path); if (_connect(LogFile, (struct sockaddr *)&SyslogAddr, sizeof(SyslogAddr)) != -1) status = CONNDEF; } if (status == NOCONN) { /* * Try the old "/dev/log" path, for backward * compatibility. */ (void)strncpy(SyslogAddr.sun_path, _PATH_OLDLOG, sizeof SyslogAddr.sun_path); if (_connect(LogFile, (struct sockaddr *)&SyslogAddr, sizeof(SyslogAddr)) != -1) status = CONNDEF; } if (status == NOCONN) { (void)_close(LogFile); LogFile = -1; } } } static void openlog_unlocked(const char *ident, int logstat, int logfac) { if (ident != NULL) LogTag = ident; LogStat = logstat; if (logfac != 0 && (logfac &~ LOG_FACMASK) == 0) LogFacility = logfac; if (LogStat & LOG_NDELAY) /* open immediately */ connectlog(); opened = 1; /* ident and facility has been set */ } void openlog(const char *ident, int logstat, int logfac) { THREAD_LOCK(); pthread_cleanup_push(syslog_cancel_cleanup, NULL); openlog_unlocked(ident, logstat, logfac); pthread_cleanup_pop(1); } void closelog(void) { THREAD_LOCK(); if (LogFile != -1) { (void)_close(LogFile); LogFile = -1; } LogTag = NULL; status = NOCONN; THREAD_UNLOCK(); } /* setlogmask -- set the log mask level */ int setlogmask(int pmask) { int omask; THREAD_LOCK(); omask = LogMask; if (pmask != 0) LogMask = pmask; THREAD_UNLOCK(); return (omask); } Index: head/lib/libc/gen/telldir.c =================================================================== --- head/lib/libc/gen/telldir.c (revision 335897) +++ head/lib/libc/gen/telldir.c (revision 335898) @@ -1,210 +1,208 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1983, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)telldir.c 8.1 (Berkeley) 6/4/93"; -#endif /* LIBC_SCCS and not lint */ #include +__SCCSID("@(#)telldir.c 8.1 (Berkeley) 6/4/93"); __FBSDID("$FreeBSD$"); #include "namespace.h" #include #include #include #include #include #include #include "un-namespace.h" #include "libc_private.h" #include "gen-private.h" #include "telldir.h" /* * return a pointer into a directory */ long telldir(DIR *dirp) { struct ddloc_mem *lp, *flp; union ddloc_packed ddloc; if (__isthreaded) _pthread_mutex_lock(&dirp->dd_lock); /* * Outline: * 1) If the directory position fits in a packed structure, return that. * 2) Otherwise, see if it's already been recorded in the linked list * 3) Otherwise, malloc a new one */ if (dirp->dd_seek < (1ul << DD_SEEK_BITS) && dirp->dd_loc < (1ul << DD_LOC_BITS)) { ddloc.s.is_packed = 1; ddloc.s.loc = dirp->dd_loc; ddloc.s.seek = dirp->dd_seek; goto out; } flp = NULL; LIST_FOREACH(lp, &dirp->dd_td->td_locq, loc_lqe) { if (lp->loc_seek == dirp->dd_seek) { if (flp == NULL) flp = lp; if (lp->loc_loc == dirp->dd_loc) break; } else if (flp != NULL) { lp = NULL; break; } } if (lp == NULL) { lp = malloc(sizeof(struct ddloc_mem)); if (lp == NULL) { if (__isthreaded) _pthread_mutex_unlock(&dirp->dd_lock); return (-1); } lp->loc_index = dirp->dd_td->td_loccnt++; lp->loc_seek = dirp->dd_seek; lp->loc_loc = dirp->dd_loc; if (flp != NULL) LIST_INSERT_BEFORE(flp, lp, loc_lqe); else LIST_INSERT_HEAD(&dirp->dd_td->td_locq, lp, loc_lqe); } ddloc.i.is_packed = 0; /* * Technically this assignment could overflow on 32-bit architectures, * but we would get ENOMEM long before that happens. */ ddloc.i.index = lp->loc_index; out: if (__isthreaded) _pthread_mutex_unlock(&dirp->dd_lock); return (ddloc.l); } /* * seek to an entry in a directory. * Only values returned by "telldir" should be passed to seekdir. */ void _seekdir(DIR *dirp, long loc) { struct ddloc_mem *lp; struct dirent *dp; union ddloc_packed ddloc; off_t loc_seek; long loc_loc; ddloc.l = loc; if (ddloc.s.is_packed) { loc_seek = ddloc.s.seek; loc_loc = ddloc.s.loc; } else { LIST_FOREACH(lp, &dirp->dd_td->td_locq, loc_lqe) { if (lp->loc_index == ddloc.i.index) break; } if (lp == NULL) return; loc_seek = lp->loc_seek; loc_loc = lp->loc_loc; } if (loc_loc == dirp->dd_loc && loc_seek == dirp->dd_seek) return; /* If it's within the same chunk of data, don't bother reloading. */ if (loc_seek == dirp->dd_seek) { /* * If we go back to 0 don't make the next readdir * trigger a call to getdirentries(). */ if (loc_loc == 0) dirp->dd_flags |= __DTF_SKIPREAD; dirp->dd_loc = loc_loc; return; } (void) lseek(dirp->dd_fd, (off_t)loc_seek, SEEK_SET); dirp->dd_seek = loc_seek; dirp->dd_loc = 0; dirp->dd_flags &= ~__DTF_SKIPREAD; /* current contents are invalid */ while (dirp->dd_loc < loc_loc) { dp = _readdir_unlocked(dirp, 0); if (dp == NULL) break; } } /* * After readdir returns the last entry in a block, a call to telldir * returns a location that is after the end of that last entry. * However, that location doesn't refer to a valid directory entry. * Ideally, the call to telldir would return a location that refers to * the first entry in the next block. That location is not known * until the next block is read, so readdir calls this function after * fetching a new block to fix any such telldir locations. */ void _fixtelldir(DIR *dirp, long oldseek, long oldloc) { struct ddloc_mem *lp; lp = LIST_FIRST(&dirp->dd_td->td_locq); if (lp != NULL) { if (lp->loc_loc == oldloc && lp->loc_seek == oldseek) { lp->loc_seek = dirp->dd_seek; lp->loc_loc = dirp->dd_loc; } } } /* * Reclaim memory for telldir cookies which weren't used. */ void _reclaim_telldir(DIR *dirp) { struct ddloc_mem *lp; struct ddloc_mem *templp; lp = LIST_FIRST(&dirp->dd_td->td_locq); while (lp != NULL) { templp = lp; lp = LIST_NEXT(lp, loc_lqe); free(templp); } LIST_INIT(&dirp->dd_td->td_locq); } Index: head/lib/libc/gen/termios.c =================================================================== --- head/lib/libc/gen/termios.c (revision 335897) +++ head/lib/libc/gen/termios.c (revision 335898) @@ -1,279 +1,277 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1989, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)termios.c 8.2 (Berkeley) 2/21/94"; -#endif /* LIBC_SCCS and not lint */ #include +__SCCSID("@(#)termios.c 8.2 (Berkeley) 2/21/94"); __FBSDID("$FreeBSD$"); #include "namespace.h" #include #include #include #include #include #include #define TTYDEFCHARS #include #include #include "un-namespace.h" #include "libc_private.h" int tcgetattr(int fd, struct termios *t) { return (_ioctl(fd, TIOCGETA, t)); } int tcsetattr(int fd, int opt, const struct termios *t) { struct termios localterm; if (opt & TCSASOFT) { localterm = *t; localterm.c_cflag |= CIGNORE; t = &localterm; } switch (opt & ~TCSASOFT) { case TCSANOW: return (_ioctl(fd, TIOCSETA, t)); case TCSADRAIN: return (_ioctl(fd, TIOCSETAW, t)); case TCSAFLUSH: return (_ioctl(fd, TIOCSETAF, t)); default: errno = EINVAL; return (-1); } } int tcsetpgrp(int fd, pid_t pgrp) { int s; s = pgrp; return (_ioctl(fd, TIOCSPGRP, &s)); } pid_t tcgetpgrp(int fd) { int s; if (_ioctl(fd, TIOCGPGRP, &s) < 0) return ((pid_t)-1); return ((pid_t)s); } pid_t tcgetsid(int fd) { int s; if (_ioctl(fd, TIOCGSID, &s) < 0) return ((pid_t)-1); return ((pid_t)s); } int tcsetsid(int fd, pid_t pid) { if (pid != getsid(0)) { errno = EINVAL; return (-1); } return (_ioctl(fd, TIOCSCTTY, NULL)); } speed_t cfgetospeed(const struct termios *t) { return (t->c_ospeed); } speed_t cfgetispeed(const struct termios *t) { return (t->c_ispeed); } int cfsetospeed(struct termios *t, speed_t speed) { t->c_ospeed = speed; return (0); } int cfsetispeed(struct termios *t, speed_t speed) { t->c_ispeed = speed; return (0); } int cfsetspeed(struct termios *t, speed_t speed) { t->c_ispeed = t->c_ospeed = speed; return (0); } /* * Make a pre-existing termios structure into "raw" mode: character-at-a-time * mode with no characters interpreted, 8-bit data path. */ void cfmakeraw(struct termios *t) { t->c_iflag &= ~(IMAXBEL|IXOFF|INPCK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON|IGNPAR); t->c_iflag |= IGNBRK; t->c_oflag &= ~OPOST; t->c_lflag &= ~(ECHO|ECHOE|ECHOK|ECHONL|ICANON|ISIG|IEXTEN|NOFLSH|TOSTOP|PENDIN); t->c_cflag &= ~(CSIZE|PARENB); t->c_cflag |= CS8|CREAD; t->c_cc[VMIN] = 1; t->c_cc[VTIME] = 0; } /* * Obtain a termios structure which is similar to the one provided by * the kernel. */ void cfmakesane(struct termios *t) { t->c_cflag = TTYDEF_CFLAG; t->c_iflag = TTYDEF_IFLAG; t->c_lflag = TTYDEF_LFLAG; t->c_oflag = TTYDEF_OFLAG; t->c_ispeed = TTYDEF_SPEED; t->c_ospeed = TTYDEF_SPEED; memcpy(&t->c_cc, ttydefchars, sizeof ttydefchars); } int tcsendbreak(int fd, int len __unused) { struct timeval sleepytime; sleepytime.tv_sec = 0; sleepytime.tv_usec = 400000; if (_ioctl(fd, TIOCSBRK, 0) == -1) return (-1); (void)_select(0, 0, 0, 0, &sleepytime); if (_ioctl(fd, TIOCCBRK, 0) == -1) return (-1); return (0); } int __libc_tcdrain(int fd) { return (_ioctl(fd, TIOCDRAIN, 0)); } #pragma weak tcdrain int tcdrain(int fd) { return (((int (*)(int)) __libc_interposing[INTERPOS_tcdrain])(fd)); } __weak_reference(__libc_tcdrain, __tcdrain); __weak_reference(__libc_tcdrain, _tcdrain); int tcflush(int fd, int which) { int com; switch (which) { case TCIFLUSH: com = FREAD; break; case TCOFLUSH: com = FWRITE; break; case TCIOFLUSH: com = FREAD | FWRITE; break; default: errno = EINVAL; return (-1); } return (_ioctl(fd, TIOCFLUSH, &com)); } int tcflow(int fd, int action) { struct termios term; u_char c; switch (action) { case TCOOFF: return (_ioctl(fd, TIOCSTOP, 0)); case TCOON: return (_ioctl(fd, TIOCSTART, 0)); case TCION: case TCIOFF: if (tcgetattr(fd, &term) == -1) return (-1); c = term.c_cc[action == TCIOFF ? VSTOP : VSTART]; if (c != _POSIX_VDISABLE && _write(fd, &c, sizeof(c)) == -1) return (-1); return (0); default: errno = EINVAL; return (-1); } /* NOTREACHED */ } Index: head/lib/libc/gen/time.c =================================================================== --- head/lib/libc/gen/time.c (revision 335897) +++ head/lib/libc/gen/time.c (revision 335898) @@ -1,54 +1,52 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1983, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)time.c 8.1 (Berkeley) 6/4/93"; -#endif /* LIBC_SCCS and not lint */ #include +__SCCSID("@(#)time.c 8.1 (Berkeley) 6/4/93"); __FBSDID("$FreeBSD$"); #include #include time_t time(time_t *t) { struct timespec tt; time_t retval; if (clock_gettime(CLOCK_SECOND, &tt) < 0) retval = -1; else retval = tt.tv_sec; if (t != NULL) *t = retval; return (retval); } Index: head/lib/libc/gen/times.c =================================================================== --- head/lib/libc/gen/times.c (revision 335897) +++ head/lib/libc/gen/times.c (revision 335898) @@ -1,69 +1,67 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)times.c 8.1 (Berkeley) 6/4/93"; -#endif /* LIBC_SCCS and not lint */ #include +__SCCSID("@(#)times.c 8.1 (Berkeley) 6/4/93"); __FBSDID("$FreeBSD$"); #include #include #include #include /* * Convert usec to clock ticks; could do (usec * CLK_TCK) / 1000000, * but this would overflow if we switch to nanosec. */ #define CONVTCK(r) (r.tv_sec * CLK_TCK + r.tv_usec / (1000000 / CLK_TCK)) clock_t times(tp) struct tms *tp; { struct rusage ru; struct timespec t; clock_t c; if (getrusage(RUSAGE_SELF, &ru) < 0) return ((clock_t)-1); tp->tms_utime = CONVTCK(ru.ru_utime); tp->tms_stime = CONVTCK(ru.ru_stime); if (getrusage(RUSAGE_CHILDREN, &ru) < 0) return ((clock_t)-1); tp->tms_cutime = CONVTCK(ru.ru_utime); tp->tms_cstime = CONVTCK(ru.ru_stime); if (clock_gettime(CLOCK_MONOTONIC, &t)) return ((clock_t)-1); c = t.tv_sec * CLK_TCK + t.tv_nsec / (1000000000 / CLK_TCK); return (c); } Index: head/lib/libc/gen/timezone.c =================================================================== --- head/lib/libc/gen/timezone.c (revision 335897) +++ head/lib/libc/gen/timezone.c (revision 335898) @@ -1,131 +1,129 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1987, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)timezone.c 8.1 (Berkeley) 6/4/93"; -#endif /* LIBC_SCCS and not lint */ #include +__SCCSID("@(#)timezone.c 8.1 (Berkeley) 6/4/93"); __FBSDID("$FreeBSD$"); #include #include #include #include #include #define TZ_MAX_CHARS 255 char *_tztab(int, int); /* * timezone -- * The arguments are the number of minutes of time you are westward * from Greenwich and whether DST is in effect. It returns a string * giving the name of the local timezone. Should be replaced, in the * application code, by a call to localtime. */ static char czone[TZ_MAX_CHARS]; /* space for zone name */ char * timezone(int zone, int dst) { char *beg, *end; if ( (beg = getenv("TZNAME")) ) { /* set in environment */ if ((end = strchr(beg, ','))) { /* "PST,PDT" */ if (dst) return(++end); *end = '\0'; (void)strncpy(czone,beg,sizeof(czone) - 1); czone[sizeof(czone) - 1] = '\0'; *end = ','; return(czone); } return(beg); } return(_tztab(zone,dst)); /* default: table or created zone */ } static struct zone { int offset; char *stdzone; char *dlzone; } zonetab[] = { {-1*60, "MET", "MET DST"}, /* Middle European */ {-2*60, "EET", "EET DST"}, /* Eastern European */ {4*60, "AST", "ADT"}, /* Atlantic */ {5*60, "EST", "EDT"}, /* Eastern */ {6*60, "CST", "CDT"}, /* Central */ {7*60, "MST", "MDT"}, /* Mountain */ {8*60, "PST", "PDT"}, /* Pacific */ #ifdef notdef /* there's no way to distinguish this from WET */ {0, "GMT", 0}, /* Greenwich */ #endif {0*60, "WET", "WET DST"}, /* Western European */ {-10*60,"EST", "EST"}, /* Aust: Eastern */ {-10*60+30,"CST", "CST"}, /* Aust: Central */ {-8*60, "WST", 0}, /* Aust: Western */ {-1} }; /* * _tztab -- * check static tables or create a new zone name; broken out so that * we can make a guess as to what the zone is if the standard tables * aren't in place in /etc. DO NOT USE THIS ROUTINE OUTSIDE OF THE * STANDARD LIBRARY. */ char * _tztab(int zone, int dst) { struct zone *zp; char sign; for (zp = zonetab; zp->offset != -1;++zp) /* static tables */ if (zp->offset == zone) { if (dst && zp->dlzone) return(zp->dlzone); if (!dst && zp->stdzone) return(zp->stdzone); } if (zone < 0) { /* create one */ zone = -zone; sign = '+'; } else sign = '-'; (void)snprintf(czone, sizeof(czone), "GMT%c%d:%02d",sign,zone / 60,zone % 60); return(czone); } Index: head/lib/libc/gen/ttyname.c =================================================================== --- head/lib/libc/gen/ttyname.c (revision 335897) +++ head/lib/libc/gen/ttyname.c (revision 335898) @@ -1,116 +1,114 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1988, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)ttyname.c 8.2 (Berkeley) 1/27/94"; -#endif /* LIBC_SCCS and not lint */ #include +__SCCSID("@(#)ttyname.c 8.2 (Berkeley) 1/27/94"); __FBSDID("$FreeBSD$"); #include "namespace.h" #include #include #include #include #include #include #include #include #include #include #include #include "reentrant.h" #include "un-namespace.h" #include "libc_private.h" static char ttyname_buf[sizeof(_PATH_DEV) + MAXNAMLEN]; static once_t ttyname_init_once = ONCE_INITIALIZER; static thread_key_t ttyname_key; static int ttyname_keycreated = 0; int ttyname_r(int fd, char *buf, size_t len) { size_t used; /* Don't write off the end of a zero-length buffer. */ if (len < 1) return (ERANGE); *buf = '\0'; /* Must be a terminal. */ if (!isatty(fd)) return (errno); /* Must have enough room */ if (len <= sizeof(_PATH_DEV)) return (ERANGE); strcpy(buf, _PATH_DEV); used = strlen(buf); if (fdevname_r(fd, buf + used, len - used) == NULL) return (errno == EINVAL ? ERANGE : errno); return (0); } static void ttyname_keycreate(void) { ttyname_keycreated = (thr_keycreate(&ttyname_key, free) == 0); } char * ttyname(int fd) { char *buf; if (thr_main() != 0) buf = ttyname_buf; else { if (thr_once(&ttyname_init_once, ttyname_keycreate) != 0 || !ttyname_keycreated) return (NULL); if ((buf = thr_getspecific(ttyname_key)) == NULL) { if ((buf = malloc(sizeof ttyname_buf)) == NULL) return (NULL); if (thr_setspecific(ttyname_key, buf) != 0) { free(buf); return (NULL); } } } if (ttyname_r(fd, buf, sizeof ttyname_buf) != 0) return (NULL); return (buf); } Index: head/lib/libc/gen/ttyslot.c =================================================================== --- head/lib/libc/gen/ttyslot.c (revision 335897) +++ head/lib/libc/gen/ttyslot.c (revision 335898) @@ -1,47 +1,45 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1988, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)ttyslot.c 8.1 (Berkeley) 6/4/93"; -#endif /* LIBC_SCCS and not lint */ #include +__SCCSID("@(#)ttyslot.c 8.1 (Berkeley) 6/4/93"); __FBSDID("$FreeBSD$"); int __ttyslot(void); int __ttyslot(void) { return (0); } __sym_compat(ttyslot, __ttyslot, FBSD_1.0); Index: head/lib/libc/gen/ualarm.c =================================================================== --- head/lib/libc/gen/ualarm.c (revision 335897) +++ head/lib/libc/gen/ualarm.c (revision 335898) @@ -1,63 +1,61 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1985, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)ualarm.c 8.1 (Berkeley) 6/4/93"; -#endif /* LIBC_SCCS and not lint */ #include +__SCCSID("@(#)ualarm.c 8.1 (Berkeley) 6/4/93"); __FBSDID("$FreeBSD$"); #include #include #define USPS 1000000 /* # of microseconds in a second */ /* * Generate a SIGALRM signal in ``usecs'' microseconds. * If ``reload'' is non-zero, keep generating SIGALRM * every ``reload'' microseconds after the first signal. */ useconds_t ualarm(useconds_t usecs, useconds_t reload) { struct itimerval new, old; new.it_interval.tv_usec = reload % USPS; new.it_interval.tv_sec = reload / USPS; new.it_value.tv_usec = usecs % USPS; new.it_value.tv_sec = usecs / USPS; if (setitimer(ITIMER_REAL, &new, &old) == 0) return (old.it_value.tv_sec * USPS + old.it_value.tv_usec); /* else */ return (-1); } Index: head/lib/libc/gen/uname.c =================================================================== --- head/lib/libc/gen/uname.c (revision 335897) +++ head/lib/libc/gen/uname.c (revision 335898) @@ -1,51 +1,49 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1994 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "From: @(#)uname.c 8.1 (Berkeley) 1/4/94"; -#endif /* LIBC_SCCS and not lint */ #include +__SCCSID("@(#)uname.c 8.1 (Berkeley) 1/4/94"); __FBSDID("$FreeBSD$"); #define uname wrapped_uname #include #include #include #include #undef uname int uname(struct utsname *); int uname(struct utsname *name) { return __xuname(32, name); } Index: head/lib/libc/gen/usleep.c =================================================================== --- head/lib/libc/gen/usleep.c (revision 335897) +++ head/lib/libc/gen/usleep.c (revision 335898) @@ -1,59 +1,57 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1989, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)usleep.c 8.1 (Berkeley) 6/4/93"; -#endif /* LIBC_SCCS and not lint */ #include +__SCCSID("@(#)usleep.c 8.1 (Berkeley) 6/4/93"); __FBSDID("$FreeBSD$"); #include "namespace.h" #include #include #include "un-namespace.h" #include "libc_private.h" int __usleep(useconds_t); int __usleep(useconds_t useconds) { struct timespec time_to_sleep; time_to_sleep.tv_nsec = (useconds % 1000000) * 1000; time_to_sleep.tv_sec = useconds / 1000000; return (((int (*)(const struct timespec *, struct timespec *)) __libc_interposing[INTERPOS_nanosleep])(&time_to_sleep, NULL)); } __weak_reference(__usleep, usleep); __weak_reference(__usleep, _usleep); Index: head/lib/libc/gen/utime.c =================================================================== --- head/lib/libc/gen/utime.c (revision 335897) +++ head/lib/libc/gen/utime.c (revision 335898) @@ -1,55 +1,53 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)utime.c 8.1 (Berkeley) 6/4/93"; -#endif /* LIBC_SCCS and not lint */ #include +__SCCSID("@(#)utime.c 8.1 (Berkeley) 6/4/93"); __FBSDID("$FreeBSD$"); #include #include int utime(const char *path, const struct utimbuf *times) { struct timeval tv[2], *tvp; if (times) { tv[0].tv_sec = times->actime; tv[1].tv_sec = times->modtime; tv[0].tv_usec = tv[1].tv_usec = 0; tvp = tv; } else tvp = NULL; return (utimes(path, tvp)); } Index: head/lib/libc/gen/valloc.c =================================================================== --- head/lib/libc/gen/valloc.c (revision 335897) +++ head/lib/libc/gen/valloc.c (revision 335898) @@ -1,50 +1,48 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1980, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)valloc.c 8.1 (Berkeley) 6/4/93"; -#endif /* LIBC_SCCS and not lint */ #include +__SCCSID("@(#)valloc.c 8.1 (Berkeley) 6/4/93"); __FBSDID("$FreeBSD$"); #include #include void * valloc(size_t i) { void *ret; if (posix_memalign(&ret, getpagesize(), i) != 0) ret = NULL; return ret; } Index: head/lib/libc/gen/wait.c =================================================================== --- head/lib/libc/gen/wait.c (revision 335897) +++ head/lib/libc/gen/wait.c (revision 335898) @@ -1,58 +1,56 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1988, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)wait.c 8.1 (Berkeley) 6/4/93"; -#endif /* LIBC_SCCS and not lint */ #include +__SCCSID("@(#)wait.c 8.1 (Berkeley) 6/4/93"); __FBSDID("$FreeBSD$"); #include "namespace.h" #include #include #include #include #include "un-namespace.h" #include "libc_private.h" pid_t __wait(int *); pid_t __wait(int *istat) { return (((pid_t (*)(pid_t, int *, int, struct rusage *)) __libc_interposing[INTERPOS_wait4])(WAIT_ANY, istat, 0, NULL)); } __weak_reference(__wait, wait); __weak_reference(__wait, _wait); Index: head/lib/libc/gen/wait3.c =================================================================== --- head/lib/libc/gen/wait3.c (revision 335897) +++ head/lib/libc/gen/wait3.c (revision 335898) @@ -1,57 +1,55 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1988, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)wait3.c 8.1 (Berkeley) 6/4/93"; -#endif /* LIBC_SCCS and not lint */ #include +__SCCSID("@(#)wait3.c 8.1 (Berkeley) 6/4/93"); __FBSDID("$FreeBSD$"); #include "namespace.h" #include #include #include #include #include "un-namespace.h" #include "libc_private.h" pid_t __wait3(int *, int, struct rusage *); pid_t __wait3(int *istat, int options, struct rusage *rup) { return (((pid_t (*)(pid_t, int *, int, struct rusage *)) __libc_interposing[INTERPOS_wait4])(WAIT_ANY, istat, options, rup)); } __weak_reference(__wait3, wait3); Index: head/lib/libc/gen/waitpid.c =================================================================== --- head/lib/libc/gen/waitpid.c (revision 335897) +++ head/lib/libc/gen/waitpid.c (revision 335898) @@ -1,58 +1,56 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1988, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)waitpid.c 8.1 (Berkeley) 6/4/93"; -#endif /* LIBC_SCCS and not lint */ #include +__SCCSID("@(#)waitpid.c 8.1 (Berkeley) 6/4/93"); __FBSDID("$FreeBSD$"); #include "namespace.h" #include #include #include #include #include "un-namespace.h" #include "libc_private.h" pid_t __waitpid(pid_t, int *, int); pid_t __waitpid(pid_t pid, int *istat, int options) { return (((pid_t (*)(pid_t, int *, int, struct rusage *)) __libc_interposing[INTERPOS_wait4])(pid, istat, options, NULL)); } __weak_reference(__waitpid, waitpid); __weak_reference(__waitpid, _waitpid);