summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--system/musl/0001-sysconf-Add-_SC_XOPEN_UUCP.patch39
-rw-r--r--system/musl/0002-confstr-Add-_CS_POSIX_V7_THREADS_.patch44
-rw-r--r--system/musl/0003-pathconf-add-_PC_TIMESTAMP_RESOLUTION.patch29
-rw-r--r--system/musl/2000-pthread-internals-increase-DEFAULT_GUARD_SIZE-to-2-p.patch29
-rw-r--r--system/musl/APKBUILD158
-rw-r--r--system/musl/__stack_chk_fail_local.c2
-rw-r--r--system/musl/complex-math.patch59
-rw-r--r--system/musl/getconf.c338
-rw-r--r--system/musl/getent.c511
-rw-r--r--system/musl/handle-aux-at_base.patch43
-rw-r--r--system/musl/iconv.c110
-rw-r--r--system/musl/ldconfig18
12 files changed, 1380 insertions, 0 deletions
diff --git a/system/musl/0001-sysconf-Add-_SC_XOPEN_UUCP.patch b/system/musl/0001-sysconf-Add-_SC_XOPEN_UUCP.patch
new file mode 100644
index 000000000..67da315b6
--- /dev/null
+++ b/system/musl/0001-sysconf-Add-_SC_XOPEN_UUCP.patch
@@ -0,0 +1,39 @@
+From 6f592a7812de3190f567174bbb4baa40790831dd Mon Sep 17 00:00:00 2001
+From: "A. Wilcox" <AWilcox@Wilcox-Tech.com>
+Date: Wed, 11 Apr 2018 23:22:33 -0500
+Subject: [PATCH 1/2] sysconf: Add _SC_XOPEN_UUCP
+
+We definitely don't /support/ UUCP, so return -1 for it.
+But this value is required to be present in <unistd.h>.
+---
+ include/unistd.h | 1 +
+ src/conf/sysconf.c | 1 +
+ 2 files changed, 2 insertions(+)
+
+diff --git a/include/unistd.h b/include/unistd.h
+index 9485da7a..2b88bbb2 100644
+--- a/include/unistd.h
++++ b/include/unistd.h
+@@ -417,6 +417,7 @@ int eaccess(const char *, int);
+ #define _SC_XOPEN_STREAMS 246
+ #define _SC_THREAD_ROBUST_PRIO_INHERIT 247
+ #define _SC_THREAD_ROBUST_PRIO_PROTECT 248
++#define _SC_XOPEN_UUCP 249
+
+ #define _CS_PATH 0
+ #define _CS_POSIX_V6_WIDTH_RESTRICTED_ENVS 1
+diff --git a/src/conf/sysconf.c b/src/conf/sysconf.c
+index 9ce330a5..58830a09 100644
+--- a/src/conf/sysconf.c
++++ b/src/conf/sysconf.c
+@@ -164,6 +164,7 @@ long sysconf(int name)
+ [_SC_XOPEN_STREAMS] = JT_ZERO,
+ [_SC_THREAD_ROBUST_PRIO_INHERIT] = -1,
+ [_SC_THREAD_ROBUST_PRIO_PROTECT] = -1,
++ [_SC_XOPEN_UUCP] = -1,
+ };
+
+ if (name >= sizeof(values)/sizeof(values[0]) || !values[name]) {
+--
+2.15.0
+
diff --git a/system/musl/0002-confstr-Add-_CS_POSIX_V7_THREADS_.patch b/system/musl/0002-confstr-Add-_CS_POSIX_V7_THREADS_.patch
new file mode 100644
index 000000000..ab1203cca
--- /dev/null
+++ b/system/musl/0002-confstr-Add-_CS_POSIX_V7_THREADS_.patch
@@ -0,0 +1,44 @@
+From 94046871d24d5408adaf61941a4751c77abe06b6 Mon Sep 17 00:00:00 2001
+From: "A. Wilcox" <AWilcox@Wilcox-Tech.com>
+Date: Wed, 11 Apr 2018 23:23:31 -0500
+Subject: [PATCH 2/2] confstr: Add _CS_POSIX_V7_THREADS_*
+
+This is used to determine what CFLAGS/LDFLAGS are needed to enable
+compilation with threads on musl. We don't have any special ones, so
+just return an empty string.
+
+This is required to be present in <unistd.h>.
+---
+ include/unistd.h | 2 ++
+ src/conf/confstr.c | 2 +-
+ 2 files changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/include/unistd.h b/include/unistd.h
+index 2b88bbb2..68686dfd 100644
+--- a/include/unistd.h
++++ b/include/unistd.h
+@@ -460,6 +460,8 @@ int eaccess(const char *, int);
+ #define _CS_POSIX_V7_LPBIG_OFFBIG_LINTFLAGS 1147
+ #define _CS_V6_ENV 1148
+ #define _CS_V7_ENV 1149
++#define _CS_POSIX_V7_THREADS_CFLAGS 1150
++#define _CS_POSIX_V7_THREADS_LDFLAGS 1151
+
+ #ifdef __cplusplus
+ }
+diff --git a/src/conf/confstr.c b/src/conf/confstr.c
+index 02cb1aa2..3d417284 100644
+--- a/src/conf/confstr.c
++++ b/src/conf/confstr.c
+@@ -7,7 +7,7 @@ size_t confstr(int name, char *buf, size_t len)
+ const char *s = "";
+ if (!name) {
+ s = "/bin:/usr/bin";
+- } else if ((name&~4U)!=1 && name-_CS_POSIX_V6_ILP32_OFF32_CFLAGS>33U) {
++ } else if ((name&~4U)!=1 && name-_CS_POSIX_V6_ILP32_OFF32_CFLAGS>35U) {
+ errno = EINVAL;
+ return 0;
+ }
+--
+2.15.0
+
diff --git a/system/musl/0003-pathconf-add-_PC_TIMESTAMP_RESOLUTION.patch b/system/musl/0003-pathconf-add-_PC_TIMESTAMP_RESOLUTION.patch
new file mode 100644
index 000000000..33b0d2379
--- /dev/null
+++ b/system/musl/0003-pathconf-add-_PC_TIMESTAMP_RESOLUTION.patch
@@ -0,0 +1,29 @@
+From da7bab19d59a0ea50e23371462f688329cd6c1a7 Mon Sep 17 00:00:00 2001
+From: "A. Wilcox" <AWilcox@Wilcox-Tech.com>
+Date: Wed, 11 Apr 2018 23:43:19 -0500
+Subject: [PATCH 3/3] pathconf: add _PC_TIMESTAMP_RESOLUTION
+
+Right now, this is a worst-case assumption; some kernels may actually
+have a value of 100000 here (100 Hz timers). This is considered the
+easiest implementation.
+
+This is required to be present in <unistd.h>.
+---
+ include/unistd.h | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/include/unistd.h b/include/unistd.h
+index 68686dfd..1bdd3292 100644
+--- a/include/unistd.h
++++ b/include/unistd.h
+@@ -274,6 +274,7 @@ int eaccess(const char *, int);
+ #define _PC_ALLOC_SIZE_MIN 18
+ #define _PC_SYMLINK_MAX 19
+ #define _PC_2_SYMLINKS 20
++#define _PC_TIMESTAMP_RESOLUTION 21
+
+ #define _SC_ARG_MAX 0
+ #define _SC_CHILD_MAX 1
+--
+2.15.0
+
diff --git a/system/musl/2000-pthread-internals-increase-DEFAULT_GUARD_SIZE-to-2-p.patch b/system/musl/2000-pthread-internals-increase-DEFAULT_GUARD_SIZE-to-2-p.patch
new file mode 100644
index 000000000..b39664dac
--- /dev/null
+++ b/system/musl/2000-pthread-internals-increase-DEFAULT_GUARD_SIZE-to-2-p.patch
@@ -0,0 +1,29 @@
+From 58dec23397e3fcc4300cc03839ce5e508389abbc Mon Sep 17 00:00:00 2001
+From: William Pitcock <nenolod@dereferenced.org>
+Date: Thu, 22 Jun 2017 22:04:51 +0000
+Subject: [PATCH] pthread internals: increase DEFAULT_GUARD_SIZE to 2 pages
+ instead of 1 page.
+
+This is intended to be a proactive mitigation against any bugs similar to CVE-2017-1000366.
+
+Signed-off-by: William Pitcock <nenolod@dereferenced.org>
+---
+ src/internal/pthread_impl.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/internal/pthread_impl.h b/src/internal/pthread_impl.h
+index ae0ab1c5..ad4ea3fa 100644
+--- a/src/internal/pthread_impl.h
++++ b/src/internal/pthread_impl.h
+@@ -146,7 +146,7 @@ void __block_app_sigs(void *);
+ void __restore_sigs(void *);
+
+ #define DEFAULT_STACK_SIZE 81920
+-#define DEFAULT_GUARD_SIZE 4096
++#define DEFAULT_GUARD_SIZE 8192
+
+ #define __ATTRP_C11_THREAD ((void*)(uintptr_t)-1)
+
+--
+2.13.0
+
diff --git a/system/musl/APKBUILD b/system/musl/APKBUILD
new file mode 100644
index 000000000..25c93f361
--- /dev/null
+++ b/system/musl/APKBUILD
@@ -0,0 +1,158 @@
+# Contributor: William Pitcock <nenolod@dereferenced.org>
+# Maintainer: Timo Teräs <timo.teras@iki.fi>
+pkgname=musl
+pkgver=1.1.19
+pkgrel=3
+pkgdesc="the musl c library (libc) implementation"
+url="http://www.musl-libc.org/"
+arch="all"
+options="!check"
+license="MIT"
+depends=""
+depends_dev="!uclibc-dev"
+makedepends="$depends_dev"
+subpackages="$pkgname-dev $pkgname-dbg libc6-compat:compat:noarch"
+case "$BOOTSTRAP" in
+nocc) pkgname="musl-dev"; subpackages="";;
+nolibc) ;;
+*) subpackages="$subpackages $pkgname-utils";;
+esac
+source="http://www.musl-libc.org/releases/musl-$pkgver.tar.gz
+ 0001-sysconf-Add-_SC_XOPEN_UUCP.patch
+ 0002-confstr-Add-_CS_POSIX_V7_THREADS_.patch
+ 0003-pathconf-add-_PC_TIMESTAMP_RESOLUTION.patch
+
+ 2000-pthread-internals-increase-DEFAULT_GUARD_SIZE-to-2-p.patch
+ complex-math.patch
+ handle-aux-at_base.patch
+
+ ldconfig
+ __stack_chk_fail_local.c
+ getent.c
+ iconv.c
+ "
+
+# secfixes:
+# 1.1.15-r4:
+# - CVE-2016-8859
+
+builddir="$srcdir"/musl-$pkgver
+
+build() {
+ cd "$builddir"
+
+ [ "$BOOTSTRAP" = "nocc" ] && return 0
+
+ # provide minimal libssp_nonshared.a so we don't need libssp from gcc
+ ${CROSS_COMPILE}gcc $CPPFLAGS $CFLAGS -c "$srcdir"/__stack_chk_fail_local.c -o __stack_chk_fail_local.o
+ ${CROSS_COMPILE}ar r libssp_nonshared.a __stack_chk_fail_local.o
+
+ if [ "$BOOTSTRAP" != "nolibc" ]; then
+ # getconf/getent/iconv
+ local i
+ for i in getent iconv ; do
+ ${CROSS_COMPILE}gcc $CPPFLAGS $CFLAGS "$srcdir"/$i.c -o $i
+ done
+ fi
+
+ # note: not autotools
+ LDFLAGS="$LDFLAGS -Wl,-soname,libc.musl-${CARCH}.so.1" \
+ ./configure \
+ --build=$CBUILD \
+ --host=$CHOST \
+ --prefix=/usr \
+ --sysconfdir=/etc \
+ --mandir=/usr/share/man \
+ --infodir=/usr/share/info \
+ --localstatedir=/var
+ make
+}
+
+package() {
+ cd "$builddir"
+
+ if [ "$BOOTSTRAP" = "nocc" ]; then
+ case "$CARCH" in
+ aarch64*) ARCH="aarch64" ;;
+ arm*) ARCH="arm" ;;
+ x86) ARCH="i386" ;;
+ x86_64) ARCH="x86_64" ;;
+ ppc) ARCH="powerpc" ;;
+ ppc64*) ARCH="powerpc64" ;;
+ s390*) ARCH="s390x" ;;
+ mips64*) ARCH="mips64" ;;
+ mips*) ARCH="mips" ;;
+ esac
+
+ make ARCH="$ARCH" prefix=/usr DESTDIR="$pkgdir" install-headers || return 1
+ else
+ make DESTDIR="$pkgdir" install || return 1
+
+ cp libssp_nonshared.a "$pkgdir"/usr/lib || return 1
+
+ # make LDSO the be the real file, and libc the symlink
+ local LDSO=$(make -f Makefile --eval "$(echo -e 'print-ldso:\n\t@echo $$(basename $(LDSO_PATHNAME))')" print-ldso)
+ mv -f "$pkgdir"/usr/lib/libc.so "$pkgdir"/lib/"$LDSO" || return 1
+ ln -sf "$LDSO" "$pkgdir"/lib/libc.musl-${CARCH}.so.1 || return 1
+ ln -sf ../../lib/"$LDSO" "$pkgdir"/usr/lib/libc.so || return 1
+ mkdir -p "$pkgdir"/usr/bin || return 1
+ ln -sf ../../lib/"$LDSO" "$pkgdir"/usr/bin/ldd || return 1
+ fi
+
+ # remove libintl.h, currently we don't want by default any NLS
+ # and use GNU gettext where needed. the plan is to migrate to
+ # musl gettext() later on as fully as possible.
+ rm "$pkgdir"/usr/include/libintl.h || return 1
+}
+
+utils() {
+ depends="!uclibc-utils scanelf"
+ replaces="libiconv uclibc-utils"
+ license="MIT BSD GPL2+"
+
+ mkdir -p "$subpkgdir"/usr "$subpkgdir"/sbin
+ mv "$pkgdir"/usr/bin "$subpkgdir"/usr/ || return 1
+
+ install -D \
+ "$builddir"/getent \
+ "$builddir"/iconv \
+ "$subpkgdir"/usr/bin
+
+ install -D -m755 "$srcdir"/ldconfig "$subpkgdir"/sbin
+}
+
+compat() {
+ pkgdesc="compatibility libraries for glibc"
+
+ mkdir -p "$subpkgdir"/lib
+ case "$CARCH" in
+ armel) _ld="ld-linux.so.3" ;;
+ armhf | armv7) _ld="ld-linux-armhf.so.3" ;;
+ aarch64) _ld="ld-linux-aarch64.so.1" ;;
+ x86) _ld="ld-linux.so.2" ;;
+ x86_64) _ld="ld-linux-x86-64.so.2"
+ # go precompiled binary uses /lib64/ld-linux-x86-64.so.2
+ # so we add a symlink
+ ln -s lib "$subpkgdir"/lib64
+ ;;
+ mips* | s390*) _ld="ld.so.1" ;;
+ ppc64le) _ld="ld64.so.2" ;;
+ esac
+ ln -sf "/lib/libc.musl-${CARCH}.so.1" "$subpkgdir/lib/$_ld"
+
+ for i in libc.so.6 libcrypt.so.1 libm.so.6 libpthread.so.0 librt.so.1 libutil.so.1; do
+ ln -sf "/lib/libc.musl-${CARCH}.so.1" "$subpkgdir/lib/$i"
+ done
+}
+
+sha512sums="abee52d53af4b3c14c9088866c911a24d2b6ef67dc494f38a7a09dfe77250026f77528c24c52469c89cffa8ced2f0fa95badbdcf8d4460c90faba47e3927bcc5 musl-1.1.19.tar.gz
+f274b1c3fff40494e44e68d5385d6f117bac43a10272e1415ed11d65f937e8c34639128860cff451357614a417bb9535a1c676be65a50dd33225c34f249dd4ff 0001-sysconf-Add-_SC_XOPEN_UUCP.patch
+e6d7ba709a53cfefb9b5fbb4ede3bde6926504e24d5111691e4a63d15085c0e6e896a3d2df84026fad9520e08b2d98a3be901f29ee47df0bd8c58f6a34ebc49f 0002-confstr-Add-_CS_POSIX_V7_THREADS_.patch
+7981521fd3aed5c6b4d6798717945ebe30de83ef327c8c6da135e6e7793f4be533833b1ff87cb25c8646c019da127e73da9adccdc7cf1f91a1ba1b60387a9e91 0003-pathconf-add-_PC_TIMESTAMP_RESOLUTION.patch
+2c8e1dde1834238097b2ee8a7bfb53471a0d9cff4a5e38b55f048b567deff1cdd47c170d0578a67b1a039f95a6c5fbb8cff369c75b6a3e4d7ed171e8e86ebb8c 2000-pthread-internals-increase-DEFAULT_GUARD_SIZE-to-2-p.patch
+8909dc260968770ace8f3ffdc04c6c7d20933ff115b4fa3e512fb7460860a8216c73ca7a7ad54f59cb5988ef011f02bf18aa13cc2287cc64ffdb8db84ef69d47 complex-math.patch
+6a7ff16d95b5d1be77e0a0fbb245491817db192176496a57b22ab037637d97a185ea0b0d19da687da66c2a2f5578e4343d230f399d49fe377d8f008410974238 handle-aux-at_base.patch
+8d3a2d5315fc56fee7da9abb8b89bb38c6046c33d154c10d168fb35bfde6b0cf9f13042a3bceee34daf091bc409d699223735dcf19f382eeee1f6be34154f26f ldconfig
+062bb49fa54839010acd4af113e20f7263dde1c8a2ca359b5fb2661ef9ed9d84a0f7c3bc10c25dcfa10bb3c5a4874588dff636ac43d5dbb3d748d75400756d0b __stack_chk_fail_local.c
+378d70e65bcc65bb4e1415354cecfa54b0c1146dfb24474b69e418cdbf7ad730472cd09f6f103e1c99ba6c324c9560bccdf287f5889bbc3ef0bdf0e08da47413 getent.c
+9d42d66fb1facce2b85dad919be5be819ee290bd26ca2db00982b2f8e055a0196290a008711cbe2b18ec9eee8d2270e3b3a4692c5a1b807013baa5c2b70a2bbf iconv.c"
diff --git a/system/musl/__stack_chk_fail_local.c b/system/musl/__stack_chk_fail_local.c
new file mode 100644
index 000000000..2b403a6e0
--- /dev/null
+++ b/system/musl/__stack_chk_fail_local.c
@@ -0,0 +1,2 @@
+extern void __stack_chk_fail(void);
+void __attribute__((visibility ("hidden"))) __stack_chk_fail_local(void) { __stack_chk_fail(); }
diff --git a/system/musl/complex-math.patch b/system/musl/complex-math.patch
new file mode 100644
index 000000000..fff4b59c1
--- /dev/null
+++ b/system/musl/complex-math.patch
@@ -0,0 +1,59 @@
+From ae2a01da2e388535da243b3d974aef74a3c06ae0 Mon Sep 17 00:00:00 2001
+From: Rich Felker <dalias@aerifal.cx>
+Date: Mon, 9 Apr 2018 12:33:17 -0400
+Subject: fix wrong result in casin and many related complex functions
+
+the factor of -i noted in the comment at the top of casin.c was
+omitted from the actual code, yielding a result rotated 90 degrees and
+propagating into errors in other functions defined in terms of casin.
+
+implement multiplication by -i as a rotation of the real and imaginary
+parts of the result, rather than by actual multiplication, since the
+latter cannot be optimized without knowledge that the operand is
+finite. here, the rotation is the actual intent, anyway.
+---
+ src/complex/casin.c | 3 ++-
+ src/complex/casinf.c | 3 ++-
+ src/complex/casinl.c | 3 ++-
+ 3 files changed, 6 insertions(+), 3 deletions(-)
+
+diff --git a/src/complex/casin.c b/src/complex/casin.c
+index dfdda98..01ed618 100644
+--- a/src/complex/casin.c
++++ b/src/complex/casin.c
+@@ -12,5 +12,6 @@ double complex casin(double complex z)
+ x = creal(z);
+ y = cimag(z);
+ w = CMPLX(1.0 - (x - y)*(x + y), -2.0*x*y);
+- return clog(CMPLX(-y, x) + csqrt(w));
++ double complex r = clog(CMPLX(-y, x) + csqrt(w));
++ return CMPLX(cimag(r), -creal(r));
+ }
+diff --git a/src/complex/casinf.c b/src/complex/casinf.c
+index 93f0e33..4fcb76f 100644
+--- a/src/complex/casinf.c
++++ b/src/complex/casinf.c
+@@ -10,5 +10,6 @@ float complex casinf(float complex z)
+ x = crealf(z);
+ y = cimagf(z);
+ w = CMPLXF(1.0 - (x - y)*(x + y), -2.0*x*y);
+- return clogf(CMPLXF(-y, x) + csqrtf(w));
++ float complex r = clogf(CMPLXF(-y, x) + csqrtf(w));
++ return CMPLXF(cimagf(r), -crealf(r));
+ }
+diff --git a/src/complex/casinl.c b/src/complex/casinl.c
+index 0916c60..3b7ceba 100644
+--- a/src/complex/casinl.c
++++ b/src/complex/casinl.c
+@@ -15,6 +15,7 @@ long double complex casinl(long double complex z)
+ x = creall(z);
+ y = cimagl(z);
+ w = CMPLXL(1.0 - (x - y)*(x + y), -2.0*x*y);
+- return clogl(CMPLXL(-y, x) + csqrtl(w));
++ long double complex r = clogl(CMPLXL(-y, x) + csqrtl(w));
++ return CMPLXL(cimagl(r), -creall(r));
+ }
+ #endif
+--
+cgit v0.11.2
+
diff --git a/system/musl/getconf.c b/system/musl/getconf.c
new file mode 100644
index 000000000..c4235242b
--- /dev/null
+++ b/system/musl/getconf.c
@@ -0,0 +1,338 @@
+/*-
+ * Copyright (c) 1996, 1998 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by J.T. Conklin.
+ *
+ * Mostly rewritten to be used in Alpine Linux (with musl c-library)
+ * by Timo Teräs.
+ *
+ * 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
+ */
+
+#include <err.h>
+#include <errno.h>
+#include <values.h>
+#include <limits.h>
+#include <locale.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+
+struct conf_variable {
+ const char *name;
+ enum { SYSCONF, CONFSTR, PATHCONF, CONSTANT, UCONSTANT, NUM_TYPES } type;
+ long value;
+};
+
+static const struct conf_variable conf_table[] = {
+{ "PATH", CONFSTR, _CS_PATH },
+
+/* Utility Limit Minimum Values */
+{ "POSIX2_BC_BASE_MAX", CONSTANT, _POSIX2_BC_BASE_MAX },
+{ "POSIX2_BC_DIM_MAX", CONSTANT, _POSIX2_BC_DIM_MAX },
+{ "POSIX2_BC_SCALE_MAX", CONSTANT, _POSIX2_BC_SCALE_MAX },
+{ "POSIX2_BC_STRING_MAX", CONSTANT, _POSIX2_BC_STRING_MAX },
+{ "POSIX2_COLL_WEIGHTS_MAX", CONSTANT, _POSIX2_COLL_WEIGHTS_MAX },
+{ "POSIX2_EXPR_NEST_MAX", CONSTANT, _POSIX2_EXPR_NEST_MAX },
+{ "POSIX2_LINE_MAX", CONSTANT, _POSIX2_LINE_MAX },
+{ "POSIX2_RE_DUP_MAX", CONSTANT, _POSIX2_RE_DUP_MAX },
+{ "POSIX2_VERSION", CONSTANT, _POSIX2_VERSION },
+
+/* POSIX.1 Minimum Values */
+{ "_POSIX_AIO_LISTIO_MAX", CONSTANT, _POSIX_AIO_LISTIO_MAX },
+{ "_POSIX_AIO_MAX", CONSTANT, _POSIX_AIO_MAX },
+{ "_POSIX_ARG_MAX", CONSTANT, _POSIX_ARG_MAX },
+{ "_POSIX_CHILD_MAX", CONSTANT, _POSIX_CHILD_MAX },
+{ "_POSIX_LINK_MAX", CONSTANT, _POSIX_LINK_MAX },
+{ "_POSIX_MAX_CANON", CONSTANT, _POSIX_MAX_CANON },
+{ "_POSIX_MAX_INPUT", CONSTANT, _POSIX_MAX_INPUT },
+{ "_POSIX_MQ_OPEN_MAX", CONSTANT, _POSIX_MQ_OPEN_MAX },
+{ "_POSIX_MQ_PRIO_MAX", CONSTANT, _POSIX_MQ_PRIO_MAX },
+{ "_POSIX_NAME_MAX", CONSTANT, _POSIX_NAME_MAX },
+{ "_POSIX_NGROUPS_MAX", CONSTANT, _POSIX_NGROUPS_MAX },
+{ "_POSIX_OPEN_MAX", CONSTANT, _POSIX_OPEN_MAX },
+{ "_POSIX_PATH_MAX", CONSTANT, _POSIX_PATH_MAX },
+{ "_POSIX_PIPE_BUF", CONSTANT, _POSIX_PIPE_BUF },
+{ "_POSIX_SSIZE_MAX", CONSTANT, _POSIX_SSIZE_MAX },
+{ "_POSIX_STREAM_MAX", CONSTANT, _POSIX_STREAM_MAX },
+{ "_POSIX_TZNAME_MAX", CONSTANT, _POSIX_TZNAME_MAX },
+
+/* Symbolic Utility Limits */
+{ "BC_BASE_MAX", SYSCONF, _SC_BC_BASE_MAX },
+{ "BC_DIM_MAX", SYSCONF, _SC_BC_DIM_MAX },
+{ "BC_SCALE_MAX", SYSCONF, _SC_BC_SCALE_MAX },
+{ "BC_STRING_MAX", SYSCONF, _SC_BC_STRING_MAX },
+{ "COLL_WEIGHTS_MAX", SYSCONF, _SC_COLL_WEIGHTS_MAX },
+{ "EXPR_NEST_MAX", SYSCONF, _SC_EXPR_NEST_MAX },
+{ "LINE_MAX", SYSCONF, _SC_LINE_MAX },
+{ "RE_DUP_MAX", SYSCONF, _SC_RE_DUP_MAX },
+
+/* Optional Facility Configuration Values */
+{ "_POSIX2_C_BIND", SYSCONF, _SC_2_C_BIND },
+{ "POSIX2_C_DEV", SYSCONF, _SC_2_C_DEV },
+{ "POSIX2_CHAR_TERM", SYSCONF, _SC_2_CHAR_TERM },
+{ "POSIX2_FORT_DEV", SYSCONF, _SC_2_FORT_DEV },
+{ "POSIX2_FORT_RUN", SYSCONF, _SC_2_FORT_RUN },
+{ "POSIX2_LOCALEDEF", SYSCONF, _SC_2_LOCALEDEF },
+{ "POSIX2_SW_DEV", SYSCONF, _SC_2_SW_DEV },
+{ "POSIX2_UPE", SYSCONF, _SC_2_UPE },
+
+/* POSIX.1 Configurable System Variables */
+{ "AIO_LISTIO_MAX", SYSCONF, _SC_AIO_LISTIO_MAX },
+{ "AIO_MAX", SYSCONF, _SC_AIO_MAX },
+{ "ARG_MAX", SYSCONF, _SC_ARG_MAX },
+{ "CHILD_MAX", SYSCONF, _SC_CHILD_MAX },
+{ "CLK_TCK", SYSCONF, _SC_CLK_TCK },
+{ "MQ_OPEN_MAX", SYSCONF, _SC_MQ_OPEN_MAX },
+{ "MQ_PRIO_MAX", SYSCONF, _SC_MQ_PRIO_MAX },
+{ "NGROUPS_MAX", SYSCONF, _SC_NGROUPS_MAX },
+{ "OPEN_MAX", SYSCONF, _SC_OPEN_MAX },
+{ "STREAM_MAX", SYSCONF, _SC_STREAM_MAX },
+{ "TZNAME_MAX", SYSCONF, _SC_TZNAME_MAX },
+{ "_POSIX_JOB_CONTROL", SYSCONF, _SC_JOB_CONTROL },
+{ "_POSIX_SAVED_IDS", SYSCONF, _SC_SAVED_IDS },
+{ "_POSIX_VERSION", SYSCONF, _SC_VERSION },
+
+{ "LINK_MAX", PATHCONF, _PC_LINK_MAX },
+{ "MAX_CANON", PATHCONF, _PC_MAX_CANON },
+{ "MAX_INPUT", PATHCONF, _PC_MAX_INPUT },
+{ "NAME_MAX", PATHCONF, _PC_NAME_MAX },
+{ "PATH_MAX", PATHCONF, _PC_PATH_MAX },
+{ "PIPE_BUF", PATHCONF, _PC_PIPE_BUF },
+{ "_POSIX_CHOWN_RESTRICTED", PATHCONF, _PC_CHOWN_RESTRICTED },
+{ "_POSIX_NO_TRUNC", PATHCONF, _PC_NO_TRUNC },
+{ "_POSIX_VDISABLE", PATHCONF, _PC_VDISABLE },
+
+/* POSIX.1b Configurable System Variables */
+{ "PAGESIZE", SYSCONF, _SC_PAGESIZE },
+{ "_POSIX_ASYNCHRONOUS_IO", SYSCONF, _SC_ASYNCHRONOUS_IO },
+{ "_POSIX_FSYNC", SYSCONF, _SC_FSYNC },
+{ "_POSIX_MAPPED_FILES", SYSCONF, _SC_MAPPED_FILES },
+{ "_POSIX_MEMLOCK", SYSCONF, _SC_MEMLOCK },
+{ "_POSIX_MEMLOCK_RANGE", SYSCONF, _SC_MEMLOCK_RANGE },
+{ "_POSIX_MEMORY_PROTECTION", SYSCONF, _SC_MEMORY_PROTECTION },
+{ "_POSIX_MESSAGE_PASSING", SYSCONF, _SC_MESSAGE_PASSING },
+{ "_POSIX_MONOTONIC_CLOCK", SYSCONF, _SC_MONOTONIC_CLOCK },
+{ "_POSIX_PRIORITY_SCHEDULING", SYSCONF, _SC_PRIORITY_SCHEDULING },
+{ "_POSIX_SEMAPHORES", SYSCONF, _SC_SEMAPHORES },
+{ "_POSIX_SHARED_MEMORY_OBJECTS", SYSCONF, _SC_SHARED_MEMORY_OBJECTS },
+{ "_POSIX_SYNCHRONIZED_IO", SYSCONF, _SC_SYNCHRONIZED_IO },
+{ "_POSIX_TIMERS", SYSCONF, _SC_TIMERS },
+
+{ "_POSIX_SYNC_IO", PATHCONF, _PC_SYNC_IO },
+
+/* POSIX.1c Configurable System Variables */
+{ "LOGIN_NAME_MAX", SYSCONF, _SC_LOGIN_NAME_MAX },
+{ "_POSIX_THREADS", SYSCONF, _SC_THREADS },
+
+/* POSIX.1j Configurable System Variables */
+{ "_POSIX_BARRIERS", SYSCONF, _SC_BARRIERS },
+{ "_POSIX_READER_WRITER_LOCKS", SYSCONF, _SC_READER_WRITER_LOCKS },
+{ "_POSIX_SPIN_LOCKS", SYSCONF, _SC_SPIN_LOCKS },
+
+/* XPG4.2 Configurable System Variables */
+{ "IOV_MAX", SYSCONF, _SC_IOV_MAX },
+{ "PAGE_SIZE", SYSCONF, _SC_PAGE_SIZE },
+{ "_XOPEN_SHM", SYSCONF, _SC_XOPEN_SHM },
+
+/* X/Open CAE Spec. Issue 5 Version 2 Configurable System Variables */
+{ "FILESIZEBITS", PATHCONF, _PC_FILESIZEBITS },
+
+/* POSIX.1-2001 XSI Option Group Configurable System Variables */
+{ "ATEXIT_MAX", SYSCONF, _SC_ATEXIT_MAX },
+
+/* POSIX.1-2001 TSF Configurable System Variables */
+{ "GETGR_R_SIZE_MAX", SYSCONF, _SC_GETGR_R_SIZE_MAX },
+{ "GETPW_R_SIZE_MAX", SYSCONF, _SC_GETPW_R_SIZE_MAX },
+
+/* Commonly provided extensions */
+{ "_PHYS_PAGES", SYSCONF, _SC_PHYS_PAGES },
+{ "_AVPHYS_PAGES", SYSCONF, _SC_AVPHYS_PAGES },
+{ "_NPROCESSORS_CONF", SYSCONF, _SC_NPROCESSORS_CONF },
+{ "_NPROCESSORS_ONLN", SYSCONF, _SC_NPROCESSORS_ONLN },
+
+/* Data type related extensions */
+{ "CHAR_BIT", CONSTANT, CHAR_BIT },
+{ "CHAR_MAX", CONSTANT, CHAR_MAX },
+{ "CHAR_MIN", CONSTANT, CHAR_MIN },
+{ "INT_MAX", CONSTANT, INT_MAX },
+{ "INT_MIN", CONSTANT, INT_MIN },
+{ "LONG_BIT", CONSTANT, LONG_BIT },
+{ "LONG_MAX", CONSTANT, LONG_MAX },
+{ "LONG_MIN", CONSTANT, LONG_MIN },
+{ "SCHAR_MAX", CONSTANT, SCHAR_MAX },
+{ "SCHAR_MIN", CONSTANT, SCHAR_MIN },
+{ "SHRT_MAX", CONSTANT, SHRT_MAX },
+{ "SHRT_MIN", CONSTANT, SHRT_MIN },
+{ "SSIZE_MAX", CONSTANT, SSIZE_MAX },
+{ "UCHAR_MAX", UCONSTANT, (long) UCHAR_MAX },
+{ "UINT_MAX", UCONSTANT, (long) UINT_MAX },
+{ "ULONG_MAX", UCONSTANT, (long) ULONG_MAX },
+{ "USHRT_MAX", UCONSTANT, (long) USHRT_MAX },
+{ "WORD_BIT", CONSTANT, WORD_BIT },
+
+{ NULL, CONSTANT, 0L }
+};
+
+static int all = 0;
+
+static void usage(const char *p)
+{
+ (void)fprintf(stderr, "Usage: %s system_var\n\t%s -a\n"
+ "\t%s path_var pathname\n\t%s -a pathname\n", p, p, p, p);
+ exit(EXIT_FAILURE);
+}
+
+static void print_long(const char *name, long val)
+{
+ if (all) printf("%s = %ld\n", name, val);
+ else printf("%ld\n", val);
+}
+
+static void print_ulong(const char *name, unsigned long val)
+{
+ if (all) printf("%s = %lu\n", name, val);
+ else printf("%lu\n", val);
+}
+
+static void print_string(const char *name, const char *val)
+{
+ if (all) printf("%s = %s\n", name, val);
+ else printf("%s\n", val);
+}
+
+static int print_constant(const struct conf_variable *cp, const char *pathname)
+{
+ print_long(cp->name, cp->value);
+ return 0;
+}
+
+static int print_uconstant(const struct conf_variable *cp, const char *pathname)
+{
+ print_ulong(cp->name, (unsigned long) cp->value);
+ return 0;
+}
+
+static int print_sysconf(const struct conf_variable *cp, const char *pathname)
+{
+ long val;
+
+ errno = 0;
+ if ((val = sysconf((int)cp->value)) == -1) {
+ if (errno != 0) err(EXIT_FAILURE, "sysconf(%ld)", cp->value);
+ return -1;
+ }
+ print_long(cp->name, val);
+ return 0;
+}
+
+static int print_confstr(const struct conf_variable *cp, const char *pathname)
+{
+ size_t len;
+ char *val;
+
+ errno = 0;
+ if ((len = confstr((int)cp->value, NULL, 0)) == 0) goto error;
+ if ((val = malloc(len)) == NULL) err(EXIT_FAILURE, "Can't allocate %zu bytes", len);
+ errno = 0;
+ if (confstr((int)cp->value, val, len) == 0) goto error;
+ print_string(cp->name, val);
+ free(val);
+ return 0;
+error:
+ if (errno != EINVAL) err(EXIT_FAILURE, "confstr(%ld)", cp->value);
+ return -1;
+}
+
+static int print_pathconf(const struct conf_variable *cp, const char *pathname)
+{
+ long val;
+
+ errno = 0;
+ if ((val = pathconf(pathname, (int)cp->value)) == -1) {
+ if (all && errno == EINVAL) return 0;
+ if (errno != 0) err(EXIT_FAILURE, "pathconf(%s, %ld)", pathname, cp->value);
+ return -1;
+ }
+ print_long(cp->name, val);
+ return 0;
+}
+
+typedef int (*handler_t)(const struct conf_variable *cp, const char *pathname);
+static const handler_t type_handlers[NUM_TYPES] = {
+ [SYSCONF] = print_sysconf,
+ [CONFSTR] = print_confstr,
+ [PATHCONF] = print_pathconf,
+ [CONSTANT] = print_constant,
+ [UCONSTANT] = print_uconstant,
+};
+
+int main(int argc, char **argv)
+{
+ const char *progname = argv[0];
+ const struct conf_variable *cp;
+ const char *varname, *pathname;
+ int ch, found = 0;
+
+ (void)setlocale(LC_ALL, "");
+ while ((ch = getopt(argc, argv, "a")) != -1) {
+ switch (ch) {
+ case 'a':
+ all = 1;
+ break;
+ case '?':
+ default:
+ usage(progname);
+ }
+ }
+ argc -= optind;
+ argv += optind;
+
+ if (!all) {
+ if (argc == 0)
+ usage(progname);
+ varname = argv[0];
+ argc--;
+ argv++;
+ } else
+ varname = NULL;
+
+ if (argc > 1)
+ usage(progname);
+ pathname = argv[0]; /* may be NULL */
+
+ for (cp = conf_table; cp->name != NULL; cp++) {
+ if (!all && strcmp(varname, cp->name) != 0) continue;
+ if ((cp->type == PATHCONF) == (pathname != NULL)) {
+ if (type_handlers[cp->type](cp, pathname) < 0)
+ print_string(cp->name, "undefined");
+ found = 1;
+ } else if (!all)
+ errx(EXIT_FAILURE, "%s: invalid variable type", cp->name);
+ }
+ if (!all && !found) errx(EXIT_FAILURE, "%s: unknown variable", varname);
+ (void)fflush(stdout);
+ return ferror(stdout) ? EXIT_FAILURE : EXIT_SUCCESS;
+}
diff --git a/system/musl/getent.c b/system/musl/getent.c
new file mode 100644
index 000000000..b10d75acc
--- /dev/null
+++ b/system/musl/getent.c
@@ -0,0 +1,511 @@
+/*-
+ * Copyright (c) 2004-2006 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Luke Mewburn.
+ * Timo Teräs cleaned up the code for use in Alpine Linux with musl libc.
+ *
+ * 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
+ */
+
+#include <sys/socket.h>
+#include <sys/param.h>
+#include <ctype.h>
+#include <errno.h>
+#include <limits.h>
+#include <netdb.h>
+#include <pwd.h>
+#include <grp.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <paths.h>
+#include <err.h>
+
+#include <arpa/inet.h>
+#include <arpa/nameser.h>
+
+#include <net/if.h>
+#include <net/ethernet.h>
+#include <netinet/ether.h>
+#include <netinet/in.h>
+
+enum {
+ RV_OK = 0,
+ RV_USAGE = 1,
+ RV_NOTFOUND = 2,
+ RV_NOENUM = 3
+};
+
+static int usage(const char *);
+
+static int parsenum(const char *word, unsigned long *result)
+{
+ unsigned long num;
+ char *ep;
+
+ if (!isdigit((unsigned char)word[0]))
+ return 0;
+ errno = 0;
+ num = strtoul(word, &ep, 10);
+ if (num == ULONG_MAX && errno == ERANGE)
+ return 0;
+ if (*ep != '\0')
+ return 0;
+ *result = num;
+ return 1;
+}
+
+/*
+ * printfmtstrings --
+ * vprintf(format, ...),
+ * then the aliases (beginning with prefix, separated by sep),
+ * then a newline
+ */
+__attribute__ ((format (printf, 4, 5)))
+static void printfmtstrings(char *strings[], const char *prefix, const char *sep,
+ const char *fmt, ...)
+{
+ va_list ap;
+ const char *curpref;
+ size_t i;
+
+ va_start(ap, fmt);
+ (void)vprintf(fmt, ap);
+ va_end(ap);
+
+ curpref = prefix;
+ for (i = 0; strings[i] != NULL; i++) {
+ (void)printf("%s%s", curpref, strings[i]);
+ curpref = sep;
+ }
+ (void)printf("\n");
+}
+
+static int ethers(int argc, char *argv[])
+{
+ char hostname[MAXHOSTNAMELEN + 1], *hp;
+ struct ether_addr ea, *eap;
+ int i, rv;
+
+ if (argc == 2) {
+ warnx("Enumeration not supported on ethers");
+ return RV_NOENUM;
+ }
+
+ rv = RV_OK;
+ for (i = 2; i < argc; i++) {
+ if ((eap = ether_aton(argv[i])) == NULL) {
+ eap = &ea;
+ hp = argv[i];
+ if (ether_hostton(hp, eap) != 0) {
+ rv = RV_NOTFOUND;
+ break;
+ }
+ } else {
+ hp = hostname;
+ if (ether_ntohost(hp, eap) != 0) {
+ rv = RV_NOTFOUND;
+ break;
+ }
+ }
+ (void)printf("%-17s %s\n", ether_ntoa(eap), hp);
+ }
+ return rv;
+}
+
+static void groupprint(const struct group *gr)
+{
+ printfmtstrings(gr->gr_mem, ":", ",", "%s:%s:%u",
+ gr->gr_name, gr->gr_passwd, gr->gr_gid);
+}
+
+static int group(int argc, char *argv[])
+{
+ struct group *gr;
+ unsigned long id;
+ int i, rv;
+
+ rv = RV_OK;
+ if (argc == 2) {
+ while ((gr = getgrent()) != NULL)
+ groupprint(gr);
+ } else {
+ for (i = 2; i < argc; i++) {
+ if (parsenum(argv[i], &id))
+ gr = getgrgid((gid_t)id);
+ else
+ gr = getgrnam(argv[i]);
+ if (gr == NULL) {
+ rv = RV_NOTFOUND;
+ break;
+ }
+ groupprint(gr);
+ }
+ }
+ endgrent();
+ return rv;
+}
+
+static void hostsprint(const struct hostent *he)
+{
+ char buf[INET6_ADDRSTRLEN];
+
+ if (inet_ntop(he->h_addrtype, he->h_addr, buf, sizeof(buf)) == NULL)
+ (void)strlcpy(buf, "# unknown", sizeof(buf));
+ printfmtstrings(he->h_aliases, " ", " ", "%-16s %s", buf, he->h_name);
+}
+
+static int hosts(int argc, char *argv[])
+{
+ struct hostent *he;
+ char addr[IN6ADDRSZ];
+ int i, rv;
+
+ sethostent(1);
+ rv = RV_OK;
+ if (argc == 2) {
+ while ((he = gethostent()) != NULL)
+ hostsprint(he);
+ } else {
+ for (i = 2; i < argc; i++) {
+ if (inet_pton(AF_INET6, argv[i], (void *)addr) > 0)
+ he = gethostbyaddr(addr, IN6ADDRSZ, AF_INET6);
+ else if (inet_pton(AF_INET, argv[i], (void *)addr) > 0)
+ he = gethostbyaddr(addr, INADDRSZ, AF_INET);
+ else if ((he = gethostbyname2(argv[i], AF_INET6)) == NULL)
+ he = gethostbyname2(argv[i], AF_INET);
+ if (he == NULL) {
+ rv = RV_NOTFOUND;
+ break;
+ }
+ hostsprint(he);
+ }
+ }
+ endhostent();
+ return rv;
+}
+
+static int ahosts_ex(int family, int flags, int argc, char *argv[])
+{
+ static const char *socktypes[] = {
+ [SOCK_STREAM] = "STREAM",
+ [SOCK_DGRAM] = "DGRAM",
+ [SOCK_RAW] = "RAW",
+ [SOCK_RDM] = "RDM",
+ [SOCK_SEQPACKET] = "SEQPACKET",
+ [SOCK_DCCP] = "DCCP",
+ [SOCK_PACKET] = "PACKET",
+ };
+ const char *sockstr;
+ char sockbuf[16], buf[INET6_ADDRSTRLEN];
+ struct addrinfo *res, *r, hint;
+ void *addr;
+ int i;
+
+ if (argc == 2)
+ return hosts(argc, argv);
+
+ hint = (struct addrinfo) {
+ .ai_family = family,
+ .ai_flags = AI_ADDRCONFIG | AI_CANONNAME | flags,
+ };
+
+ for (i = 2; i < argc; i++) {
+ if (getaddrinfo(argv[i], 0, &hint, &res) != 0)
+ return RV_NOTFOUND;
+
+ for (r = res; r; r = r->ai_next) {
+ sockstr = NULL;
+ if (r->ai_socktype >= 0 && r->ai_socktype < sizeof(socktypes)/sizeof(socktypes[0]))
+ sockstr = socktypes[r->ai_socktype];
+ if (!sockstr) {
+ sprintf(buf, "%d", r->ai_socktype);
+ sockstr = sockbuf;
+ }
+ switch (r->ai_family) {
+ case AF_INET:
+ addr = &((struct sockaddr_in*) r->ai_addr)->sin_addr;
+ break;
+ case AF_INET6:
+ addr = &((struct sockaddr_in6*) r->ai_addr)->sin6_addr;
+ break;
+ default:
+ continue;
+ }
+ if (inet_ntop(r->ai_family, addr, buf, sizeof(buf)) == NULL)
+ (void)strlcpy(buf, "# unknown", sizeof(buf));
+ printf("%-15s %-6s %s\n", buf, sockstr, r->ai_canonname ?: "");
+ }
+ }
+
+ return RV_OK;
+}
+
+static int ahosts(int argc, char *argv[])
+{
+ return ahosts_ex(AF_UNSPEC, 0, argc, argv);
+}
+
+static int ahostsv4(int argc, char *argv[])
+{
+ return ahosts_ex(AF_INET, 0, argc, argv);
+}
+
+static int ahostsv6(int argc, char *argv[])
+{
+ return ahosts_ex(AF_INET6, AI_V4MAPPED, argc, argv);
+}
+
+static void networksprint(const struct netent *ne)
+{
+ char buf[INET6_ADDRSTRLEN];
+ struct in_addr ianet;
+
+ ianet = inet_makeaddr(ne->n_net, 0);
+ if (inet_ntop(ne->n_addrtype, &ianet, buf, sizeof(buf)) == NULL)
+ (void)strlcpy(buf, "# unknown", sizeof(buf));
+ printfmtstrings(ne->n_aliases, " ", " ", "%-16s %s", ne->n_name, buf);
+}
+
+static int networks(int argc, char *argv[])
+{
+ struct netent *ne;
+ in_addr_t net;
+ int i, rv;
+
+ setnetent(1);
+ rv = RV_OK;
+ if (argc == 2) {
+ while ((ne = getnetent()) != NULL)
+ networksprint(ne);
+ } else {
+ for (i = 2; i < argc; i++) {
+ net = inet_network(argv[i]);
+ if (net != INADDR_NONE)
+ ne = getnetbyaddr(net, AF_INET);
+ else
+ ne = getnetbyname(argv[i]);
+ if (ne != NULL) {
+ rv = RV_NOTFOUND;
+ break;
+ }
+ networksprint(ne);
+ }
+ }
+ endnetent();
+ return rv;
+}
+
+static void passwdprint(struct passwd *pw)
+{
+ (void)printf("%s:%s:%u:%u:%s:%s:%s\n",
+ pw->pw_name, pw->pw_passwd, pw->pw_uid,
+ pw->pw_gid, pw->pw_gecos, pw->pw_dir, pw->pw_shell);
+}
+
+static int passwd(int argc, char *argv[])
+{
+ struct passwd *pw;
+ unsigned long id;
+ int i, rv;
+
+ rv = RV_OK;
+ if (argc == 2) {
+ while ((pw = getpwent()) != NULL)
+ passwdprint(pw);
+ } else {
+ for (i = 2; i < argc; i++) {
+ if (parsenum(argv[i], &id))
+ pw = getpwuid((uid_t)id);
+ else
+ pw = getpwnam(argv[i]);
+ if (pw == NULL) {
+ rv = RV_NOTFOUND;
+ break;
+ }
+ passwdprint(pw);
+ }
+ }
+ endpwent();
+ return rv;
+}
+
+static void protocolsprint(struct protoent *pe)
+{
+ printfmtstrings(pe->p_aliases, " ", " ",
+ "%-16s %5d", pe->p_name, pe->p_proto);
+}
+
+static int protocols(int argc, char *argv[])
+{
+ struct protoent *pe;
+ unsigned long id;
+ int i, rv;
+
+ setprotoent(1);
+ rv = RV_OK;
+ if (argc == 2) {
+ while ((pe = getprotoent()) != NULL)
+ protocolsprint(pe);
+ } else {
+ for (i = 2; i < argc; i++) {
+ if (parsenum(argv[i], &id))
+ pe = getprotobynumber((int)id);
+ else
+ pe = getprotobyname(argv[i]);
+ if (pe == NULL) {
+ rv = RV_NOTFOUND;
+ break;
+ }
+ protocolsprint(pe);
+ }
+ }
+ endprotoent();
+ return rv;
+}
+
+static void servicesprint(struct servent *se)
+{
+ printfmtstrings(se->s_aliases, " ", " ",
+ "%-16s %5d/%s",
+ se->s_name, ntohs(se->s_port), se->s_proto);
+
+}
+
+static int services(int argc, char *argv[])
+{
+ struct servent *se;
+ unsigned long id;
+ char *proto;
+ int i, rv;
+
+ setservent(1);
+ rv = RV_OK;
+ if (argc == 2) {
+ while ((se = getservent()) != NULL)
+ servicesprint(se);
+ } else {
+ for (i = 2; i < argc; i++) {
+ proto = strchr(argv[i], '/');
+ if (proto != NULL)
+ *proto++ = '\0';
+ if (parsenum(argv[i], &id))
+ se = getservbyport(htons(id), proto);
+ else
+ se = getservbyname(argv[i], proto);
+ if (se == NULL) {
+ rv = RV_NOTFOUND;
+ break;
+ }
+ servicesprint(se);
+ }
+ }
+ endservent();
+ return rv;
+}
+
+static int shells(int argc, char *argv[])
+{
+ const char *sh;
+ int i, rv;
+
+ setusershell();
+ rv = RV_OK;
+ if (argc == 2) {
+ while ((sh = getusershell()) != NULL)
+ (void)printf("%s\n", sh);
+ } else {
+ for (i = 2; i < argc; i++) {
+ setusershell();
+ while ((sh = getusershell()) != NULL) {
+ if (strcmp(sh, argv[i]) == 0) {
+ (void)printf("%s\n", sh);
+ break;
+ }
+ }
+ if (sh == NULL) {
+ rv = RV_NOTFOUND;
+ break;
+ }
+ }
+ }
+ endusershell();
+ return rv;
+}
+
+static struct getentdb {
+ const char *name;
+ int (*callback)(int, char *[]);
+} databases[] = {
+ { "ethers", ethers, },
+ { "group", group, },
+ { "hosts", hosts, },
+ { "ahosts", ahosts, },
+ { "ahostsv4", ahostsv4, },
+ { "ahostsv6", ahostsv6, },
+ { "networks", networks, },
+ { "passwd", passwd, },
+ { "protocols", protocols, },
+ { "services", services, },
+ { "shells", shells, },
+
+ { NULL, NULL, },
+};
+
+static int usage(const char *arg0)
+{
+ struct getentdb *curdb;
+ size_t i;
+
+ (void)fprintf(stderr, "Usage: %s database [key ...]\n", arg0);
+ (void)fprintf(stderr, "\tdatabase may be one of:");
+ for (i = 0, curdb = databases; curdb->name != NULL; curdb++, i++) {
+ if (i % 7 == 0)
+ (void)fputs("\n\t\t", stderr);
+ (void)fprintf(stderr, "%s%s", i % 7 == 0 ? "" : " ",
+ curdb->name);
+ }
+ (void)fprintf(stderr, "\n");
+ exit(RV_USAGE);
+ /* NOTREACHED */
+}
+
+int
+main(int argc, char *argv[])
+{
+ struct getentdb *curdb;
+
+ if (argc < 2)
+ usage(argv[0]);
+ for (curdb = databases; curdb->name != NULL; curdb++)
+ if (strcmp(curdb->name, argv[1]) == 0)
+ return (*curdb->callback)(argc, argv);
+
+ warn("Unknown database `%s'", argv[1]);
+ usage(argv[0]);
+ /* NOTREACHED */
+}
diff --git a/system/musl/handle-aux-at_base.patch b/system/musl/handle-aux-at_base.patch
new file mode 100644
index 000000000..c16463824
--- /dev/null
+++ b/system/musl/handle-aux-at_base.patch
@@ -0,0 +1,43 @@
+diff --git a/src/env/__init_tls.c b/src/env/__init_tls.c
+index b125eb1..616c6a6 100644
+--- a/src/env/__init_tls.c
++++ b/src/env/__init_tls.c
+@@ -66,8 +66,10 @@ void *__copy_tls(unsigned char *mem)
+ }
+
+ #if ULONG_MAX == 0xffffffff
++typedef Elf32_Ehdr Ehdr;
+ typedef Elf32_Phdr Phdr;
+ #else
++typedef Elf64_Ehdr Ehdr;
+ typedef Elf64_Phdr Phdr;
+ #endif
+
+@@ -77,15 +79,23 @@ extern const size_t _DYNAMIC[];
+ static void static_init_tls(size_t *aux)
+ {
+ unsigned char *p;
+- size_t n;
++ size_t n, e;
+ Phdr *phdr, *tls_phdr=0;
+ size_t base = 0;
+ void *mem;
+
+- for (p=(void *)aux[AT_PHDR],n=aux[AT_PHNUM]; n; n--,p+=aux[AT_PHENT]) {
++ if (aux[AT_BASE]) {
++ Ehdr *ehdr = (void *)aux[AT_BASE];
++ p = (unsigned char *)aux[AT_BASE] + ehdr->e_phoff;
++ n = ehdr->e_phnum;
++ e = ehdr->e_phentsize;
++ } else {
++ p = (void *)aux[AT_PHDR];
++ n = aux[AT_PHNUM];
++ e = aux[AT_PHENT];
++ }
++ for (; n; n--, p+=e) {
+ phdr = (void *)p;
+- if (phdr->p_type == PT_PHDR)
+- base = aux[AT_PHDR] - phdr->p_vaddr;
+ if (phdr->p_type == PT_DYNAMIC && _DYNAMIC)
+ base = (size_t)_DYNAMIC - phdr->p_vaddr;
+ if (phdr->p_type == PT_TLS)
diff --git a/system/musl/iconv.c b/system/musl/iconv.c
new file mode 100644
index 000000000..f5d5ce2aa
--- /dev/null
+++ b/system/musl/iconv.c
@@ -0,0 +1,110 @@
+/*
+ * iconv.c
+ * Implementation of SUSv4 XCU iconv utility
+ * Copyright © 2011 Rich Felker
+ * Licensed under the terms of the GNU General Public License, v2 or later
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <iconv.h>
+#include <locale.h>
+#include <langinfo.h>
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+
+int main(int argc, char **argv)
+{
+ const char *from=0, *to=0;
+ int b;
+ iconv_t cd;
+ char buf[BUFSIZ];
+ char outbuf[BUFSIZ*4];
+ char *in, *out;
+ size_t inb;
+ size_t l;
+ size_t unitsize=0;
+ int err=0;
+ FILE *f;
+
+ while ((b = getopt(argc, argv, "f:t:csl")) != EOF) switch(b) {
+ case 'l':
+ puts("UTF-8, UTF-16BE, UTF-16LE, UTF-32BE, UTF32-LE, UCS-2BE, UCS-2LE, WCHAR_T,\n"
+ "US_ASCII, ISO8859-1, ISO8859-2, ISO8859-3, ISO8859-4, ISO8859-5,\n"
+ "ISO8859-6, ISO8859-7, ...");
+ exit(0);
+ case 'c': case 's': break;
+ case 'f': from=optarg; break;
+ case 't': to=optarg; break;
+ default: exit(1);
+ }
+
+ if (!from || !to) {
+ setlocale(LC_CTYPE, "");
+ if (!to) to = nl_langinfo(CODESET);
+ if (!from) from = nl_langinfo(CODESET);
+ }
+ cd = iconv_open(to, from);
+ if (cd == (iconv_t)-1) {
+ if (iconv_open(to, "WCHAR_T") == (iconv_t)-1)
+ fprintf(stderr, "iconv: destination charset %s: ", to);
+ else
+ fprintf(stderr, "iconv: source charset %s: ", from);
+ perror("");
+ exit(1);
+ }
+ if (optind == argc) argv[argc++] = "-";
+
+ for (; optind < argc; optind++) {
+ if (argv[optind][0]=='-' && !argv[optind][1]) {
+ f = stdin;
+ argv[optind] = "(stdin)";
+ } else if (!(f = fopen(argv[optind], "rb"))) {
+ fprintf(stderr, "iconv: %s: ", argv[optind]);
+ perror("");
+ err = 1;
+ continue;
+ }
+ inb = 0;
+ for (;;) {
+ in = buf;
+ out = outbuf;
+ l = fread(buf+inb, 1, sizeof(buf)-inb, f);
+ inb += l;
+ if (!inb) break;
+ if (iconv(cd, &in, &inb, &out, (size_t [1]){sizeof outbuf})==-1
+ && errno == EILSEQ) {
+ if (!unitsize) {
+ wchar_t wc='0';
+ char dummy[4], *dummyp=dummy;
+ iconv_t cd2 = iconv_open(from, "WCHAR_T");
+ if (cd == (iconv_t)-1) {
+ unitsize = 1;
+ } else {
+ iconv(cd2,
+ (char *[1]){(char *)&wc},
+ (size_t[1]){1},
+ &dummyp, (size_t[1]){4});
+ unitsize = dummyp-dummy;
+ if (!unitsize) unitsize=1;
+ }
+ }
+ inb-=unitsize;
+ in+=unitsize;
+ }
+ if (inb && !l && errno==EINVAL) break;
+ if (out>outbuf && !fwrite(outbuf, out-outbuf, 1, stdout)) {
+ perror("iconv: write error");
+ exit(1);
+ }
+ if (inb) memmove(buf, in, inb);
+ }
+ if (ferror(f)) {
+ fprintf(stderr, "iconv: %s: ", argv[optind]);
+ perror("");
+ err = 1;
+ }
+ }
+ return err;
+}
diff --git a/system/musl/ldconfig b/system/musl/ldconfig
new file mode 100644
index 000000000..ccf7c2aa4
--- /dev/null
+++ b/system/musl/ldconfig
@@ -0,0 +1,18 @@
+#!/bin/sh
+scan_dirs() {
+ scanelf -qS "$@" | while read SONAME FILE; do
+ TARGET="${FILE##*/}"
+ LINK="${FILE%/*}/$SONAME"
+ case "$FILE" in
+ /lib/*|/usr/lib/*|/usr/local/lib/*) ;;
+ *) [ -h "$LINK" -o ! -e "$LINK" ] && ln -sf "$TARGET" "$LINK"
+ esac
+ done
+ return 0
+}
+# eat ldconfig options
+while getopts "nNvXvf:C:r:" opt; do
+ :
+done
+shift $(( $OPTIND - 1 ))
+[ $# -gt 0 ] && scan_dirs "$@"