mailing list of musl libc
 help / color / mirror / code / Atom feed
From: Рысь <lynx@sibserver.ru>
To: musl@lists.openwall.com
Subject: Re: musl and android
Date: Thu, 22 Jan 2015 09:37:52 +0700	[thread overview]
Message-ID: <20150122093752.671ec2f0@sibserver.ru> (raw)
In-Reply-To: <20150121183637.GK4574@brightrain.aerifal.cx>

[-- Attachment #1: Type: text/plain, Size: 459 bytes --]

В Wed, 21 Jan 2015 13:36:37 -0500
Rich Felker <dalias@libc.org> пишет:

> It would be very much appreciated to send patches as attachments
> rather than links. There's no way to have a well-documented ongoing
> discussion of the patch if it's not in a permanent place for review,
> and attached to the email/archives is the best way to achieve that.
> 
> Rich

Sorry.

Now patch is attached (I think it is more sane now to include it here)

[-- Attachment #2: musl-1.1.4_android.patch --]
[-- Type: application/octet-stream, Size: 33347 bytes --]

--- /dev/null
+++ musl-1.1.4/include/android/atz.h
@@ -0,0 +1,7 @@
+#define A_TZ_IDEXFILE "/system/usr/share/zoneinfo/zoneinfo.idx"
+#define A_TZ_ZONEFILE "/system/usr/share/zoneinfo/zoneinfo.dat"
+#define A_TZ_NAMELEN 40
+#define A_TZ_INTLEN 4
+
+int android_find_tz(const char *tzname, off_t *offs, size_t *len);
+int android_get_tz(unsigned char *out, size_t outl, off_t offs, size_t len);
--- /dev/null
+++ musl-1.1.4/include/android/idmap.h
@@ -0,0 +1,7 @@
+#define A_LNSIZE 256
+
+char *android_getpasswddb(size_t *sz);
+char *android_getgroupdb(size_t *sz);
+char *android_mkpasswd(const char *name, uid_t uid);
+char *android_mkgroup(const char *name, gid_t gid);
+int android_isappusr(const char *name);
--- /dev/null
+++ musl-1.1.4/include/android/istonum.h
@@ -0,0 +1,5 @@
+int __istonum(const char *s, long int *res);
+int __istonum_i(const char *s, int *res);
+int __istonum_sz(const char *s, size_t *res);
+int __istonum_uid(const char *s, uid_t *res);
+int __istonum_gid(const char *s, gid_t *res);
--- /dev/null
+++ musl-1.1.4/include/android/property.h
@@ -0,0 +1,10 @@
+extern int __prop_fd;
+extern size_t __prop_size;
+extern void *__prop_map;
+
+#define PROP_NAMELEN 32
+#define PROP_VALUELEN 92
+#define PROP_SERIALLEN 4
+
+int android_property_get(const char *name, char *val);
+int android_property_set(const char *name, const char *val);
--- /dev/null
+++ musl-1.1.4/include/android/version.h
@@ -0,0 +1 @@
+int android_get_version(int *maj, int *min, int *sub, int *rsvd);
--- musl-1.1.4.o/include/mntent.h
+++ musl-1.1.4/include/mntent.h
@@ -8,7 +8,7 @@
 #define __NEED_FILE
 #include <bits/alltypes.h>
 
-#define MOUNTED "/etc/mtab"
+#define MOUNTED "/proc/mounts"
 
 #define MNTTYPE_IGNORE	"ignore"
 #define MNTTYPE_NFS	"nfs"
--- musl-1.1.4.o/include/paths.h
+++ musl-1.1.4/include/paths.h
@@ -1,31 +1,31 @@
 #ifndef _PATHS_H
 #define _PATHS_H
 
-#define	_PATH_DEFPATH "/usr/local/bin:/bin:/usr/bin"
-#define	_PATH_STDPATH "/bin:/usr/bin:/sbin:/usr/sbin"
+#define	_PATH_DEFPATH "/system/bin:/system/xbin:/vendor/bin"
+#define	_PATH_STDPATH "/system/bin:/system/xbin"
 
-#define	_PATH_BSHELL	"/bin/sh"
+#define	_PATH_BSHELL	"/system/bin/sh"
 #define	_PATH_CONSOLE	"/dev/console"
 #define	_PATH_DEVNULL	"/dev/null"
 #define	_PATH_KLOG	"/proc/kmsg"
-#define	_PATH_LASTLOG	"/var/log/lastlog"
-#define	_PATH_MAILDIR	"/var/mail"
-#define	_PATH_MAN	"/usr/share/man"
+#define	_PATH_LASTLOG	"/data/misc/lastlog"
+#define	_PATH_MAILDIR	"/data/misc/mail"
+#define	_PATH_MAN	"/system/share/man"
 #define	_PATH_MNTTAB	"/etc/fstab"
-#define	_PATH_MOUNTED	"/etc/mtab"
+#define	_PATH_MOUNTED	"/proc/mounts"
 #define	_PATH_NOLOGIN	"/etc/nologin"
-#define	_PATH_SENDMAIL	"/usr/sbin/sendmail"
-#define	_PATH_SHADOW	"/etc/shadow"
-#define	_PATH_SHELLS	"/etc/shells"
+#define	_PATH_SENDMAIL	"/system/xbin/sendmail"
+#define	_PATH_SHADOW	"/system/etc/shadow"
+#define	_PATH_SHELLS	"/system/etc/shells"
 #define	_PATH_TTY	"/dev/tty"
 #define _PATH_UTMP	"/dev/null/utmp"
-#define	_PATH_VI	"/usr/bin/vi"
+#define	_PATH_VI	"/system/xbin/vi"
 #define _PATH_WTMP	"/dev/null/wtmp"
 
 #define	_PATH_DEV	"/dev/"
-#define	_PATH_TMP	"/tmp/"
-#define	_PATH_VARDB	"/var/lib/misc/"
-#define	_PATH_VARRUN	"/var/run/"
-#define	_PATH_VARTMP	"/var/tmp/"
+#define	_PATH_TMP	"/data/tmp/"
+#define	_PATH_VARDB	"/data/misc/"
+#define	_PATH_VARRUN	"/data/run/"
+#define	_PATH_VARTMP	"/data/tmp/"
 
 #endif
--- musl-1.1.4.o/include/resolv.h
+++ musl-1.1.4/include/resolv.h
@@ -64,7 +64,7 @@
 #define	__RES	19991006
 
 #ifndef _PATH_RESCONF
-#define _PATH_RESCONF        "/etc/resolv.conf"
+#define _PATH_RESCONF        "/system/etc/resolv.conf"
 #endif
 
 struct res_sym {
--- musl-1.1.4.o/include/stdio.h
+++ musl-1.1.4/include/stdio.h
@@ -154,7 +154,7 @@
 
 #if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) \
  || defined(_BSD_SOURCE)
-#define P_tmpdir "/tmp"
+#define P_tmpdir "/data/tmp"
 char *tempnam(const char *, const char *);
 #endif
 
--- /dev/null
+++ musl-1.1.4/src/android/atz.c
@@ -0,0 +1,70 @@
+#define _GNU_SOURCE
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <fcntl.h>
+#include <android/atz.h>
+#include "syscall.h"
+
+static int __toint(unsigned char *s)
+{
+	return (s[0] << 24) | (s[1] << 16) | (s[2] << 8) | s[3];
+}
+
+int android_find_tz(const char *tzname, off_t *offs, size_t *len)
+{
+	size_t nl;
+	int fd = -1;
+	struct stat st;
+	unsigned char *map = MAP_FAILED, *p;
+
+	nl = strnlen(tzname, A_TZ_NAMELEN);
+
+	fd = open(A_TZ_IDEXFILE, O_RDONLY|O_CLOEXEC);
+	if (fd == -1) goto _err;
+
+	if (!fstat(fd, &st))
+		map = mmap(0, st.st_size, PROT_READ, MAP_SHARED, fd, 0);
+
+	if (map == MAP_FAILED) goto _err;
+	close(fd);
+
+	p = memmem(map, st.st_size, tzname, nl);
+	if (!p) goto _err;
+
+	if (offs) *offs = (off_t)__toint(p + A_TZ_NAMELEN);
+	if (len) *len = (size_t)__toint(p + A_TZ_NAMELEN + A_TZ_INTLEN);
+
+	munmap(map, st.st_size);
+
+	return 1;
+
+_err:
+	if (map && st.st_size) munmap(map, st.st_size);
+	return 0;
+}
+
+int android_get_tz(unsigned char *out, size_t outl, off_t offs, size_t len)
+{
+	int fd = -1;
+
+	if (len > outl) goto _err;
+
+	fd = open(A_TZ_ZONEFILE, O_RDONLY|O_CLOEXEC);
+	if (fd == -1) goto _err;
+
+	if (lseek(fd, offs, SEEK_SET) == -1) goto _err;
+
+	if (read(fd, out, len) < len) goto _err;
+
+	close(fd);
+
+	return 1;
+
+_err:
+	if (fd != -1) close(fd);
+	return 0;
+}
--- /dev/null
+++ musl-1.1.4/src/android/idmap.c
@@ -0,0 +1,232 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/types.h>
+#include <android/idmap.h>
+#include <android/istonum.h>
+#include <android/version.h>
+
+#define NOUID ((uid_t)-1)
+#define NOGID ((gid_t)-1)
+
+#define A_FIRSTAPPID 10000
+#define A_PERUSRAPPS 100000
+
+#define MULTISID(x) ((x-A_FIRSTAPPID)/A_PERUSRAPPS)
+#define SIDMULTI(x) ((x*A_PERUSRAPPS)+A_FIRSTAPPID)
+#define MULTIUID(x) (x-SIDMULTI(MULTISID(x)))
+
+static char __a_users[] =
+"root:x:0:0:android root:/data/root:/system/bin/sh\n"
+"system:x:1000:1000:android user:/:/system/bin/sh\n"
+"radio:x:1001:1001:android user:/:/system/bin/sh\n"
+"bluetooth:x:1002:1002:android user:/:/system/bin/sh\n"
+"graphics:x:1003:1003:android user:/:/system/bin/sh\n"
+"input:x:1004:1004:android user:/:/system/bin/sh\n"
+"audio:x:1005:1005:android user:/:/system/bin/sh\n"
+"camera:x:1006:1006:android user:/:/system/bin/sh\n"
+"log:x:1007:1007:android user:/:/system/bin/sh\n"
+"compass:x:1008:1008:android user:/:/system/bin/sh\n"
+"mount:x:1009:1009:android user:/:/system/bin/sh\n"
+"wifi:x:1010:1010:android user:/:/system/bin/sh\n"
+"adb:x:1011:1011:android user:/:/system/bin/sh\n"
+"install:x:1012:1012:android user:/:/system/bin/sh\n"
+"media:x:1013:1013:android user:/:/system/bin/sh\n"
+"dhcp:x:1014:1014:android user:/:/system/bin/sh\n"
+"sdcard_rw:x:1015:1015:android user:/:/system/bin/sh\n"
+"vpn:x:1016:1016:android user:/:/system/bin/sh\n"
+"keystore:x:1017:1017:android user:/:/system/bin/sh\n"
+"usb:x:1018:1018:android user:/:/system/bin/sh\n"
+"drm:x:1019:1019:android user:/:/system/bin/sh\n"
+"available:x:1020:1020:android user:/:/system/bin/sh\n"
+"gps:x:1021:1021:android user:/:/system/bin/sh\n"
+"media_rw:x:1023:1023:android user:/:/system/bin/sh\n"
+"mtp:x:1024:1024:android user:/:/system/bin/sh\n"
+"nfc:x:1027:1027:android user:/:/system/bin/sh\n"
+"shell:x:2000:2000:android shell:/data:/system/bin/sh\n"
+"cache:x:2001:2001:android user:/:/system/bin/sh\n"
+"diag:x:2002:2002:android user:/:/system/bin/sh\n"
+"misc:x:9998:9998:android user:/:/system/bin/sh\n"
+"nobody:x:9999:9999:android nobody:/:/system/bin/sh\n"
+;
+
+static char __a_groups[] =
+"root:x:0:\n"
+"system:x:1000:\n"
+"radio:x:1001:\n"
+"bluetooth:x:1002:\n"
+"graphics:x:1003:\n"
+"input:x:1004:\n"
+"audio:x:1005:\n"
+"camera:x:1006:\n"
+"log:x:1007:\n"
+"compass:x:1008:\n"
+"mount:x:1009:\n"
+"wifi:x:1010:\n"
+"adb:x:1011:\n"
+"install:x:1012:\n"
+"media:x:1013:\n"
+"dhcp:x:1014:\n"
+"sdcard_rw:x:1015:\n"
+"vpn:x:1016:\n"
+"keystore:x:1017:\n"
+"usb:x:1018:\n"
+"drm:x:1019:\n"
+"available:x:1020:\n"
+"gps:x:1021:\n"
+"media_rw:x:1023:\n"
+"mtp:x:1024:\n"
+"drmrpc:x:1026:\n"
+"nfc:x:1027:\n"
+"shell:x:2000:\n"
+"cache:x:2001:\n"
+"diag:x:2002:\n"
+"net_bt_admin:x:3001:\n"
+"net_bt:x:3002:\n"
+"inet:x:3003:\n"
+"net_raw:x:3004:\n"
+"net_admin:x:3005:\n"
+"net_bw_stats:x:3006:\n"
+"net_bw_acct:x:3007:\n"
+"misc:x:9998:\n"
+"nobody:x:9999:\n"
+;
+
+static char gecos[] = "android virtual";
+
+static int __issuper(void)
+{
+	return !!(getuid() == 0);
+}
+
+static char *__xgetenv(const char *name)
+{
+	if (__issuper()) return getenv(name);
+	else return NULL;
+}
+
+static int __a_is_multiuser(void)
+{
+	int maj, min;
+
+	if (!android_get_version(&maj, &min, NULL, NULL)) return 0;
+	if (maj >= 5) return 1;
+	if (maj == 4) {
+		if (min >= 1) return 1;
+		else return 0;
+	}
+	if (maj <= 3) return 0;
+}
+
+char *android_getpasswddb(size_t *sz)
+{
+	*sz = sizeof(__a_users);
+	return __a_users;
+}
+
+char *android_getgroupdb(size_t *sz)
+{
+	*sz = sizeof(__a_groups);
+	return __a_groups;
+}
+
+char *android_mkpasswd(const char *name, uid_t uid)
+{
+	static char p[A_LNSIZE];
+	char *udir = "/data";
+	char *sh = "/system/bin/sh";
+	char *s, *d;
+
+	memset(p, 0, sizeof(p));
+
+	s = __xgetenv("_A_USERDIR");
+	if (s) udir = s;
+	s = __xgetenv("_A_SHELL");
+	if (s) sh = s;
+
+	if (name) {
+		uid_t a, b;
+		if (__a_is_multiuser() && *name == 'u' && strchr(name, '_')) {
+			strncpy(p, name, A_LNSIZE);
+			s = p+1;
+			d = strstr(s, "_a");
+			if (!d) return NULL;
+			*d = 0; d += 2;
+			if (!__istonum_uid(s, &a)) return NULL;
+			if (!__istonum_uid(d, &b)) return NULL;
+			uid = SIDMULTI(a)+b;
+		}
+		else if (!strncmp(name, "app_", 4)) {
+			uid_t y;
+			const char *S;
+
+			S = name+4;
+			if (!__istonum_uid(S, &y)) return NULL;
+			uid = y+A_FIRSTAPPID;
+		}
+		else return NULL;
+
+		snprintf(p, sizeof(p), "%s:x:%u:%u:%s:%s:%s", name, uid, uid, gecos, udir, sh);
+	}
+	else if (uid >= A_FIRSTAPPID) {
+		if (__a_is_multiuser())
+			snprintf(p, sizeof(p), "u%u_a%u:x:%u:%u:%s:%s:%s", MULTISID(uid), MULTIUID(uid), uid, uid, gecos, udir, sh);
+		else
+			snprintf(p, sizeof(p), "app_%u:x:%u:%u:%s:%s:%s", uid-A_FIRSTAPPID, uid, uid, gecos, udir, sh);
+	}
+	else return NULL;
+
+	return p;
+}
+
+char *android_mkgroup(const char *name, gid_t gid)
+{
+	static char g[A_LNSIZE];
+	char *s, *d;
+
+	memset(g, 0, sizeof(g));
+
+	if (name) {
+		if (__a_is_multiuser() && *name == 'u' && strchr(name, '_')) {
+			gid_t a, b;
+
+			strncpy(g, name, A_LNSIZE);
+			s = g+1;
+			d = strstr(s, "_a");
+			if (!d) return NULL;
+			*d = 0; d += 2;
+			if (!__istonum_gid(s, &a)) return NULL;
+			if (!__istonum_gid(d, &b)) return NULL;
+			gid = SIDMULTI(a)+b;
+		}
+		else if (!strncmp(name, "app_", 4)) {
+			gid_t y;
+			const char *S;
+
+			S = name+4;
+			if (!__istonum_gid(S, &y)) return NULL;
+			else gid = y+A_FIRSTAPPID;
+		}
+		else return NULL;
+
+		snprintf(g, sizeof(g), "%s:x:%u:", name, gid);
+	}
+	else if (gid >= A_FIRSTAPPID) {
+		if (__a_is_multiuser())
+			snprintf(g, sizeof(g), "u%u_a%u:x:%u:", MULTISID(gid), MULTIUID(gid), gid);
+		else
+			snprintf(g, sizeof(g), "app_%u:x:%u:", gid-A_FIRSTAPPID, gid);
+	}
+	else return NULL;
+
+	return g;
+}
+
+int android_isappusr(const char *name)
+{
+	char *p;
+
+	p = android_mkpasswd(name, 0);
+	return (p == 0);
+}
--- /dev/null
+++ musl-1.1.4/src/android/istonum.c
@@ -0,0 +1,48 @@
+#include <sys/types.h>
+#include <stdlib.h>
+#include <android/istonum.h>
+
+int __istonum(const char *s, long int *res)
+{
+	char *p;
+	if (!s || *s == 0) return 0;
+	if (res) *res = strtol(s, &p, 10);
+	else strtol(s, &p, 10);
+	return (*p == 0);
+}
+
+int __istonum_i(const char *s, int *res)
+{
+	long int x = 0;
+	int y;
+	y = __istonum(s, &x);
+	*res = (int)x;
+	return y;
+}
+
+int __istonum_sz(const char *s, size_t *res)
+{
+	long int x = 0;
+	int y;
+	y = __istonum(s, &x);
+	*res = (size_t)x;
+	return y;
+}
+
+int __istonum_uid(const char *s, uid_t *res)
+{
+	long int x = 0;
+	int y;
+	y = __istonum(s, &x);
+	*res = (uid_t)x;
+	return y;
+}
+
+int __istonum_gid(const char *s, gid_t *res)
+{
+	long int x = 0;
+	int y;
+	y = __istonum(s, &x);
+	*res = (gid_t)x;
+	return y;
+}
--- /dev/null
+++ musl-1.1.4/src/android/property.c
@@ -0,0 +1,92 @@
+#define _GNU_SOURCE
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <errno.h>
+#include <android/istonum.h>
+#include <android/property.h>
+
+int __prop_fd = -1;
+size_t __prop_size = 0;
+void *__prop_map = NULL;
+
+static int __android_init_prop(void)
+{
+	char propcfg[64];
+	char *s, *d;
+
+	if (__prop_map) return 1;
+
+	s = getenv("ANDROID_PROPERTY_WORKSPACE");
+	if (!s) return 0;
+	strncpy(propcfg, s, sizeof(propcfg)); s = propcfg;
+
+	d = strchr(s, ',');
+	if (!d) return 0;
+	*d = 0; d++;
+
+	if (!__istonum_i(s, &__prop_fd)) return 0;
+	if (!__istonum_sz(d, &__prop_size)) return 0;
+
+	__prop_map = mmap(NULL, __prop_size, PROT_READ, MAP_SHARED, __prop_fd, 0);
+
+	if (__prop_map == MAP_FAILED) {
+		__prop_map = NULL;
+		return 0;
+	}
+
+	return 1;
+}
+
+#if 0
+static void __android_fini_prop(void)
+{
+	munmap(__prop_map, __prop_size);
+	__prop_map = NULL; __prop_size = 0;
+}
+#endif
+
+int android_property_get(const char *name, char *val)
+{
+	char *s, *d;
+	size_t nl;
+
+	if (!__android_init_prop()) return 0;
+
+	nl = strnlen(name, PROP_NAMELEN);
+	s = memmem(__prop_map, __prop_size, name, nl);
+
+	if (!s) return 0;
+
+	d = s+PROP_NAMELEN+PROP_SERIALLEN;
+	strncpy(val, d, PROP_VALUELEN);
+
+	return 1;
+}
+
+#if 0
+int android_property_getonce(const char *name, char *val)
+{
+	int r;
+
+	r = android_property_get(name, val);
+	__android_fini_prop();
+}
+
+char *android_getprop(const char *name)
+{
+	static char *r;
+
+	if (!r) r = malloc(PROP_VALUELEN);
+	if (!r) return r;
+	if (!android_property_get(name, r)) return NULL;
+	return r;
+}
+#endif
+
+int android_property_set(const char *name, const char *val)
+{
+	/* Sorry, unimplemented */
+	return 0;
+}
--- /dev/null
+++ musl-1.1.4/src/android/version.c
@@ -0,0 +1,62 @@
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <android/istonum.h>
+#include <android/property.h>
+
+int android_get_version(int *maj, int *min, int *sub, int *rsvd)
+{
+	char verstr[PROP_VALUELEN] = {0};
+	char *s, *d, *t;
+	int x;
+
+	if (!android_property_get("ro.build.version.release", verstr)) goto _err;
+
+	if (maj) *maj = 0;
+	if (min) *min = 0;
+	if (sub) *sub = 0;
+	if (rsvd) *rsvd = 0;
+
+	s = d = verstr; t = NULL; x = 0;
+	while ((s = strtok_r(d, ".", &t))) {
+		if (d) d = NULL;
+
+		switch (x) {
+			case 0: if (maj) if (!__istonum_i(s, maj)) goto _err; break;
+			case 1: if (min) if (!__istonum_i(s, min)) goto _err; break;
+			case 2: if (sub) if (!__istonum_i(s, sub)) goto _err; break;
+			case 3: if (rsvd) if (!__istonum_i(s, rsvd)) goto _err; break;
+		}
+
+		x++;
+	}
+
+	return 1;
+_err:	return 0;
+}
+
+#if 0
+int android_get_major(void)
+{
+	int r;
+
+	if (!android_get_version(&r, NULL, NULL, NULL)) return -1;
+	return r;
+}
+
+int android_get_minor(void)
+{
+	int r;
+
+	if (!android_get_version(NULL, &r, NULL, NULL)) return -1;
+	return r;
+}
+
+int android_get_subminor(void)
+{
+	int r;
+
+	if (!android_get_version(NULL, NULL, &r, NULL)) return -1;
+	return r;
+}
+#endif
--- musl-1.1.4.o/src/conf/confstr.c
+++ musl-1.1.4/src/conf/confstr.c
@@ -6,7 +6,7 @@
 {
 	const char *s = "";
 	if (!name) {
-		s = "/bin:/usr/bin";
+		s = "/system/bin:/system/xbin";
 	} else if ((name&~4U)!=1 && name-_CS_POSIX_V6_ILP32_OFF32_CFLAGS>31U) {
 		errno = EINVAL;
 		return 0;
--- musl-1.1.4.o/src/ldso/dynlink.c
+++ musl-1.1.4/src/ldso/dynlink.c
@@ -751,7 +751,7 @@
 					sys_path = "";
 				}
 			}
-			if (!sys_path) sys_path = "/lib:/usr/local/lib:/usr/lib";
+			if (!sys_path) sys_path = "/system/lib:/system/xlib:/vendor/lib";
 			fd = path_open(name, sys_path, buf, sizeof buf);
 		}
 		pathname = buf;
--- musl-1.1.4.o/src/legacy/getusershell.c
+++ musl-1.1.4/src/legacy/getusershell.c
@@ -2,7 +2,7 @@
 #include <stdio.h>
 #include <unistd.h>
 
-static const char defshells[] = "/bin/sh\n/bin/csh\n";
+static const char defshells[] = "/system/bin/sh\n/system/bin/csh\n";
 
 static char *line;
 static size_t linesize;
@@ -16,7 +16,7 @@
 
 void setusershell(void)
 {
-	if (!f) f = fopen("/etc/shells", "rbe");
+	if (!f) f = fopen("/system/etc/shells", "rbe");
 	if (!f) f = fmemopen((void *)defshells, sizeof defshells - 1, "rb");
 }
 
--- musl-1.1.4.o/src/misc/getgrouplist.c
+++ musl-1.1.4/src/misc/getgrouplist.c
@@ -1,8 +1,13 @@
 #define _GNU_SOURCE
+#include <sys/types.h>
+#include <pwd.h>
 #include <grp.h>
 #include <string.h>
 #include <limits.h>
+#include <android/idmap.h>
 
+struct group *__getgrent_android();
+
 int getgrouplist(const char *user, gid_t gid, gid_t *groups, int *ngroups)
 {
 	size_t n, i;
@@ -12,6 +17,8 @@
 	*groups++ = gid;
 	*ngroups = 1;
 
+	if (android_isappusr(user)) goto _end;
+
 	setgrent();
 	while ((gr = getgrent()) && *ngroups < INT_MAX) {
 		for (i=0; gr->gr_mem[i] && strcmp(user, gr->gr_mem[i]); i++);
@@ -20,5 +27,13 @@
 	}
 	endgrent();
 
-	return *ngroups > n ? -1 : *ngroups;
+	setgrent();
+	while ((gr = __getgrent_android()) && *ngroups < INT_MAX) {
+		for (i=0; gr->gr_mem[i] && strcmp(user, gr->gr_mem[i]); i++);
+		if (!gr->gr_mem[i]) continue;
+		if (++*ngroups <= n) *groups++ = gr->gr_gid;
+	}
+	endgrent();
+
+_end:	return *ngroups > n ? -1 : *ngroups;
 }
--- musl-1.1.4.o/src/misc/wordexp.c
+++ musl-1.1.4/src/misc/wordexp.c
@@ -113,7 +113,7 @@
 	if (!pid) {
 		if (p[1] == 1) fcntl(1, F_SETFD, 0);
 		else dup2(p[1], 1);
-		execl("/bin/sh", "sh", "-c",
+		execl("/system/bin/sh", "sh", "-c",
 			"eval \"printf %s\\\\\\\\0 x $1 $2\"",
 			"sh", s, redir, (char *)0);
 		_exit(1);
--- musl-1.1.4.o/src/network/getnameinfo.c
+++ musl-1.1.4/src/network/getnameinfo.c
@@ -50,7 +50,7 @@
 	char line[512], *p, *z;
 	unsigned char _buf[1032], atmp[16];
 	struct address iplit;
-	FILE _f, *f = __fopen_rb_ca("/etc/hosts", &_f, _buf, sizeof _buf);
+	FILE _f, *f = __fopen_rb_ca("/system/etc/hosts", &_f, _buf, sizeof _buf);
 	if (!f) return;
 	if (family == AF_INET) {
 		memcpy(atmp+12, a, 4);
@@ -90,7 +90,7 @@
 	unsigned long svport;
 	char line[128], *p, *z;
 	unsigned char _buf[1032];
-	FILE _f, *f = __fopen_rb_ca("/etc/services", &_f, _buf, sizeof _buf);
+	FILE _f, *f = __fopen_rb_ca("/system/etc/services", &_f, _buf, sizeof _buf);
 	if (!f) return;
 	while (fgets(line, sizeof line, f)) {
 		if ((p=strchr(line, '#'))) *p++='\n', *p=0;
--- musl-1.1.4.o/src/network/lookup_name.c
+++ musl-1.1.4/src/network/lookup_name.c
@@ -50,7 +50,7 @@
 	size_t l = strlen(name);
 	int cnt = 0;
 	unsigned char _buf[1032];
-	FILE _f, *f = __fopen_rb_ca("/etc/hosts", &_f, _buf, sizeof _buf);
+	FILE _f, *f = __fopen_rb_ca("/system/etc/hosts", &_f, _buf, sizeof _buf);
 	if (!f) return 0;
 	while (fgets(line, sizeof line, f) && cnt < MAXADDRS) {
 		char *p, *z;
--- musl-1.1.4.o/src/network/lookup_serv.c
+++ musl-1.1.4/src/network/lookup_serv.c
@@ -36,7 +36,7 @@
 	size_t l = strlen(name);
 
 	unsigned char _buf[1032];
-	FILE _f, *f = __fopen_rb_ca("/etc/services", &_f, _buf, sizeof _buf);
+	FILE _f, *f = __fopen_rb_ca("/system/etc/services", &_f, _buf, sizeof _buf);
 	if (!f) return EAI_SERVICE;
 
 	while (fgets(line, sizeof line, f) && cnt < MAXSERVS) {
--- musl-1.1.4.o/src/network/res_msend.c
+++ musl-1.1.4/src/network/res_msend.c
@@ -13,6 +13,7 @@
 #include "stdio_impl.h"
 #include "syscall.h"
 #include "lookup.h"
+#include <android/property.h>
 
 static void cleanup(void *p)
 {
@@ -53,7 +54,7 @@
 	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
 
 	/* Get nameservers from resolv.conf, fallback to localhost */
-	f = __fopen_rb_ca("/etc/resolv.conf", &_f, _buf, sizeof _buf);
+	f = __fopen_rb_ca("/system/etc/resolv.conf", &_f, _buf, sizeof _buf);
 	if (f) for (nns=0; nns<3 && fgets(line, sizeof line, f); ) {
 		if (!strncmp(line, "options", 7) && isspace(line[7])) {
 			unsigned long x;
@@ -93,7 +94,30 @@
 		}
 	}
 	if (f) __fclose_ca(f);
+
+	/* if there is no /etc/resolv.conf, then get nameservers from android config */
 	if (!nns) {
+		strcpy(line, "net.dns1");
+_second:	if (line[7] > '2') goto _out;
+		if (android_property_get(line, (char *)_buf)) {
+			if (__lookup_ipliteral(&iplit, (char *)_buf, AF_UNSPEC)>0) {
+				if (iplit.family == AF_INET) {
+					memcpy(&ns[nns].sin.sin_addr, iplit.addr, 4);
+					ns[nns].sin.sin_port = htons(53);
+					ns[nns++].sin.sin_family = AF_INET;
+				}
+				else {
+					sl = sizeof sa.sin6;
+					memcpy(&ns[nns].sin6.sin6_addr, iplit.addr, 16);
+					ns[nns].sin6.sin6_port = htons(53);
+					ns[nns].sin6.sin6_scope_id = iplit.scopeid;
+					ns[nns++].sin6.sin6_family = family = AF_INET6;
+				}
+			}
+		}
+		line[7]++; goto _second;
+	}
+_out:	if (!nns) {
 		ns[0].sin.sin_family = AF_INET;
 		ns[0].sin.sin_port = htons(53);
 		ns[0].sin.sin_addr.s_addr = htonl(0x7f000001);
--- musl-1.1.4.o/src/passwd/getgr_r.c
+++ musl-1.1.4/src/passwd/getgr_r.c
@@ -1,11 +1,11 @@
 #include "pwf.h"
 #include <pthread.h>
+#include <android/idmap.h>
 
 #define FIX(x) (gr->gr_##x = gr->gr_##x-line+buf)
 
-static int getgr_r(const char *name, gid_t gid, struct group *gr, char *buf, size_t size, struct group **res)
+static int getgr_r(FILE *f, const char *name, gid_t gid, struct group *gr, char *buf, size_t size, struct group **res)
 {
-	FILE *f;
 	char *line = 0;
 	size_t len = 0;
 	char **mem = 0;
@@ -16,13 +16,13 @@
 
 	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
 
-	f = fopen("/etc/group", "rbe");
+	*res = 0;
+	if (!f) f = fopen("/system/etc/group", "rbe");
 	if (!f) {
 		rv = errno;
 		goto done;
 	}
 
-	*res = 0;
 	while (__getgrent_a(f, gr, &line, &len, &mem, &nmem)) {
 		if (name && !strcmp(name, gr->gr_name)
 		|| !name && gr->gr_gid == gid) {
@@ -51,12 +51,55 @@
 	return rv;
 }
 
+static int __getgr_android_r(const char *name, gid_t gid, struct group *gr, char *buf, size_t size, struct group **res)
+{
+	char *p;
+	size_t sz;
+	FILE *f;
+
+	*res = 0;
+	p = android_getgroupdb(&sz);
+	if (!p) return 0;
+
+	f = fmemopen(p, sz, "rb");
+	if (!f) return 0;
+
+	return getgr_r(f, name, gid, gr, buf, size, res);
+}
+
+static int __getgr_android_app_r(const char *name, gid_t gid, struct group *gr, char *buf, size_t size, struct group **res)
+{
+	char *p;
+	size_t sz;
+	FILE *f;
+
+	*res = 0;
+	p = android_mkgroup(name, gid);
+	if (!p) return 0;
+	sz = strnlen(p, A_LNSIZE)+1;
+
+	f = fmemopen(p, sz, "rb");
+	if (!f) return 0;
+
+	return getgr_r(f, name, gid, gr, buf, size, res);
+}
+
 int getgrnam_r(const char *name, struct group *gr, char *buf, size_t size, struct group **res)
 {
-	return getgr_r(name, 0, gr, buf, size, res);
+	int r;
+
+	r = getgr_r(0, name, 0, gr, buf, size, res);
+	if (!*res) __getgr_android_r(name, 0, gr, buf, size, res);
+	if (!*res) __getgr_android_app_r(name, 0, gr, buf, size, res);
+	return r;
 }
 
 int getgrgid_r(gid_t gid, struct group *gr, char *buf, size_t size, struct group **res)
 {
-	return getgr_r(0, gid, gr, buf, size, res);
+	int r;
+
+	r = getgr_r(0, 0, gid, gr, buf, size, res);
+	if (!*res) __getgr_android_r(0, gid, gr, buf, size, res);
+	if (!*res) __getgr_android_app_r(0, gid, gr, buf, size, res);
+	return r;
 }
--- musl-1.1.4.o/src/passwd/getgrent.c
+++ musl-1.1.4/src/passwd/getgrent.c
@@ -1,6 +1,9 @@
 #include "pwf.h"
+#include <android/idmap.h>
 
 static FILE *f;
+static char *line, **mem;
+static struct group grs;
 
 void setgrent()
 {
@@ -12,14 +15,45 @@
 
 struct group *getgrent()
 {
-	static char *line, **mem;
-	static struct group gr;
 	size_t size=0, nmem=0;
-	if (!f) f = fopen("/etc/group", "rbe");
+	if (!f) f = fopen("/system/etc/group", "rbe");
 	if (!f) return 0;
-	return __getgrent_a(f, &gr, &line, &size, &mem, &nmem);
+	return __getgrent_a(f, &grs, &line, &size, &mem, &nmem);
 }
 
+struct group *__getgrent_android()
+{
+	char *p;
+	size_t size, nmem=0;
+
+	if (!f) {
+		p = android_getgroupdb(&size);
+		if (!p) return 0;
+
+		f = fmemopen(p, size, "rb");
+		if (!f) return 0;
+	}
+
+	return __getgrent_a(f, &grs, &line, &size, &mem, &nmem);
+}
+
+static struct group *__getgr_android_app(const char *name, gid_t gid)
+{
+	char *p;
+	size_t size, nmem=0;
+
+	if (!f) {
+		p = android_mkgroup(name, gid);
+		if (!p) return 0;
+		size = strnlen(p, A_LNSIZE)+1;
+
+		f = fmemopen(p, size, "rb");
+		if (!f) return 0;
+	}
+
+	return __getgrent_a(f, &grs, &line, &size, &mem, &nmem);
+}
+
 struct group *getgrgid(gid_t gid)
 {
 	struct group *gr;
@@ -28,6 +62,14 @@
 	while ((gr=getgrent()) && gr->gr_gid != gid);
 	errno_saved = errno;
 	endgrent();
+	if (!gr) {
+		setgrent();
+		while ((gr=__getgrent_android()) && gr->gr_gid != gid);
+		endgrent();
+	}
+	setgrent();
+	if (!gr) gr = __getgr_android_app(NULL, gid);
+	endgrent();
 	errno = errno_saved;
 	return gr;
 }
@@ -39,6 +81,14 @@
 	setgrent();
 	while ((gr=getgrent()) && strcmp(gr->gr_name, name));
 	errno_saved = errno;
+	endgrent();
+	if (!gr) {
+		setgrent();
+		while ((gr=__getgrent_android()) && strcmp(gr->gr_name, name));
+		endgrent();
+	}
+	setgrent();
+	if (!gr) gr = __getgr_android_app(name, 0);
 	endgrent();
 	errno = errno_saved;
 	return gr;
--- musl-1.1.4.o/src/passwd/getpw_r.c
+++ musl-1.1.4/src/passwd/getpw_r.c
@@ -1,11 +1,11 @@
 #include "pwf.h"
 #include <pthread.h>
+#include <android/idmap.h>
 
 #define FIX(x) (pw->pw_##x = pw->pw_##x-line+buf)
 
-static int getpw_r(const char *name, uid_t uid, struct passwd *pw, char *buf, size_t size, struct passwd **res)
+static int getpw_r(FILE *f, const char *name, uid_t uid, struct passwd *pw, char *buf, size_t size, struct passwd **res)
 {
-	FILE *f;
 	char *line = 0;
 	size_t len = 0;
 	int rv = 0;
@@ -13,13 +13,13 @@
 
 	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
 
-	f = fopen("/etc/passwd", "rbe");
+	*res = 0;
+	if (!f) f = fopen("/system/etc/passwd", "rbe");
 	if (!f) {
 		rv = errno;
 		goto done;
 	}
 
-	*res = 0;
 	while (__getpwent_a(f, pw, &line, &len)) {
 		if (name && !strcmp(name, pw->pw_name)
 		|| !name && pw->pw_uid == uid) {
@@ -37,19 +37,63 @@
 			break;
 		}
 	}
- 	free(line);
+	free(line);
 	fclose(f);
 done:
 	pthread_setcancelstate(cs, 0);
 	return rv;
 }
 
+static int __getpw_android_r(const char *name, uid_t uid, struct passwd *pw, char *buf, size_t size, struct passwd **res)
+{
+	char *p;
+	size_t sz;
+	FILE *f;
+
+	*res = 0;
+	p = android_getpasswddb(&sz);
+	if (!p) return 0;
+
+	f = fmemopen(p, sz, "rb");
+	if (!f) return 0;
+
+	return getpw_r(f, name, uid, pw, buf, size, res);
+}
+
+static int __getpw_android_app_r(const char *name, uid_t uid, struct passwd *pw, char *buf, size_t size, struct passwd **res)
+{
+	char *p;
+	size_t sz;
+	FILE *f;
+
+	*res = 0;
+	p = android_mkpasswd(name, uid);
+	if (!p) return 0;
+	sz = strnlen(p, A_LNSIZE)+1;
+
+	f = fmemopen(p, sz, "rb");
+	if (!f) return 0;
+
+	return getpw_r(f, name, uid, pw, buf, size, res);
+}
+
 int getpwnam_r(const char *name, struct passwd *pw, char *buf, size_t size, struct passwd **res)
 {
-	return getpw_r(name, 0, pw, buf, size, res);
+	int r;
+
+	r = getpw_r(0, name, 0, pw, buf, size, res);
+	if (!*res) __getpw_android_r(name, 0, pw, buf, size, res);
+	if (!*res) __getpw_android_app_r(name, 0, pw, buf, size, res);
+	return r;
 }
 
 int getpwuid_r(uid_t uid, struct passwd *pw, char *buf, size_t size, struct passwd **res)
 {
-	return getpw_r(0, uid, pw, buf, size, res);
+	int r;
+
+	r = getpw_r(0, 0, uid, pw, buf, size, res);
+	/* dispose any android errors */
+	if (!*res) __getpw_android_r(0, uid, pw, buf, size, res);
+	if (!*res) __getpw_android_app_r(0, uid, pw, buf, size, res);
+	return r;
 }
--- musl-1.1.4.o/src/passwd/getpwent.c
+++ musl-1.1.4/src/passwd/getpwent.c
@@ -1,6 +1,9 @@
 #include "pwf.h"
+#include <android/idmap.h>
 
 static FILE *f;
+static char *line;
+static struct passwd pws;
 
 void setpwent()
 {
@@ -12,14 +15,46 @@
 
 struct passwd *getpwent()
 {
-	static char *line;
-	static struct passwd pw;
+	struct passwd *r;
 	size_t size=0;
-	if (!f) f = fopen("/etc/passwd", "rbe");
+	if (!f) f = fopen("/system/etc/passwd", "rbe");
 	if (!f) return 0;
-	return __getpwent_a(f, &pw, &line, &size);
+	return __getpwent_a(f, &pws, &line, &size);
 }
 
+static struct passwd *__getpwent_android()
+{
+	char *p;
+	size_t size;
+
+	if (!f) {
+		p = android_getpasswddb(&size);
+		if (!p) return 0;
+
+		f = fmemopen(p, size, "rb");
+		if (!f) return 0;
+	}
+
+	return __getpwent_a(f, &pws, &line, &size);
+}
+
+static struct passwd *__getpw_android_app(const char *name, uid_t uid)
+{
+	char *p;
+	size_t size;
+
+	if (!f) {
+		p = android_mkpasswd(name, uid);
+		if (!p) return 0;
+		size = strnlen(p, A_LNSIZE)+1;
+
+		f = fmemopen(p, size, "rb");
+		if (!f) return 0;
+	}
+
+	return __getpwent_a(f, &pws, &line, &size);
+}
+
 struct passwd *getpwuid(uid_t uid)
 {
 	struct passwd *pw;
@@ -28,6 +63,16 @@
 	while ((pw=getpwent()) && pw->pw_uid != uid);
 	errno_saved = errno;
 	endpwent();
+	/* ask about android defined virtual users */
+	if (!pw) {
+		setpwent();
+		while ((pw=__getpwent_android()) && pw->pw_uid != uid);
+		endpwent();
+	}
+	/* for "app_XX"/"uX_aYY" translation you still need a dedicated function... */
+	setpwent();
+	if (!pw) pw = __getpw_android_app(NULL, uid);
+	endpwent();
 	errno = errno_saved;
 	return pw;
 }
@@ -39,6 +84,14 @@
 	setpwent();
 	while ((pw=getpwent()) && strcmp(pw->pw_name, name));
 	errno_saved = errno;
+	endpwent();
+	if (!pw) {
+		setpwent();
+		while ((pw=__getpwent_android()) && strcmp(pw->pw_name, name));
+		endpwent();
+	}
+	setpwent();
+	if (!pw) pw = __getpw_android_app(name, 0);
 	endpwent();
 	errno = errno_saved;
 	return pw;
--- musl-1.1.4.o/src/process/execvp.c
+++ musl-1.1.4/src/process/execvp.c
@@ -18,7 +18,7 @@
 	if (strchr(file, '/'))
 		return execve(file, argv, envp);
 
-	if (!path) path = "/usr/local/bin:/bin:/usr/bin";
+	if (!path) path = "/system/bin:/system/xbin:/vendor/bin";
 	k = strnlen(file, NAME_MAX+1);
 	if (k > NAME_MAX) {
 		errno = ENAMETOOLONG;
--- musl-1.1.4.o/src/process/system.c
+++ musl-1.1.4/src/process/system.c
@@ -33,7 +33,7 @@
 	posix_spawnattr_setsigmask(&attr, &old);
 	posix_spawnattr_setsigdefault(&attr, &reset);
 	posix_spawnattr_setflags(&attr, POSIX_SPAWN_SETSIGDEF|POSIX_SPAWN_SETSIGMASK);
-	ret = posix_spawn(&pid, "/bin/sh", 0, &attr,
+	ret = posix_spawn(&pid, "/system/bin/sh", 0, &attr,
 		(char *[]){"sh", "-c", (char *)cmd, 0}, __environ);
 	posix_spawnattr_destroy(&attr);
 
--- musl-1.1.4.o/src/stdio/popen.c
+++ musl-1.1.4/src/stdio/popen.c
@@ -51,7 +51,7 @@
 	e = ENOMEM;
 	if (!posix_spawn_file_actions_init(&fa)) {
 		if (!posix_spawn_file_actions_adddup2(&fa, p[1-op], 1-op)) {
-			if (!(e = posix_spawn(&pid, "/bin/sh", &fa, 0,
+			if (!(e = posix_spawn(&pid, "/system/bin/sh", &fa, 0,
 			    (char *[]){ "sh", "-c", (char *)cmd, 0 }, __environ))) {
 				posix_spawn_file_actions_destroy(&fa);
 				f->pipe_pid = pid;
--- musl-1.1.4.o/src/stdio/tmpfile.c
+++ musl-1.1.4/src/stdio/tmpfile.c
@@ -8,7 +8,7 @@
 
 FILE *tmpfile(void)
 {
-	char s[] = "/tmp/tmpfile_XXXXXX";
+	char s[] = "/data/tmp/tmpfile_XXXXXX";
 	int fd;
 	FILE *f;
 	int try;
--- musl-1.1.4.o/src/stdio/tmpnam.c
+++ musl-1.1.4/src/stdio/tmpnam.c
@@ -12,7 +12,7 @@
 char *tmpnam(char *buf)
 {
 	static char internal[L_tmpnam];
-	char s[] = "/tmp/tmpnam_XXXXXX";
+	char s[] = "/data/tmp/tmpnam_XXXXXX";
 	int try;
 	int r;
 	for (try=0; try<MAXTRIES; try++) {
--- musl-1.1.4.o/src/time/__tz.c
+++ musl-1.1.4/src/time/__tz.c
@@ -1,9 +1,12 @@
-#include "time_impl.h"
 #include <stdint.h>
 #include <limits.h>
 #include <stdlib.h>
 #include <string.h>
+#include <sys/types.h>
+#include "time_impl.h"
 #include "libc.h"
+#include <android/property.h>
+#include <android/atz.h>
 
 long  __timezone = 0;
 int   __daylight = 0;
@@ -121,14 +124,19 @@
 static void do_tzset()
 {
 	char buf[NAME_MAX+25], *pathname=buf+24;
+	char atz[PROP_VALUELEN]; unsigned char atzdata[2048];
+	off_t aoffs; size_t alen;
 	const char *try, *s, *p;
 	const unsigned char *map = 0;
 	size_t i;
 	static const char search[] =
-		"/usr/share/zoneinfo/\0/share/zoneinfo/\0/etc/zoneinfo/\0";
+		"/system/share/zoneinfo/\0/system/usr/share/zoneinfo/\0/etc/zoneinfo/\0";
 
 	s = getenv("TZ");
-	if (!s || !*s) s = "/etc/localtime";
+	if (!s || !*s) {
+		s = "/system/etc/localtime";
+		if (android_property_get("persist.sys.timezone", atz)) s = atz;
+	}
 
 	if (old_tz && !strcmp(s, old_tz)) return;
 
@@ -147,13 +155,22 @@
 	}
 	if (old_tz) memcpy(old_tz, s, i+1);
 
+	if (s == atz) {
+		if (android_find_tz(s, &aoffs, &alen)
+		    && android_get_tz(atzdata, sizeof(atzdata), aoffs, alen)) {
+			map = atzdata;
+			map_size = alen;
+		}
+		else s = __gmt;
+	}
+	else {
 	/* Non-suid can use an absolute tzfile pathname or a relative
 	 * pathame beginning with "."; in secure mode, only the
 	 * standard path will be searched. */
 	if (*s == ':' || ((p=strchr(s, '/')) && !memchr(s, ',', p-s))) {
 		if (*s == ':') s++;
 		if (*s == '/' || *s == '.') {
-			if (!libc.secure || !strcmp(s, "/etc/localtime"))
+			if (!libc.secure || !strcmp(s, "/system/etc/localtime"))
 				map = __map_file(s, &map_size);
 		} else {
 			size_t l = strlen(s);
@@ -168,6 +185,7 @@
 			}
 		}
 		if (!map) s = __gmt;
+	}
 	}
 	if (map && (map_size < 44 || memcmp(map, "TZif", 4))) {
 		__munmap((void *)map, map_size);

  reply	other threads:[~2015-01-22  2:37 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-01-15  9:13 Рысь
2015-01-15 11:01 ` Rich Felker
2015-01-15 12:00   ` dynamic linking (Re: [musl] musl and android) u-wsnj
2015-01-15 12:15     ` Rich Felker
2015-01-15 13:04       ` u-wsnj
2015-01-15 13:34         ` Rich Felker
2015-01-15 15:56           ` OT: " u-wsnj
2015-01-15 13:53   ` musl and android Рысь
2015-01-18  6:32 ` Рысь
2015-01-18  6:44   ` Rich Felker
2015-01-18  8:01     ` Рысь
2015-01-18 16:40       ` Rich Felker
2015-01-19 18:00         ` Рысь
2015-01-21 10:34         ` Рысь
2015-01-21 18:36           ` Rich Felker
2015-01-22  2:37             ` Рысь [this message]
2015-01-31 15:08               ` Рысь
2015-02-03  5:52                 ` Rich Felker

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20150122093752.671ec2f0@sibserver.ru \
    --to=lynx@sibserver.ru \
    --cc=musl@lists.openwall.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/musl/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).