Merge "fs_mgr: Support filesystem labels in fstab"
diff --git a/CleanSpec.mk b/CleanSpec.mk
index e78fc88..7f9536e 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -54,3 +54,4 @@
 $(call add-clean-step, rm -rf $(PRODUCT_OUT)/root/default.prop)
 $(call add-clean-step, rm -rf $(PRODUCT_OUT)/recovery/root/default.prop)
 $(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/EXECUTABLES/lmkd_intermediates/import_includes)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES/libsysutils_intermediates/import_includes)
diff --git a/README b/README
deleted file mode 100644
index 0083247..0000000
--- a/README
+++ /dev/null
@@ -1,20 +0,0 @@
-
-The system/ directory is intended for pieces of the world that are the
-core of the embedded linux platform at the heart of Android.  These
-essential bits are required for basic booting, operation, and debugging.
-
-They should not depend on libraries outside of system/... (some of them
-do currently -- they need to be updated or changed) and they should not
-be required for the simulator build.
-
-The license for all these pieces should be clean (Apache2, BSD, or MIT).
-
-Currently system/bluetooth/... and system/extra/... have some pieces
-with GPL/LGPL licensed code.
-
-Assorted Issues:
-
-- pppd depends on libutils for logging
-- pppd depends on libcrypt/libcrypto
-- init, linker, debuggerd, toolbox, usbd depend on libcutils
-- should probably rename bionic to libc
diff --git a/ThirdPartyProject.prop b/ThirdPartyProject.prop
deleted file mode 100644
index 18b0594..0000000
--- a/ThirdPartyProject.prop
+++ /dev/null
@@ -1,10 +0,0 @@
-# Copyright 2010 Google Inc. All Rights Reserved.
-#Fri Jul 16 10:03:09 PDT 2010
-currentVersion=2.6.32
-version=2.6.32
-isNative=true
-feedurl=http\://kernel.org/pub/linux/kernel/v2.6/
-name=linux
-keywords=linux
-onDevice=true
-homepage=http\://kernel.org
diff --git a/adb/Android.mk b/adb/Android.mk
index 7136afb..8ebcbf0 100644
--- a/adb/Android.mk
+++ b/adb/Android.mk
@@ -110,6 +110,7 @@
 	jdwp_service.c \
 	framebuffer_service.c \
 	remount_service.c \
+	set_verity_enable_state_service.c \
 	usb_linux_client.c
 
 LOCAL_CFLAGS := \
@@ -124,14 +125,27 @@
 LOCAL_CFLAGS += -DALLOW_ADBD_ROOT=1
 endif
 
+ifneq (,$(filter userdebug,$(TARGET_BUILD_VARIANT)))
+LOCAL_CFLAGS += -DALLOW_ADBD_DISABLE_VERITY=1
+endif
+
 LOCAL_MODULE := adbd
 
 LOCAL_FORCE_STATIC_EXECUTABLE := true
 LOCAL_MODULE_PATH := $(TARGET_ROOT_OUT_SBIN)
 LOCAL_UNSTRIPPED_PATH := $(TARGET_ROOT_OUT_SBIN_UNSTRIPPED)
+LOCAL_C_INCLUDES += system/extras/ext4_utils system/core/fs_mgr/include
 
-LOCAL_STATIC_LIBRARIES := liblog libcutils libc libmincrypt libselinux
+LOCAL_STATIC_LIBRARIES := liblog \
+	libfs_mgr \
+	libcutils \
+	libc \
+	libmincrypt \
+	libselinux \
+	libext4_utils_static
+
 LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
+
 include $(BUILD_EXECUTABLE)
 
 
diff --git a/adb/adb.h b/adb/adb.h
index 6f5f997..a37fd5b 100644
--- a/adb/adb.h
+++ b/adb/adb.h
@@ -328,7 +328,10 @@
 
 #if !ADB_HOST
 void framebuffer_service(int fd, void *cookie);
+// Allow enable-verity to write to system and vendor block devices
+int make_block_device_writable(const char* dev);
 void remount_service(int fd, void *cookie);
+void set_verity_enabled_state_service(int fd, void* cookie);
 #endif
 
 /* packet allocator */
@@ -338,6 +341,9 @@
 int check_header(apacket *p);
 int check_data(apacket *p);
 
+// Define it if you want to dump packets.
+#define DEBUG_PACKETS 0
+
 #if !DEBUG_PACKETS
 #define print_packet(tag,p) do {} while (0)
 #endif
diff --git a/adb/adb_auth.h b/adb/adb_auth.h
index b24c674..54dd537 100644
--- a/adb/adb_auth.h
+++ b/adb/adb_auth.h
@@ -18,6 +18,7 @@
 #define __ADB_AUTH_H
 
 void adb_auth_init(void);
+int adb_auth_keygen(const char* filename);
 void adb_auth_verified(atransport *t);
 
 void send_auth_request(atransport *t);
diff --git a/adb/adb_auth_host.c b/adb/adb_auth_host.c
index c72fe42..a859199 100644
--- a/adb/adb_auth_host.c
+++ b/adb/adb_auth_host.c
@@ -15,9 +15,12 @@
  */
 
 #include <stdio.h>
+#include <stdlib.h>
 
 #ifdef _WIN32
-#  define WIN32_LEAN_AND_MEAN
+#  ifndef WIN32_LEAN_AND_MEAN
+#    define WIN32_LEAN_AND_MEAN
+#  endif
 #  include "windows.h"
 #  include "shlobj.h"
 #else
@@ -114,18 +117,34 @@
 static void get_user_info(char *buf, size_t len)
 {
     char hostname[1024], username[1024];
-    int ret;
+    int ret = -1;
+
+    if (getenv("HOSTNAME") != NULL) {
+        strncpy(hostname, getenv("HOSTNAME"), sizeof(hostname));
+        hostname[sizeof(hostname)-1] = '\0';
+        ret = 0;
+    }
 
 #ifndef _WIN32
-    ret = gethostname(hostname, sizeof(hostname));
     if (ret < 0)
+        ret = gethostname(hostname, sizeof(hostname));
 #endif
+    if (ret < 0)
         strcpy(hostname, "unknown");
 
+    ret = -1;
+
+    if (getenv("LOGNAME") != NULL) {
+        strncpy(username, getenv("LOGNAME"), sizeof(username));
+        username[sizeof(username)-1] = '\0';
+        ret = 0;
+    }
+
 #if !defined _WIN32 && !defined ADB_HOST_ON_TARGET
-    ret = getlogin_r(username, sizeof(username));
     if (ret < 0)
+        ret = getlogin_r(username, sizeof(username));
 #endif
+    if (ret < 0)
         strcpy(username, "unknown");
 
     ret = snprintf(buf, len, " %s@%s", username, hostname);
@@ -436,6 +455,11 @@
     return ret + 1;
 }
 
+int adb_auth_keygen(const char* filename) {
+    adb_trace_mask |= (1 << TRACE_AUTH);
+    return (generate_key(filename) == 0);
+}
+
 void adb_auth_init(void)
 {
     int ret;
diff --git a/adb/adb_client.c b/adb/adb_client.c
index eb1720d..ac5e15a 100644
--- a/adb/adb_client.c
+++ b/adb/adb_client.c
@@ -279,7 +279,7 @@
 
     fd = _adb_connect(service);
     if(fd == -1) {
-        D("_adb_connect error: %s\n", __adb_error);
+        D("_adb_connect error: %s", __adb_error);
     } else if(fd == -2) {
         fprintf(stderr,"** daemon still not running\n");
     }
diff --git a/adb/adb_trace.h b/adb/adb_trace.h
index 8a5d9f8..b8a2f4c 100644
--- a/adb/adb_trace.h
+++ b/adb/adb_trace.h
@@ -73,8 +73,9 @@
             if (ADB_TRACING) {                         \
                 int save_errno = errno;                \
                 adb_mutex_lock(&D_lock);               \
-                fprintf(stderr, "%s::%s():",           \
-                        __FILE__, __FUNCTION__);       \
+                fprintf(stderr, "%16s: %5d:%5lu | ",   \
+                        __FUNCTION__,                  \
+                        getpid(), adb_thread_id());    \
                 errno = save_errno;                    \
                 fprintf(stderr, __VA_ARGS__ );         \
                 fflush(stderr);                        \
@@ -96,15 +97,16 @@
         } while (0)
 #  define  DD(...)                                     \
         do {                                           \
-          int save_errno = errno;                      \
-          adb_mutex_lock(&D_lock);                     \
-          fprintf(stderr, "%s::%s():",                 \
-                  __FILE__, __FUNCTION__);             \
-          errno = save_errno;                          \
-          fprintf(stderr, __VA_ARGS__ );               \
-          fflush(stderr);                              \
-          adb_mutex_unlock(&D_lock);                   \
-          errno = save_errno;                          \
+            int save_errno = errno;                    \
+            adb_mutex_lock(&D_lock);                   \
+            fprintf(stderr, "%16s: %5d:%5lu | ",       \
+                    __FUNCTION__,                      \
+                    getpid(), adb_thread_id());        \
+            errno = save_errno;                        \
+            fprintf(stderr, __VA_ARGS__ );             \
+            fflush(stderr);                            \
+            adb_mutex_unlock(&D_lock);                 \
+            errno = save_errno;                        \
         } while (0)
 #else
 #  define  D(...)                                      \
diff --git a/adb/commandline.c b/adb/commandline.c
index 23e9ea4..f345787 100644
--- a/adb/commandline.c
+++ b/adb/commandline.c
@@ -36,6 +36,7 @@
 #define  TRACE_TAG  TRACE_ADB
 #include "adb.h"
 #include "adb_client.h"
+#include "adb_auth.h"
 #include "file_sync_service.h"
 
 static int do_cmd(transport_type ttype, char* serial, char *cmd, ...);
@@ -189,6 +190,11 @@
         "\n"
         "  adb restore <file>           - restore device contents from the <file> backup archive\n"
         "\n"
+        "  adb disable-verity           - disable dm-verity checking on USERDEBUG builds\n"
+        "  adb enable-verity            - re-enable dm-verity checking on USERDEBUG builds\n"
+        "  adb keygen <file>            - generate adb public/private key. The private key is stored in <file>,\n"
+        "                                 and the public key is stored in <file>.pub. Any existing files\n"
+        "                                 are overwritten.\n"
         "  adb help                     - show this help message\n"
         "  adb version                  - show version num\n"
         "\n"
@@ -205,8 +211,7 @@
         "  adb reboot-bootloader        - reboots the device into the bootloader\n"
         "  adb root                     - restarts the adbd daemon with root permissions\n"
         "  adb usb                      - restarts the adbd daemon listening on USB\n"
-        "  adb tcpip <port>             - restarts the adbd daemon listening on TCP on the specified port"
-        "\n"
+        "  adb tcpip <port>             - restarts the adbd daemon listening on TCP on the specified port\n"
         "networking:\n"
         "  adb ppp <tty> [parameters]   - Run PPP over USB.\n"
         " Note: you should not automatically start a PPP connection.\n"
@@ -1163,17 +1168,17 @@
     }
 
     /* modifiers and flags */
-    while(argc > 0) {
-        if(!strcmp(argv[0],"server")) {
+    while (argc > 0) {
+        if (!strcmp(argv[0],"server")) {
             is_server = 1;
-        } else if(!strcmp(argv[0],"nodaemon")) {
+        } else if (!strcmp(argv[0],"nodaemon")) {
             no_daemon = 1;
         } else if (!strcmp(argv[0], "fork-server")) {
             /* this is a special flag used only when the ADB client launches the ADB Server */
             is_daemon = 1;
-        } else if(!strcmp(argv[0],"persist")) {
+        } else if (!strcmp(argv[0],"persist")) {
             persist = 1;
-        } else if(!strncmp(argv[0], "-p", 2)) {
+        } else if (!strncmp(argv[0], "-p", 2)) {
             const char *product = NULL;
             if (argv[0][2] == '\0') {
                 if (argc < 2) return usage();
@@ -1193,7 +1198,7 @@
             if (isdigit(argv[0][2])) {
                 serial = argv[0] + 2;
             } else {
-                if(argc < 2 || argv[0][2] != '\0') return usage();
+                if (argc < 2 || argv[0][2] != '\0') return usage();
                 serial = argv[1];
                 argc--;
                 argv++;
@@ -1204,7 +1209,7 @@
             ttype = kTransportLocal;
         } else if (!strcmp(argv[0],"-a")) {
             gListenAll = 1;
-        } else if(!strncmp(argv[0], "-H", 2)) {
+        } else if (!strncmp(argv[0], "-H", 2)) {
             const char *hostname = NULL;
             if (argv[0][2] == '\0') {
                 if (argc < 2) return usage();
@@ -1216,7 +1221,7 @@
             }
             adb_set_tcp_name(hostname);
 
-        } else if(!strncmp(argv[0], "-P", 2)) {
+        } else if (!strncmp(argv[0], "-P", 2)) {
             if (argv[0][2] == '\0') {
                 if (argc < 2) return usage();
                 server_port_str = argv[1];
@@ -1255,20 +1260,51 @@
         } else {
             r = launch_server(server_port);
         }
-        if(r) {
+        if (r) {
             fprintf(stderr,"* could not start server *\n");
         }
         return r;
     }
 
-top:
-    if(argc == 0) {
+    if (argc == 0) {
         return usage();
     }
 
-    /* adb_connect() commands */
+    /* handle wait-for-* prefix */
+    if (!strncmp(argv[0], "wait-for-", strlen("wait-for-"))) {
+        char* service = argv[0];
+        if (!strncmp(service, "wait-for-device", strlen("wait-for-device"))) {
+            if (ttype == kTransportUsb) {
+                service = "wait-for-usb";
+            } else if (ttype == kTransportLocal) {
+                service = "wait-for-local";
+            } else {
+                service = "wait-for-any";
+            }
+        }
 
-    if(!strcmp(argv[0], "devices")) {
+        format_host_command(buf, sizeof buf, service, ttype, serial);
+
+        if (adb_command(buf)) {
+            D("failure: %s *\n",adb_error());
+            fprintf(stderr,"error: %s\n", adb_error());
+            return 1;
+        }
+
+        /* Allow a command to be run after wait-for-device,
+            * e.g. 'adb wait-for-device shell'.
+            */
+        if (argc == 1) {
+            return 0;
+        }
+
+        /* Fall through */
+        argc--;
+        argv++;
+    }
+
+    /* adb_connect() commands */
+    if (!strcmp(argv[0], "devices")) {
         char *tmp;
         char *listopt;
         if (argc < 2)
@@ -1281,7 +1317,7 @@
         }
         snprintf(buf, sizeof buf, "host:%s%s", argv[0], listopt);
         tmp = adb_query(buf);
-        if(tmp) {
+        if (tmp) {
             printf("List of devices attached \n");
             printf("%s\n", tmp);
             return 0;
@@ -1289,8 +1325,7 @@
             return 1;
         }
     }
-
-    if(!strcmp(argv[0], "connect")) {
+    else if (!strcmp(argv[0], "connect")) {
         char *tmp;
         if (argc != 2) {
             fprintf(stderr, "Usage: adb connect <host>[:<port>]\n");
@@ -1298,15 +1333,14 @@
         }
         snprintf(buf, sizeof buf, "host:connect:%s", argv[1]);
         tmp = adb_query(buf);
-        if(tmp) {
+        if (tmp) {
             printf("%s\n", tmp);
             return 0;
         } else {
             return 1;
         }
     }
-
-    if(!strcmp(argv[0], "disconnect")) {
+    else if (!strcmp(argv[0], "disconnect")) {
         char *tmp;
         if (argc > 2) {
             fprintf(stderr, "Usage: adb disconnect [<host>[:<port>]]\n");
@@ -1318,19 +1352,17 @@
             snprintf(buf, sizeof buf, "host:disconnect:");
         }
         tmp = adb_query(buf);
-        if(tmp) {
+        if (tmp) {
             printf("%s\n", tmp);
             return 0;
         } else {
             return 1;
         }
     }
-
-    if (!strcmp(argv[0], "emu")) {
+    else if (!strcmp(argv[0], "emu")) {
         return adb_send_emulator_command(argc, argv);
     }
-
-    if(!strcmp(argv[0], "shell") || !strcmp(argv[0], "hell")) {
+    else if (!strcmp(argv[0], "shell") || !strcmp(argv[0], "hell")) {
         int r;
         int fd;
 
@@ -1341,7 +1373,7 @@
             fflush(stdout);
         }
 
-        if(argc < 2) {
+        if (argc < 2) {
             D("starting interactive shell\n");
             r = interactive_shell();
             if (h) {
@@ -1364,7 +1396,7 @@
         for(;;) {
             D("interactive shell loop. buff=%s\n", buf);
             fd = adb_connect(buf);
-            if(fd >= 0) {
+            if (fd >= 0) {
                 D("about to read_and_dump(fd=%d)\n", fd);
                 read_and_dump(fd);
                 D("read_and_dump() done.\n");
@@ -1375,7 +1407,7 @@
                 r = -1;
             }
 
-            if(persist) {
+            if (persist) {
                 fprintf(stderr,"\n- waiting for device -\n");
                 adb_sleep_ms(1000);
                 do_cmd(ttype, serial, "wait-for-device", 0);
@@ -1389,8 +1421,7 @@
             }
         }
     }
-
-    if (!strcmp(argv[0], "exec-in") || !strcmp(argv[0], "exec-out")) {
+    else if (!strcmp(argv[0], "exec-in") || !strcmp(argv[0], "exec-out")) {
         int exec_in = !strcmp(argv[0], "exec-in");
         int fd;
 
@@ -1419,30 +1450,31 @@
         adb_close(fd);
         return 0;
     }
-
-    if(!strcmp(argv[0], "kill-server")) {
+    else if (!strcmp(argv[0], "kill-server")) {
         int fd;
         fd = _adb_connect("host:kill");
-        if(fd == -1) {
+        if (fd == -1) {
             fprintf(stderr,"* server not running *\n");
             return 1;
         }
         return 0;
     }
-
-    if(!strcmp(argv[0], "sideload")) {
-        if(argc != 2) return usage();
+    else if (!strcmp(argv[0], "sideload")) {
+        if (argc != 2) return usage();
         if (adb_sideload_host(argv[1])) {
             return 1;
         } else {
             return 0;
         }
     }
-
-    if(!strcmp(argv[0], "remount") || !strcmp(argv[0], "reboot")
-            || !strcmp(argv[0], "reboot-bootloader")
-            || !strcmp(argv[0], "tcpip") || !strcmp(argv[0], "usb")
-            || !strcmp(argv[0], "root")) {
+    else if (!strcmp(argv[0], "remount") ||
+             !strcmp(argv[0], "reboot") ||
+             !strcmp(argv[0], "reboot-bootloader") ||
+             !strcmp(argv[0], "tcpip") ||
+             !strcmp(argv[0], "usb") ||
+             !strcmp(argv[0], "root") ||
+             !strcmp(argv[0], "disable-verity") ||
+             !strcmp(argv[0], "enable-verity")) {
         char command[100];
         if (!strcmp(argv[0], "reboot-bootloader"))
             snprintf(command, sizeof(command), "reboot:bootloader");
@@ -1451,7 +1483,7 @@
         else
             snprintf(command, sizeof(command), "%s:", argv[0]);
         int fd = adb_connect(command);
-        if(fd >= 0) {
+        if (fd >= 0) {
             read_and_dump(fd);
             adb_close(fd);
             return 0;
@@ -1459,49 +1491,13 @@
         fprintf(stderr,"error: %s\n", adb_error());
         return 1;
     }
-
-    if(!strcmp(argv[0], "bugreport")) {
+    else if (!strcmp(argv[0], "bugreport")) {
         if (argc != 1) return usage();
         do_cmd(ttype, serial, "shell", "bugreport", 0);
         return 0;
     }
-
     /* adb_command() wrapper commands */
-
-    if(!strncmp(argv[0], "wait-for-", strlen("wait-for-"))) {
-        char* service = argv[0];
-        if (!strncmp(service, "wait-for-device", strlen("wait-for-device"))) {
-            if (ttype == kTransportUsb) {
-                service = "wait-for-usb";
-            } else if (ttype == kTransportLocal) {
-                service = "wait-for-local";
-            } else {
-                service = "wait-for-any";
-            }
-        }
-
-        format_host_command(buf, sizeof buf, service, ttype, serial);
-
-        if (adb_command(buf)) {
-            D("failure: %s *\n",adb_error());
-            fprintf(stderr,"error: %s\n", adb_error());
-            return 1;
-        }
-
-        /* Allow a command to be run after wait-for-device,
-            * e.g. 'adb wait-for-device shell'.
-            */
-        if(argc > 1) {
-            argc--;
-            argv++;
-            goto top;
-        }
-        return 0;
-    }
-
-    if(!strcmp(argv[0], "forward") ||
-       !strcmp(argv[0], "reverse"))
-    {
+    else if (!strcmp(argv[0], "forward") || !strcmp(argv[0], "reverse")) {
         char host_prefix[64];
         char reverse = (char) !strcmp(argv[0], "reverse");
         char remove = 0;
@@ -1586,21 +1582,18 @@
           snprintf(buf, sizeof buf, "%s:%s:%s;%s", host_prefix, command, argv[1], argv[2]);
         }
 
-        if(adb_command(buf)) {
+        if (adb_command(buf)) {
             fprintf(stderr,"error: %s\n", adb_error());
             return 1;
         }
         return 0;
     }
-
     /* do_sync_*() commands */
-
-    if(!strcmp(argv[0], "ls")) {
-        if(argc != 2) return usage();
+    else if (!strcmp(argv[0], "ls")) {
+        if (argc != 2) return usage();
         return do_sync_ls(argv[1]);
     }
-
-    if(!strcmp(argv[0], "push")) {
+    else if (!strcmp(argv[0], "push")) {
         int show_progress = 0;
         int copy_attrs = 0; // unused
         const char* lpath = NULL, *rpath = NULL;
@@ -1613,8 +1606,7 @@
 
         return usage();
     }
-
-    if(!strcmp(argv[0], "pull")) {
+    else if (!strcmp(argv[0], "pull")) {
         int show_progress = 0;
         int copy_attrs = 0;
         const char* rpath = NULL, *lpath = ".";
@@ -1627,28 +1619,24 @@
 
         return usage();
     }
-
-    if (!strcmp(argv[0], "install")) {
+    else if (!strcmp(argv[0], "install")) {
         if (argc < 2) return usage();
         return install_app(ttype, serial, argc, argv);
     }
-
-    if (!strcmp(argv[0], "install-multiple")) {
+    else if (!strcmp(argv[0], "install-multiple")) {
         if (argc < 2) return usage();
         return install_multiple_app(ttype, serial, argc, argv);
     }
-
-    if (!strcmp(argv[0], "uninstall")) {
+    else if (!strcmp(argv[0], "uninstall")) {
         if (argc < 2) return usage();
         return uninstall_app(ttype, serial, argc, argv);
     }
-
-    if(!strcmp(argv[0], "sync")) {
+    else if (!strcmp(argv[0], "sync")) {
         char *srcarg, *android_srcpath, *data_srcpath, *vendor_srcpath;
         int listonly = 0;
 
         int ret;
-        if(argc < 2) {
+        if (argc < 2) {
             /* No local path was specified. */
             srcarg = NULL;
         } else if (argc >= 2 && strcmp(argv[1], "-l") == 0) {
@@ -1658,20 +1646,20 @@
             } else {
                 srcarg = NULL;
             }
-        } else if(argc == 2) {
+        } else if (argc == 2) {
             /* A local path or "android"/"data" arg was specified. */
             srcarg = argv[1];
         } else {
             return usage();
         }
         ret = find_sync_dirs(srcarg, &android_srcpath, &data_srcpath, &vendor_srcpath);
-        if(ret != 0) return usage();
+        if (ret != 0) return usage();
 
-        if(android_srcpath != NULL)
+        if (android_srcpath != NULL)
             ret = do_sync_sync(android_srcpath, "/system", listonly);
-        if(ret == 0 && vendor_srcpath != NULL)
+        if (ret == 0 && vendor_srcpath != NULL)
             ret = do_sync_sync(vendor_srcpath, "/vendor", listonly);
-        if(ret == 0 && data_srcpath != NULL)
+        if (ret == 0 && data_srcpath != NULL)
             ret = do_sync_sync(data_srcpath, "/data", listonly);
 
         free(android_srcpath);
@@ -1679,10 +1667,8 @@
         free(data_srcpath);
         return ret;
     }
-
     /* passthrough commands */
-
-    if(!strcmp(argv[0],"get-state") ||
+    else if (!strcmp(argv[0],"get-state") ||
         !strcmp(argv[0],"get-serialno") ||
         !strcmp(argv[0],"get-devpath"))
     {
@@ -1690,42 +1676,38 @@
 
         format_host_command(buf, sizeof buf, argv[0], ttype, serial);
         tmp = adb_query(buf);
-        if(tmp) {
+        if (tmp) {
             printf("%s\n", tmp);
             return 0;
         } else {
             return 1;
         }
     }
-
     /* other commands */
-
-    if(!strcmp(argv[0],"status-window")) {
+    else if (!strcmp(argv[0],"status-window")) {
         status_window(ttype, serial);
         return 0;
     }
-
-    if(!strcmp(argv[0],"logcat") || !strcmp(argv[0],"lolcat") || !strcmp(argv[0],"longcat")) {
+    else if (!strcmp(argv[0],"logcat") || !strcmp(argv[0],"lolcat") || !strcmp(argv[0],"longcat")) {
         return logcat(ttype, serial, argc, argv);
     }
-
-    if(!strcmp(argv[0],"ppp")) {
+    else if (!strcmp(argv[0],"ppp")) {
         return ppp(argc, argv);
     }
-
-    if (!strcmp(argv[0], "start-server")) {
+    else if (!strcmp(argv[0], "start-server")) {
         return adb_connect("host:start-server");
     }
-
-    if (!strcmp(argv[0], "backup")) {
+    else if (!strcmp(argv[0], "backup")) {
         return backup(argc, argv);
     }
-
-    if (!strcmp(argv[0], "restore")) {
+    else if (!strcmp(argv[0], "restore")) {
         return restore(argc, argv);
     }
-
-    if (!strcmp(argv[0], "jdwp")) {
+    else if (!strcmp(argv[0], "keygen")) {
+        if (argc < 2) return usage();
+        return adb_auth_keygen(argv[1]);
+    }
+    else if (!strcmp(argv[0], "jdwp")) {
         int  fd = adb_connect("jdwp");
         if (fd >= 0) {
             read_and_dump(fd);
@@ -1736,14 +1718,12 @@
             return -1;
         }
     }
-
     /* "adb /?" is a common idiom under Windows */
-    if(!strcmp(argv[0], "help") || !strcmp(argv[0], "/?")) {
+    else if (!strcmp(argv[0], "help") || !strcmp(argv[0], "/?")) {
         help();
         return 0;
     }
-
-    if(!strcmp(argv[0], "version")) {
+    else if (!strcmp(argv[0], "version")) {
         version(stdout);
         return 0;
     }
diff --git a/adb/fdevent.c b/adb/fdevent.c
index 43e600c..f5ecd14 100644
--- a/adb/fdevent.c
+++ b/adb/fdevent.c
@@ -661,6 +661,8 @@
     if(adb_socketpair(s)) {
         FATAL("cannot create shell-exit socket-pair\n");
     }
+    D("socketpair: (%d,%d)", s[0], s[1]);
+
     SHELL_EXIT_NOTIFY_FD = s[0];
     fdevent *fde;
     fde = fdevent_create(s[1], fdevent_subproc_event_func, NULL);
diff --git a/adb/file_sync_client.c b/adb/file_sync_client.c
index ad59e81..ee09d5d 100644
--- a/adb/file_sync_client.c
+++ b/adb/file_sync_client.c
@@ -309,7 +309,9 @@
     return err;
 }
 
-#ifdef HAVE_SYMLINKS
+#if defined(_WIN32)
+extern int write_data_link(int fd, const char *path, syncsendbuf *sbuf) __attribute__((error("no symlinks on Windows")));
+#else
 static int write_data_link(int fd, const char *path, syncsendbuf *sbuf)
 {
     int len, ret;
@@ -364,10 +366,8 @@
         free(file_buffer);
     } else if (S_ISREG(mode))
         write_data_file(fd, lpath, sbuf, show_progress);
-#ifdef HAVE_SYMLINKS
     else if (S_ISLNK(mode))
         write_data_link(fd, lpath, sbuf);
-#endif
     else
         goto fail;
 
@@ -893,6 +893,21 @@
     return r1 ? : r2;
 }
 
+/* Return a copy of the path string with / appended if needed */
+static char *add_slash_to_path(const char *path)
+{
+    if (path[strlen(path) - 1] != '/') {
+        size_t len = strlen(path) + 2;
+        char *path_with_slash = malloc(len);
+        if (path_with_slash == NULL)
+            return NULL;
+        snprintf(path_with_slash, len, "%s/", path);
+        return path_with_slash;
+    } else {
+        return strdup(path);
+    }
+}
+
 static int copy_remote_dir_local(int fd, const char *rpath, const char *lpath,
                                  int copy_attrs)
 {
@@ -900,28 +915,32 @@
     copyinfo *ci, *next;
     int pulled = 0;
     int skipped = 0;
+    char *rpath_clean = NULL;
+    char *lpath_clean = NULL;
+    int ret = 0;
+
+    if (rpath[0] == '\0' || lpath[0] == '\0') {
+        ret = -1;
+        goto finish;
+    }
 
     /* Make sure that both directory paths end in a slash. */
-    if (rpath[0] == 0 || lpath[0] == 0) return -1;
-    if (rpath[strlen(rpath) - 1] != '/') {
-        int  tmplen = strlen(rpath) + 2;
-        char *tmp = malloc(tmplen);
-        if (tmp == 0) return -1;
-        snprintf(tmp, tmplen, "%s/", rpath);
-        rpath = tmp;
+    rpath_clean = add_slash_to_path(rpath);
+    if (!rpath_clean) {
+        ret = -1;
+        goto finish;
     }
-    if (lpath[strlen(lpath) - 1] != '/') {
-        int  tmplen = strlen(lpath) + 2;
-        char *tmp = malloc(tmplen);
-        if (tmp == 0) return -1;
-        snprintf(tmp, tmplen, "%s/", lpath);
-        lpath = tmp;
+    lpath_clean = add_slash_to_path(lpath);
+    if (!lpath_clean) {
+        ret = -1;
+        goto finish;
     }
 
-    fprintf(stderr, "pull: building file list...\n");
     /* Recursively build the list of files to copy. */
-    if (remote_build_list(fd, &filelist, rpath, lpath)) {
-        return -1;
+    fprintf(stderr, "pull: building file list...\n");
+    if (remote_build_list(fd, &filelist, rpath_clean, lpath_clean)) {
+        ret = -1;
+        goto finish;
     }
 
     for (ci = filelist; ci != 0; ci = next) {
@@ -929,11 +948,13 @@
         if (ci->flag == 0) {
             fprintf(stderr, "pull: %s -> %s\n", ci->src, ci->dst);
             if (sync_recv(fd, ci->src, ci->dst, 0 /* no show progress */)) {
-                return 1;
+                ret = -1;
+                goto finish;
             }
 
             if (copy_attrs && set_time_and_mode(ci->dst, ci->time, ci->mode)) {
-               return 1;
+                ret = -1;
+                goto finish;
             }
             pulled++;
         } else {
@@ -946,7 +967,10 @@
             pulled, (pulled == 1) ? "" : "s",
             skipped, (skipped == 1) ? "" : "s");
 
-    return 0;
+finish:
+    free(lpath_clean);
+    free(rpath_clean);
+    return ret;
 }
 
 int do_sync_pull(const char *rpath, const char *lpath, int show_progress, int copy_attrs)
diff --git a/adb/file_sync_service.c b/adb/file_sync_service.c
index 7933858..7de82b7 100644
--- a/adb/file_sync_service.c
+++ b/adb/file_sync_service.c
@@ -270,7 +270,9 @@
     return -1;
 }
 
-#ifdef HAVE_SYMLINKS
+#if defined(_WIN32)
+extern int handle_send_link(int s, char *path, char *buffer) __attribute__((error("no symlinks on Windows")));
+#else
 static int handle_send_link(int s, char *path, char *buffer)
 {
     syncmsg msg;
@@ -321,25 +323,20 @@
 
     return 0;
 }
-#endif /* HAVE_SYMLINKS */
+#endif
 
 static int do_send(int s, char *path, char *buffer)
 {
-    char *tmp;
     unsigned int mode;
-    int is_link, ret;
+    bool is_link = false;
     bool do_unlink;
 
-    tmp = strrchr(path,',');
+    char* tmp = strrchr(path,',');
     if(tmp) {
         *tmp = 0;
         errno = 0;
         mode = strtoul(tmp + 1, NULL, 0);
-#ifndef HAVE_SYMLINKS
-        is_link = 0;
-#else
         is_link = S_ISLNK((mode_t) mode);
-#endif
         mode &= 0777;
     }
     if(!tmp || errno) {
@@ -355,32 +352,26 @@
         }
     }
 
-#ifdef HAVE_SYMLINKS
-    if(is_link)
-        ret = handle_send_link(s, path, buffer);
-    else {
-#else
-    {
-#endif
-        uid_t uid = -1;
-        gid_t gid = -1;
-        uint64_t cap = 0;
-
-        /* copy user permission bits to "group" and "other" permissions */
-        mode |= ((mode >> 3) & 0070);
-        mode |= ((mode >> 3) & 0007);
-
-        tmp = path;
-        if(*tmp == '/') {
-            tmp++;
-        }
-        if (is_on_system(path) || is_on_vendor(path)) {
-            fs_config(tmp, 0, &uid, &gid, &mode, &cap);
-        }
-        ret = handle_send_file(s, path, uid, gid, mode, buffer, do_unlink);
+    if (is_link) {
+        return handle_send_link(s, path, buffer);
     }
 
-    return ret;
+    uid_t uid = -1;
+    gid_t gid = -1;
+    uint64_t cap = 0;
+
+    /* copy user permission bits to "group" and "other" permissions */
+    mode |= ((mode >> 3) & 0070);
+    mode |= ((mode >> 3) & 0007);
+
+    tmp = path;
+    if(*tmp == '/') {
+        tmp++;
+    }
+    if (is_on_system(path) || is_on_vendor(path)) {
+        fs_config(tmp, 0, &uid, &gid, &mode, &cap);
+    }
+    return handle_send_file(s, path, uid, gid, mode, buffer, do_unlink);
 }
 
 static int do_recv(int s, const char *path, char *buffer)
diff --git a/adb/jdwp_service.c b/adb/jdwp_service.c
index cd62b55..3074e42 100644
--- a/adb/jdwp_service.c
+++ b/adb/jdwp_service.c
@@ -415,6 +415,7 @@
               __FUNCTION__, strerror(errno));
             return -1;
         }
+        D("socketpair: (%d,%d)", fds[0], fds[1]);
 
         proc->out_fds[ proc->out_count ] = fds[1];
         if (++proc->out_count == 1)
diff --git a/adb/remount_service.c b/adb/remount_service.c
index 72d15a1..d7b0dd1 100644
--- a/adb/remount_service.c
+++ b/adb/remount_service.c
@@ -14,15 +14,18 @@
  * limitations under the License.
  */
 
+#include "sysdeps.h"
+
 #include <errno.h>
 #include <fcntl.h>
+#include <mntent.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <sys/mount.h>
 #include <unistd.h>
 
-#include "sysdeps.h"
+#include "cutils/properties.h"
 
 #define  TRACE_TAG  TRACE_ADB
 #include "adb.h"
@@ -34,38 +37,21 @@
 /* Returns the device used to mount a directory in /proc/mounts */
 static char *find_mount(const char *dir)
 {
-    int fd;
-    int res;
-    char *token = NULL;
-    const char delims[] = "\n";
-    char buf[4096];
+    FILE* fp;
+    struct mntent* mentry;
+    char* device = NULL;
 
-    fd = unix_open("/proc/mounts", O_RDONLY | O_CLOEXEC);
-    if (fd < 0)
+    if ((fp = setmntent("/proc/mounts", "r")) == NULL) {
         return NULL;
-
-    buf[sizeof(buf) - 1] = '\0';
-    adb_read(fd, buf, sizeof(buf) - 1);
-    adb_close(fd);
-
-    token = strtok(buf, delims);
-
-    while (token) {
-        char mount_dev[256];
-        char mount_dir[256];
-        int mount_freq;
-        int mount_passno;
-
-        res = sscanf(token, "%255s %255s %*s %*s %d %d\n",
-                     mount_dev, mount_dir, &mount_freq, &mount_passno);
-        mount_dev[255] = 0;
-        mount_dir[255] = 0;
-        if (res == 4 && (strcmp(dir, mount_dir) == 0))
-            return strdup(mount_dev);
-
-        token = strtok(NULL, delims);
     }
-    return NULL;
+    while ((mentry = getmntent(fp)) != NULL) {
+        if (strcmp(dir, mentry->mnt_dir) == 0) {
+            device = strdup(mentry->mnt_fsname);
+            break;
+        }
+    }
+    endmntent(fp);
+    return device;
 }
 
 static int hasVendorPartition()
@@ -77,34 +63,50 @@
     return false;
 }
 
-/* Init mounts /system as read only, remount to enable writes. */
-static int remount(const char* dir, int* dir_ro)
+int make_block_device_writable(const char* dev)
 {
-    char *dev;
-    int fd;
+    int fd = -1;
     int OFF = 0;
-
-    if (dir_ro == 0) {
-        return 0;
-    }
-
-    dev = find_mount(dir);
+    int rc = -1;
 
     if (!dev)
-        return -1;
+        goto errout;
 
     fd = unix_open(dev, O_RDONLY | O_CLOEXEC);
     if (fd < 0)
-        return -1;
+        goto errout;
 
-    ioctl(fd, BLKROSET, &OFF);
-    adb_close(fd);
+    if (ioctl(fd, BLKROSET, &OFF)) {
+        goto errout;
+    }
 
-    *dir_ro = mount(dev, dir, "none", MS_REMOUNT, NULL);
+    rc = 0;
 
+errout:
+    if (fd >= 0) {
+        adb_close(fd);
+    }
+    return rc;
+}
+
+/* Init mounts /system as read only, remount to enable writes. */
+static int remount(const char* dir, int* dir_ro)
+{
+    char *dev = 0;
+    int rc = -1;
+
+    dev = find_mount(dir);
+
+    if (!dev || make_block_device_writable(dev)) {
+        goto errout;
+    }
+
+    rc = mount(dev, dir, "none", MS_REMOUNT, NULL);
+    *dir_ro = rc;
+
+errout:
     free(dev);
-
-    return *dir_ro;
+    return rc;
 }
 
 static void write_string(int fd, const char* str)
@@ -115,6 +117,36 @@
 void remount_service(int fd, void *cookie)
 {
     char buffer[200];
+    char prop_buf[PROPERTY_VALUE_MAX];
+
+    bool system_verified = false, vendor_verified = false;
+    property_get("partition.system.verified", prop_buf, "0");
+    if (!strcmp(prop_buf, "1")) {
+        system_verified = true;
+    }
+
+    property_get("partition.vendor.verified", prop_buf, "0");
+    if (!strcmp(prop_buf, "1")) {
+        vendor_verified = true;
+    }
+
+    if (system_verified || vendor_verified) {
+        // Allow remount but warn of likely bad effects
+        bool both = system_verified && vendor_verified;
+        snprintf(buffer, sizeof(buffer),
+                 "dm_verity is enabled on the %s%s%s partition%s.\n",
+                 system_verified ? "system" : "",
+                 both ? " and " : "",
+                 vendor_verified ? "vendor" : "",
+                 both ? "s" : "");
+        write_string(fd, buffer);
+        snprintf(buffer, sizeof(buffer),
+                 "Use \"adb disable-verity\" to disable verity.\n"
+                 "If you do not, remount may succeed, however, you will still "
+                 "not be able to write to these volumes.\n");
+        write_string(fd, buffer);
+    }
+
     if (remount("/system", &system_ro)) {
         snprintf(buffer, sizeof(buffer), "remount of system failed: %s\n",strerror(errno));
         write_string(fd, buffer);
@@ -135,4 +167,3 @@
 
     adb_close(fd);
 }
-
diff --git a/adb/services.c b/adb/services.c
index bcfc163..d5a4642 100644
--- a/adb/services.c
+++ b/adb/services.c
@@ -164,6 +164,7 @@
         printf("cannot create service socket pair\n");
         return -1;
     }
+    D("socketpair: (%d,%d)", s[0], s[1]);
 
     sti = malloc(sizeof(stinfo));
     if(sti == 0) fatal("cannot allocate stinfo");
@@ -264,10 +265,11 @@
 
     // 0 is parent socket, 1 is child socket
     int sv[2];
-    if (unix_socketpair(AF_UNIX, SOCK_STREAM, 0, sv) < 0) {
+    if (adb_socketpair(sv) < 0) {
         printf("[ cannot create socket pair - %s ]\n", strerror(errno));
         return -1;
     }
+    D("socketpair: (%d,%d)", sv[0], sv[1]);
 
     *pid = fork();
     if (*pid < 0) {
@@ -469,6 +471,10 @@
                 free(cookie);
             }
         }
+    } else if(!strncmp(name, "disable-verity:", 15)) {
+        ret = create_service_thread(set_verity_enabled_state_service, (void*)0);
+    } else if(!strncmp(name, "enable-verity:", 15)) {
+        ret = create_service_thread(set_verity_enabled_state_service, (void*)1);
 #endif
     }
     if (ret >= 0) {
diff --git a/adb/set_verity_enable_state_service.c b/adb/set_verity_enable_state_service.c
new file mode 100644
index 0000000..2660ddd
--- /dev/null
+++ b/adb/set_verity_enable_state_service.c
@@ -0,0 +1,221 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "sysdeps.h"
+
+#define  TRACE_TAG  TRACE_ADB
+#include "adb.h"
+
+#include <stdio.h>
+#include <stdarg.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <inttypes.h>
+
+#include "cutils/properties.h"
+#include "ext4_sb.h"
+#include <fs_mgr.h>
+
+#define FSTAB_PREFIX "/fstab."
+struct fstab *fstab;
+
+__attribute__((__format__(printf, 2, 3))) __nonnull((2))
+static void write_console(int fd, const char* format, ...)
+{
+    char buffer[256];
+    va_list args;
+    va_start (args, format);
+    vsnprintf (buffer, sizeof(buffer), format, args);
+    va_end (args);
+
+    adb_write(fd, buffer, strnlen(buffer, sizeof(buffer)));
+}
+
+#ifdef ALLOW_ADBD_DISABLE_VERITY
+static int get_target_device_size(int fd, const char *blk_device,
+                                  uint64_t *device_size)
+{
+    int data_device;
+    struct ext4_super_block sb;
+    struct fs_info info;
+
+    info.len = 0;  /* Only len is set to 0 to ask the device for real size. */
+
+    data_device = adb_open(blk_device, O_RDONLY | O_CLOEXEC);
+    if (data_device < 0) {
+        write_console(fd, "Error opening block device (%s)\n", strerror(errno));
+        return -1;
+    }
+
+    if (lseek64(data_device, 1024, SEEK_SET) < 0) {
+        write_console(fd, "Error seeking to superblock\n");
+        adb_close(data_device);
+        return -1;
+    }
+
+    if (adb_read(data_device, &sb, sizeof(sb)) != sizeof(sb)) {
+        write_console(fd, "Error reading superblock\n");
+        adb_close(data_device);
+        return -1;
+    }
+
+    ext4_parse_sb(&sb, &info);
+    *device_size = info.len;
+
+    adb_close(data_device);
+    return 0;
+}
+
+/* Turn verity on/off */
+static int set_verity_enabled_state(int fd, const char *block_device,
+                                    const char* mount_point, bool enable)
+{
+    uint32_t magic_number;
+    const uint32_t new_magic = enable ? VERITY_METADATA_MAGIC_NUMBER
+                                      : VERITY_METADATA_MAGIC_DISABLE;
+    uint64_t device_length;
+    int device = -1;
+    int retval = -1;
+
+    if (make_block_device_writable(block_device)) {
+        write_console(fd, "Could not make block device %s writable (%s).\n",
+                      block_device, strerror(errno));
+        goto errout;
+    }
+
+    device = adb_open(block_device, O_RDWR | O_CLOEXEC);
+    if (device == -1) {
+        write_console(fd, "Could not open block device %s (%s).\n",
+                      block_device, strerror(errno));
+        write_console(fd, "Maybe run adb remount?\n");
+        goto errout;
+    }
+
+    // find the start of the verity metadata
+    if (get_target_device_size(fd, (char*)block_device, &device_length) < 0) {
+        write_console(fd, "Could not get target device size.\n");
+        goto errout;
+    }
+
+    if (lseek64(device, device_length, SEEK_SET) < 0) {
+        write_console(fd,
+                      "Could not seek to start of verity metadata block.\n");
+        goto errout;
+    }
+
+    // check the magic number
+    if (adb_read(device, &magic_number, sizeof(magic_number))
+             != sizeof(magic_number)) {
+        write_console(fd, "Couldn't read magic number!\n");
+        goto errout;
+    }
+
+    if (!enable && magic_number == VERITY_METADATA_MAGIC_DISABLE) {
+        write_console(fd, "Verity already disabled on %s\n", mount_point);
+        goto errout;
+    }
+
+    if (enable && magic_number == VERITY_METADATA_MAGIC_NUMBER) {
+        write_console(fd, "Verity already enabled on %s\n", mount_point);
+        goto errout;
+    }
+
+    if (magic_number != VERITY_METADATA_MAGIC_NUMBER
+            && magic_number != VERITY_METADATA_MAGIC_DISABLE) {
+        write_console(fd,
+                      "Couldn't find verity metadata at offset %"PRIu64"!\n",
+                      device_length);
+        goto errout;
+    }
+
+    if (lseek64(device, device_length, SEEK_SET) < 0) {
+        write_console(fd,
+                      "Could not seek to start of verity metadata block.\n");
+        goto errout;
+    }
+
+    if (adb_write(device, &new_magic, sizeof(new_magic)) != sizeof(new_magic)) {
+        write_console(fd, "Could not set verity %s flag on device %s with error %s\n",
+                      enable ? "enabled" : "disabled",
+                      block_device,
+                      strerror(errno));
+        goto errout;
+    }
+
+    write_console(fd, "Verity %s on %s\n",
+                  enable ? "enabled" : "disabled",
+                  mount_point);
+    retval = 0;
+errout:
+    if (device != -1)
+        adb_close(device);
+    return retval;
+}
+#endif
+
+void set_verity_enabled_state_service(int fd, void* cookie)
+{
+    bool enable = (cookie != NULL);
+#ifdef ALLOW_ADBD_DISABLE_VERITY
+    char fstab_filename[PROPERTY_VALUE_MAX + sizeof(FSTAB_PREFIX)];
+    char propbuf[PROPERTY_VALUE_MAX];
+    int i;
+    bool any_changed = false;
+
+    property_get("ro.secure", propbuf, "0");
+    if (strcmp(propbuf, "1")) {
+        write_console(fd, "verity not enabled - ENG build\n");
+        goto errout;
+    }
+
+    property_get("ro.debuggable", propbuf, "0");
+    if (strcmp(propbuf, "1")) {
+        write_console(fd, "verity cannot be disabled/enabled - USER build\n");
+        goto errout;
+    }
+
+    property_get("ro.hardware", propbuf, "");
+    snprintf(fstab_filename, sizeof(fstab_filename), FSTAB_PREFIX"%s", propbuf);
+
+    fstab = fs_mgr_read_fstab(fstab_filename);
+    if (!fstab) {
+        write_console(fd, "Failed to open %s\nMaybe run adb root?\n",
+                      fstab_filename);
+        goto errout;
+    }
+
+    /* Loop through entries looking for ones that vold manages */
+    for (i = 0; i < fstab->num_entries; i++) {
+        if(fs_mgr_is_verified(&fstab->recs[i])) {
+            if (!set_verity_enabled_state(fd, fstab->recs[i].blk_device,
+                                          fstab->recs[i].mount_point, enable)) {
+                any_changed = true;
+            }
+       }
+    }
+
+    if (any_changed) {
+        write_console(fd,
+                      "Now reboot your device for settings to take effect\n");
+    }
+errout:
+#else
+    write_console(fd, "%s-verity only works for userdebug builds\n",
+                  enable ? "enable" : "disable");
+#endif
+
+    adb_close(fd);
+}
diff --git a/adb/sysdeps.h b/adb/sysdeps.h
index cc1f839..8d63d14 100644
--- a/adb/sysdeps.h
+++ b/adb/sysdeps.h
@@ -77,6 +77,11 @@
     return 0;
 }
 
+static __inline__  unsigned long adb_thread_id()
+{
+    return GetCurrentThreadId();
+}
+
 static __inline__ void  close_on_exec(int  fd)
 {
     /* nothing really */
@@ -516,6 +521,12 @@
 {
     return strtok_r(str, delim, saveptr);
 }
+
+static __inline__ unsigned long adb_thread_id()
+{
+    return (unsigned long)pthread_self();
+}
+
 #undef   strtok_r
 #define  strtok_r  ___xxx_strtok_r
 
diff --git a/adb/sysdeps_win32.c b/adb/sysdeps_win32.c
index b082c6d..e69ec2b 100644
--- a/adb/sysdeps_win32.c
+++ b/adb/sysdeps_win32.c
@@ -2,6 +2,7 @@
 #include <winsock2.h>
 #include <windows.h>
 #include <stdio.h>
+#include <stdlib.h>
 #include <errno.h>
 #define  TRACE_TAG  TRACE_SYSDEPS
 #include "adb.h"
diff --git a/adb/tests/test_adb.py b/adb/tests/test_adb.py
new file mode 100644
index 0000000..b0ae07f
--- /dev/null
+++ b/adb/tests/test_adb.py
@@ -0,0 +1,390 @@
+#!/usr/bin/env python2
+"""Simple conformance test for adb.
+
+This script will use the available adb in path and run simple
+tests that attempt to touch all accessible attached devices.
+"""
+import hashlib
+import os
+import random
+import re
+import subprocess
+import tempfile
+import unittest
+import sys
+import shlex
+
+
+def trace(cmd):
+    """Print debug message if tracing enabled."""
+    if False:
+        print >> sys.stderr, cmd
+
+
+def call(cmd_str):
+    """Run process and return output tuple (stdout, stderr, ret code)."""
+    trace(cmd_str)
+    process = subprocess.Popen(shlex.split(cmd_str),
+                               stdout=subprocess.PIPE,
+                               stderr=subprocess.PIPE)
+    stdout, stderr = process.communicate()
+    return stdout, stderr, process.returncode
+
+
+def call_combined(cmd_str):
+    """Run process and return output tuple (stdout+stderr, ret code)."""
+    trace(cmd_str)
+    process = subprocess.Popen(shlex.split(cmd_str),
+                               stdout=subprocess.PIPE,
+                               stderr=subprocess.STDOUT)
+    stdout, _ = process.communicate()
+    return stdout, process.returncode
+
+
+def call_checked(cmd_str):
+    """Run process and get stdout+stderr, raise an exception on trouble."""
+    trace(cmd_str)
+    return subprocess.check_output(shlex.split(cmd_str),
+                                   stderr=subprocess.STDOUT)
+
+
+def call_checked_list(cmd_str):
+    return call_checked(cmd_str).split('\n')
+
+
+def call_checked_list_skip(cmd_str):
+    out_list = call_checked_list(cmd_str)
+
+    def is_init_line(line):
+        if (len(line) >= 3) and (line[0] == "*") and (line[-2] == "*"):
+            return True
+        else:
+            return False
+
+    return [line for line in out_list if not is_init_line(line)]
+
+
+def get_device_list():
+    output = call_checked_list_skip("adb devices")
+    dev_list = []
+    for line in output[1:]:
+        if line.strip() == "":
+            continue
+        device, _ = line.split()
+        dev_list.append(device)
+    return dev_list
+
+
+def get_attached_device_count():
+    return len(get_device_list())
+
+
+def compute_md5(string):
+    hsh = hashlib.md5()
+    hsh.update(string)
+    return hsh.hexdigest()
+
+
+class HostFile(object):
+    def __init__(self, handle, md5):
+        self.handle = handle
+        self.md5 = md5
+        self.full_path = handle.name
+        self.base_name = os.path.basename(self.full_path)
+
+
+class DeviceFile(object):
+    def __init__(self, md5, full_path):
+        self.md5 = md5
+        self.full_path = full_path
+        self.base_name = os.path.basename(self.full_path)
+
+
+def make_random_host_files(in_dir, num_files, rand_size=True):
+    files = {}
+    min_size = 1 * (1 << 10)
+    max_size = 16 * (1 << 10)
+    fixed_size = min_size
+
+    for _ in range(num_files):
+        file_handle = tempfile.NamedTemporaryFile(dir=in_dir)
+
+        if rand_size:
+            size = random.randrange(min_size, max_size, 1024)
+        else:
+            size = fixed_size
+        rand_str = os.urandom(size)
+        file_handle.write(rand_str)
+        file_handle.flush()
+
+        md5 = compute_md5(rand_str)
+        files[file_handle.name] = HostFile(file_handle, md5)
+    return files
+
+
+def make_random_device_files(adb, in_dir, num_files, rand_size=True):
+    files = {}
+    min_size = 1 * (1 << 10)
+    max_size = 16 * (1 << 10)
+    fixed_size = min_size
+
+    for i in range(num_files):
+        if rand_size:
+            size = random.randrange(min_size, max_size, 1024)
+        else:
+            size = fixed_size
+
+        base_name = "device_tmpfile" + str(i)
+        full_path = in_dir + "/" + base_name
+
+        adb.shell("dd if=/dev/urandom of={} bs={} count=1".format(full_path,
+                                                                  size))
+        dev_md5, _ = adb.shell("md5sum {}".format(full_path)).split()
+
+        files[full_path] = DeviceFile(dev_md5, full_path)
+    return files
+
+
+class AdbWrapper(object):
+    """Convenience wrapper object for the adb command."""
+    def __init__(self, device=None, out_dir=None):
+        self.device = device
+        self.out_dir = out_dir
+        self.adb_cmd = "adb "
+        if self.device:
+            self.adb_cmd += "-s {} ".format(device)
+        if self.out_dir:
+            self.adb_cmd += "-p {} ".format(out_dir)
+
+    def shell(self, cmd):
+        return call_checked(self.adb_cmd + "shell " + cmd)
+
+    def shell_nocheck(self, cmd):
+        return call_combined(self.adb_cmd + "shell " + cmd)
+
+    def push(self, local, remote):
+        return call_checked(self.adb_cmd + "push {} {}".format(local, remote))
+
+    def pull(self, remote, local):
+        return call_checked(self.adb_cmd + "pull {} {}".format(remote, local))
+
+    def sync(self, directory=""):
+        return call_checked(self.adb_cmd + "sync {}".format(directory))
+
+    def forward(self, local, remote):
+        return call_checked(self.adb_cmd + "forward {} {}".format(local,
+                                                                  remote))
+
+    def tcpip(self, port):
+        return call_checked(self.adb_cmd + "tcpip {}".format(port))
+
+    def usb(self):
+        return call_checked(self.adb_cmd + "usb")
+
+    def forward_remove(self, local):
+        return call_checked(self.adb_cmd + "forward --remove {}".format(local))
+
+    def forward_remove_all(self):
+        return call_checked(self.adb_cmd + "forward --remove-all")
+
+    def connect(self, host):
+        return call_checked(self.adb_cmd + "connect {}".format(host))
+
+    def disconnect(self, host):
+        return call_checked(self.adb_cmd + "disconnect {}".format(host))
+
+    def reverse(self, remote, local):
+        return call_checked(self.adb_cmd + "reverse {} {}".format(remote,
+                                                                  local))
+
+    def reverse_remove_all(self):
+        return call_checked(self.adb_cmd + "reverse --remove-all")
+
+    def reverse_remove(self, remote):
+        return call_checked(
+            self.adb_cmd + "reverse --remove {}".format(remote))
+
+    def wait(self):
+        return call_checked(self.adb_cmd + "wait-for-device")
+
+
+class AdbBasic(unittest.TestCase):
+    def test_devices(self):
+        """Get uptime for each device plugged in from /proc/uptime."""
+        dev_list = get_device_list()
+        for device in dev_list:
+            out = call_checked(
+                "adb -s {} shell cat /proc/uptime".format(device))
+            self.assertEqual(len(out.split()), 2)
+            self.assertGreater(float(out.split()[0]), 0.0)
+            self.assertGreater(float(out.split()[1]), 0.0)
+
+    def test_help(self):
+        """Make sure we get _something_ out of help."""
+        out = call_checked("adb help")
+        self.assertTrue(len(out) > 0)
+
+    def test_version(self):
+        """Get a version number out of the output of adb."""
+        out = call_checked("adb version").split()
+        version_num = False
+        for item in out:
+            if re.match(r"[\d+\.]*\d", item):
+                version_num = True
+        self.assertTrue(version_num)
+
+
+class AdbFile(unittest.TestCase):
+    SCRATCH_DIR = "/data/local/tmp"
+    DEVICE_TEMP_FILE = SCRATCH_DIR + "/adb_test_file"
+    DEVICE_TEMP_DIR = SCRATCH_DIR + "/adb_test_dir"
+
+    def test_push(self):
+        """Push a file to all attached devices."""
+        dev_list = get_device_list()
+        for device in dev_list:
+            self.push_with_device(device)
+
+    def push_with_device(self, device):
+        """Push a randomly generated file to specified device."""
+        kbytes = 512
+        adb = AdbWrapper(device)
+        with tempfile.NamedTemporaryFile(mode="w") as tmp:
+            rand_str = os.urandom(1024 * kbytes)
+            tmp.write(rand_str)
+            tmp.flush()
+
+            host_md5 = compute_md5(rand_str)
+            adb.shell_nocheck("rm -r {}".format(AdbFile.DEVICE_TEMP_FILE))
+            try:
+                adb.push(local=tmp.name, remote=AdbFile.DEVICE_TEMP_FILE)
+                dev_md5, _ = adb.shell(
+                    "md5sum {}".format(AdbFile.DEVICE_TEMP_FILE)).split()
+                self.assertEqual(host_md5, dev_md5)
+            finally:
+                adb.shell_nocheck("rm {}".format(AdbFile.DEVICE_TEMP_FILE))
+
+    # TODO: write push directory test.
+
+    def test_pull(self):
+        """Pull a file from all attached devices."""
+        dev_list = get_device_list()
+        for device in dev_list:
+            self.pull_with_device(device)
+
+    def pull_with_device(self, device):
+        """Pull a randomly generated file from specified device."""
+        kbytes = 512
+        adb = AdbWrapper(device)
+        adb.shell_nocheck("rm -r {}".format(AdbFile.DEVICE_TEMP_FILE))
+        try:
+            adb.shell("dd if=/dev/urandom of={} bs=1024 count={}".format(
+                AdbFile.DEVICE_TEMP_FILE, kbytes))
+            dev_md5, _ = adb.shell(
+                "md5sum {}".format(AdbFile.DEVICE_TEMP_FILE)).split()
+
+            with tempfile.NamedTemporaryFile(mode="w") as tmp_write:
+                adb.pull(remote=AdbFile.DEVICE_TEMP_FILE, local=tmp_write.name)
+                with open(tmp_write.name) as tmp_read:
+                    host_contents = tmp_read.read()
+                    host_md5 = compute_md5(host_contents)
+                self.assertEqual(dev_md5, host_md5)
+        finally:
+            adb.shell_nocheck("rm {}".format(AdbFile.DEVICE_TEMP_FILE))
+
+    def test_pull_dir(self):
+        """Pull a directory from all attached devices."""
+        dev_list = get_device_list()
+        for device in dev_list:
+            self.pull_dir_with_device(device)
+
+    def pull_dir_with_device(self, device):
+        """Pull a randomly generated directory of files from the device."""
+        adb = AdbWrapper(device)
+        temp_files = {}
+        host_dir = None
+        try:
+            # create temporary host directory
+            host_dir = tempfile.mkdtemp()
+
+            # create temporary dir on device
+            adb.shell_nocheck("rm -r {}".format(AdbFile.DEVICE_TEMP_DIR))
+            adb.shell("mkdir -p {}".format(AdbFile.DEVICE_TEMP_DIR))
+
+            # populate device dir with random files
+            temp_files = make_random_device_files(
+                adb, in_dir=AdbFile.DEVICE_TEMP_DIR, num_files=32)
+
+            adb.pull(remote=AdbFile.DEVICE_TEMP_DIR, local=host_dir)
+
+            for device_full_path in temp_files:
+                host_path = os.path.join(
+                    host_dir, temp_files[device_full_path].base_name)
+                with open(host_path) as host_file:
+                    host_md5 = compute_md5(host_file.read())
+                    self.assertEqual(host_md5,
+                                     temp_files[device_full_path].md5)
+        finally:
+            for dev_file in temp_files.values():
+                host_path = os.path.join(host_dir, dev_file.base_name)
+                os.remove(host_path)
+            adb.shell_nocheck("rm -r {}".format(AdbFile.DEVICE_TEMP_DIR))
+            if host_dir:
+                os.removedirs(host_dir)
+
+    def test_sync(self):
+        """Sync a directory with all attached devices."""
+        dev_list = get_device_list()
+        for device in dev_list:
+            self.sync_dir_with_device(device)
+
+    def sync_dir_with_device(self, device):
+        """Sync a randomly generated directory of files to specified device."""
+        try:
+            adb = AdbWrapper(device)
+            temp_files = {}
+
+            # create temporary host directory
+            base_dir = tempfile.mkdtemp()
+
+            # create mirror device directory hierarchy within base_dir
+            full_dir_path = base_dir + AdbFile.DEVICE_TEMP_DIR
+            os.makedirs(full_dir_path)
+
+            # create 32 random files within the host mirror
+            temp_files = make_random_host_files(in_dir=full_dir_path,
+                                                num_files=32)
+
+            # clean up any trash on the device
+            adb = AdbWrapper(device, out_dir=base_dir)
+            adb.shell_nocheck("rm -r {}".format(AdbFile.DEVICE_TEMP_DIR))
+
+            # issue the sync
+            adb.sync("data")
+
+            # confirm that every file on the device mirrors that on the host
+            for host_full_path in temp_files.keys():
+                device_full_path = os.path.join(
+                    AdbFile.DEVICE_TEMP_DIR,
+                    temp_files[host_full_path].base_name)
+                dev_md5, _ = adb.shell(
+                    "md5sum {}".format(device_full_path)).split()
+                self.assertEqual(temp_files[host_full_path].md5, dev_md5)
+
+        finally:
+            adb.shell_nocheck("rm -r {}".format(AdbFile.DEVICE_TEMP_DIR))
+            if temp_files:
+                for tf in temp_files.values():
+                    tf.handle.close()
+            if base_dir:
+                os.removedirs(base_dir + AdbFile.DEVICE_TEMP_DIR)
+
+
+if __name__ == '__main__':
+    random.seed(0)
+    dev_count = get_attached_device_count()
+    if dev_count:
+        suite = unittest.TestLoader().loadTestsFromName(__name__)
+        unittest.TextTestRunner(verbosity=3).run(suite)
+    else:
+        print "Test suite must be run with attached devices"
diff --git a/adb/transport.c b/adb/transport.c
index f35880c..7db6a47 100644
--- a/adb/transport.c
+++ b/adb/transport.c
@@ -629,7 +629,7 @@
             fatal_errno("cannot open transport socketpair");
         }
 
-        D("transport: %s (%d,%d) starting\n", t->serial, s[0], s[1]);
+        D("transport: %s socketpair: (%d,%d) starting", t->serial, s[0], s[1]);
 
         t->transport_socket = s[0];
         t->fd = s[1];
@@ -673,6 +673,7 @@
     if(adb_socketpair(s)){
         fatal_errno("cannot open transport registration socketpair");
     }
+    D("socketpair: (%d,%d)", s[0], s[1]);
 
     transport_registration_send = s[0];
     transport_registration_recv = s[1];
diff --git a/adb/usb_linux_client.c b/adb/usb_linux_client.c
index 70d2ad0..fd566f4 100644
--- a/adb/usb_linux_client.c
+++ b/adb/usb_linux_client.c
@@ -56,119 +56,85 @@
     int bulk_in;  /* "in" from the host's perspective => sink for adbd */
 };
 
-static const struct {
-    __le32 magic;
-    __le32 length;
-    __le32 flags;
-    __le32 fs_count;
-    __le32 hs_count;
-    __le32 ss_count;
-    struct {
-        struct usb_interface_descriptor intf;
-        struct usb_endpoint_descriptor_no_audio source;
-        struct usb_endpoint_descriptor_no_audio sink;
-    } __attribute__((packed)) fs_descs, hs_descs;
-    struct {
-        struct usb_interface_descriptor intf;
-        struct usb_endpoint_descriptor_no_audio source;
-        struct usb_ss_ep_comp_descriptor source_comp;
-        struct usb_endpoint_descriptor_no_audio sink;
-        struct usb_ss_ep_comp_descriptor sink_comp;
-    } __attribute__((packed)) ss_descs;
-} __attribute__((packed)) descriptors = {
-    .magic = cpu_to_le32(FUNCTIONFS_DESCRIPTORS_MAGIC_V2),
-    .length = cpu_to_le32(sizeof(descriptors)),
-    .flags = cpu_to_le32(FUNCTIONFS_HAS_FS_DESC |
-                         FUNCTIONFS_HAS_HS_DESC |
-                         FUNCTIONFS_HAS_SS_DESC),
-    .fs_count = 3,
-    .hs_count = 3,
-    .ss_count = 5,
-    .fs_descs = {
-        .intf = {
-            .bLength = sizeof(descriptors.fs_descs.intf),
-            .bDescriptorType = USB_DT_INTERFACE,
-            .bInterfaceNumber = 0,
-            .bNumEndpoints = 2,
-            .bInterfaceClass = ADB_CLASS,
-            .bInterfaceSubClass = ADB_SUBCLASS,
-            .bInterfaceProtocol = ADB_PROTOCOL,
-            .iInterface = 1, /* first string from the provided table */
-        },
-        .source = {
-            .bLength = sizeof(descriptors.fs_descs.source),
-            .bDescriptorType = USB_DT_ENDPOINT,
-            .bEndpointAddress = 1 | USB_DIR_OUT,
-            .bmAttributes = USB_ENDPOINT_XFER_BULK,
-            .wMaxPacketSize = MAX_PACKET_SIZE_FS,
-        },
-        .sink = {
-            .bLength = sizeof(descriptors.fs_descs.sink),
-            .bDescriptorType = USB_DT_ENDPOINT,
-            .bEndpointAddress = 2 | USB_DIR_IN,
-            .bmAttributes = USB_ENDPOINT_XFER_BULK,
-            .wMaxPacketSize = MAX_PACKET_SIZE_FS,
-        },
+struct func_desc {
+    struct usb_interface_descriptor intf;
+    struct usb_endpoint_descriptor_no_audio source;
+    struct usb_endpoint_descriptor_no_audio sink;
+} __attribute__((packed));
+
+struct desc_v1 {
+    struct usb_functionfs_descs_head_v1 {
+        __le32 magic;
+        __le32 length;
+        __le32 fs_count;
+        __le32 hs_count;
+    } __attribute__((packed)) header;
+    struct func_desc fs_descs, hs_descs;
+} __attribute__((packed));
+
+struct desc_v2 {
+    struct usb_functionfs_descs_head_v2 {
+        __le32 magic;
+        __le32 length;
+        __le32 flags;
+        __le32 fs_count;
+        __le32 hs_count;
+        __le32 ss_count;
+    } __attribute__((packed)) header;
+    struct func_desc fs_descs, hs_descs;
+} __attribute__((packed));
+
+struct func_desc fs_descriptors = {
+    .intf = {
+        .bLength = sizeof(fs_descriptors.intf),
+        .bDescriptorType = USB_DT_INTERFACE,
+        .bInterfaceNumber = 0,
+        .bNumEndpoints = 2,
+        .bInterfaceClass = ADB_CLASS,
+        .bInterfaceSubClass = ADB_SUBCLASS,
+        .bInterfaceProtocol = ADB_PROTOCOL,
+        .iInterface = 1, /* first string from the provided table */
     },
-    .hs_descs = {
-        .intf = {
-            .bLength = sizeof(descriptors.hs_descs.intf),
-            .bDescriptorType = USB_DT_INTERFACE,
-            .bInterfaceNumber = 0,
-            .bNumEndpoints = 2,
-            .bInterfaceClass = ADB_CLASS,
-            .bInterfaceSubClass = ADB_SUBCLASS,
-            .bInterfaceProtocol = ADB_PROTOCOL,
-            .iInterface = 1, /* first string from the provided table */
-        },
-        .source = {
-            .bLength = sizeof(descriptors.hs_descs.source),
-            .bDescriptorType = USB_DT_ENDPOINT,
-            .bEndpointAddress = 1 | USB_DIR_OUT,
-            .bmAttributes = USB_ENDPOINT_XFER_BULK,
-            .wMaxPacketSize = MAX_PACKET_SIZE_HS,
-        },
-        .sink = {
-            .bLength = sizeof(descriptors.hs_descs.sink),
-            .bDescriptorType = USB_DT_ENDPOINT,
-            .bEndpointAddress = 2 | USB_DIR_IN,
-            .bmAttributes = USB_ENDPOINT_XFER_BULK,
-            .wMaxPacketSize = MAX_PACKET_SIZE_HS,
-        },
+    .source = {
+        .bLength = sizeof(fs_descriptors.source),
+        .bDescriptorType = USB_DT_ENDPOINT,
+        .bEndpointAddress = 1 | USB_DIR_OUT,
+        .bmAttributes = USB_ENDPOINT_XFER_BULK,
+        .wMaxPacketSize = MAX_PACKET_SIZE_FS,
     },
-    .ss_descs = {
-        .intf = {
-            .bLength = sizeof(descriptors.ss_descs.intf),
-            .bDescriptorType = USB_DT_INTERFACE,
-            .bInterfaceNumber = 0,
-            .bNumEndpoints = 2,
-            .bInterfaceClass = ADB_CLASS,
-            .bInterfaceSubClass = ADB_SUBCLASS,
-            .bInterfaceProtocol = ADB_PROTOCOL,
-            .iInterface = 1, /* first string from the provided table */
-        },
-        .source = {
-            .bLength = sizeof(descriptors.ss_descs.source),
-            .bDescriptorType = USB_DT_ENDPOINT,
-            .bEndpointAddress = 1 | USB_DIR_OUT,
-            .bmAttributes = USB_ENDPOINT_XFER_BULK,
-            .wMaxPacketSize = MAX_PACKET_SIZE_SS,
-        },
-        .source_comp = {
-            .bLength = sizeof(descriptors.ss_descs.source_comp),
-            .bDescriptorType = USB_DT_SS_ENDPOINT_COMP,
-        },
-        .sink = {
-            .bLength = sizeof(descriptors.ss_descs.sink),
-            .bDescriptorType = USB_DT_ENDPOINT,
-            .bEndpointAddress = 2 | USB_DIR_IN,
-            .bmAttributes = USB_ENDPOINT_XFER_BULK,
-            .wMaxPacketSize = MAX_PACKET_SIZE_SS,
-        },
-        .sink_comp = {
-            .bLength = sizeof(descriptors.ss_descs.sink_comp),
-            .bDescriptorType = USB_DT_SS_ENDPOINT_COMP,
-        },
+    .sink = {
+        .bLength = sizeof(fs_descriptors.sink),
+        .bDescriptorType = USB_DT_ENDPOINT,
+        .bEndpointAddress = 2 | USB_DIR_IN,
+        .bmAttributes = USB_ENDPOINT_XFER_BULK,
+        .wMaxPacketSize = MAX_PACKET_SIZE_FS,
+    },
+};
+
+struct func_desc hs_descriptors = {
+    .intf = {
+        .bLength = sizeof(hs_descriptors.intf),
+        .bDescriptorType = USB_DT_INTERFACE,
+        .bInterfaceNumber = 0,
+        .bNumEndpoints = 2,
+        .bInterfaceClass = ADB_CLASS,
+        .bInterfaceSubClass = ADB_SUBCLASS,
+        .bInterfaceProtocol = ADB_PROTOCOL,
+        .iInterface = 1, /* first string from the provided table */
+    },
+    .source = {
+        .bLength = sizeof(hs_descriptors.source),
+        .bDescriptorType = USB_DT_ENDPOINT,
+        .bEndpointAddress = 1 | USB_DIR_OUT,
+        .bmAttributes = USB_ENDPOINT_XFER_BULK,
+        .wMaxPacketSize = MAX_PACKET_SIZE_HS,
+    },
+    .sink = {
+        .bLength = sizeof(hs_descriptors.sink),
+        .bDescriptorType = USB_DT_ENDPOINT,
+        .bEndpointAddress = 2 | USB_DIR_IN,
+        .bmAttributes = USB_ENDPOINT_XFER_BULK,
+        .wMaxPacketSize = MAX_PACKET_SIZE_HS,
     },
 };
 
@@ -312,6 +278,17 @@
 static void init_functionfs(struct usb_handle *h)
 {
     ssize_t ret;
+    struct desc_v1 v1_descriptor;
+    struct desc_v2 v2_descriptor;
+
+    v2_descriptor.header.magic = cpu_to_le32(FUNCTIONFS_DESCRIPTORS_MAGIC_V2);
+    v2_descriptor.header.length = cpu_to_le32(sizeof(v2_descriptor));
+    v2_descriptor.header.flags = FUNCTIONFS_HAS_FS_DESC | FUNCTIONFS_HAS_HS_DESC;
+    v2_descriptor.header.fs_count = 3;
+    v2_descriptor.header.hs_count = 3;
+    v2_descriptor.header.ss_count = 0;
+    v2_descriptor.fs_descs = fs_descriptors;
+    v2_descriptor.hs_descs = hs_descriptors;
 
     if (h->control < 0) { // might have already done this before
         D("OPENING %s\n", USB_FFS_ADB_EP0);
@@ -321,10 +298,20 @@
             goto err;
         }
 
-        ret = adb_write(h->control, &descriptors, sizeof(descriptors));
+        ret = adb_write(h->control, &v2_descriptor, sizeof(v2_descriptor));
         if (ret < 0) {
-            D("[ %s: write descriptors failed: errno=%d ]\n", USB_FFS_ADB_EP0, errno);
-            goto err;
+            v1_descriptor.header.magic = cpu_to_le32(FUNCTIONFS_DESCRIPTORS_MAGIC);
+            v1_descriptor.header.length = cpu_to_le32(sizeof(v1_descriptor));
+            v1_descriptor.header.fs_count = 3;
+            v1_descriptor.header.hs_count = 3;
+            v1_descriptor.fs_descs = fs_descriptors;
+            v1_descriptor.hs_descs = hs_descriptors;
+            D("[ %s: Switching to V1_descriptor format errno=%d ]\n", USB_FFS_ADB_EP0, errno);
+            ret = adb_write(h->control, &v1_descriptor, sizeof(v1_descriptor));
+            if (ret < 0) {
+                D("[ %s: write descriptors failed: errno=%d ]\n", USB_FFS_ADB_EP0, errno);
+                goto err;
+            }
         }
 
         ret = adb_write(h->control, &strings, sizeof(strings));
diff --git a/adb/usb_windows.c b/adb/usb_windows.c
index b7ad913..a2d7226 100644
--- a/adb/usb_windows.c
+++ b/adb/usb_windows.c
@@ -21,6 +21,7 @@
 #include <usb100.h>
 #include <adb_api.h>
 #include <stdio.h>
+#include <stdlib.h>
 
 #include "sysdeps.h"
 
diff --git a/debuggerd/Android.mk b/debuggerd/Android.mk
index 1b8b98d..fbaac39 100644
--- a/debuggerd/Android.mk
+++ b/debuggerd/Android.mk
@@ -22,12 +22,18 @@
     -Wunused \
     -Werror \
 
+ifeq ($(TARGET_IS_64_BIT),true)
+LOCAL_CPPFLAGS += -DTARGET_IS_64_BIT
+endif
+
 LOCAL_SHARED_LIBRARIES := \
     libbacktrace \
     libcutils \
     liblog \
     libselinux \
 
+LOCAL_CLANG := true
+
 LOCAL_MODULE := debuggerd
 LOCAL_MODULE_STEM_32 := debuggerd
 LOCAL_MODULE_STEM_64 := debuggerd64
diff --git a/debuggerd/crasher.c b/debuggerd/crasher.c
index d0c3912..af86fe9 100644
--- a/debuggerd/crasher.c
+++ b/debuggerd/crasher.c
@@ -32,16 +32,23 @@
     }
 }
 
-static int smash_stack(int i __unused) {
+static char* smash_stack_dummy_buf;
+__attribute__ ((noinline)) static void smash_stack_dummy_function(volatile int* plen) {
+  smash_stack_dummy_buf[*plen] = 0;
+}
+
+// This must be marked with "__attribute__ ((noinline))", to ensure the
+// compiler generates the proper stack guards around this function.
+// Assign local array address to global variable to force stack guards.
+// Use another noinline function to corrupt the stack.
+__attribute__ ((noinline)) static int smash_stack(volatile int* plen) {
     printf("crasher: deliberately corrupting stack...\n");
-    // Unless there's a "big enough" buffer on the stack, gcc
-    // doesn't bother inserting checks.
-    char buf[8];
-    // If we don't write something relatively unpredictable
-    // into the buffer and then do something with it, gcc
-    // optimizes everything away and just returns a constant.
-    *(int*)(&buf[7]) = (uintptr_t) &buf[0];
-    return *(int*)(&buf[0]);
+
+    char buf[128];
+    smash_stack_dummy_buf = buf;
+    // This should corrupt stack guards and make process abort.
+    smash_stack_dummy_function(plen);
+    return 0;
 }
 
 static void* global = 0; // So GCC doesn't optimize the tail recursion out of overflow_stack.
@@ -125,7 +132,8 @@
     } else if (!strcmp(arg, "SIGSEGV-non-null")) {
         sigsegv_non_null();
     } else if (!strcmp(arg, "smash-stack")) {
-        return smash_stack(42);
+        volatile int len = 128;
+        return smash_stack(&len);
     } else if (!strcmp(arg, "stack-overflow")) {
         overflow_stack(NULL);
     } else if (!strcmp(arg, "nostack")) {
diff --git a/debuggerd/debuggerd.cpp b/debuggerd/debuggerd.cpp
index 318b224..039b8ec 100644
--- a/debuggerd/debuggerd.cpp
+++ b/debuggerd/debuggerd.cpp
@@ -47,6 +47,14 @@
 #include "tombstone.h"
 #include "utility.h"
 
+// If the 32 bit executable is compiled on a 64 bit system,
+// use the 32 bit socket name.
+#if defined(TARGET_IS_64_BIT) && !defined(__LP64__)
+#define SOCKET_NAME DEBUGGER32_SOCKET_NAME
+#else
+#define SOCKET_NAME DEBUGGER_SOCKET_NAME
+#endif
+
 struct debugger_request_t {
   debugger_action_t action;
   pid_t pid, tid;
@@ -207,7 +215,7 @@
     return -1;
   }
 
-  out_request->action = msg.action;
+  out_request->action = static_cast<debugger_action_t>(msg.action);
   out_request->tid = msg.tid;
   out_request->pid = cr.pid;
   out_request->uid = cr.uid;
@@ -255,6 +263,85 @@
   return false;
 }
 
+#if defined(__LP64__)
+static bool is32bit(pid_t tid) {
+  char* exeline;
+  if (asprintf(&exeline, "/proc/%d/exe", tid) == -1) {
+    return false;
+  }
+  int fd = TEMP_FAILURE_RETRY(open(exeline, O_RDONLY | O_CLOEXEC));
+  int saved_errno = errno;
+  free(exeline);
+  if (fd == -1) {
+    ALOGW("Failed to open /proc/%d/exe %s", tid, strerror(saved_errno));
+    return false;
+  }
+
+  char ehdr[EI_NIDENT];
+  ssize_t bytes = TEMP_FAILURE_RETRY(read(fd, &ehdr, sizeof(ehdr)));
+  TEMP_FAILURE_RETRY(close(fd));
+  if (bytes != (ssize_t) sizeof(ehdr) || memcmp(ELFMAG, ehdr, SELFMAG) != 0) {
+    return false;
+  }
+  if (ehdr[EI_CLASS] == ELFCLASS32) {
+    return true;
+  }
+  return false;
+}
+
+static void redirect_to_32(int fd, debugger_request_t* request) {
+  debugger_msg_t msg;
+  memset(&msg, 0, sizeof(msg));
+  msg.tid = request->tid;
+  msg.action = request->action;
+
+  int sock_fd = socket_local_client(DEBUGGER32_SOCKET_NAME, ANDROID_SOCKET_NAMESPACE_ABSTRACT,
+                                    SOCK_STREAM | SOCK_CLOEXEC);
+  if (sock_fd < 0) {
+    ALOGE("Failed to connect to debuggerd32: %s", strerror(errno));
+    return;
+  }
+
+  if (TEMP_FAILURE_RETRY(write(sock_fd, &msg, sizeof(msg))) != (ssize_t) sizeof(msg)) {
+    ALOGE("Failed to write request to debuggerd32 socket: %s", strerror(errno));
+    TEMP_FAILURE_RETRY(close(sock_fd));
+    return;
+  }
+
+  char ack;
+  if (TEMP_FAILURE_RETRY(read(sock_fd, &ack, 1)) == -1) {
+    ALOGE("Failed to read ack from debuggerd32 socket: %s", strerror(errno));
+    TEMP_FAILURE_RETRY(close(sock_fd));
+    return;
+  }
+
+  char buffer[1024];
+  ssize_t bytes_read;
+  while ((bytes_read = TEMP_FAILURE_RETRY(read(sock_fd, buffer, sizeof(buffer)))) > 0) {
+    ssize_t bytes_to_send = bytes_read;
+    ssize_t bytes_written;
+    do {
+      bytes_written = TEMP_FAILURE_RETRY(write(fd, buffer + bytes_read - bytes_to_send,
+                                               bytes_to_send));
+      if (bytes_written == -1) {
+        if (errno == EAGAIN) {
+          // Retry the write.
+          continue;
+        }
+        ALOGE("Error while writing data to fd: %s", strerror(errno));
+        break;
+      }
+      bytes_to_send -= bytes_written;
+    } while (bytes_written != 0 && bytes_to_send > 0);
+    if (bytes_to_send != 0) {
+        ALOGE("Failed to write all data to fd: read %zd, sent %zd", bytes_read, bytes_to_send);
+        break;
+    }
+  }
+  TEMP_FAILURE_RETRY(close(sock_fd));
+}
+#endif
+
 static void handle_request(int fd) {
   ALOGV("handle_request(%d)\n", fd);
 
@@ -265,6 +352,24 @@
     ALOGV("BOOM: pid=%d uid=%d gid=%d tid=%d\n",
          request.pid, request.uid, request.gid, request.tid);
 
+#if defined(__LP64__)
+    // On 64 bit systems, requests to dump 32 bit and 64 bit tids come
+    // to the 64 bit debuggerd. If the process is a 32 bit executable,
+    // redirect the request to the 32 bit debuggerd.
+    if (is32bit(request.tid)) {
+      // Only dump backtrace and dump tombstone requests can be redirected.
+      if (request.action == DEBUGGER_ACTION_DUMP_BACKTRACE
+          || request.action == DEBUGGER_ACTION_DUMP_TOMBSTONE) {
+        redirect_to_32(fd, &request);
+      } else {
+        ALOGE("debuggerd: Not allowed to redirect action %d to 32 bit debuggerd\n",
+              request.action);
+      }
+      TEMP_FAILURE_RETRY(close(fd));
+      return;
+    }
+#endif
+
     // At this point, the thread that made the request is blocked in
     // a read() call.  If the thread has crashed, then this gives us
     // time to PTRACE_ATTACH to it before it has a chance to really fault.
@@ -428,7 +533,7 @@
   act.sa_flags = SA_NOCLDWAIT;
   sigaction(SIGCHLD, &act, 0);
 
-  int s = socket_local_server(DEBUGGER_SOCKET_NAME, ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM);
+  int s = socket_local_server(SOCKET_NAME, ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM);
   if (s < 0)
     return 1;
   fcntl(s, F_SETFD, FD_CLOEXEC);
diff --git a/debuggerd/tombstone.cpp b/debuggerd/tombstone.cpp
index 0c1b80f..38e9d17 100644
--- a/debuggerd/tombstone.cpp
+++ b/debuggerd/tombstone.cpp
@@ -16,6 +16,7 @@
 
 #define LOG_TAG "DEBUG"
 
+#include <arpa/inet.h>
 #include <dirent.h>
 #include <errno.h>
 #include <fcntl.h>
diff --git a/debuggerd/utility.cpp b/debuggerd/utility.cpp
index 2baf9de..e10feff 100644
--- a/debuggerd/utility.cpp
+++ b/debuggerd/utility.cpp
@@ -131,12 +131,6 @@
   return -1;
 }
 
-#if defined (__mips__)
-#define DUMP_MEMORY_AS_ASCII 1
-#else
-#define DUMP_MEMORY_AS_ASCII 0
-#endif
-
 void dump_memory(log_t* log, pid_t tid, uintptr_t addr) {
     char code_buffer[64];
     char ascii_buffer[32];
@@ -183,7 +177,6 @@
                                static_cast<uintptr_t>(data));
             }
 
-#if DUMP_MEMORY_AS_ASCII
             for (size_t j = 0; j < sizeof(long); j++) {
                 /*
                  * Our isprint() allows high-ASCII characters that display
@@ -197,7 +190,6 @@
                     *asc_out++ = '.';
                 }
             }
-#endif
             p += sizeof(long);
         }
         *asc_out = '\0';
diff --git a/fastboot/Android.mk b/fastboot/Android.mk
index f03bbea..aa5b14a 100644
--- a/fastboot/Android.mk
+++ b/fastboot/Android.mk
@@ -53,7 +53,6 @@
 LOCAL_STATIC_LIBRARIES := \
     $(EXTRA_STATIC_LIBS) \
     libzipfile \
-    libunz \
     libext4_utils_host \
     libsparse_host \
     libz
diff --git a/fastboot/usb_windows.c b/fastboot/usb_windows.c
index 0d13863..a09610f 100644
--- a/fastboot/usb_windows.c
+++ b/fastboot/usb_windows.c
@@ -32,6 +32,7 @@
 #include <usb100.h>
 #include <adb_api.h>
 #include <stdio.h>
+#include <stdlib.h>
 
 #include "usb.h"
 
diff --git a/fastbootd/Android.mk b/fastbootd/Android.mk
index bccac68..1e69e7a 100644
--- a/fastbootd/Android.mk
+++ b/fastbootd/Android.mk
@@ -16,12 +16,6 @@
 
 include $(CLEAR_VARS)
 
-LOCAL_C_INCLUDES := \
-    external/openssl/include \
-    external/mdnsresponder/mDNSShared \
-    $(LOCAL_PATH)/include \
-    external/zlib/ \
-
 LOCAL_SRC_FILES := \
     config.c \
     commands.c \
@@ -60,8 +54,6 @@
 include $(BUILD_EXECUTABLE)
 
 include $(CLEAR_VARS)
-LOCAL_C_INCLUDES := \
-    external/zlib/
 
 LOCAL_SRC_FILES := \
     commands/partitions.c \
diff --git a/fastbootd/commands.c b/fastbootd/commands.c
index 98b7866..9be96dc 100644
--- a/fastbootd/commands.c
+++ b/fastbootd/commands.c
@@ -173,7 +173,7 @@
         return;
     }
 
-    if (path == NULL) {
+    if (!path[0]) {
         fastboot_fail(phandle, "Couldn't find partition");
         return;
     }
diff --git a/fastbootd/commands/partitions.c b/fastbootd/commands/partitions.c
index f2c9da7..3b27959 100644
--- a/fastbootd/commands/partitions.c
+++ b/fastbootd/commands/partitions.c
@@ -31,6 +31,7 @@
 
 #include <sys/types.h>
 #include <sys/stat.h>
+#include <errno.h>
 #include <fcntl.h>
 #include <sys/mman.h>
 #include <sys/stat.h>
diff --git a/fastbootd/config.c b/fastbootd/config.c
index fe6da69..012a197 100644
--- a/fastbootd/config.c
+++ b/fastbootd/config.c
@@ -29,6 +29,7 @@
  * SUCH DAMAGE.
  */
 
+#include <errno.h>
 #include <fcntl.h>
 #include <string.h>
 #include <unistd.h>
diff --git a/fastbootd/transport.c b/fastbootd/transport.c
index 9a16fd7..232c999 100644
--- a/fastbootd/transport.c
+++ b/fastbootd/transport.c
@@ -14,6 +14,7 @@
  * limitations under the License.
  */
 
+#include <errno.h>
 #include <pthread.h>
 #include <stddef.h>
 #include <stdio.h>
diff --git a/fastbootd/usb_linux_client.c b/fastbootd/usb_linux_client.c
index 64420e9..beaafc3 100644
--- a/fastbootd/usb_linux_client.c
+++ b/fastbootd/usb_linux_client.c
@@ -15,6 +15,7 @@
  */
 
 #include <endian.h>
+#include <errno.h>
 #include <fcntl.h>
 #include <pthread.h>
 #include <stdio.h>
@@ -69,71 +70,85 @@
     struct transport_handle handle;
 };
 
-static const struct {
-    struct usb_functionfs_descs_head header;
-    struct {
-        struct usb_interface_descriptor intf;
-        struct usb_endpoint_descriptor_no_audio source;
-        struct usb_endpoint_descriptor_no_audio sink;
-    } __attribute__((packed)) fs_descs, hs_descs;
-} __attribute__((packed)) descriptors = {
-    .header = {
-        .magic = cpu_to_le32(FUNCTIONFS_DESCRIPTORS_MAGIC),
-        .length = cpu_to_le32(sizeof(descriptors)),
-        .fs_count = 3,
-        .hs_count = 3,
+struct func_desc {
+    struct usb_interface_descriptor intf;
+    struct usb_endpoint_descriptor_no_audio source;
+    struct usb_endpoint_descriptor_no_audio sink;
+} __attribute__((packed));
+
+struct desc_v1 {
+    struct usb_functionfs_descs_head_v1 {
+        __le32 magic;
+        __le32 length;
+        __le32 fs_count;
+        __le32 hs_count;
+    } __attribute__((packed)) header;
+    struct func_desc fs_descs, hs_descs;
+} __attribute__((packed));
+
+struct desc_v2 {
+    struct usb_functionfs_descs_head_v2 {
+        __le32 magic;
+        __le32 length;
+        __le32 flags;
+        __le32 fs_count;
+        __le32 hs_count;
+        __le32 ss_count;
+    } __attribute__((packed)) header;
+    struct func_desc fs_descs, hs_descs;
+} __attribute__((packed));
+
+struct func_desc fs_descriptors = {
+    .intf = {
+        .bLength = sizeof(fs_descriptors.intf),
+        .bDescriptorType = USB_DT_INTERFACE,
+        .bInterfaceNumber = 0,
+        .bNumEndpoints = 2,
+        .bInterfaceClass = FASTBOOT_CLASS,
+        .bInterfaceSubClass = FASTBOOT_SUBCLASS,
+        .bInterfaceProtocol = FASTBOOT_PROTOCOL,
+        .iInterface = 1, /* first string from the provided table */
     },
-    .fs_descs = {
-        .intf = {
-            .bLength = sizeof(descriptors.fs_descs.intf),
-            .bDescriptorType = USB_DT_INTERFACE,
-            .bInterfaceNumber = 0,
-            .bNumEndpoints = 2,
-            .bInterfaceClass = FASTBOOT_CLASS,
-            .bInterfaceSubClass = FASTBOOT_SUBCLASS,
-            .bInterfaceProtocol = FASTBOOT_PROTOCOL,
-            .iInterface = 1, /* first string from the provided table */
-        },
-        .source = {
-            .bLength = sizeof(descriptors.fs_descs.source),
-            .bDescriptorType = USB_DT_ENDPOINT,
-            .bEndpointAddress = 1 | USB_DIR_OUT,
-            .bmAttributes = USB_ENDPOINT_XFER_BULK,
-            .wMaxPacketSize = MAX_PACKET_SIZE_FS,
-        },
-        .sink = {
-            .bLength = sizeof(descriptors.fs_descs.sink),
-            .bDescriptorType = USB_DT_ENDPOINT,
-            .bEndpointAddress = 2 | USB_DIR_IN,
-            .bmAttributes = USB_ENDPOINT_XFER_BULK,
-            .wMaxPacketSize = MAX_PACKET_SIZE_FS,
-        },
+    .source = {
+        .bLength = sizeof(fs_descriptors.source),
+        .bDescriptorType = USB_DT_ENDPOINT,
+        .bEndpointAddress = 1 | USB_DIR_OUT,
+        .bmAttributes = USB_ENDPOINT_XFER_BULK,
+        .wMaxPacketSize = MAX_PACKET_SIZE_FS,
     },
-    .hs_descs = {
-        .intf = {
-            .bLength = sizeof(descriptors.hs_descs.intf),
-            .bDescriptorType = USB_DT_INTERFACE,
-            .bInterfaceNumber = 0,
-            .bNumEndpoints = 2,
-            .bInterfaceClass = FASTBOOT_CLASS,
-            .bInterfaceSubClass = FASTBOOT_SUBCLASS,
-            .bInterfaceProtocol = FASTBOOT_PROTOCOL,
-            .iInterface = 1, /* first string from the provided table */
-        },
-        .source = {
-            .bLength = sizeof(descriptors.hs_descs.source),
-            .bDescriptorType = USB_DT_ENDPOINT,
-            .bEndpointAddress = 1 | USB_DIR_OUT,
-            .bmAttributes = USB_ENDPOINT_XFER_BULK,
-            .wMaxPacketSize = MAX_PACKET_SIZE_HS,
-        },
-        .sink = {
-            .bLength = sizeof(descriptors.hs_descs.sink),
-            .bDescriptorType = USB_DT_ENDPOINT,
-            .bEndpointAddress = 2 | USB_DIR_IN,
-            .bmAttributes = USB_ENDPOINT_XFER_BULK,
-            .wMaxPacketSize = MAX_PACKET_SIZE_HS,
-        },
+    .sink = {
+        .bLength = sizeof(fs_descriptors.sink),
+        .bDescriptorType = USB_DT_ENDPOINT,
+        .bEndpointAddress = 2 | USB_DIR_IN,
+        .bmAttributes = USB_ENDPOINT_XFER_BULK,
+        .wMaxPacketSize = MAX_PACKET_SIZE_FS,
+    },
+};
+
+struct func_desc hs_descriptors = {
+    .intf = {
+        .bLength = sizeof(hs_descriptors.intf),
+        .bDescriptorType = USB_DT_INTERFACE,
+        .bInterfaceNumber = 0,
+        .bNumEndpoints = 2,
+        .bInterfaceClass = FASTBOOT_CLASS,
+        .bInterfaceSubClass = FASTBOOT_SUBCLASS,
+        .bInterfaceProtocol = FASTBOOT_PROTOCOL,
+        .iInterface = 1, /* first string from the provided table */
+    },
+    .source = {
+        .bLength = sizeof(hs_descriptors.source),
+        .bDescriptorType = USB_DT_ENDPOINT,
+        .bEndpointAddress = 1 | USB_DIR_OUT,
+        .bmAttributes = USB_ENDPOINT_XFER_BULK,
+        .wMaxPacketSize = MAX_PACKET_SIZE_HS,
+    },
+    .sink = {
+        .bLength = sizeof(hs_descriptors.sink),
+        .bDescriptorType = USB_DT_ENDPOINT,
+        .bEndpointAddress = 2 | USB_DIR_IN,
+        .bmAttributes = USB_ENDPOINT_XFER_BULK,
+        .wMaxPacketSize = MAX_PACKET_SIZE_HS,
     },
 };
 
@@ -161,6 +176,17 @@
 static int init_functionfs(struct usb_transport *usb_transport)
 {
     ssize_t ret;
+    struct desc_v1 v1_descriptor;
+    struct desc_v2 v2_descriptor;
+
+    v2_descriptor.header.magic = cpu_to_le32(FUNCTIONFS_DESCRIPTORS_MAGIC_V2);
+    v2_descriptor.header.length = cpu_to_le32(sizeof(v2_descriptor));
+    v2_descriptor.header.flags = FUNCTIONFS_HAS_FS_DESC | FUNCTIONFS_HAS_HS_DESC;
+    v2_descriptor.header.fs_count = 3;
+    v2_descriptor.header.hs_count = 3;
+    v2_descriptor.header.ss_count = 0;
+    v2_descriptor.fs_descs = fs_descriptors;
+    v2_descriptor.hs_descs = hs_descriptors;
 
     D(VERBOSE, "OPENING %s", USB_FFS_FASTBOOT_EP0);
     usb_transport->control = open(USB_FFS_FASTBOOT_EP0, O_RDWR);
@@ -169,10 +195,20 @@
         goto err;
     }
 
-    ret = write(usb_transport->control, &descriptors, sizeof(descriptors));
+    ret = write(usb_transport->control, &v2_descriptor, sizeof(v2_descriptor));
     if (ret < 0) {
-        D(ERR, "[ %s: write descriptors failed: errno=%d ]", USB_FFS_FASTBOOT_EP0, errno);
-        goto err;
+        v1_descriptor.header.magic = cpu_to_le32(FUNCTIONFS_DESCRIPTORS_MAGIC);
+        v1_descriptor.header.length = cpu_to_le32(sizeof(v1_descriptor));
+        v1_descriptor.header.fs_count = 3;
+        v1_descriptor.header.hs_count = 3;
+        v1_descriptor.fs_descs = fs_descriptors;
+        v1_descriptor.hs_descs = hs_descriptors;
+        D(ERR, "[ %s: Switching to V1_descriptor format errno=%d ]\n", USB_FFS_FASTBOOT_EP0, errno);
+        ret = write(usb_transport->control, &v1_descriptor, sizeof(v1_descriptor));
+        if (ret < 0) {
+            D(ERR, "[ %s: write descriptors failed: errno=%d ]", USB_FFS_FASTBOOT_EP0, errno);
+            goto err;
+        }
     }
 
     ret = write(usb_transport->control, &strings, sizeof(strings));
diff --git a/fastbootd/utils.c b/fastbootd/utils.c
index bef2463..a9ab47e 100644
--- a/fastbootd/utils.c
+++ b/fastbootd/utils.c
@@ -28,6 +28,7 @@
  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  */
+#include <errno.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <unistd.h>
diff --git a/fs_mgr/Android.mk b/fs_mgr/Android.mk
index 7cffc37..61bf1ee 100644
--- a/fs_mgr/Android.mk
+++ b/fs_mgr/Android.mk
@@ -13,6 +13,10 @@
 LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
 LOCAL_CFLAGS := -Werror
 
+ifneq (,$(filter userdebug,$(TARGET_BUILD_VARIANT)))
+LOCAL_CFLAGS += -DALLOW_ADBD_DISABLE_VERITY=1
+endif
+
 include $(BUILD_STATIC_LIBRARY)
 
 
diff --git a/fs_mgr/fs_mgr.c b/fs_mgr/fs_mgr.c
index 09331f0..19f5ac5 100644
--- a/fs_mgr/fs_mgr.c
+++ b/fs_mgr/fs_mgr.c
@@ -248,6 +248,16 @@
     return strcmp(value, "1") ? 0 : 1;
 }
 
+static int device_is_secure() {
+    int ret = -1;
+    char value[PROP_VALUE_MAX];
+    ret = __system_property_get("ro.secure", value);
+    /* If error, we want to fail secure */
+    if (ret < 0)
+        return 1;
+    return strcmp(value, "0") ? 1 : 0;
+}
+
 /*
  * Tries to mount any of the consecutive fstab entries that match
  * the mountpoint of the one given by fstab->recs[start_idx].
@@ -441,9 +451,11 @@
             wait_for_file(fstab->recs[i].blk_device, WAIT_TIMEOUT);
         }
 
-        if ((fstab->recs[i].fs_mgr_flags & MF_VERIFY) &&
-            !device_is_debuggable()) {
-            if (fs_mgr_setup_verity(&fstab->recs[i]) < 0) {
+        if ((fstab->recs[i].fs_mgr_flags & MF_VERIFY) && device_is_secure()) {
+            int rc = fs_mgr_setup_verity(&fstab->recs[i]);
+            if (device_is_debuggable() && rc == FS_MGR_SETUP_VERITY_DISABLED) {
+                INFO("Verity disabled");
+            } else if (rc != FS_MGR_SETUP_VERITY_SUCCESS) {
                 ERROR("Could not set up verified partition, skipping!\n");
                 continue;
             }
@@ -558,9 +570,11 @@
                      fstab->recs[i].mount_point);
         }
 
-        if ((fstab->recs[i].fs_mgr_flags & MF_VERIFY) &&
-            !device_is_debuggable()) {
-            if (fs_mgr_setup_verity(&fstab->recs[i]) < 0) {
+        if ((fstab->recs[i].fs_mgr_flags & MF_VERIFY) && device_is_secure()) {
+            int rc = fs_mgr_setup_verity(&fstab->recs[i]);
+            if (device_is_debuggable() && rc == FS_MGR_SETUP_VERITY_DISABLED) {
+                INFO("Verity disabled");
+            } else if (rc != FS_MGR_SETUP_VERITY_SUCCESS) {
                 ERROR("Could not set up verified partition, skipping!\n");
                 continue;
             }
diff --git a/fs_mgr/fs_mgr_fstab.c b/fs_mgr/fs_mgr_fstab.c
index 3f84179..ab8f128 100644
--- a/fs_mgr/fs_mgr_fstab.c
+++ b/fs_mgr/fs_mgr_fstab.c
@@ -418,6 +418,11 @@
     return fstab->fs_mgr_flags & MF_NONREMOVABLE;
 }
 
+int fs_mgr_is_verified(struct fstab_rec *fstab)
+{
+    return fstab->fs_mgr_flags & MF_VERIFY;
+}
+
 int fs_mgr_is_encryptable(struct fstab_rec *fstab)
 {
     return fstab->fs_mgr_flags & (MF_CRYPT | MF_FORCECRYPT);
diff --git a/fs_mgr/fs_mgr_priv_verity.h b/fs_mgr/fs_mgr_priv_verity.h
index 6193784..f90e596 100644
--- a/fs_mgr/fs_mgr_priv_verity.h
+++ b/fs_mgr/fs_mgr_priv_verity.h
@@ -14,4 +14,7 @@
  * limitations under the License.
  */
 
-int fs_mgr_setup_verity(struct fstab_rec *fstab);
\ No newline at end of file
+#define FS_MGR_SETUP_VERITY_DISABLED -2
+#define FS_MGR_SETUP_VERITY_FAIL -1
+#define FS_MGR_SETUP_VERITY_SUCCESS 0
+int fs_mgr_setup_verity(struct fstab_rec *fstab);
diff --git a/fs_mgr/fs_mgr_verity.c b/fs_mgr/fs_mgr_verity.c
index 01f7844..ef7cf6e 100644
--- a/fs_mgr/fs_mgr_verity.c
+++ b/fs_mgr/fs_mgr_verity.c
@@ -43,7 +43,6 @@
 #include "fs_mgr_priv_verity.h"
 
 #define VERITY_METADATA_SIZE 32768
-#define VERITY_METADATA_MAGIC_NUMBER 0xb001b001
 #define VERITY_TABLE_RSA_KEY "/verity_key"
 
 extern struct fs_info info;
@@ -125,28 +124,28 @@
 
     info.len = 0;  /* Only len is set to 0 to ask the device for real size. */
 
-    data_device = open(blk_device, O_RDONLY);
-    if (data_device < 0) {
+    data_device = TEMP_FAILURE_RETRY(open(blk_device, O_RDONLY | O_CLOEXEC));
+    if (data_device == -1) {
         ERROR("Error opening block device (%s)", strerror(errno));
         return -1;
     }
 
-    if (lseek64(data_device, 1024, SEEK_SET) < 0) {
+    if (TEMP_FAILURE_RETRY(lseek64(data_device, 1024, SEEK_SET)) < 0) {
         ERROR("Error seeking to superblock");
-        close(data_device);
+        TEMP_FAILURE_RETRY(close(data_device));
         return -1;
     }
 
-    if (read(data_device, &sb, sizeof(sb)) != sizeof(sb)) {
+    if (TEMP_FAILURE_RETRY(read(data_device, &sb, sizeof(sb))) != sizeof(sb)) {
         ERROR("Error reading superblock");
-        close(data_device);
+        TEMP_FAILURE_RETRY(close(data_device));
         return -1;
     }
 
     ext4_parse_sb(&sb, &info);
     *device_size = info.len;
 
-    close(data_device);
+    TEMP_FAILURE_RETRY(close(data_device));
     return 0;
 }
 
@@ -156,11 +155,13 @@
     unsigned table_length;
     uint64_t device_length;
     int protocol_version;
-    FILE *device;
-    int retval = -1;
+    int device;
+    int retval = FS_MGR_SETUP_VERITY_FAIL;
+    *signature = 0;
+    *table = 0;
 
-    device = fopen(block_device, "r");
-    if (!device) {
+    device = TEMP_FAILURE_RETRY(open(block_device, O_RDONLY | O_CLOEXEC));
+    if (device == -1) {
         ERROR("Could not open block device %s (%s).\n", block_device, strerror(errno));
         goto out;
     }
@@ -170,23 +171,35 @@
         ERROR("Could not get target device size.\n");
         goto out;
     }
-    if (fseek(device, device_length, SEEK_SET) < 0) {
+    if (TEMP_FAILURE_RETRY(lseek64(device, device_length, SEEK_SET)) < 0) {
         ERROR("Could not seek to start of verity metadata block.\n");
         goto out;
     }
 
     // check the magic number
-    if (!fread(&magic_number, sizeof(int), 1, device)) {
+    if (TEMP_FAILURE_RETRY(read(device, &magic_number, sizeof(magic_number))) !=
+            sizeof(magic_number)) {
         ERROR("Couldn't read magic number!\n");
         goto out;
     }
+
+#ifdef ALLOW_ADBD_DISABLE_VERITY
+    if (magic_number == VERITY_METADATA_MAGIC_DISABLE) {
+        retval = FS_MGR_SETUP_VERITY_DISABLED;
+        INFO("Attempt to cleanly disable verity - only works in USERDEBUG");
+        goto out;
+    }
+#endif
+
     if (magic_number != VERITY_METADATA_MAGIC_NUMBER) {
-        ERROR("Couldn't find verity metadata at offset %"PRIu64"!\n", device_length);
+        ERROR("Couldn't find verity metadata at offset %"PRIu64"!\n",
+              device_length);
         goto out;
     }
 
     // check the protocol version
-    if (!fread(&protocol_version, sizeof(int), 1, device)) {
+    if (TEMP_FAILURE_RETRY(read(device, &protocol_version,
+            sizeof(protocol_version))) != sizeof(protocol_version)) {
         ERROR("Couldn't read verity metadata protocol version!\n");
         goto out;
     }
@@ -196,43 +209,49 @@
     }
 
     // get the signature
-    *signature = (char*) malloc(RSANUMBYTES * sizeof(char));
+    *signature = (char*) malloc(RSANUMBYTES);
     if (!*signature) {
         ERROR("Couldn't allocate memory for signature!\n");
         goto out;
     }
-    if (!fread(*signature, RSANUMBYTES, 1, device)) {
+    if (TEMP_FAILURE_RETRY(read(device, *signature, RSANUMBYTES)) != RSANUMBYTES) {
         ERROR("Couldn't read signature from verity metadata!\n");
-        free(*signature);
         goto out;
     }
 
     // get the size of the table
-    if (!fread(&table_length, sizeof(int), 1, device)) {
+    if (TEMP_FAILURE_RETRY(read(device, &table_length, sizeof(table_length))) !=
+            sizeof(table_length)) {
         ERROR("Couldn't get the size of the verity table from metadata!\n");
-        free(*signature);
         goto out;
     }
 
     // get the table + null terminator
-    table_length += 1;
-    *table = malloc(table_length);
-    if(!*table) {
+    *table = malloc(table_length + 1);
+    if (!*table) {
         ERROR("Couldn't allocate memory for verity table!\n");
         goto out;
     }
-    if (!fgets(*table, table_length, device)) {
+    if (TEMP_FAILURE_RETRY(read(device, *table, table_length)) !=
+            (ssize_t)table_length) {
         ERROR("Couldn't read the verity table from metadata!\n");
-        free(*table);
-        free(*signature);
         goto out;
     }
 
-    retval = 0;
+    (*table)[table_length] = 0;
+    retval = FS_MGR_SETUP_VERITY_SUCCESS;
 
 out:
-    if (device)
-        fclose(device);
+    if (device != -1)
+        TEMP_FAILURE_RETRY(close(device));
+
+    if (retval != FS_MGR_SETUP_VERITY_SUCCESS) {
+        free(*table);
+        free(*signature);
+        *table = 0;
+        *signature = 0;
+    }
+
     return retval;
 }
 
@@ -360,10 +379,11 @@
 int fs_mgr_setup_verity(struct fstab_rec *fstab) {
 
     int retval = -1;
+    int fd = -1;
 
-    char *verity_blk_name;
-    char *verity_table;
-    char *verity_table_signature;
+    char *verity_blk_name = 0;
+    char *verity_table = 0;
+    char *verity_table_signature = 0;
 
     char buffer[DM_BUF_SIZE];
     struct dm_ioctl *io = (struct dm_ioctl *) buffer;
@@ -380,11 +400,19 @@
         return retval;
     }
 
+    // read the verity block at the end of the block device
+    // send error code up the chain so we can detect attempts to disable verity
+    retval = read_verity_metadata(fstab->blk_device,
+                                  &verity_table_signature,
+                                  &verity_table);
+    if (retval < 0) {
+        goto out;
+    }
+
     // get the device mapper fd
-    int fd;
     if ((fd = open("/dev/device-mapper", O_RDWR)) < 0) {
         ERROR("Error opening device mapper (%s)", strerror(errno));
-        return retval;
+        goto out;
     }
 
     // create the device
@@ -399,14 +427,6 @@
         goto out;
     }
 
-    verity_table = verity_table_signature = NULL;
-    // read the verity block at the end of the block device
-    if (read_verity_metadata(fstab->blk_device,
-                                    &verity_table_signature,
-                                    &verity_table) < 0) {
-        goto out;
-    }
-
     // verify the signature on the table
     if (verify_table(verity_table_signature,
                             verity_table,
@@ -427,6 +447,7 @@
     // assign the new verity block device as the block device
     free(fstab->blk_device);
     fstab->blk_device = verity_blk_name;
+    verity_blk_name = 0;
 
     // make sure we've set everything up properly
     if (test_access(fstab->blk_device) < 0) {
@@ -437,6 +458,13 @@
     retval = set_verified_property(mount_point);
 
 out:
-    close(fd);
+    if (fd != -1) {
+        close(fd);
+    }
+
+    free(verity_table);
+    free(verity_table_signature);
+    free(verity_blk_name);
+
     return retval;
 }
diff --git a/fs_mgr/include/fs_mgr.h b/fs_mgr/include/fs_mgr.h
index 0c7eb20..5e2ff41 100644
--- a/fs_mgr/include/fs_mgr.h
+++ b/fs_mgr/include/fs_mgr.h
@@ -20,6 +20,13 @@
 #include <stdint.h>
 #include <linux/dm-ioctl.h>
 
+// Magic number at start of verity metadata
+#define VERITY_METADATA_MAGIC_NUMBER 0xb001b001
+
+// Replacement magic number at start of verity metadata to cleanly
+// turn verity off in userdebug builds.
+#define VERITY_METADATA_MAGIC_DISABLE 0x46464f56 // "VOFF"
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -74,6 +81,7 @@
 struct fstab_rec *fs_mgr_get_entry_for_mount_point(struct fstab *fstab, const char *path);
 int fs_mgr_is_voldmanaged(struct fstab_rec *fstab);
 int fs_mgr_is_nonremovable(struct fstab_rec *fstab);
+int fs_mgr_is_verified(struct fstab_rec *fstab);
 int fs_mgr_is_encryptable(struct fstab_rec *fstab);
 int fs_mgr_is_noemulatedsd(struct fstab_rec *fstab);
 int fs_mgr_swapon_all(struct fstab *fstab);
diff --git a/include/cutils/cpu_info.h b/include/cutils/cpu_info.h
deleted file mode 100644
index 78c1884..0000000
--- a/include/cutils/cpu_info.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef __CUTILS_CPU_INFO_H
-#define __CUTILS_CPU_INFO_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* returns a string contiaining an ASCII representation of the CPU serial number, 
-** or NULL if cpu info not available.
-** The string is a static variable, so don't call free() on it.
-*/
-extern const char* get_cpu_serial_number(void);
-    
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __CUTILS_CPU_INFO_H */ 
diff --git a/include/cutils/debugger.h b/include/cutils/debugger.h
index 4bcc8e6..285e1af 100644
--- a/include/cutils/debugger.h
+++ b/include/cutils/debugger.h
@@ -17,20 +17,14 @@
 #ifndef __CUTILS_DEBUGGER_H
 #define __CUTILS_DEBUGGER_H
 
+#include <sys/cdefs.h>
 #include <sys/types.h>
 
-#ifdef __cplusplus
-extern "C" {
-#endif
+__BEGIN_DECLS
 
-#define DEBUGGER32_SOCKET_NAME "android:debuggerd"
-#define DEBUGGER64_SOCKET_NAME "android:debuggerd64"
-
-#if defined(__LP64__)
-#define DEBUGGER_SOCKET_NAME DEBUGGER64_SOCKET_NAME
-#else
-#define DEBUGGER_SOCKET_NAME DEBUGGER32_SOCKET_NAME
-#endif
+#define DEBUGGER_SOCKET_NAME "android:debuggerd"
+#define DEBUGGER32_SOCKET_NAME "android:debuggerd32"
+#define DEBUGGER64_SOCKET_NAME DEBUGGER_SOCKET_NAME
 
 typedef enum {
     // dump a crash
@@ -41,36 +35,43 @@
     DEBUGGER_ACTION_DUMP_BACKTRACE,
 } debugger_action_t;
 
-typedef struct {
-    debugger_action_t action;
+// Make sure that all values have a fixed size so that this structure
+// is the same for 32 bit and 64 bit processes.
+// NOTE: Any changes to this structure must also be reflected in
+//       bionic/linker/debugger.cpp.
+typedef struct __attribute__((packed)) {
+    int32_t action;
     pid_t tid;
-    uintptr_t abort_msg_address;
+    uint64_t abort_msg_address;
     int32_t original_si_code;
 } debugger_msg_t;
 
-#if defined(__LP64__)
-// For a 64 bit process to contact the 32 bit debuggerd.
-typedef struct {
-    debugger_action_t action;
-    pid_t tid;
-    uint32_t abort_msg_address;
-    int32_t original_si_code;
-} debugger32_msg_t;
-#endif
-
 /* Dumps a process backtrace, registers, and stack to a tombstone file (requires root).
  * Stores the tombstone path in the provided buffer.
  * Returns 0 on success, -1 on error.
  */
 int dump_tombstone(pid_t tid, char* pathbuf, size_t pathlen);
 
+/* Dumps a process backtrace, registers, and stack to a tombstone file (requires root).
+ * Stores the tombstone path in the provided buffer.
+ * If reading debugger data from debuggerd ever takes longer than timeout_secs
+ * seconds, then stop and return an error.
+ * Returns 0 on success, -1 on error.
+ */
+int dump_tombstone_timeout(pid_t tid, char* pathbuf, size_t pathlen, int timeout_secs);
+
 /* Dumps a process backtrace only to the specified file (requires root).
  * Returns 0 on success, -1 on error.
  */
 int dump_backtrace_to_file(pid_t tid, int fd);
 
-#ifdef __cplusplus
-}
-#endif
+/* Dumps a process backtrace only to the specified file (requires root).
+ * If reading debugger data from debuggerd ever takes longer than timeout_secs
+ * seconds, then stop and return an error.
+ * Returns 0 on success, -1 on error.
+ */
+int dump_backtrace_to_file_timeout(pid_t tid, int fd, int timeout_secs);
+
+__END_DECLS
 
 #endif /* __CUTILS_DEBUGGER_H */
diff --git a/include/cutils/properties.h b/include/cutils/properties.h
index 798db8b..24aa224 100644
--- a/include/cutils/properties.h
+++ b/include/cutils/properties.h
@@ -126,22 +126,6 @@
 
 #endif
 
-#ifdef HAVE_SYSTEM_PROPERTY_SERVER
-/*
- * We have an external property server instead of built-in libc support.
- * Used by the simulator.
- */
-#define SYSTEM_PROPERTY_PIPE_NAME       "/tmp/android-sysprop"
-
-enum {
-    kSystemPropertyUnknown = 0,
-    kSystemPropertyGet,
-    kSystemPropertySet,
-    kSystemPropertyList
-};
-#endif /*HAVE_SYSTEM_PROPERTY_SERVER*/
-
-
 #ifdef __cplusplus
 }
 #endif
diff --git a/include/cutils/sockets.h b/include/cutils/sockets.h
index daf43ec..c47588c 100644
--- a/include/cutils/sockets.h
+++ b/include/cutils/sockets.h
@@ -25,7 +25,7 @@
 #ifdef HAVE_WINSOCK
 #include <winsock2.h>
 typedef int  socklen_t;
-#elif HAVE_SYS_SOCKET_H
+#else
 #include <sys/socket.h>
 #endif
 
diff --git a/include/cutils/uevent.h b/include/cutils/uevent.h
index 4cca7e5..da1c2aa 100644
--- a/include/cutils/uevent.h
+++ b/include/cutils/uevent.h
@@ -27,6 +27,7 @@
 int uevent_open_socket(int buf_sz, bool passcred);
 ssize_t uevent_kernel_multicast_recv(int socket, void *buffer, size_t length);
 ssize_t uevent_kernel_multicast_uid_recv(int socket, void *buffer, size_t length, uid_t *uid);
+ssize_t uevent_kernel_recv(int socket, void *buffer, size_t length, bool require_group, uid_t *uid);
 
 #ifdef __cplusplus
 }
diff --git a/include/log/log_read.h b/include/log/log_read.h
index 946711a..1b70aff 100644
--- a/include/log/log_read.h
+++ b/include/log/log_read.h
@@ -100,6 +100,12 @@
         log_time local(*this);
         return local -= T;
     }
+    log_time operator+= (const timespec &T);
+    log_time operator+ (const timespec &T) const
+    {
+        log_time local(*this);
+        return local += T;
+    }
 
     // log_time
     bool operator== (const log_time &T) const
@@ -134,6 +140,12 @@
         log_time local(*this);
         return local -= T;
     }
+    log_time operator+= (const log_time &T);
+    log_time operator+ (const log_time &T) const
+    {
+        log_time local(*this);
+        return local += T;
+    }
 
     uint64_t nsec() const
     {
diff --git a/include/sysutils/NetlinkEvent.h b/include/sysutils/NetlinkEvent.h
index c345cdb..4fa49c5 100644
--- a/include/sysutils/NetlinkEvent.h
+++ b/include/sysutils/NetlinkEvent.h
@@ -57,6 +57,7 @@
     bool parseIfInfoMessage(const struct nlmsghdr *nh);
     bool parseIfAddrMessage(const struct nlmsghdr *nh);
     bool parseUlogPacketMessage(const struct nlmsghdr *nh);
+    bool parseNfPacketMessage(struct nlmsghdr *nh);
     bool parseRtMessage(const struct nlmsghdr *nh);
     bool parseNdUserOptMessage(const struct nlmsghdr *nh);
 };
diff --git a/include/sysutils/NetlinkListener.h b/include/sysutils/NetlinkListener.h
index 6e52c3b..82465d6 100644
--- a/include/sysutils/NetlinkListener.h
+++ b/include/sysutils/NetlinkListener.h
@@ -27,6 +27,7 @@
 public:
     static const int NETLINK_FORMAT_ASCII = 0;
     static const int NETLINK_FORMAT_BINARY = 1;
+    static const int NETLINK_FORMAT_BINARY_UNICAST = 2;
 
 #if 1
     /* temporary version until we can get Motorola to update their
diff --git a/include/utils/Condition.h b/include/utils/Condition.h
index 1c99d1a..db9be59 100644
--- a/include/utils/Condition.h
+++ b/include/utils/Condition.h
@@ -113,15 +113,15 @@
     return -pthread_cond_timedwait_relative_np(&mCond, &mutex.mMutex, &ts);
 #else // HAVE_PTHREAD_COND_TIMEDWAIT_RELATIVE
     struct timespec ts;
-#if defined(HAVE_POSIX_CLOCKS)
+#if defined(__linux__)
     clock_gettime(CLOCK_REALTIME, &ts);
-#else // HAVE_POSIX_CLOCKS
+#else // __APPLE__
     // we don't support the clocks here.
     struct timeval t;
     gettimeofday(&t, NULL);
     ts.tv_sec = t.tv_sec;
     ts.tv_nsec= t.tv_usec*1000;
-#endif // HAVE_POSIX_CLOCKS
+#endif
     ts.tv_sec += reltime/1000000000;
     ts.tv_nsec+= reltime%1000000000;
     if (ts.tv_nsec >= 1000000000) {
diff --git a/include/utils/Mutex.h b/include/utils/Mutex.h
index dd201c8..a3b594d 100644
--- a/include/utils/Mutex.h
+++ b/include/utils/Mutex.h
@@ -26,6 +26,7 @@
 #endif
 
 #include <utils/Errors.h>
+#include <utils/Timers.h>
 
 // ---------------------------------------------------------------------------
 namespace android {
@@ -45,7 +46,7 @@
         PRIVATE = 0,
         SHARED = 1
     };
-    
+
                 Mutex();
                 Mutex(const char* name);
                 Mutex(int type, const char* name = NULL);
@@ -58,6 +59,16 @@
     // lock if possible; returns 0 on success, error otherwise
     status_t    tryLock();
 
+#if HAVE_ANDROID_OS
+    // lock the mutex, but don't wait longer than timeoutMilliseconds.
+    // Returns 0 on success, TIMED_OUT for failure due to timeout expiration.
+    //
+    // OSX doesn't have pthread_mutex_timedlock() or equivalent. To keep
+    // capabilities consistent across host OSes, this method is only available
+    // when building Android binaries.
+    status_t    timedLock(nsecs_t timeoutMilliseconds);
+#endif
+
     // Manages the mutex automatically. It'll be locked when Autolock is
     // constructed and released when Autolock goes out of scope.
     class Autolock {
@@ -71,11 +82,11 @@
 
 private:
     friend class Condition;
-    
+
     // A mutex cannot be copied
                 Mutex(const Mutex&);
     Mutex&      operator = (const Mutex&);
-    
+
 #if defined(HAVE_PTHREADS)
     pthread_mutex_t mMutex;
 #else
@@ -117,6 +128,15 @@
 inline status_t Mutex::tryLock() {
     return -pthread_mutex_trylock(&mMutex);
 }
+#if HAVE_ANDROID_OS
+inline status_t Mutex::timedLock(nsecs_t timeoutNs) {
+    const struct timespec ts = {
+        /* .tv_sec = */ static_cast<time_t>(timeoutNs / 1000000000),
+        /* .tv_nsec = */ static_cast<long>(timeoutNs % 1000000000),
+    };
+    return -pthread_mutex_timedlock(&mMutex, &ts);
+}
+#endif
 
 #endif // HAVE_PTHREADS
 
@@ -127,7 +147,7 @@
  * When the function returns, it will go out of scope, and release the
  * mutex.
  */
- 
+
 typedef Mutex::Autolock AutoMutex;
 
 // ---------------------------------------------------------------------------
diff --git a/include/utils/Singleton.h b/include/utils/Singleton.h
index c60680e..ffc03cb 100644
--- a/include/utils/Singleton.h
+++ b/include/utils/Singleton.h
@@ -65,9 +65,10 @@
  */
 
 #define ANDROID_SINGLETON_STATIC_INSTANCE(TYPE)                 \
-    template<> Mutex Singleton< TYPE >::sLock(Mutex::PRIVATE);  \
-    template<> TYPE* Singleton< TYPE >::sInstance(0);           \
-    template class Singleton< TYPE >;
+    template<> ::android::Mutex  \
+        (::android::Singleton< TYPE >::sLock)(::android::Mutex::PRIVATE);  \
+    template<> TYPE* ::android::Singleton< TYPE >::sInstance(0);  \
+    template class ::android::Singleton< TYPE >;
 
 
 // ---------------------------------------------------------------------------
diff --git a/include/utils/Unicode.h b/include/utils/Unicode.h
index aaf951b..b76a5e2 100644
--- a/include/utils/Unicode.h
+++ b/include/utils/Unicode.h
@@ -22,12 +22,6 @@
 
 extern "C" {
 
-// Definitions exist in C++11
-#if defined __cplusplus && __cplusplus < 201103L
-typedef unsigned int   char32_t;
-typedef unsigned short char16_t;
-#endif
-
 // Standard string functions on char16_t strings.
 int strcmp16(const char16_t *, const char16_t *);
 int strncmp16(const char16_t *s1, const char16_t *s2, size_t n);
diff --git a/init/init.c b/init/init.c
index 2b82937..7ddab80 100644
--- a/init/init.c
+++ b/init/init.c
@@ -858,26 +858,6 @@
 }
 #endif
 
-static const struct selinux_opt seopts_prop[] = {
-        { SELABEL_OPT_PATH, "/property_contexts" },
-        { SELABEL_OPT_PATH, "/data/security/current/property_contexts" },
-        { 0, NULL }
-};
-
-struct selabel_handle* selinux_android_prop_context_handle(void)
-{
-    int policy_index = selinux_android_use_data_policy() ? 1 : 0;
-    struct selabel_handle* sehandle = selabel_open(SELABEL_CTX_ANDROID_PROP,
-                                                   &seopts_prop[policy_index], 1);
-    if (!sehandle) {
-        ERROR("SELinux:  Could not load property_contexts:  %s\n",
-              strerror(errno));
-        return NULL;
-    }
-    INFO("SELinux: Loaded property contexts from %s\n", seopts_prop[policy_index].value);
-    return sehandle;
-}
-
 void selinux_init_all_handles(void)
 {
     sehandle = selinux_android_file_context_handle();
diff --git a/init/property_service.c b/init/property_service.c
index 1f98e13..55e37b9 100644
--- a/init/property_service.c
+++ b/init/property_service.c
@@ -534,6 +534,7 @@
     load_properties_from_file(PROP_PATH_SYSTEM_BUILD, NULL);
     load_properties_from_file(PROP_PATH_SYSTEM_DEFAULT, NULL);
     load_properties_from_file(PROP_PATH_VENDOR_BUILD, NULL);
+    load_properties_from_file(PROP_PATH_BOOTIMAGE_BUILD, NULL);
     load_properties_from_file(PROP_PATH_FACTORY, "ro.*");
 
     load_override_properties();
diff --git a/libbacktrace/Android.mk b/libbacktrace/Android.mk
index f2f71f9..ca1e4bf 100755
--- a/libbacktrace/Android.mk
+++ b/libbacktrace/Android.mk
@@ -51,9 +51,6 @@
 	UnwindMap.cpp \
 	UnwindPtrace.cpp \
 
-libbacktrace_c_includes := \
-	external/libunwind/include \
-
 libbacktrace_shared_libraries := \
 	libunwind \
 	libunwind-ptrace \
diff --git a/libcutils/Android.mk b/libcutils/Android.mk
index 7202704..2c5e351 100644
--- a/libcutils/Android.mk
+++ b/libcutils/Android.mk
@@ -21,7 +21,6 @@
 	atomic.c.arm \
 	native_handle.c \
 	config_utils.c \
-	cpu_info.c \
 	load_file.c \
 	open_memstream.c \
 	strdup16to8.c \
diff --git a/libcutils/android_reboot.c b/libcutils/android_reboot.c
index 5d98295..aa86206 100644
--- a/libcutils/android_reboot.c
+++ b/libcutils/android_reboot.c
@@ -20,6 +20,7 @@
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
+#include <mntent.h>
 #include <stdio.h>
 #include <string.h>
 
@@ -33,37 +34,21 @@
  */
 static int remount_ro_done(void)
 {
-    FILE *f;
-    char mount_dev[256];
-    char mount_dir[256];
-    char mount_type[256];
-    char mount_opts[256];
-    int mount_freq;
-    int mount_passno;
-    int match;
+    FILE* fp;
+    struct mntent* mentry;
     int found_rw_fs = 0;
 
-    f = fopen("/proc/mounts", "r");
-    if (! f) {
-        /* If we can't read /proc/mounts, just give up */
+    if ((fp = setmntent("/proc/mounts", "r")) == NULL) {
+        /* If we can't read /proc/mounts, just give up. */
         return 1;
     }
-
-    do {
-        match = fscanf(f, "%255s %255s %255s %255s %d %d\n",
-                       mount_dev, mount_dir, mount_type,
-                       mount_opts, &mount_freq, &mount_passno);
-        mount_dev[255] = 0;
-        mount_dir[255] = 0;
-        mount_type[255] = 0;
-        mount_opts[255] = 0;
-        if ((match == 6) && !strncmp(mount_dev, "/dev/block", 10) && strstr(mount_opts, "rw,")) {
+    while ((mentry = getmntent(fp)) != NULL) {
+        if (!strncmp(mentry->mnt_fsname, "/dev/block", 10) && strstr(mentry->mnt_opts, "rw,")) {
             found_rw_fs = 1;
             break;
         }
-    } while (match != EOF);
-
-    fclose(f);
+    }
+    endmntent(fp);
 
     return !found_rw_fs;
 }
diff --git a/libcutils/cpu_info.c b/libcutils/cpu_info.c
deleted file mode 100644
index 21fa1dc..0000000
--- a/libcutils/cpu_info.c
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
-** Copyright 2007, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License"); 
-** you may not use this file except in compliance with the License. 
-** You may obtain a copy of the License at 
-**
-**     http://www.apache.org/licenses/LICENSE-2.0 
-**
-** Unless required by applicable law or agreed to in writing, software 
-** distributed under the License is distributed on an "AS IS" BASIS, 
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
-** See the License for the specific language governing permissions and 
-** limitations under the License.
-*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <cutils/cpu_info.h>
-
-// we cache the serial number here.
-// this is also used as a fgets() line buffer when we are reading /proc/cpuinfo
-static char serial_number[100] = { 0 };
-
-extern const char* get_cpu_serial_number(void)
-{
-    if (serial_number[0] == 0)
-    {
-        FILE* file;
-        char* chp, *end;
-        char* whitespace;
-        
-        // read serial number from /proc/cpuinfo
-        file = fopen("proc/cpuinfo", "r");
-        if (! file)
-            return NULL;
-        
-        while ((chp = fgets(serial_number, sizeof(serial_number), file)) != NULL)
-        {
-            // look for something like "Serial          : 999206122a03591c"
-
-            if (strncmp(chp, "Serial", 6) != 0)
-                continue;
-            
-            chp = strchr(chp, ':');
-            if (!chp)
-                continue;
-                
-             // skip colon and whitespace
-            while ( *(++chp) == ' ') {}
-            
-            // truncate trailing whitespace
-            end = chp;
-            while (*end && *end != ' ' && *end != '\t' && *end != '\n' && *end != '\r')
-                ++end;
-            *end = 0; 
-            
-            whitespace = strchr(chp, ' ');
-            if (whitespace)
-                *whitespace = 0;
-            whitespace = strchr(chp, '\t');
-            if (whitespace)
-                *whitespace = 0;
-            whitespace = strchr(chp, '\r');
-            if (whitespace)
-                *whitespace = 0;
-            whitespace = strchr(chp, '\n');
-            if (whitespace)
-                *whitespace = 0;
-
-            // shift serial number to beginning of the buffer
-            memmove(serial_number, chp, strlen(chp) + 1);
-            break;
-        }
-        
-        fclose(file);
-    }
-
-    return (serial_number[0] ? serial_number : NULL);
-}
diff --git a/libcutils/debugger.c b/libcutils/debugger.c
index 4035ee1..2cd8ec3 100644
--- a/libcutils/debugger.c
+++ b/libcutils/debugger.c
@@ -19,37 +19,15 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
 #include <unistd.h>
 
 #include <cutils/debugger.h>
 #include <cutils/sockets.h>
 
-#if defined(__LP64__)
-#include <elf.h>
-
-static bool is32bit(pid_t tid) {
-  char* exeline;
-  if (asprintf(&exeline, "/proc/%d/exe", tid) == -1) {
-    return false;
-  }
-  int fd = open(exeline, O_RDONLY | O_CLOEXEC);
-  free(exeline);
-  if (fd == -1) {
-    return false;
-  }
-
-  char ehdr[EI_NIDENT];
-  ssize_t bytes = read(fd, &ehdr, sizeof(ehdr));
-  close(fd);
-  if (bytes != (ssize_t) sizeof(ehdr) || memcmp(ELFMAG, ehdr, SELFMAG) != 0) {
-    return false;
-  }
-  if (ehdr[EI_CLASS] == ELFCLASS32) {
-    return true;
-  }
-  return false;
-}
-#endif
+#define LOG_TAG "DEBUG"
+#include <log/log.h>
 
 static int send_request(int sock_fd, void* msg_ptr, size_t msg_len) {
   int result = 0;
@@ -64,41 +42,33 @@
   return result;
 }
 
-static int make_dump_request(debugger_action_t action, pid_t tid) {
+static int make_dump_request(debugger_action_t action, pid_t tid, int timeout_secs) {
   const char* socket_name;
   debugger_msg_t msg;
-  size_t msg_len;
-  void* msg_ptr;
+  memset(&msg, 0, sizeof(msg));
+  msg.tid = tid;
+  msg.action = action;
 
-#if defined(__LP64__)
-  debugger32_msg_t msg32;
-  if (is32bit(tid)) {
-    msg_len = sizeof(debugger32_msg_t);
-    memset(&msg32, 0, msg_len);
-    msg32.tid = tid;
-    msg32.action = action;
-    msg_ptr = &msg32;
-
-    socket_name = DEBUGGER32_SOCKET_NAME;
-  } else
-#endif
-  {
-    msg_len = sizeof(debugger_msg_t);
-    memset(&msg, 0, msg_len);
-    msg.tid = tid;
-    msg.action = action;
-    msg_ptr = &msg;
-
-    socket_name = DEBUGGER_SOCKET_NAME;
-  }
-
-  int sock_fd = socket_local_client(socket_name, ANDROID_SOCKET_NAMESPACE_ABSTRACT,
+  int sock_fd = socket_local_client(DEBUGGER_SOCKET_NAME, ANDROID_SOCKET_NAMESPACE_ABSTRACT,
       SOCK_STREAM | SOCK_CLOEXEC);
   if (sock_fd < 0) {
     return -1;
   }
 
-  if (send_request(sock_fd, msg_ptr, msg_len) < 0) {
+  if (timeout_secs > 0) {
+    struct timeval tm;
+    tm.tv_sec = timeout_secs;
+    tm.tv_usec = 0;
+    if (setsockopt(sock_fd, SOL_SOCKET, SO_RCVTIMEO, &tm, sizeof(tm)) == -1) {
+      ALOGE("WARNING: Cannot set receive timeout value on socket: %s", strerror(errno));
+    }
+
+    if (setsockopt(sock_fd, SOL_SOCKET, SO_SNDTIMEO, &tm, sizeof(tm)) == -1) {
+      ALOGE("WARNING: Cannot set send timeout value on socket: %s", strerror(errno));
+    }
+  }
+
+  if (send_request(sock_fd, &msg, sizeof(msg)) < 0) {
     TEMP_FAILURE_RETRY(close(sock_fd));
     return -1;
   }
@@ -107,7 +77,11 @@
 }
 
 int dump_backtrace_to_file(pid_t tid, int fd) {
-  int sock_fd = make_dump_request(DEBUGGER_ACTION_DUMP_BACKTRACE, tid);
+  return dump_backtrace_to_file_timeout(tid, fd, 0);
+}
+
+int dump_backtrace_to_file_timeout(pid_t tid, int fd, int timeout_secs) {
+  int sock_fd = make_dump_request(DEBUGGER_ACTION_DUMP_BACKTRACE, tid, timeout_secs);
   if (sock_fd < 0) {
     return -1;
   }
@@ -127,7 +101,11 @@
 }
 
 int dump_tombstone(pid_t tid, char* pathbuf, size_t pathlen) {
-  int sock_fd = make_dump_request(DEBUGGER_ACTION_DUMP_TOMBSTONE, tid);
+  return dump_tombstone_timeout(tid, pathbuf, pathlen, 0);
+}
+
+int dump_tombstone_timeout(pid_t tid, char* pathbuf, size_t pathlen, int timeout_secs) {
+  int sock_fd = make_dump_request(DEBUGGER_ACTION_DUMP_TOMBSTONE, tid, timeout_secs);
   if (sock_fd < 0) {
     return -1;
   }
diff --git a/libcutils/process_name.c b/libcutils/process_name.c
index 9c3dfb8..cc931eb 100644
--- a/libcutils/process_name.c
+++ b/libcutils/process_name.c
@@ -17,7 +17,7 @@
 #include <fcntl.h>
 #include <stdlib.h>
 #include <string.h>
-#if defined(HAVE_PRCTL)
+#if defined(__linux__)
 #include <sys/prctl.h>
 #endif
 #include <sys/stat.h>
@@ -51,7 +51,7 @@
     strcpy(copy, new_name);
     process_name = (const char*) copy;
 
-#if defined(HAVE_PRCTL)
+#if defined(__linux__)
     if (len < 16) {
         prctl(PR_SET_NAME, (unsigned long) new_name, 0, 0, 0);
     } else {
diff --git a/libcutils/properties.c b/libcutils/properties.c
index b283658..1190ab7 100644
--- a/libcutils/properties.c
+++ b/libcutils/properties.c
@@ -104,7 +104,7 @@
     return (int32_t)property_get_imax(key, INT32_MIN, INT32_MAX, default_value);
 }
 
-#ifdef HAVE_LIBC_SYSTEM_PROPERTIES
+#ifdef __BIONIC__
 
 #define _REALLY_INCLUDE_SYS__SYSTEM_PROPERTIES_H_
 #include <sys/_system_properties.h>
@@ -157,191 +157,9 @@
     return __system_property_foreach(property_list_callback, &data);
 }
 
-#elif defined(HAVE_SYSTEM_PROPERTY_SERVER)
-
-/*
- * The Linux simulator provides a "system property server" that uses IPC
- * to set/get/list properties.  The file descriptor is shared by all
- * threads in the process, so we use a mutex to ensure that requests
- * from multiple threads don't get interleaved.
- */
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <pthread.h>
-
-static pthread_once_t gInitOnce = PTHREAD_ONCE_INIT;
-static pthread_mutex_t gPropertyFdLock = PTHREAD_MUTEX_INITIALIZER;
-static int gPropFd = -1;
-
-/*
- * Connect to the properties server.
- *
- * Returns the socket descriptor on success.
- */
-static int connectToServer(const char* fileName)
-{
-    int sock = -1;
-    int cc;
-
-    struct sockaddr_un addr;
-    
-    sock = socket(AF_UNIX, SOCK_STREAM, 0);
-    if (sock < 0) {
-        ALOGW("UNIX domain socket create failed (errno=%d)\n", errno);
-        return -1;
-    }
-
-    /* connect to socket; fails if file doesn't exist */
-    strcpy(addr.sun_path, fileName);    // max 108 bytes
-    addr.sun_family = AF_UNIX;
-    cc = connect(sock, (struct sockaddr*) &addr, SUN_LEN(&addr));
-    if (cc < 0) {
-        // ENOENT means socket file doesn't exist
-        // ECONNREFUSED means socket exists but nobody is listening
-        //ALOGW("AF_UNIX connect failed for '%s': %s\n",
-        //    fileName, strerror(errno));
-        close(sock);
-        return -1;
-    }
-
-    return sock;
-}
-
-/*
- * Perform one-time initialization.
- */
-static void init(void)
-{
-    assert(gPropFd == -1);
-
-    gPropFd = connectToServer(SYSTEM_PROPERTY_PIPE_NAME);
-    if (gPropFd < 0) {
-        //ALOGW("not connected to system property server\n");
-    } else {
-        //ALOGV("Connected to system property server\n");
-    }
-}
-
-int property_get(const char *key, char *value, const char *default_value)
-{
-    char sendBuf[1+PROPERTY_KEY_MAX];
-    char recvBuf[1+PROPERTY_VALUE_MAX];
-    int len = -1;
-
-    //ALOGV("PROPERTY GET [%s]\n", key);
-
-    pthread_once(&gInitOnce, init);
-    if (gPropFd < 0) {
-        /* this mimics the behavior of the device implementation */
-        if (default_value != NULL) {
-            strcpy(value, default_value);
-            len = strlen(value);
-        }
-        return len;
-    }
-
-    if (strlen(key) >= PROPERTY_KEY_MAX) return -1;
-
-    memset(sendBuf, 0xdd, sizeof(sendBuf));    // placate valgrind
-
-    sendBuf[0] = (char) kSystemPropertyGet;
-    strcpy(sendBuf+1, key);
-
-    pthread_mutex_lock(&gPropertyFdLock);
-    if (write(gPropFd, sendBuf, sizeof(sendBuf)) != sizeof(sendBuf)) {
-        pthread_mutex_unlock(&gPropertyFdLock);
-        return -1;
-    }
-    if (read(gPropFd, recvBuf, sizeof(recvBuf)) != sizeof(recvBuf)) {
-        pthread_mutex_unlock(&gPropertyFdLock);
-        return -1;
-    }
-    pthread_mutex_unlock(&gPropertyFdLock);
-
-    /* first byte is 0 if value not defined, 1 if found */
-    if (recvBuf[0] == 0) {
-        if (default_value != NULL) {
-            strcpy(value, default_value);
-            len = strlen(value);
-        } else {
-            /*
-             * If the value isn't defined, hand back an empty string and
-             * a zero length, rather than a failure.  This seems wrong,
-             * since you can't tell the difference between "undefined" and
-             * "defined but empty", but it's what the device does.
-             */
-            value[0] = '\0';
-            len = 0;
-        }
-    } else if (recvBuf[0] == 1) {
-        strcpy(value, recvBuf+1);
-        len = strlen(value);
-    } else {
-        ALOGE("Got strange response to property_get request (%d)\n",
-            recvBuf[0]);
-        assert(0);
-        return -1;
-    }
-    //ALOGV("PROP [found=%d def='%s'] (%d) [%s]: [%s]\n",
-    //    recvBuf[0], default_value, len, key, value);
-
-    return len;
-}
-
-
-int property_set(const char *key, const char *value)
-{
-    char sendBuf[1+PROPERTY_KEY_MAX+PROPERTY_VALUE_MAX];
-    char recvBuf[1];
-    int result = -1;
-
-    //ALOGV("PROPERTY SET [%s]: [%s]\n", key, value);
-
-    pthread_once(&gInitOnce, init);
-    if (gPropFd < 0)
-        return -1;
-
-    if (strlen(key) >= PROPERTY_KEY_MAX) return -1;
-    if (strlen(value) >= PROPERTY_VALUE_MAX) return -1;
-
-    memset(sendBuf, 0xdd, sizeof(sendBuf));    // placate valgrind
-
-    sendBuf[0] = (char) kSystemPropertySet;
-    strcpy(sendBuf+1, key);
-    strcpy(sendBuf+1+PROPERTY_KEY_MAX, value);
-
-    pthread_mutex_lock(&gPropertyFdLock);
-    if (write(gPropFd, sendBuf, sizeof(sendBuf)) != sizeof(sendBuf)) {
-        pthread_mutex_unlock(&gPropertyFdLock);
-        return -1;
-    }
-    if (read(gPropFd, recvBuf, sizeof(recvBuf)) != sizeof(recvBuf)) {
-        pthread_mutex_unlock(&gPropertyFdLock);
-        return -1;
-    }
-    pthread_mutex_unlock(&gPropertyFdLock);
-
-    if (recvBuf[0] != 1)
-        return -1;
-    return 0;
-}
-
-int property_list(void (*propfn)(const char *key, const char *value, void *cookie), 
-                  void *cookie)
-{
-    //ALOGV("PROPERTY LIST\n");
-    pthread_once(&gInitOnce, init);
-    if (gPropFd < 0)
-        return -1;
-
-    return 0;
-}
-
 #else
 
-/* SUPER-cheesy place-holder implementation for Win32 */
+/* SUPER-cheesy place-holder implementation for glibc/Mac OS/Windows. */
 
 #include <cutils/threads.h>
 
diff --git a/libcutils/sched_policy.c b/libcutils/sched_policy.c
index d3cedd4..2a9d96b 100644
--- a/libcutils/sched_policy.c
+++ b/libcutils/sched_policy.c
@@ -37,7 +37,7 @@
    return p == SP_DEFAULT ? SP_SYSTEM_DEFAULT : p;
 }
 
-#if defined(HAVE_ANDROID_OS) && defined(HAVE_SCHED_H) && defined(HAVE_PTHREADS)
+#if defined(HAVE_ANDROID_OS)
 
 #include <pthread.h>
 #include <sched.h>
diff --git a/libcutils/uevent.c b/libcutils/uevent.c
index 97a81e3..827170a 100644
--- a/libcutils/uevent.c
+++ b/libcutils/uevent.c
@@ -31,12 +31,12 @@
  */
 ssize_t uevent_kernel_multicast_recv(int socket, void *buffer, size_t length)
 {
-    uid_t user = -1;
-    return uevent_kernel_multicast_uid_recv(socket, buffer, length, &user);
+    uid_t uid = -1;
+    return uevent_kernel_multicast_uid_recv(socket, buffer, length, &uid);
 }
 
 /**
- * Like the above, but passes a uid_t in by reference. In the event that this
+ * Like the above, but passes a uid_t in by pointer. In the event that this
  * fails due to a bad uid check, the uid_t will be set to the uid of the
  * socket's peer.
  *
@@ -44,8 +44,12 @@
  * returns -1, sets errno to EIO, and sets "user" to the UID associated with the
  * message. If the peer UID cannot be determined, "user" is set to -1."
  */
-ssize_t uevent_kernel_multicast_uid_recv(int socket, void *buffer,
-                                         size_t length, uid_t *user)
+ssize_t uevent_kernel_multicast_uid_recv(int socket, void *buffer, size_t length, uid_t *uid)
+{
+    return uevent_kernel_recv(socket, buffer, length, true, uid);
+}
+
+ssize_t uevent_kernel_recv(int socket, void *buffer, size_t length, bool require_group, uid_t *uid)
 {
     struct iovec iov = { buffer, length };
     struct sockaddr_nl addr;
@@ -60,7 +64,7 @@
         0,
     };
 
-    *user = -1;
+    *uid = -1;
     ssize_t n = recvmsg(socket, &hdr, 0);
     if (n <= 0) {
         return n;
@@ -73,14 +77,18 @@
     }
 
     struct ucred *cred = (struct ucred *)CMSG_DATA(cmsg);
-    *user = cred->uid;
+    *uid = cred->uid;
     if (cred->uid != 0) {
         /* ignoring netlink message from non-root user */
         goto out;
     }
 
-    if (addr.nl_groups == 0 || addr.nl_pid != 0) {
-        /* ignoring non-kernel or unicast netlink message */
+    if (addr.nl_pid != 0) {
+        /* ignore non-kernel */
+        goto out;
+    }
+    if (require_group && addr.nl_groups == 0) {
+        /* ignore unicast messages when requested */
         goto out;
     }
 
diff --git a/liblog/log_time.cpp b/liblog/log_time.cpp
index 209a9da..50742df 100644
--- a/liblog/log_time.cpp
+++ b/liblog/log_time.cpp
@@ -150,6 +150,17 @@
     return *this;
 }
 
+log_time log_time::operator+= (const timespec &T) {
+    this->tv_nsec += (unsigned long int)T.tv_nsec;
+    if (this->tv_nsec >= NS_PER_SEC) {
+        this->tv_nsec -= NS_PER_SEC;
+        ++this->tv_sec;
+    }
+    this->tv_sec += T.tv_sec;
+
+    return *this;
+}
+
 log_time log_time::operator-= (const log_time &T) {
     // No concept of negative time, clamp to EPOCH
     if (*this <= T) {
@@ -166,3 +177,14 @@
 
     return *this;
 }
+
+log_time log_time::operator+= (const log_time &T) {
+    this->tv_nsec += T.tv_nsec;
+    if (this->tv_nsec >= NS_PER_SEC) {
+        this->tv_nsec -= NS_PER_SEC;
+        ++this->tv_sec;
+    }
+    this->tv_sec += T.tv_sec;
+
+    return *this;
+}
diff --git a/liblog/logprint.c b/liblog/logprint.c
index 5987782..7ba4c8e 100644
--- a/liblog/logprint.c
+++ b/liblog/logprint.c
@@ -824,7 +824,7 @@
      * set the length at the maximum (size minus null byte)
      */
     prefixLen += MIN(len, sizeof(prefixBuf) - prefixLen);
-    suffixLen = MIN(suffixLen, sizeof(suffixLen));
+    suffixLen = MIN(suffixLen, sizeof(suffixBuf));
 
     /* the following code is tragically unreadable */
 
diff --git a/libmemtrack/memtrack.c b/libmemtrack/memtrack.c
index 9a656df..5d68083 100644
--- a/libmemtrack/memtrack.c
+++ b/libmemtrack/memtrack.c
@@ -20,6 +20,7 @@
 
 #include <log/log.h>
 
+#include <errno.h>
 #include <hardware/memtrack.h>
 
 #define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
diff --git a/libmincrypt/Android.mk b/libmincrypt/Android.mk
index 7906986..503bcb4 100644
--- a/libmincrypt/Android.mk
+++ b/libmincrypt/Android.mk
@@ -6,6 +6,8 @@
 LOCAL_MODULE := libmincrypt
 LOCAL_SRC_FILES := dsa_sig.c p256.c p256_ec.c p256_ecdsa.c rsa.c sha.c sha256.c
 LOCAL_CFLAGS := -Wall -Werror
+# Clang's slp-vectorize phase has segmentation fault when compiling p256_ec.c.
+LOCAL_CLANG_CFLAGS += -fno-slp-vectorize
 include $(BUILD_STATIC_LIBRARY)
 
 include $(CLEAR_VARS)
diff --git a/libpixelflinger/pixelflinger.cpp b/libpixelflinger/pixelflinger.cpp
index ea5bc8e..fd449b2 100644
--- a/libpixelflinger/pixelflinger.cpp
+++ b/libpixelflinger/pixelflinger.cpp
@@ -727,18 +727,10 @@
 
 int64_t ggl_system_time()
 {
-#if defined(HAVE_POSIX_CLOCKS)
     struct timespec t;
     t.tv_sec = t.tv_nsec = 0;
     clock_gettime(CLOCK_THREAD_CPUTIME_ID, &t);
     return int64_t(t.tv_sec)*1000000000LL + t.tv_nsec;
-#else
-    // we don't support the clocks here.
-    struct timeval t;
-    t.tv_sec = t.tv_usec = 0;
-    gettimeofday(&t, NULL);
-    return int64_t(t.tv_sec)*1000000000LL + int64_t(t.tv_usec)*1000LL;
-#endif
 }
 
 // ----------------------------------------------------------------------------
diff --git a/libprocessgroup/processgroup.cpp b/libprocessgroup/processgroup.cpp
index 4b09f24..a80965f 100644
--- a/libprocessgroup/processgroup.cpp
+++ b/libprocessgroup/processgroup.cpp
@@ -19,6 +19,7 @@
 
 #include <assert.h>
 #include <dirent.h>
+#include <errno.h>
 #include <fcntl.h>
 #include <inttypes.h>
 #include <stdbool.h>
diff --git a/libsparse/Android.mk b/libsparse/Android.mk
index 0abe33d..925b98b 100644
--- a/libsparse/Android.mk
+++ b/libsparse/Android.mk
@@ -16,7 +16,7 @@
 LOCAL_SRC_FILES := $(libsparse_src_files)
 LOCAL_MODULE := libsparse_host
 LOCAL_STATIC_LIBRARIES := libz
-LOCAL_C_INCLUDES += $(LOCAL_PATH)/include external/zlib
+LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
 LOCAL_CFLAGS := -Werror
 include $(BUILD_HOST_STATIC_LIBRARY)
 
@@ -25,7 +25,7 @@
 LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
 LOCAL_SRC_FILES := $(libsparse_src_files)
 LOCAL_MODULE := libsparse
-LOCAL_C_INCLUDES += $(LOCAL_PATH)/include external/zlib
+LOCAL_C_INCLUDES += $(LOCAL_PATH)/include
 LOCAL_SHARED_LIBRARIES := \
     libz
 LOCAL_CFLAGS := -Werror
@@ -36,7 +36,7 @@
 LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
 LOCAL_SRC_FILES := $(libsparse_src_files)
 LOCAL_MODULE := libsparse_static
-LOCAL_C_INCLUDES += $(LOCAL_PATH)/include external/zlib
+LOCAL_C_INCLUDES += $(LOCAL_PATH)/include
 LOCAL_STATIC_LIBRARIES := libz
 LOCAL_CFLAGS := -Werror
 include $(BUILD_STATIC_LIBRARY)
diff --git a/libsysutils/Android.mk b/libsysutils/Android.mk
index 246f954..b902a81 100644
--- a/libsysutils/Android.mk
+++ b/libsysutils/Android.mk
@@ -16,11 +16,12 @@
 
 LOCAL_MODULE:= libsysutils
 
-LOCAL_C_INCLUDES :=
-
 LOCAL_CFLAGS := -Werror
 
-LOCAL_SHARED_LIBRARIES := libcutils liblog
+LOCAL_SHARED_LIBRARIES := \
+        libcutils \
+        liblog \
+        libnl
 
 include $(BUILD_SHARED_LIBRARY)
 
diff --git a/libsysutils/src/NetlinkEvent.cpp b/libsysutils/src/NetlinkEvent.cpp
index 9d596ef..909df86 100644
--- a/libsysutils/src/NetlinkEvent.cpp
+++ b/libsysutils/src/NetlinkEvent.cpp
@@ -32,13 +32,21 @@
 #include <linux/if_addr.h>
 #include <linux/if_link.h>
 #include <linux/netfilter/nfnetlink.h>
+#include <linux/netfilter/nfnetlink_log.h>
 #include <linux/netfilter_ipv4/ipt_ULOG.h>
+
 /* From kernel's net/netfilter/xt_quota2.c */
-const int QLOG_NL_EVENT  = 112;
+const int LOCAL_QLOG_NL_EVENT = 112;
+const int LOCAL_NFLOG_PACKET = NFNL_SUBSYS_ULOG << 8 | NFULNL_MSG_PACKET;
 
 #include <linux/netlink.h>
 #include <linux/rtnetlink.h>
 
+#include <netlink/attr.h>
+#include <netlink/genl/genl.h>
+#include <netlink/handlers.h>
+#include <netlink/msg.h>
+
 const int NetlinkEvent::NlActionUnknown = 0;
 const int NetlinkEvent::NlActionAdd = 1;
 const int NetlinkEvent::NlActionRemove = 2;
@@ -95,7 +103,8 @@
         NL_EVENT_RTM_NAME(RTM_NEWROUTE);
         NL_EVENT_RTM_NAME(RTM_DELROUTE);
         NL_EVENT_RTM_NAME(RTM_NEWNDUSEROPT);
-        NL_EVENT_RTM_NAME(QLOG_NL_EVENT);
+        NL_EVENT_RTM_NAME(LOCAL_QLOG_NL_EVENT);
+        NL_EVENT_RTM_NAME(LOCAL_NFLOG_PACKET);
         default:
             return NULL;
     }
@@ -272,6 +281,41 @@
 }
 
 /*
+ * Parse a LOCAL_NFLOG_PACKET message.
+ */
+bool NetlinkEvent::parseNfPacketMessage(struct nlmsghdr *nh) {
+    int uid = -1;
+    int len = 0;
+    char* raw = NULL;
+
+    struct nlattr *uid_attr = nlmsg_find_attr(nh, sizeof(struct genlmsghdr), NFULA_UID);
+    if (uid_attr) {
+        uid = ntohl(nla_get_u32(uid_attr));
+    }
+
+    struct nlattr *payload = nlmsg_find_attr(nh, sizeof(struct genlmsghdr), NFULA_PAYLOAD);
+    if (payload) {
+        /* First 256 bytes is plenty */
+        len = nla_len(payload);
+        if (len > 256) len = 256;
+        raw = (char*) nla_data(payload);
+    }
+
+    char* hex = (char*) calloc(1, 5 + (len * 2));
+    strcpy(hex, "HEX=");
+    for (int i = 0; i < len; i++) {
+        hex[4 + (i * 2)] = "0123456789abcdef"[(raw[i] >> 4) & 0xf];
+        hex[5 + (i * 2)] = "0123456789abcdef"[raw[i] & 0xf];
+    }
+
+    asprintf(&mParams[0], "UID=%d", uid);
+    mParams[1] = hex;
+    mSubsystem = strdup("strict");
+    mAction = NlActionChange;
+    return true;
+}
+
+/*
  * Parse a RTM_NEWROUTE or RTM_DELROUTE message.
  */
 bool NetlinkEvent::parseRtMessage(const struct nlmsghdr *nh) {
@@ -478,7 +522,7 @@
  * TODO: consider only ever looking at the first message.
  */
 bool NetlinkEvent::parseBinaryNetlinkMessage(char *buffer, int size) {
-    const struct nlmsghdr *nh;
+    struct nlmsghdr *nh;
 
     for (nh = (struct nlmsghdr *) buffer;
          NLMSG_OK(nh, (unsigned) size) && (nh->nlmsg_type != NLMSG_DONE);
@@ -493,7 +537,7 @@
             if (parseIfInfoMessage(nh))
                 return true;
 
-        } else if (nh->nlmsg_type == QLOG_NL_EVENT) {
+        } else if (nh->nlmsg_type == LOCAL_QLOG_NL_EVENT) {
             if (parseUlogPacketMessage(nh))
                 return true;
 
@@ -511,6 +555,10 @@
             if (parseNdUserOptMessage(nh))
                 return true;
 
+        } else if (nh->nlmsg_type == LOCAL_NFLOG_PACKET) {
+            if (parseNfPacketMessage(nh))
+                return true;
+
         }
     }
 
@@ -588,7 +636,8 @@
 }
 
 bool NetlinkEvent::decode(char *buffer, int size, int format) {
-    if (format == NetlinkListener::NETLINK_FORMAT_BINARY) {
+    if (format == NetlinkListener::NETLINK_FORMAT_BINARY
+            || format == NetlinkListener::NETLINK_FORMAT_BINARY_UNICAST) {
         return parseBinaryNetlinkMessage(buffer, size);
     } else {
         return parseAsciiNetlinkMessage(buffer, size);
diff --git a/libsysutils/src/NetlinkListener.cpp b/libsysutils/src/NetlinkListener.cpp
index 81c5cc2..637aa1e 100644
--- a/libsysutils/src/NetlinkListener.cpp
+++ b/libsysutils/src/NetlinkListener.cpp
@@ -47,8 +47,13 @@
     ssize_t count;
     uid_t uid = -1;
 
-    count = TEMP_FAILURE_RETRY(uevent_kernel_multicast_uid_recv(
-                                       socket, mBuffer, sizeof(mBuffer), &uid));
+    bool require_group = true;
+    if (mFormat == NETLINK_FORMAT_BINARY_UNICAST) {
+        require_group = false;
+    }
+
+    count = TEMP_FAILURE_RETRY(uevent_kernel_recv(socket,
+            mBuffer, sizeof(mBuffer), require_group, &uid));
     if (count < 0) {
         if (uid > 0)
             LOG_EVENT_INT(65537, uid);
diff --git a/libutils/Threads.cpp b/libutils/Threads.cpp
index 9bcd063..b2c6903 100644
--- a/libutils/Threads.cpp
+++ b/libutils/Threads.cpp
@@ -35,7 +35,7 @@
 # define HAVE_CREATETHREAD  // Cygwin, vs. HAVE__BEGINTHREADEX for MinGW
 #endif
 
-#if defined(HAVE_PRCTL)
+#if defined(__linux__)
 #include <sys/prctl.h>
 #endif
 
@@ -100,7 +100,7 @@
 };
 
 void androidSetThreadName(const char* name) {
-#if defined(HAVE_PRCTL)
+#if defined(__linux__)
     // Mac OS doesn't have this, and we build libutil for the host too
     int hasAt = 0;
     int hasDot = 0;
diff --git a/logd/LogBuffer.cpp b/logd/LogBuffer.cpp
index 1c74ba5..6307bed 100644
--- a/logd/LogBuffer.cpp
+++ b/logd/LogBuffer.cpp
@@ -242,7 +242,7 @@
     LastLogTimes::iterator t = mTimes.begin();
     while(t != mTimes.end()) {
         LogTimeEntry *entry = (*t);
-        if (entry->owned_Locked()
+        if (entry->owned_Locked() && entry->isWatching(id)
                 && (!oldest || (oldest->mStart > entry->mStart))) {
             oldest = entry;
         }
@@ -354,7 +354,7 @@
                         // kick a misbehaving log reader client off the island
                         oldest->release_Locked();
                     } else {
-                        oldest->triggerSkip_Locked(pruneRows);
+                        oldest->triggerSkip_Locked(id, pruneRows);
                     }
                 }
                 break;
@@ -385,7 +385,7 @@
                         // kick a misbehaving log reader client off the island
                         oldest->release_Locked();
                     } else {
-                        oldest->triggerSkip_Locked(pruneRows);
+                        oldest->triggerSkip_Locked(id, pruneRows);
                     }
                     break;
                 }
diff --git a/logd/LogTimes.cpp b/logd/LogTimes.cpp
index ea4e8c8..5f9db8d 100644
--- a/logd/LogTimes.cpp
+++ b/logd/LogTimes.cpp
@@ -36,7 +36,6 @@
         , mReader(reader)
         , mLogMask(logMask)
         , mPid(pid)
-        , skipAhead(0)
         , mCount(0)
         , mTail(tail)
         , mIndex(0)
@@ -46,6 +45,7 @@
         , mEnd(CLOCK_MONOTONIC)
 {
         pthread_cond_init(&threadTriggeredCondition, NULL);
+        cleanSkip_Locked();
 }
 
 void LogTimeEntry::startReader_Locked(void) {
@@ -148,6 +148,8 @@
             break;
         }
 
+        me->cleanSkip_Locked();
+
         pthread_cond_wait(&me->threadTriggeredCondition, &timesLock);
     }
 
@@ -169,7 +171,7 @@
     }
 
     if ((!me->mPid || (me->mPid == element->getPid()))
-            && (me->mLogMask & (1 << element->getLogId()))) {
+            && (me->isWatching(element->getLogId()))) {
         ++me->mCount;
     }
 
@@ -184,19 +186,19 @@
 
     LogTimeEntry::lock();
 
-    if (me->skipAhead) {
-        me->skipAhead--;
+    me->mStart = element->getMonotonicTime();
+
+    if (me->skipAhead[element->getLogId()]) {
+        me->skipAhead[element->getLogId()]--;
         goto skip;
     }
 
-    me->mStart = element->getMonotonicTime();
-
     // Truncate to close race between first and second pass
     if (me->mNonBlock && me->mTail && (me->mIndex >= me->mCount)) {
         goto skip;
     }
 
-    if ((me->mLogMask & (1 << element->getLogId())) == 0) {
+    if (!me->isWatching(element->getLogId())) {
         goto skip;
     }
 
@@ -223,7 +225,7 @@
     }
 
 ok:
-    if (!me->skipAhead) {
+    if (!me->skipAhead[element->getLogId()]) {
         LogTimeEntry::unlock();
         return true;
     }
@@ -233,3 +235,9 @@
     LogTimeEntry::unlock();
     return false;
 }
+
+void LogTimeEntry::cleanSkip_Locked(void) {
+    for (log_id_t i = LOG_ID_MIN; i < LOG_ID_MAX; i = (log_id_t) (i + 1)) {
+        skipAhead[i] = 0;
+    }
+}
diff --git a/logd/LogTimes.h b/logd/LogTimes.h
index 0bfa7a2..81aedfb 100644
--- a/logd/LogTimes.h
+++ b/logd/LogTimes.h
@@ -22,6 +22,7 @@
 #include <sys/types.h>
 #include <sysutils/SocketClient.h>
 #include <utils/List.h>
+#include <log/log.h>
 
 class LogReader;
 
@@ -38,7 +39,7 @@
     static void threadStop(void *me);
     const unsigned int mLogMask;
     const pid_t mPid;
-    unsigned int skipAhead;
+    unsigned int skipAhead[LOG_ID_MAX];
     unsigned long mCount;
     unsigned long mTail;
     unsigned long mIndex;
@@ -67,7 +68,8 @@
         pthread_cond_signal(&threadTriggeredCondition);
     }
 
-    void triggerSkip_Locked(unsigned int skip) { skipAhead = skip; }
+    void triggerSkip_Locked(log_id_t id, unsigned int skip) { skipAhead[id] = skip; }
+    void cleanSkip_Locked(void);
 
     // Called after LogTimeEntry removed from list, lock implicitly held
     void release_Locked(void) {
@@ -99,7 +101,7 @@
         // No one else is holding a reference to this
         delete this;
     }
-
+    bool isWatching(log_id_t id) { return (mLogMask & (1<<id)) != 0; }
     // flushTo filter callbacks
     static bool FilterFirstPass(const LogBufferElement *element, void *me);
     static bool FilterSecondPass(const LogBufferElement *element, void *me);
diff --git a/rootdir/etc/hosts b/rootdir/etc/hosts
index 99848f6..649151c 100644
--- a/rootdir/etc/hosts
+++ b/rootdir/etc/hosts
@@ -1 +1,2 @@
-127.0.0.1		    localhost
+127.0.0.1       localhost
+::1             ip6-localhost
diff --git a/rootdir/init.rc b/rootdir/init.rc
index 9093b54..642af09 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -157,6 +157,8 @@
     mount pstore pstore /sys/fs/pstore
     chown system log /sys/fs/pstore/console-ramoops
     chmod 0440 /sys/fs/pstore/console-ramoops
+    chown system log /sys/fs/pstore/pmsg-ramoops-0
+    chmod 0440 /sys/fs/pstore/pmsg-ramoops-0
 
 # Healthd can trigger a full boot from charger mode by signaling this
 # property when the power button is held.
diff --git a/rootdir/ueventd.rc b/rootdir/ueventd.rc
index eff24c3..43d7bc9 100644
--- a/rootdir/ueventd.rc
+++ b/rootdir/ueventd.rc
@@ -16,6 +16,7 @@
 # Anyone can read the logs, but if they're not in the "logs"
 # group, then they'll only see log entries for their UID.
 /dev/log/*                0666   root       log
+/dev/pmsg0                0222   root       log
 
 # the msm hw3d client device node is world writable/readable.
 /dev/msm_hw3dc            0666   root       root
diff --git a/sdcard/sdcard.c b/sdcard/sdcard.c
index 2318978..4d50bf0 100644
--- a/sdcard/sdcard.c
+++ b/sdcard/sdcard.c
@@ -169,6 +169,11 @@
     __u32 refcount;
     __u64 nid;
     __u64 gen;
+    /*
+     * The inode number for this FUSE node. Note that this isn't stable across
+     * multiple invocations of the FUSE daemon.
+     */
+    __u32 ino;
 
     /* State derived based on current position in hierarchy. */
     perm_t perm;
@@ -225,6 +230,25 @@
     struct node root;
     char obbpath[PATH_MAX];
 
+    /* Used to allocate unique inode numbers for fuse nodes. We use
+     * a simple counter based scheme where inode numbers from deleted
+     * nodes aren't reused. Note that inode allocations are not stable
+     * across multiple invocation of the sdcard daemon, but that shouldn't
+     * be a huge problem in practice.
+     *
+     * Note that we restrict inodes to 32 bit unsigned integers to prevent
+     * truncation on 32 bit processes when unsigned long long stat.st_ino is
+     * assigned to an unsigned long ino_t type in an LP32 process.
+     *
+     * Also note that fuse_attr and fuse_dirent inode values are 64 bits wide
+     * on both LP32 and LP64, but the fuse kernel code doesn't squash 64 bit
+     * inode numbers into 32 bit values on 64 bit kernels (see fuse_squash_ino
+     * in fs/fuse/inode.c).
+     *
+     * Accesses must be guarded by |lock|.
+     */
+    __u32 inode_ctr;
+
     Hashmap* package_to_appid;
     Hashmap* appid_with_rw;
 };
@@ -388,7 +412,7 @@
 
 static void attr_from_stat(struct fuse_attr *attr, const struct stat *s, const struct node* node)
 {
-    attr->ino = node->nid;
+    attr->ino = node->ino;
     attr->size = s->st_size;
     attr->blocks = s->st_blocks;
     attr->atime = s->st_atim.tv_sec;
@@ -576,6 +600,13 @@
     struct node *node;
     size_t namelen = strlen(name);
 
+    // Detect overflows in the inode counter. "4 billion nodes should be enough
+    // for everybody".
+    if (fuse->inode_ctr == 0) {
+        ERROR("No more inode numbers available");
+        return NULL;
+    }
+
     node = calloc(1, sizeof(struct node));
     if (!node) {
         return NULL;
@@ -597,6 +628,7 @@
     }
     node->namelen = namelen;
     node->nid = ptr_to_id(node);
+    node->ino = fuse->inode_ctr++;
     node->gen = fuse->next_generation++;
 
     derive_permissions_locked(fuse, parent, node);
@@ -701,6 +733,7 @@
     fuse->derive = derive;
     fuse->split_perms = split_perms;
     fuse->write_gid = write_gid;
+    fuse->inode_ctr = 1;
 
     memset(&fuse->root, 0, sizeof(fuse->root));
     fuse->root.nid = FUSE_ROOT_ID; /* 1 */
@@ -904,7 +937,9 @@
     if (!node) {
         return -ENOENT;
     }
-    if (!check_caller_access_to_node(fuse, hdr, node, W_OK, has_rw)) {
+
+    if (!(req->valid & FATTR_FH) &&
+            !check_caller_access_to_node(fuse, hdr, node, W_OK, has_rw)) {
         return -EACCES;
     }
 
diff --git a/toolbox/Android.mk b/toolbox/Android.mk
index 249f91e..f0eec68 100644
--- a/toolbox/Android.mk
+++ b/toolbox/Android.mk
@@ -13,29 +13,6 @@
 
 
 include $(CLEAR_VARS)
-LOCAL_SRC_FILES := upstream-netbsd/bin/cat/cat.c
-LOCAL_CFLAGS += $(common_cflags) -Dmain=cat_main
-LOCAL_MODULE := libtoolbox_cat
-LOCAL_ADDITIONAL_DEPENDENCIES += $(LOCAL_PATH)/Android.mk
-include $(BUILD_STATIC_LIBRARY)
-
-include $(CLEAR_VARS)
-LOCAL_SRC_FILES := upstream-netbsd/sbin/chown/chown.c
-LOCAL_CFLAGS += $(common_cflags) -Dmain=chown_main
-LOCAL_MODULE := libtoolbox_chown
-LOCAL_ADDITIONAL_DEPENDENCIES += $(LOCAL_PATH)/Android.mk
-include $(BUILD_STATIC_LIBRARY)
-
-include $(CLEAR_VARS)
-LOCAL_SRC_FILES := \
-    upstream-netbsd/bin/cp/cp.c \
-    upstream-netbsd/bin/cp/utils.c
-LOCAL_CFLAGS += $(common_cflags) -Dmain=cp_main
-LOCAL_MODULE := libtoolbox_cp
-LOCAL_ADDITIONAL_DEPENDENCIES += $(LOCAL_PATH)/Android.mk
-include $(BUILD_STATIC_LIBRARY)
-
-include $(CLEAR_VARS)
 LOCAL_SRC_FILES := \
     upstream-netbsd/bin/dd/args.c \
     upstream-netbsd/bin/dd/conv.c \
@@ -67,62 +44,19 @@
 LOCAL_ADDITIONAL_DEPENDENCIES += $(LOCAL_PATH)/Android.mk
 include $(BUILD_STATIC_LIBRARY)
 
-include $(CLEAR_VARS)
-LOCAL_SRC_FILES := upstream-netbsd/bin/ln/ln.c
-LOCAL_CFLAGS += $(common_cflags) -Dmain=ln_main
-LOCAL_MODULE := libtoolbox_ln
-LOCAL_ADDITIONAL_DEPENDENCIES += $(LOCAL_PATH)/Android.mk
-include $(BUILD_STATIC_LIBRARY)
-
-include $(CLEAR_VARS)
-LOCAL_SRC_FILES := upstream-netbsd/bin/mv/mv.c
-LOCAL_CFLAGS += $(common_cflags) -Dmain=mv_main -D__SVR4
-LOCAL_MODULE := libtoolbox_mv
-LOCAL_ADDITIONAL_DEPENDENCIES += $(LOCAL_PATH)/Android.mk
-include $(BUILD_STATIC_LIBRARY)
-
-include $(CLEAR_VARS)
-LOCAL_SRC_FILES := upstream-netbsd/bin/rm/rm.c
-LOCAL_CFLAGS += $(common_cflags) -Dmain=rm_main
-LOCAL_MODULE := libtoolbox_rm
-LOCAL_ADDITIONAL_DEPENDENCIES += $(LOCAL_PATH)/Android.mk
-include $(BUILD_STATIC_LIBRARY)
-
-include $(CLEAR_VARS)
-LOCAL_SRC_FILES := upstream-netbsd/bin/rmdir/rmdir.c
-LOCAL_CFLAGS += $(common_cflags) -Dmain=rmdir_main
-LOCAL_MODULE := libtoolbox_rmdir
-LOCAL_ADDITIONAL_DEPENDENCIES += $(LOCAL_PATH)/Android.mk
-include $(BUILD_STATIC_LIBRARY)
-
 
 include $(CLEAR_VARS)
 
 BSD_TOOLS := \
-    cat \
-    chown \
-    cp \
     dd \
     du \
     grep \
-    ln \
-    mv \
-    rm \
-    rmdir \
 
 OUR_TOOLS := \
-    chcon \
-    chmod \
-    cmp \
-    date \
     df \
-    getenforce \
     getevent \
     getprop \
     getsebool \
-    hd \
-    id \
-    ifconfig \
     iftop \
     ioctl \
     ionice \
@@ -130,14 +64,9 @@
     log \
     ls \
     lsof \
-    md5 \
-    mkdir \
-    mknod \
     mount \
     nandread \
-    netstat \
     newfs_msdos \
-    notify \
     ps \
     renice \
     restorecon \
@@ -145,7 +74,6 @@
     runcon \
     schedtop \
     sendevent \
-    setenforce \
     setprop \
     setsebool \
     smd \
@@ -167,16 +95,12 @@
     upstream-netbsd/lib/libc/string/swab.c \
     upstream-netbsd/lib/libutil/raise_default_signal.c \
     dynarray.c \
-    pwcache.c \
     $(patsubst %,%.c,$(OUR_TOOLS)) \
     toolbox.c \
 
 LOCAL_CFLAGS += $(common_cflags)
 
-LOCAL_C_INCLUDES += external/openssl/include
-
 LOCAL_SHARED_LIBRARIES := \
-    libcrypto \
     libcutils \
     libselinux \
 
diff --git a/toolbox/bsd-compatibility.h b/toolbox/bsd-compatibility.h
index 36ddca9..434d370 100644
--- a/toolbox/bsd-compatibility.h
+++ b/toolbox/bsd-compatibility.h
@@ -52,11 +52,6 @@
 
 __BEGIN_DECLS
 
-/* From NetBSD <grp.h> and <pwd.h>. */
-char* group_from_gid(gid_t gid, int noname);
-int uid_from_user(const char* name, uid_t* uid);
-char* user_from_uid(uid_t uid, int noname);
-
 /* From NetBSD <stdlib.h>. */
 #define HN_DECIMAL              0x01
 #define HN_NOSPACE              0x02
diff --git a/toolbox/chcon.c b/toolbox/chcon.c
deleted file mode 100644
index d594b9b..0000000
--- a/toolbox/chcon.c
+++ /dev/null
@@ -1,25 +0,0 @@
-#include <unistd.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <selinux/selinux.h>
-
-int chcon_main(int argc, char **argv)
-{
-    int rc, i;
-
-    if (argc < 3) {
-        fprintf(stderr, "usage:  %s context path...\n", argv[0]);
-        exit(1);
-    }
-
-    for (i = 2; i < argc; i++) {
-        rc = setfilecon(argv[i], argv[1]);
-        if (rc < 0) {
-            fprintf(stderr, "%s:  Could not label %s with %s:  %s\n",
-                    argv[0], argv[i], argv[1], strerror(errno));
-            exit(2);
-        }
-    }
-    exit(0);
-}
diff --git a/toolbox/chmod.c b/toolbox/chmod.c
deleted file mode 100644
index 2a524e9..0000000
--- a/toolbox/chmod.c
+++ /dev/null
@@ -1,101 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-#include <dirent.h>
-#include <errno.h>
-#include <sys/limits.h>
-#include <sys/stat.h>
-
-#include <unistd.h>
-#include <time.h>
-
-void recurse_chmod(char* path, int mode)
-{
-    struct dirent *dp;
-    DIR *dir = opendir(path);
-    if (dir == NULL) {
-        // not a directory, carry on
-        return;
-    }
-    char *subpath = malloc(sizeof(char)*PATH_MAX);
-    int pathlen = strlen(path);
-
-    while ((dp = readdir(dir)) != NULL) {
-        if (strcmp(dp->d_name, ".") == 0 ||
-            strcmp(dp->d_name, "..") == 0) continue;
-
-        if (strlen(dp->d_name) + pathlen + 2/*NUL and slash*/ > PATH_MAX) {
-            fprintf(stderr, "Invalid path specified: too long\n");
-            exit(1);
-        }
-
-        strcpy(subpath, path);
-        strcat(subpath, "/");
-        strcat(subpath, dp->d_name);
-
-        if (chmod(subpath, mode) < 0) {
-            fprintf(stderr, "Unable to chmod %s: %s\n", subpath, strerror(errno));
-            exit(1);
-        }
-
-        recurse_chmod(subpath, mode);
-    }
-    free(subpath);
-    closedir(dir);
-}
-
-static int usage()
-{
-    fprintf(stderr, "Usage: chmod [OPTION] <MODE> <FILE>\n");
-    fprintf(stderr, "  -R, --recursive         change files and directories recursively\n");
-    fprintf(stderr, "  --help                  display this help and exit\n");
-
-    return 10;
-}
-
-int chmod_main(int argc, char **argv)
-{
-    int i;
-
-    if (argc < 3 || strcmp(argv[1], "--help") == 0) {
-        return usage();
-    }
-
-    int recursive = (strcmp(argv[1], "-R") == 0 ||
-                     strcmp(argv[1], "--recursive") == 0) ? 1 : 0;
-
-    if (recursive && argc < 4) {
-        return usage();
-    }
-
-    if (recursive) {
-        argc--;
-        argv++;
-    }
-
-    int mode = 0;
-    const char* s = argv[1];
-    while (*s) {
-        if (*s >= '0' && *s <= '7') {
-            mode = (mode<<3) | (*s-'0');
-        }
-        else {
-            fprintf(stderr, "Bad mode\n");
-            return 10;
-        }
-        s++;
-    }
-
-    for (i = 2; i < argc; i++) {
-        if (chmod(argv[i], mode) < 0) {
-            fprintf(stderr, "Unable to chmod %s: %s\n", argv[i], strerror(errno));
-            return 10;
-        }
-        if (recursive) {
-            recurse_chmod(argv[i], mode);
-        }
-    }
-    return 0;
-}
-
diff --git a/toolbox/cmp.c b/toolbox/cmp.c
deleted file mode 100644
index 80635ad..0000000
--- a/toolbox/cmp.c
+++ /dev/null
@@ -1,91 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdint.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <sys/ioctl.h>
-#include <errno.h>
-
-int cmp_main(int argc, char *argv[])
-{
-    int c;
-    int fd1, fd2;
-	char buf1[4096], buf2[4096];
-    int res, res1, res2;
-	int rv = 0;
-	int i;
-	int filepos = 0;
-
-	int show_byte = 0;
-	int show_all = 0;
-	int limit = 0;
-
-    do {
-        c = getopt(argc, argv, "bln:");
-        if (c == EOF)
-            break;
-        switch (c) {
-        case 'b':
-            show_byte = 1;
-            break;
-        case 'l':
-            show_all = 1;
-            break;
-        case 'n':
-            limit = atoi(optarg);
-            break;
-        case '?':
-            fprintf(stderr, "%s: invalid option -%c\n",
-                argv[0], optopt);
-            exit(1);
-        }
-    } while (1);
-
-    if (optind + 2 != argc) {
-        fprintf(stderr, "Usage: %s [-b] [-l] [-n count] file1 file2\n", argv[0]);
-        exit(1);
-    }
-
-    fd1 = open(argv[optind], O_RDONLY);
-    if(fd1 < 0) {
-        fprintf(stderr, "could not open %s, %s\n", argv[optind], strerror(errno));
-        return 1;
-    }
-
-    fd2 = open(argv[optind+1], O_RDONLY);
-    if(fd2 < 0) {
-        fprintf(stderr, "could not open %s, %s\n", argv[optind+1], strerror(errno));
-        return 1;
-    }
-    
-    while(1) {
-        res1 = read(fd1, &buf1, sizeof(buf1));
-        res2 = read(fd2, &buf2, sizeof(buf2));
-		res = res1 < res2 ? res1 : res2;
-		if(res1 == 0 && res2 == 0) {
-			return rv;
-		}
-		for(i = 0; i < res; i++) {
-			if(buf1[i] != buf2[i]) {
-				printf("%s %s differ byte %d", argv[optind], argv[optind+1], filepos + i);
-				if(show_byte)
-					printf(" 0x%02x 0x%02x", buf1[i], buf2[i]);
-				printf("\n");
-				if(!show_all)
-					return 1;
-				rv = 1;
-			}
-			if(limit) {
-				limit--;
-				if(limit == 0)
-					return rv;
-			}
-		}
-		if(res1 != res2 || res < 0) {
-			printf("%s on %s\n", res < 0 ? "Read error" : "EOF", res1 < res2 ? argv[optind] : argv[optind+1]);
-			return 1;
-		}
-		filepos += res;
-    }
-}
diff --git a/toolbox/date.c b/toolbox/date.c
deleted file mode 100644
index 70ce1d5..0000000
--- a/toolbox/date.c
+++ /dev/null
@@ -1,227 +0,0 @@
-#include <ctype.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <inttypes.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-#include <unistd.h>
-
-#include <linux/android_alarm.h>
-#include <linux/rtc.h>
-#include <sys/ioctl.h>
-
-static int settime_alarm(struct timespec *ts) {
-    int fd, ret;
-
-    fd = open("/dev/alarm", O_RDWR);
-    if (fd < 0)
-        return fd;
-
-    ret = ioctl(fd, ANDROID_ALARM_SET_RTC, ts);
-    close(fd);
-    return ret;
-}
-
-static int settime_alarm_tm(struct tm *tm) {
-    time_t t;
-    struct timespec ts;
-
-    t = mktime(tm);
-    ts.tv_sec = t;
-    ts.tv_nsec = 0;
-    return settime_alarm(&ts);
-}
-
-static int settime_alarm_timeval(struct timeval *tv) {
-    struct timespec ts;
-
-    ts.tv_sec = tv->tv_sec;
-    ts.tv_nsec = tv->tv_usec * 1000;
-    return settime_alarm(&ts);
-}
-
-static int settime_rtc_tm(struct tm *tm) {
-    int fd, ret;
-    struct timeval tv;
-    struct rtc_time rtc;
-
-    fd = open("/dev/rtc0", O_RDWR);
-    if (fd < 0)
-        return fd;
-
-    tv.tv_sec = mktime(tm);
-    tv.tv_usec = 0;
-
-    ret = settimeofday(&tv, NULL);
-    if (ret < 0)
-        goto done;
-
-    memset(&rtc, 0, sizeof(rtc));
-    rtc.tm_sec = tm->tm_sec;
-    rtc.tm_min = tm->tm_min;
-    rtc.tm_hour = tm->tm_hour;
-    rtc.tm_mday = tm->tm_mday;
-    rtc.tm_mon = tm->tm_mon;
-    rtc.tm_year = tm->tm_year;
-    rtc.tm_wday = tm->tm_wday;
-    rtc.tm_yday = tm->tm_yday;
-    rtc.tm_isdst = tm->tm_isdst;
-
-    ret = ioctl(fd, RTC_SET_TIME, rtc);
-done:
-    close(fd);
-    return ret;
-}
-
-static int settime_rtc_timeval(struct timeval *tv) {
-    struct tm tm, *err;
-    time_t t = tv->tv_sec;
-
-    err = gmtime_r(&t, &tm);
-    if (!err)
-        return -1;
-
-    return settime_rtc_tm(&tm);
-}
-
-static void settime(char *s) {
-    struct tm tm;
-    int day = atoi(s);
-    int hour;
-
-    while (*s && *s != '.')
-        s++;
-
-    if (*s)
-        s++;
-
-    hour = atoi(s);
-
-    tm.tm_year = day / 10000 - 1900;
-    tm.tm_mon = (day % 10000) / 100 - 1;
-    tm.tm_mday = (day % 100);
-    tm.tm_hour = hour / 10000;
-    tm.tm_min = (hour % 10000) / 100;
-    tm.tm_sec = (hour % 100);
-    tm.tm_isdst = -1;
-
-    if (settime_alarm_tm(&tm) < 0)
-        settime_rtc_tm(&tm);
-}
-
-static char *parse_time(const char *str, struct timeval *ts) {
-  char *s;
-  long fs = 0; /* fractional seconds */
-
-  ts->tv_sec = strtoumax(str, &s, 10);
-
-  if (*s == '.') {
-    s++;
-    int count = 0;
-
-    /* read up to 6 digits (microseconds) */
-    while (*s && isdigit(*s)) {
-      if (++count < 7) {
-        fs = fs*10 + (*s - '0');
-      }
-      s++;
-    }
-
-    for (; count < 6; count++) {
-      fs *= 10;
-    }
-  }
-
-  ts->tv_usec = fs;
-  return s;
-}
-
-int date_main(int argc, char *argv[])
-{
-    int c;
-    int res;
-    struct tm tm;
-    time_t t;
-    struct timeval tv;
-    char strbuf[260];
-
-    int useutc = 0;
-
-    tzset();
-
-    do {
-        c = getopt(argc, argv, "us:");
-        if (c == EOF)
-            break;
-        switch (c) {
-        case 'u':
-            useutc = 1;
-            break;
-        case 's':
-            settime(optarg);
-            break;
-        case '?':
-            fprintf(stderr, "%s: invalid option -%c\n",
-                argv[0], optopt);
-            exit(1);
-        }
-    } while (1);
-    if(optind + 2 < argc) {
-        fprintf(stderr,"%s [-u] [date]\n", argv[0]);
-        return 1;
-    }
-
-    int hasfmt = argc == optind + 1 && argv[optind][0] == '+';
-    if(optind == argc || hasfmt) {
-        time(&t);
-        if (useutc) {
-            gmtime_r(&t, &tm);
-            strftime(strbuf, sizeof(strbuf),
-                     (hasfmt ? argv[optind] + 1 : "%a %b %e %H:%M:%S GMT %Y"),
-                     &tm);
-        } else {
-            localtime_r(&t, &tm);
-            strftime(strbuf, sizeof(strbuf),
-                     (hasfmt ? argv[optind] + 1 : "%a %b %e %H:%M:%S %Z %Y"),
-                     &tm);
-        }
-        printf("%s\n", strbuf);
-    }
-    else if(optind + 1 == argc) {
-#if 0
-        struct tm *tmptr;
-        tmptr = getdate(argv[optind]);
-        if(tmptr == NULL) {
-            fprintf(stderr,"getdate_r failed\n");
-            return 1;
-        }
-        tm = *tmptr;
-#if 0
-        if(getdate_r(argv[optind], &tm) < 0) {
-            fprintf(stderr,"getdate_r failed %s\n", strerror(errno));
-            return 1;
-        }
-#endif
-#endif
-        //strptime(argv[optind], NULL, &tm);
-        //tv.tv_sec = mktime(&tm);
-        //tv.tv_usec = 0;
-        parse_time(argv[optind], &tv);
-        printf("time %s -> %lu.%lu\n", argv[optind], tv.tv_sec, tv.tv_usec);
-        res = settime_alarm_timeval(&tv);
-        if (res < 0)
-            res = settime_rtc_timeval(&tv);
-        if(res < 0) {
-            fprintf(stderr,"settimeofday failed %s\n", strerror(errno));
-            return 1;
-        }
-    }
-    else {
-        fprintf(stderr,"%s [-s 20070325.123456] [-u] [date]\n", argv[0]);
-        return 1;
-    }
-
-    return 0;
-}
diff --git a/toolbox/getenforce.c b/toolbox/getenforce.c
deleted file mode 100644
index 9e7589a..0000000
--- a/toolbox/getenforce.c
+++ /dev/null
@@ -1,30 +0,0 @@
-#include <unistd.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <selinux/selinux.h>
-
-int getenforce_main(int argc, char **argv)
-{
-    int rc;
-
-    rc = is_selinux_enabled();
-    if (rc <= 0) {
-        printf("Disabled\n");
-        return 0;
-    }
-
-    rc = security_getenforce();
-    if (rc < 0) {
-        fprintf(stderr, "Could not get enforcing status:  %s\n",
-                strerror(errno));
-        return 2;
-    }
-
-    if (rc)
-        printf("Enforcing\n");
-    else
-        printf("Permissive\n");
-
-    return 0;
-}
diff --git a/toolbox/getevent.c b/toolbox/getevent.c
index da83ec3..c58eb5d 100644
--- a/toolbox/getevent.c
+++ b/toolbox/getevent.c
@@ -10,6 +10,7 @@
 #include <sys/poll.h>
 #include <linux/input.h>
 #include <errno.h>
+#include <unistd.h>
 
 #include "getevent.h"
 
diff --git a/toolbox/hd.c b/toolbox/hd.c
deleted file mode 100644
index 7c9998e..0000000
--- a/toolbox/hd.c
+++ /dev/null
@@ -1,97 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdint.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <sys/ioctl.h>
-#include <errno.h>
-
-int hd_main(int argc, char *argv[])
-{
-    int c;
-    int fd;
-	unsigned char buf[4096];
-    int res;
-	int read_len;
-	int i;
-	int filepos = 0;
-	int sum;
-	int lsum;
-
-	int base = -1;
-	int count = 0;
-	int repeat = 0;
-
-    do {
-        c = getopt(argc, argv, "b:c:r:");
-        if (c == EOF)
-            break;
-        switch (c) {
-        case 'b':
-            base = strtol(optarg, NULL, 0);
-            break;
-        case 'c':
-            count = strtol(optarg, NULL, 0);
-            break;
-		case 'r':
-			repeat = strtol(optarg, NULL, 0);
-			break;
-        case '?':
-            fprintf(stderr, "%s: invalid option -%c\n",
-                argv[0], optopt);
-            exit(1);
-        }
-    } while (1);
-
-    if (optind + 1 != argc) {
-        fprintf(stderr, "Usage: %s [-b base] [-c count] [-r delay] file\n", argv[0]);
-        exit(1);
-    }
-
-    fd = open(argv[optind], O_RDONLY);
-    if(fd < 0) {
-        fprintf(stderr, "could not open %s, %s\n", argv[optind], strerror(errno));
-        return 1;
-    }
-
-	do {
-		if(base >= 0) {
-			lseek(fd, base, SEEK_SET);
-			filepos = base;
-		}
-		sum = 0;
-		lsum = 0;
-	    while(1) {
-			read_len = sizeof(buf);
-			if(count > 0 && base + count - filepos < read_len)
-				read_len = base + count - filepos;
-	        res = read(fd, &buf, read_len);
-			if(res == 0)
-				break;
-			for(i = 0; i < res; i++) {
-				if((i & 15) == 0) {
-					printf("%08x: ", filepos + i);
-				}
-				lsum += buf[i];
-				sum += buf[i];
-				printf("%02x ", buf[i]);
-				if(((i & 15) == 15) || (i == res - 1)) {
-					printf("s %x\n", lsum);
-					lsum = 0;
-				}
-			}
-			if(res < 0) {
-				printf("Read error on %s, offset %d len %d, %s\n", argv[optind], filepos, read_len, strerror(errno));
-				return 1;
-			}
-			filepos += res;
-			if(filepos == base + count)
-				break;
-	    }
-		printf("sum %x\n", sum);
-		if(repeat)
-			sleep(repeat);
-	} while(repeat);
-	return 0;
-}
diff --git a/toolbox/id.c b/toolbox/id.c
deleted file mode 100644
index 8ec79c1..0000000
--- a/toolbox/id.c
+++ /dev/null
@@ -1,57 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <pwd.h>
-#include <grp.h>
-#include <selinux/selinux.h>
-
-static void print_uid(uid_t uid)
-{
-    struct passwd *pw = getpwuid(uid);
-
-    if (pw) {
-        printf("%d(%s)", uid, pw->pw_name);
-    } else {
-        printf("%d",uid);
-    }
-}
-
-static void print_gid(gid_t gid)
-{
-    struct group *gr = getgrgid(gid);
-    if (gr) {
-        printf("%d(%s)", gid, gr->gr_name);
-    } else {
-        printf("%d",gid);
-    }
-}
-
-int id_main(int argc, char **argv)
-{
-    gid_t list[64];
-    int n, max;
-    char *secctx;
-
-    max = getgroups(64, list);
-    if (max < 0) max = 0;
-
-    printf("uid=");
-    print_uid(getuid());
-    printf(" gid=");
-    print_gid(getgid());
-    if (max) {
-        printf(" groups=");
-        print_gid(list[0]);
-        for(n = 1; n < max; n++) {
-            printf(",");
-            print_gid(list[n]);
-        }
-    }
-    if (getcon(&secctx) == 0) {
-        printf(" context=%s", secctx);
-        free(secctx);
-    }
-    printf("\n");
-    return 0;
-}
diff --git a/toolbox/ifconfig.c b/toolbox/ifconfig.c
deleted file mode 100644
index b953176..0000000
--- a/toolbox/ifconfig.c
+++ /dev/null
@@ -1,157 +0,0 @@
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-#include <errno.h>
-#include <string.h>
-#include <ctype.h>
-
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <linux/if.h>
-#include <linux/sockios.h>
-#include <arpa/inet.h>
-
-static void die(const char *s)
-{
-    fprintf(stderr,"error: %s (%s)\n", s, strerror(errno));
-    exit(-1);
-}
-
-static void setflags(int s, struct ifreq *ifr, int set, int clr)
-{
-    if(ioctl(s, SIOCGIFFLAGS, ifr) < 0) die("SIOCGIFFLAGS");
-    ifr->ifr_flags = (ifr->ifr_flags & (~clr)) | set;
-    if(ioctl(s, SIOCSIFFLAGS, ifr) < 0) die("SIOCSIFFLAGS");
-}
-
-static inline void init_sockaddr_in(struct sockaddr_in *sin, const char *addr)
-{
-    sin->sin_family = AF_INET;
-    sin->sin_port = 0;
-    sin->sin_addr.s_addr = inet_addr(addr);
-}
-
-static void setmtu(int s, struct ifreq *ifr, const char *mtu)
-{
-    int m = atoi(mtu);
-    ifr->ifr_mtu = m;
-    if(ioctl(s, SIOCSIFMTU, ifr) < 0) die("SIOCSIFMTU");
-}
-static void setdstaddr(int s, struct ifreq *ifr, const char *addr)
-{
-    init_sockaddr_in((struct sockaddr_in *) &ifr->ifr_dstaddr, addr);
-    if(ioctl(s, SIOCSIFDSTADDR, ifr) < 0) die("SIOCSIFDSTADDR");
-}
-
-static void setnetmask(int s, struct ifreq *ifr, const char *addr)
-{
-    init_sockaddr_in((struct sockaddr_in *) &ifr->ifr_netmask, addr);
-    if(ioctl(s, SIOCSIFNETMASK, ifr) < 0) die("SIOCSIFNETMASK");
-}
-
-static void setaddr(int s, struct ifreq *ifr, const char *addr)
-{
-    init_sockaddr_in((struct sockaddr_in *) &ifr->ifr_addr, addr);
-    if(ioctl(s, SIOCSIFADDR, ifr) < 0) die("SIOCSIFADDR");
-}
-
-int ifconfig_main(int argc, char *argv[])
-{
-    struct ifreq ifr;
-    int s;
-    unsigned int flags;
-    char astring[20];
-    char mstring[20];
-    char *updown, *brdcst, *loopbk, *ppp, *running, *multi;
-
-    argc--;
-    argv++;
-
-    if(argc == 0) return 0;
-
-    memset(&ifr, 0, sizeof(struct ifreq));
-    strncpy(ifr.ifr_name, argv[0], IFNAMSIZ);
-    ifr.ifr_name[IFNAMSIZ-1] = 0;
-    argc--, argv++;
-
-    if((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
-        die("cannot open control socket\n");
-    }
-
-    if (argc == 0) {
-        if (ioctl(s, SIOCGIFADDR, &ifr) < 0) {
-            perror(ifr.ifr_name);
-            return -1;
-        } else
-            strlcpy(astring,
-                   inet_ntoa(((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr),
-                   sizeof(astring));
-
-        if (ioctl(s, SIOCGIFNETMASK, &ifr) < 0) {
-            perror(ifr.ifr_name);
-            return -1;
-        } else
-            strlcpy(mstring,
-                   inet_ntoa(((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr),
-                   sizeof(mstring));
-
-        if (ioctl(s, SIOCGIFFLAGS, &ifr) < 0) {
-            perror(ifr.ifr_name);
-            return -1;
-        } else
-            flags = ifr.ifr_flags;
-
-        printf("%s: ip %s mask %s flags [", ifr.ifr_name,
-               astring,
-               mstring
-               );
-
-        updown =  (flags & IFF_UP)           ? "up" : "down";
-        brdcst =  (flags & IFF_BROADCAST)    ? " broadcast" : "";
-        loopbk =  (flags & IFF_LOOPBACK)     ? " loopback" : "";
-        ppp =     (flags & IFF_POINTOPOINT)  ? " point-to-point" : "";
-        running = (flags & IFF_RUNNING)      ? " running" : "";
-        multi =   (flags & IFF_MULTICAST)    ? " multicast" : "";
-        printf("%s%s%s%s%s%s]\n", updown, brdcst, loopbk, ppp, running, multi);
-        return 0;
-    }
-    
-    while(argc > 0) {
-        if (!strcmp(argv[0], "up")) {
-            setflags(s, &ifr, IFF_UP, 0);
-        } else if (!strcmp(argv[0], "mtu")) {
-            argc--, argv++;
-            if (!argc) {
-                errno = EINVAL;
-                die("expecting a value for parameter \"mtu\"");
-            }
-            setmtu(s, &ifr, argv[0]);
-        } else if (!strcmp(argv[0], "-pointopoint")) {
-            setflags(s, &ifr, IFF_POINTOPOINT, 1);
-        } else if (!strcmp(argv[0], "pointopoint")) {
-            argc--, argv++;
-            if (!argc) { 
-                errno = EINVAL;
-                die("expecting an IP address for parameter \"pointtopoint\"");
-            }
-            setdstaddr(s, &ifr, argv[0]);
-            setflags(s, &ifr, IFF_POINTOPOINT, 0);
-        } else if (!strcmp(argv[0], "down")) {
-            setflags(s, &ifr, 0, IFF_UP);
-        } else if (!strcmp(argv[0], "netmask")) {
-            argc--, argv++;
-            if (!argc) { 
-                errno = EINVAL;
-                die("expecting an IP address for parameter \"netmask\"");
-            }
-            setnetmask(s, &ifr, argv[0]);
-        } else if (isdigit(argv[0][0])) {
-            setaddr(s, &ifr, argv[0]);
-            setflags(s, &ifr, IFF_UP, 0);
-        }
-        argc--, argv++;
-    }
-    return 0;
-}
diff --git a/toolbox/ioctl.c b/toolbox/ioctl.c
index 73539d1..d1cc14a 100644
--- a/toolbox/ioctl.c
+++ b/toolbox/ioctl.c
@@ -9,6 +9,7 @@
 #include <errno.h>
 #include <pthread.h>
 #include <sys/ioctl.h>
+#include <unistd.h>
 
 int ioctl_main(int argc, char *argv[])
 {
diff --git a/toolbox/md5.c b/toolbox/md5.c
deleted file mode 100644
index 5de4d9e..0000000
--- a/toolbox/md5.c
+++ /dev/null
@@ -1,71 +0,0 @@
-#include <errno.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <openssl/md5.h>
-
-static int usage()
-{
-    fprintf(stderr,"md5 file ...\n");
-    return -1;
-}
-
-static int do_md5(const char *path)
-{
-    unsigned int i;
-    int fd;
-    MD5_CTX md5_ctx;
-    unsigned char md5[MD5_DIGEST_LENGTH];
-
-    fd = open(path, O_RDONLY);
-    if (fd < 0) {
-        fprintf(stderr,"could not open %s, %s\n", path, strerror(errno));
-        return -1;
-    }
-
-    MD5_Init(&md5_ctx);
-
-    while (1) {
-        char buf[4096];
-        ssize_t rlen;
-        rlen = read(fd, buf, sizeof(buf));
-        if (rlen == 0)
-            break;
-        else if (rlen < 0) {
-            (void)close(fd);
-            fprintf(stderr,"could not read %s, %s\n", path, strerror(errno));
-            return -1;
-        }
-        MD5_Update(&md5_ctx, buf, rlen);
-    }
-    if (close(fd)) {
-        fprintf(stderr,"could not close %s, %s\n", path, strerror(errno));
-        return -1;
-    }
-
-    MD5_Final(md5, &md5_ctx);
-
-    for (i = 0; i < (int)sizeof(md5); i++)
-        printf("%02x", md5[i]);
-    printf("  %s\n", path);
-
-    return 0;
-}
-
-int md5_main(int argc, char *argv[])
-{
-    int i, ret = 0;
-
-    if (argc < 2)
-        return usage();
-
-    /* loop over the file args */
-    for (i = 1; i < argc; i++) {
-        if (do_md5(argv[i]))
-            ret = 1;
-    }
-
-    return ret;
-}
diff --git a/toolbox/mkdir.c b/toolbox/mkdir.c
deleted file mode 100644
index 398d350..0000000
--- a/toolbox/mkdir.c
+++ /dev/null
@@ -1,77 +0,0 @@
-#include <stdio.h>
-#include <unistd.h>
-#include <string.h>
-#include <errno.h>
-#include <sys/limits.h>
-#include <sys/stat.h>
-
-static int usage()
-{
-    fprintf(stderr,"mkdir [OPTION] <target>\n");
-    fprintf(stderr,"    --help           display usage and exit\n");
-    fprintf(stderr,"    -p, --parents    create parent directories as needed\n");
-    return -1;
-}
-
-int mkdir_main(int argc, char *argv[])
-{
-    int ret;
-    if(argc < 2 || strcmp(argv[1], "--help") == 0) {
-        return usage();
-    }
-
-    int recursive = (strcmp(argv[1], "-p") == 0 ||
-                     strcmp(argv[1], "--parents") == 0) ? 1 : 0;
-
-    if(recursive && argc < 3) {
-        // -p specified without a path
-        return usage();
-    }
-
-    if(recursive) {
-        argc--;
-        argv++;
-    }
-
-    char currpath[PATH_MAX], *pathpiece;
-    struct stat st;
-
-    while(argc > 1) {
-        argc--;
-        argv++;
-        if(recursive) {
-            // reset path
-            strcpy(currpath, "");
-            // create the pieces of the path along the way
-            pathpiece = strtok(argv[0], "/");
-            if(argv[0][0] == '/') {
-                // prepend / if needed
-                strcat(currpath, "/");
-            }
-            while(pathpiece != NULL) {
-                if(strlen(currpath) + strlen(pathpiece) + 2/*NUL and slash*/ > PATH_MAX) {
-                    fprintf(stderr, "Invalid path specified: too long\n");
-                    return 1;
-                }
-                strcat(currpath, pathpiece);
-                strcat(currpath, "/");
-                if(stat(currpath, &st) != 0) {
-                    ret = mkdir(currpath, 0777);
-                    if(ret < 0) {
-                        fprintf(stderr, "mkdir failed for %s, %s\n", currpath, strerror(errno));
-                        return ret;
-                    }
-                }
-                pathpiece = strtok(NULL, "/");
-            }
-        } else {
-            ret = mkdir(argv[0], 0777);
-            if(ret < 0) {
-                fprintf(stderr, "mkdir failed for %s, %s\n", argv[0], strerror(errno));
-                return ret;
-            }
-        }
-    }
-    
-    return 0;
-}
diff --git a/toolbox/mknod.c b/toolbox/mknod.c
deleted file mode 100644
index 0fedece..0000000
--- a/toolbox/mknod.c
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright (c) 2014, The Android Open Source Project
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *  * Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *  * 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.
- *  * Neither the name of Google, Inc. 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 COPYRIGHT HOLDERS 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
- * COPYRIGHT OWNER 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 <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <sys/stat.h>
-
-static int print_usage() {
-    fprintf(stderr, "mknod <path> [b|c|u|p] <major> <minor>\n");
-    return EXIT_FAILURE;
-}
-
-int mknod_main(int argc, char **argv) {
-    char *path = NULL;
-    int major = 0;
-    int minor = 0;
-    int args = 0;
-    mode_t mode = 0660;
-
-    /* Check correct argument count is 3 or 5 */
-    if (argc != 3 && argc != 5) {
-        fprintf(stderr, "Incorrect argument count\n");
-        return print_usage();
-    }
-
-    path = argv[1];
-
-    const char node_type = *argv[2];
-    switch (node_type) {
-    case 'b':
-        mode |= S_IFBLK;
-        args = 5;
-        break;
-    case 'c':
-    case 'u':
-        mode |= S_IFCHR;
-        args = 5;
-        break;
-    case 'p':
-        mode |= S_IFIFO;
-        args = 3;
-        break;
-    default:
-        fprintf(stderr, "Invalid node type '%c'\n", node_type);
-        return print_usage();
-    }
-
-    if (argc != args) {
-        if (args == 5) {
-            fprintf(stderr, "Node type '%c' requires <major> and <minor>\n", node_type);
-        } else {
-            fprintf(stderr, "Node type '%c' does not require <major> and <minor>\n", node_type);
-        }
-        return print_usage();
-    }
-
-    if (args == 5) {
-        major = atoi(argv[3]);
-        minor = atoi(argv[4]);
-    }
-
-    if (mknod(path, mode, makedev(major, minor))) {
-        perror("Unable to create node");
-        return EXIT_FAILURE;
-    }
-    return 0;
-}
diff --git a/toolbox/netstat.c b/toolbox/netstat.c
deleted file mode 100644
index 05dc640..0000000
--- a/toolbox/netstat.c
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * Copyright (c) 2008, The Android Open Source Project
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *  * Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *  * 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.
- *  * Neither the name of Google, Inc. 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 COPYRIGHT HOLDERS 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
- * COPYRIGHT OWNER 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 <arpa/inet.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/socket.h>
-#include <sys/types.h>
-
-typedef union iaddr iaddr;
-typedef union iaddr6 iaddr6;
-
-union iaddr {
-    unsigned u;
-    unsigned char b[4];
-};
-
-union iaddr6 {
-    struct {
-        unsigned a;
-        unsigned b;
-        unsigned c;
-        unsigned d;
-    } u;
-    unsigned char b[16];
-};
-
-static const char *state2str(unsigned state)
-{
-    switch(state){
-    case 0x1: return "ESTABLISHED";
-    case 0x2: return "SYN_SENT";
-    case 0x3: return "SYN_RECV";
-    case 0x4: return "FIN_WAIT1";
-    case 0x5: return "FIN_WAIT2";
-    case 0x6: return "TIME_WAIT";
-    case 0x7: return "CLOSE";
-    case 0x8: return "CLOSE_WAIT";
-    case 0x9: return "LAST_ACK";
-    case 0xA: return "LISTEN";
-    case 0xB: return "CLOSING";
-    default: return "UNKNOWN";
-    }
-}
-
-/* addr + : + port + \0 */
-#define ADDR_LEN INET6_ADDRSTRLEN + 1 + 5 + 1
-
-static void addr2str(int af, const void *addr, unsigned port, char *buf)
-{
-    if (inet_ntop(af, addr, buf, ADDR_LEN) == NULL) {
-        *buf = '\0';
-        return;
-    }
-    size_t len = strlen(buf);
-    if (port) {
-        snprintf(buf+len, ADDR_LEN-len, ":%d", port);
-    } else {
-        strncat(buf+len, ":*", ADDR_LEN-len-1);
-    }
-}
-
-static void ipv4(const char *filename, const char *label) {
-    FILE *fp = fopen(filename, "r");
-    if (fp == NULL) {
-        return;
-    }
-    char buf[BUFSIZ];
-    fgets(buf, BUFSIZ, fp);
-    while (fgets(buf, BUFSIZ, fp)){
-        char lip[ADDR_LEN];
-        char rip[ADDR_LEN];
-        iaddr laddr, raddr;
-        unsigned lport, rport, state, txq, rxq, num;
-        int n = sscanf(buf, " %d: %x:%x %x:%x %x %x:%x",
-                       &num, &laddr.u, &lport, &raddr.u, &rport,
-                       &state, &txq, &rxq);
-        if (n == 8) {
-            addr2str(AF_INET, &laddr, lport, lip);
-            addr2str(AF_INET, &raddr, rport, rip);
-
-            printf("%4s  %6d %6d %-22s %-22s %s\n",
-                   label, rxq, txq, lip, rip,
-                   state2str(state));
-        }
-    }
-    fclose(fp);
-}
-
-static void ipv6(const char *filename, const char *label) {
-    FILE *fp = fopen(filename, "r");
-    if (fp == NULL) {
-        return;
-    }
-    char buf[BUFSIZ];
-    fgets(buf, BUFSIZ, fp);
-    while (fgets(buf, BUFSIZ, fp)){
-        char lip[ADDR_LEN];
-        char rip[ADDR_LEN];
-        iaddr6 laddr6, raddr6;
-        unsigned lport, rport, state, txq, rxq, num;
-        int n = sscanf(buf, " %d: %8x%8x%8x%8x:%x %8x%8x%8x%8x:%x %x %x:%x",
-                       &num, &laddr6.u.a, &laddr6.u.b, &laddr6.u.c, &laddr6.u.d, &lport,
-                       &raddr6.u.a, &raddr6.u.b, &raddr6.u.c, &raddr6.u.d, &rport,
-                       &state, &txq, &rxq);
-        if (n == 14) {
-            addr2str(AF_INET6, &laddr6, lport, lip);
-            addr2str(AF_INET6, &raddr6, rport, rip);
-
-            printf("%4s  %6d %6d %-22s %-22s %s\n",
-                   label, rxq, txq, lip, rip,
-                   state2str(state));
-        }
-    }
-    fclose(fp);
-}
-
-int netstat_main(int argc, char *argv[])
-{
-    printf("Proto Recv-Q Send-Q Local Address          Foreign Address        State\n");
-    ipv4("/proc/net/tcp",  "tcp");
-    ipv4("/proc/net/udp",  "udp");
-    ipv6("/proc/net/tcp6", "tcp6");
-    ipv6("/proc/net/udp6", "udp6");
-    return 0;
-}
diff --git a/toolbox/notify.c b/toolbox/notify.c
deleted file mode 100644
index 8ce346c..0000000
--- a/toolbox/notify.c
+++ /dev/null
@@ -1,149 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdint.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <sys/ioctl.h>
-#include <sys/inotify.h>
-#include <errno.h>
-
-int notify_main(int argc, char *argv[])
-{
-    int c;
-    int nfd, ffd;
-    int res;
-	char event_buf[512];
-    struct inotify_event *event;
-	int event_mask = IN_ALL_EVENTS;
-    int event_count = 1;
-	int print_files = 0;
-	int verbose = 2;
-	int width = 80;
-	char **file_names;
-	int file_count;
-	int id_offset = 0;
-	int i;
-	char *buf;
-
-    do {
-        c = getopt(argc, argv, "m:c:pv:w:");
-        if (c == EOF)
-            break;
-        switch (c) {
-        case 'm':
-            event_mask = strtol(optarg, NULL, 0);
-            break;
-        case 'c':
-            event_count = atoi(optarg);
-            break;
-		case 'p':
-			print_files = 1;
-			break;
-        case 'v':
-            verbose = atoi(optarg);
-            break;
-        case 'w':
-            width = atoi(optarg);
-            break;
-        case '?':
-            fprintf(stderr, "%s: invalid option -%c\n",
-                argv[0], optopt);
-            exit(1);
-        }
-    } while (1);
-
-    if (argc <= optind) {
-        fprintf(stderr, "Usage: %s [-m eventmask] [-c count] [-p] [-v verbosity] path [path ...]\n", argv[0]);
-		return 1;
-    }
-
-    nfd = inotify_init();
-    if(nfd < 0) {
-        fprintf(stderr, "inotify_init failed, %s\n", strerror(errno));
-        return 1;
-    }
-	file_names = argv + optind;
-	file_count = argc - optind;
-	for(i = 0; i < file_count; i++) {
-		res = inotify_add_watch(nfd, file_names[i], event_mask);
-		if(res < 0) {
-	        fprintf(stderr, "inotify_add_watch failed for %s, %s\n", file_names[i], strerror(errno));
-			return 1;
-		}
-		if(i == 0)
-			id_offset = -res;
-		if(res + id_offset != i) {
-			fprintf(stderr, "%s got unexpected id %d instead of %d\n", file_names[i], res, i);
-			return 1;
-		}
-	}
-
-	buf = malloc(width + 2);
-    
-    while(1) {
-		int event_pos = 0;
-        res = read(nfd, event_buf, sizeof(event_buf));
-        if(res < (int)sizeof(*event)) {
-			if(errno == EINTR)
-				continue;
-            fprintf(stderr, "could not get event, %s\n", strerror(errno));
-            return 1;
-        }
-		//printf("got %d bytes of event information\n", res);
-		while(res >= (int)sizeof(*event)) {
-			int event_size;
-			event = (struct inotify_event *)(event_buf + event_pos);
-			if(verbose >= 2)
-		        printf("%s: %08x %08x \"%s\"\n", file_names[event->wd + id_offset], event->mask, event->cookie, event->len ? event->name : "");
-			else if(verbose >= 2)
-		        printf("%s: %08x \"%s\"\n", file_names[event->wd + id_offset], event->mask, event->len ? event->name : "");
-			else if(verbose >= 1)
-		        printf("%d: %08x \"%s\"\n", event->wd, event->mask, event->len ? event->name : "");
-			if(print_files && (event->mask & IN_MODIFY)) {
-				char* filename = file_names[event->wd + id_offset];
-				char* alloc_buf = NULL;
-				ssize_t read_len;
-				char *display_name;
-				int buflen;
-				if(event->len) {
-					if(asprintf(&alloc_buf, "%s/%s", filename, event->name) < 0) {
-						fprintf(stderr, "asprintf failed, %s\n", strerror(errno));
-						return 1;
-					}
-					filename = alloc_buf;
-				}
-				ffd = open(filename, O_RDONLY);
-				display_name = (verbose >= 2 || event->len == 0) ? filename : event->name;
-				buflen = width - strlen(display_name);
-				read_len = read(ffd, buf, buflen);
-				if(read_len > 0) {
-					if(read_len < buflen && buf[read_len-1] != '\n') {
-						buf[read_len] = '\n';
-						read_len++;
-					}
-					if(read_len == buflen) {
-						buf[--read_len] = '\0';
-						buf[--read_len] = '\n';
-						buf[--read_len] = '.';
-						buf[--read_len] = '.';
-						buf[--read_len] = '.';
-					}
-					else {
-						buf[read_len] = '\0';
-					}
-					printf("%s: %s", display_name, buf);
-				}
-				close(ffd);
-				free(alloc_buf);
-			}
-	        if(event_count && --event_count == 0)
-	            return 0;
-			event_size = sizeof(*event) + event->len;
-			res -= event_size;
-			event_pos += event_size;
-		}
-    }
-
-    return 0;
-}
diff --git a/toolbox/ps.c b/toolbox/ps.c
index 4f001b8..7d6dfa0 100644
--- a/toolbox/ps.c
+++ b/toolbox/ps.c
@@ -1,15 +1,13 @@
+#include <ctype.h>
+#include <dirent.h>
+#include <fcntl.h>
+#include <pwd.h>
 #include <stdio.h>
 #include <stdlib.h>
-#include <ctype.h>
-#include <fcntl.h>
-
 #include <string.h>
-
 #include <sys/stat.h>
 #include <sys/types.h>
-#include <dirent.h>
-
-#include <pwd.h>
+#include <unistd.h>
 
 #include <cutils/sched_policy.h>
 
diff --git a/toolbox/pwcache.c b/toolbox/pwcache.c
deleted file mode 100644
index 9d81981..0000000
--- a/toolbox/pwcache.c
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (C) 2014, The Android Open Source Project
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *  * Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *  * 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 COPYRIGHT HOLDERS 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
- * COPYRIGHT OWNER 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 <grp.h>
-#include <pwd.h>
-#include <stdio.h>
-#include <sys/types.h>
-
-int uid_from_user(const char* name, uid_t* uid) {
-  struct passwd* pw = getpwnam(name);
-  if (pw == NULL) {
-    return -1;
-  }
-  *uid = pw->pw_uid;
-  return 0;
-}
-
-char* group_from_gid(gid_t gid, int noname) {
-  struct group* g = getgrgid(gid);
-  if (g == NULL) {
-    static char buf[32];
-    snprintf(buf, sizeof(buf), "%lu", (long) gid);
-    return noname ? NULL : buf;
-  }
-  return g->gr_name;
-}
-
-char* user_from_uid(uid_t uid, int noname) {
-  struct passwd* pw = getpwuid(uid);
-  if (pw == NULL) {
-    static char buf[32];
-    snprintf(buf, sizeof(buf), "%lu", (long) uid);
-    return noname ? NULL : buf;
-  }
-  return pw->pw_name;
-}
diff --git a/toolbox/r.c b/toolbox/r.c
index 6183677..b96cdb2 100644
--- a/toolbox/r.c
+++ b/toolbox/r.c
@@ -5,6 +5,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <sys/mman.h>
+#include <unistd.h>
 
 #if __LP64__
 #define strtoptr strtoull
diff --git a/toolbox/sendevent.c b/toolbox/sendevent.c
index 4b5a761..4d0ca17 100644
--- a/toolbox/sendevent.c
+++ b/toolbox/sendevent.c
@@ -6,6 +6,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <sys/ioctl.h>
+#include <unistd.h>
 
 int sendevent_main(int argc, char *argv[])
 {
diff --git a/toolbox/setenforce.c b/toolbox/setenforce.c
deleted file mode 100644
index 444073d..0000000
--- a/toolbox/setenforce.c
+++ /dev/null
@@ -1,44 +0,0 @@
-#include <unistd.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <ctype.h>
-#include <string.h>
-#include <strings.h>
-#include <errno.h>
-#include <selinux/selinux.h>
-
-static void usage(const char *progname)
-{
-    fprintf(stderr, "usage:  %s [ Enforcing | Permissive | 1 | 0 ]\n",
-            progname);
-    exit(1);
-}
-
-int setenforce_main(int argc, char **argv)
-{
-    int rc = 0;
-    if (argc != 2) {
-        usage(argv[0]);
-    }
-
-    if (is_selinux_enabled() <= 0) {
-        fprintf(stderr, "%s: SELinux is disabled\n", argv[0]);
-        return 1;
-    }
-    if (strlen(argv[1]) == 1 && (argv[1][0] == '0' || argv[1][0] == '1')) {
-        rc = security_setenforce(atoi(argv[1]));
-    } else {
-        if (strcasecmp(argv[1], "enforcing") == 0) {
-            rc = security_setenforce(1);
-        } else if (strcasecmp(argv[1], "permissive") == 0) {
-            rc = security_setenforce(0);
-        } else
-            usage(argv[0]);
-    }
-    if (rc < 0) {
-        fprintf(stderr, "%s:  Could not set enforcing status:  %s\n",
-                argv[0], strerror(errno));
-        return 2;
-    }
-    return 0;
-}
diff --git a/toolbox/smd.c b/toolbox/smd.c
index 91e495c..343dea7 100644
--- a/toolbox/smd.c
+++ b/toolbox/smd.c
@@ -3,6 +3,7 @@
 #include <string.h>
 #include <fcntl.h>
 #include <errno.h>
+#include <unistd.h>
 
 int smd_main(int argc, char **argv)
 {
diff --git a/toolbox/touch.c b/toolbox/touch.c
index 52ddf2a..980f0d3 100644
--- a/toolbox/touch.c
+++ b/toolbox/touch.c
@@ -6,6 +6,7 @@
 #include <stdlib.h>
 #include <fcntl.h>
 #include <time.h>
+#include <unistd.h>
 
 static void usage(void)
 {
diff --git a/toolbox/upstream-netbsd/bin/cat/cat.c b/toolbox/upstream-netbsd/bin/cat/cat.c
deleted file mode 100644
index cca8cf5..0000000
--- a/toolbox/upstream-netbsd/bin/cat/cat.c
+++ /dev/null
@@ -1,329 +0,0 @@
-/* $NetBSD: cat.c,v 1.54 2013/12/08 08:32:13 spz Exp $	*/
-
-/*
- * Copyright (c) 1989, 1993
- *	The Regents of the University of California.  All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Kevin Fall.
- *
- * 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 HAVE_NBTOOL_CONFIG_H
-#include "nbtool_config.h"
-#endif
-
-#include <sys/cdefs.h>
-#if !defined(lint)
-__COPYRIGHT(
-"@(#) Copyright (c) 1989, 1993\
- The Regents of the University of California.  All rights reserved.");
-#if 0
-static char sccsid[] = "@(#)cat.c	8.2 (Berkeley) 4/27/95";
-#else
-__RCSID("$NetBSD: cat.c,v 1.54 2013/12/08 08:32:13 spz Exp $");
-#endif
-#endif /* not lint */
-
-#include <sys/param.h>
-#include <sys/stat.h>
-
-#include <ctype.h>
-#include <err.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <locale.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-static int bflag, eflag, fflag, lflag, nflag, sflag, tflag, vflag;
-static size_t bsize;
-static int rval;
-static const char *filename;
-
-void cook_args(char *argv[]);
-void cook_buf(FILE *);
-void raw_args(char *argv[]);
-void raw_cat(int);
-
-int
-main(int argc, char *argv[])
-{
-	int ch;
-	struct flock stdout_lock;
-
-	setprogname(argv[0]);
-	(void)setlocale(LC_ALL, "");
-
-	while ((ch = getopt(argc, argv, "B:beflnstuv")) != -1)
-		switch (ch) {
-		case 'B':
-			bsize = (size_t)strtol(optarg, NULL, 0);
-			break;
-		case 'b':
-			bflag = nflag = 1;	/* -b implies -n */
-			break;
-		case 'e':
-			eflag = vflag = 1;	/* -e implies -v */
-			break;
-		case 'f':
-			fflag = 1;
-			break;
-		case 'l':
-			lflag = 1;
-			break;
-		case 'n':
-			nflag = 1;
-			break;
-		case 's':
-			sflag = 1;
-			break;
-		case 't':
-			tflag = vflag = 1;	/* -t implies -v */
-			break;
-		case 'u':
-			setbuf(stdout, NULL);
-			break;
-		case 'v':
-			vflag = 1;
-			break;
-		default:
-		case '?':
-			(void)fprintf(stderr,
-			    "Usage: %s [-beflnstuv] [-B bsize] [-] "
-			    "[file ...]\n", getprogname());
-			return EXIT_FAILURE;
-		}
-	argv += optind;
-
-	if (lflag) {
-		stdout_lock.l_len = 0;
-		stdout_lock.l_start = 0;
-		stdout_lock.l_type = F_WRLCK;
-		stdout_lock.l_whence = SEEK_SET;
-		if (fcntl(STDOUT_FILENO, F_SETLKW, &stdout_lock) == -1)
-			err(EXIT_FAILURE, "stdout");
-	}
-
-	if (bflag || eflag || nflag || sflag || tflag || vflag)
-		cook_args(argv);
-	else
-		raw_args(argv);
-	if (fclose(stdout))
-		err(EXIT_FAILURE, "stdout");
-	return rval;
-}
-
-void
-cook_args(char **argv)
-{
-	FILE *fp;
-
-	fp = stdin;
-	filename = "stdin";
-	do {
-		if (*argv) {
-			if (!strcmp(*argv, "-"))
-				fp = stdin;
-			else if ((fp = fopen(*argv,
-			    fflag ? "rf" : "r")) == NULL) {
-				warn("%s", *argv);
-				rval = EXIT_FAILURE;
-				++argv;
-				continue;
-			}
-			filename = *argv++;
-		}
-		cook_buf(fp);
-		if (fp != stdin)
-			(void)fclose(fp);
-		else
-			clearerr(fp);
-	} while (*argv);
-}
-
-void
-cook_buf(FILE *fp)
-{
-	int ch, gobble, line, prev;
-
-	line = gobble = 0;
-	for (prev = '\n'; (ch = getc(fp)) != EOF; prev = ch) {
-		if (prev == '\n') {
-			if (ch == '\n') {
-				if (sflag) {
-					if (!gobble && nflag && !bflag)
-						(void)fprintf(stdout,
-							"%6d\t\n", ++line);
-					else if (!gobble && putchar(ch) == EOF)
-						break;
-					gobble = 1;
-					continue;
-				}
-				if (nflag) {
-					if (!bflag) {
-						(void)fprintf(stdout,
-						    "%6d\t", ++line);
-						if (ferror(stdout))
-							break;
-					} else if (eflag) {
-						(void)fprintf(stdout,
-						    "%6s\t", "");
-						if (ferror(stdout))
-							break;
-					}
-				}
-			} else if (nflag) {
-				(void)fprintf(stdout, "%6d\t", ++line);
-				if (ferror(stdout))
-					break;
-			}
-		}
-		gobble = 0;
-		if (ch == '\n') {
-			if (eflag)
-				if (putchar('$') == EOF)
-					break;
-		} else if (ch == '\t') {
-			if (tflag) {
-				if (putchar('^') == EOF || putchar('I') == EOF)
-					break;
-				continue;
-			}
-		} else if (vflag) {
-			if (!isascii(ch)) {
-				if (putchar('M') == EOF || putchar('-') == EOF)
-					break;
-				ch = toascii(ch);
-			}
-			if (iscntrl(ch)) {
-				if (putchar('^') == EOF ||
-				    putchar(ch == '\177' ? '?' :
-				    ch | 0100) == EOF)
-					break;
-				continue;
-			}
-		}
-		if (putchar(ch) == EOF)
-			break;
-	}
-	if (ferror(fp)) {
-		warn("%s", filename);
-		rval = EXIT_FAILURE;
-		clearerr(fp);
-	}
-	if (ferror(stdout))
-		err(EXIT_FAILURE, "stdout");
-}
-
-void
-raw_args(char **argv)
-{
-	int fd;
-
-	fd = fileno(stdin);
-	filename = "stdin";
-	do {
-		if (*argv) {
-			if (!strcmp(*argv, "-")) {
-				fd = fileno(stdin);
-				if (fd < 0)
-					goto skip;
-			} else if (fflag) {
-				struct stat st;
-				fd = open(*argv, O_RDONLY|O_NONBLOCK, 0);
-				if (fd < 0)
-					goto skip;
-
-				if (fstat(fd, &st) == -1) {
-					close(fd);
-					goto skip;
-				}
-				if (!S_ISREG(st.st_mode)) {
-					close(fd);
-					warnx("%s: not a regular file", *argv);
-					goto skipnomsg;
-				}
-			}
-			else if ((fd = open(*argv, O_RDONLY, 0)) < 0) {
-skip:
-				warn("%s", *argv);
-skipnomsg:
-				rval = EXIT_FAILURE;
-				++argv;
-				continue;
-			}
-			filename = *argv++;
-		} else if (fd < 0) {
-			err(EXIT_FAILURE, "stdin");
-		}
-		raw_cat(fd);
-		if (fd != fileno(stdin))
-			(void)close(fd);
-	} while (*argv);
-}
-
-void
-raw_cat(int rfd)
-{
-	static char *buf;
-	static char fb_buf[BUFSIZ];
-
-	ssize_t nr, nw, off;
-	int wfd;
-
-	wfd = fileno(stdout);
-	if (wfd < 0)
-		err(EXIT_FAILURE, "stdout");
-	if (buf == NULL) {
-		struct stat sbuf;
-
-		if (bsize == 0) {
-			if (fstat(wfd, &sbuf) == 0 && sbuf.st_blksize > 0 &&
-			    (size_t)sbuf.st_blksize > sizeof(fb_buf))
-				bsize = sbuf.st_blksize;
-		}
-		if (bsize > sizeof(fb_buf)) {
-			buf = malloc(bsize);
-			if (buf == NULL)
-				warnx("malloc, using %zu buffer", bsize);
-		}
-		if (buf == NULL) {
-			bsize = sizeof(fb_buf);
-			buf = fb_buf;
-		}
-	}
-	while ((nr = read(rfd, buf, bsize)) > 0)
-		for (off = 0; nr; nr -= nw, off += nw)
-			if ((nw = write(wfd, buf + off, (size_t)nr)) < 0)
-				err(EXIT_FAILURE, "stdout");
-	if (nr < 0) {
-		warn("%s", filename);
-		rval = EXIT_FAILURE;
-	}
-}
diff --git a/toolbox/upstream-netbsd/bin/cp/cp.c b/toolbox/upstream-netbsd/bin/cp/cp.c
deleted file mode 100644
index 4bbe1b7..0000000
--- a/toolbox/upstream-netbsd/bin/cp/cp.c
+++ /dev/null
@@ -1,548 +0,0 @@
-/* $NetBSD: cp.c,v 1.58 2012/01/04 15:58:37 christos Exp $ */
-
-/*
- * Copyright (c) 1988, 1993, 1994
- *	The Regents of the University of California.  All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * David Hitz of Auspex Systems 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.
- */
-
-#include <sys/cdefs.h>
-#ifndef lint
-__COPYRIGHT(
-"@(#) Copyright (c) 1988, 1993, 1994\
- The Regents of the University of California.  All rights reserved.");
-#endif /* not lint */
-
-#ifndef lint
-#if 0
-static char sccsid[] = "@(#)cp.c	8.5 (Berkeley) 4/29/95";
-#else
-__RCSID("$NetBSD: cp.c,v 1.58 2012/01/04 15:58:37 christos Exp $");
-#endif
-#endif /* not lint */
-
-/*
- * Cp copies source files to target files.
- * 
- * The global PATH_T structure "to" always contains the path to the
- * current target file.  Since fts(3) does not change directories,
- * this path can be either absolute or dot-relative.
- * 
- * The basic algorithm is to initialize "to" and use fts(3) to traverse
- * the file hierarchy rooted in the argument list.  A trivial case is the
- * case of 'cp file1 file2'.  The more interesting case is the case of
- * 'cp file1 file2 ... fileN dir' where the hierarchy is traversed and the
- * path (relative to the root of the traversal) is appended to dir (stored
- * in "to") to form the final target path.
- */
-
-#include <sys/param.h>
-#include <sys/stat.h>
-
-#include <assert.h>
-#include <err.h>
-#include <errno.h>
-#include <fts.h>
-#include <locale.h>
-#include <signal.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-
-#include "extern.h"
-
-#define	STRIP_TRAILING_SLASH(p) {					\
-        while ((p).p_end > (p).p_path + 1 && (p).p_end[-1] == '/')	\
-                *--(p).p_end = '\0';					\
-}
-
-static char empty[] = "";
-PATH_T to = { .p_end = to.p_path, .target_end = empty  };
-
-uid_t myuid;
-int Hflag, Lflag, Rflag, Pflag, fflag, iflag, lflag, pflag, rflag, vflag, Nflag;
-mode_t myumask;
-sig_atomic_t pinfo;
-
-enum op { FILE_TO_FILE, FILE_TO_DIR, DIR_TO_DNE };
-
-static int copy(char *[], enum op, int);
-
-static void
-progress(int sig __unused)
-{
-
-	pinfo++;
-}
-
-int
-main(int argc, char *argv[])
-{
-	struct stat to_stat, tmp_stat;
-	enum op type;
-	int ch, fts_options, r, have_trailing_slash;
-	char *target, **src;
-
-	setprogname(argv[0]);
-	(void)setlocale(LC_ALL, "");
-
-	Hflag = Lflag = Pflag = Rflag = 0;
-	while ((ch = getopt(argc, argv, "HLNPRfailprv")) != -1) 
-		switch (ch) {
-		case 'H':
-			Hflag = 1;
-			Lflag = Pflag = 0;
-			break;
-		case 'L':
-			Lflag = 1;
-			Hflag = Pflag = 0;
-			break;
-		case 'N':
-			Nflag = 1;
-			break;
-		case 'P':
-			Pflag = 1;
-			Hflag = Lflag = 0;
-			break;
-		case 'R':
-			Rflag = 1;
-			break;
-		case 'a':
-			Pflag = 1;
-			pflag = 1;
-			Rflag = 1;
-			Hflag = Lflag = 0;
-			break;
-		case 'f':
-			fflag = 1;
-			iflag = 0;
-			break;
-		case 'i':
-			iflag = isatty(fileno(stdin));
-			fflag = 0;
-			break;
-		case 'l':
-			lflag = 1;
-			break;
-		case 'p':
-			pflag = 1;
-			break;
-		case 'r':
-			rflag = 1;
-			break;
-		case 'v':
-			vflag = 1;
-			break;
-		case '?':
-		default:
-			usage();
-			/* NOTREACHED */
-		}
-	argc -= optind;
-	argv += optind;
-
-	if (argc < 2)
-		usage();
-
-	fts_options = FTS_NOCHDIR | FTS_PHYSICAL;
-	if (rflag) {
-		if (Rflag) {
-			errx(EXIT_FAILURE,
-		    "the -R and -r options may not be specified together.");
-			/* NOTREACHED */
-		}
-		if (Hflag || Lflag || Pflag) {
-			errx(EXIT_FAILURE,
-	"the -H, -L, and -P options may not be specified with the -r option.");
-			/* NOTREACHED */
-		}
-		fts_options &= ~FTS_PHYSICAL;
-		fts_options |= FTS_LOGICAL;
-	}
-
-	if (Rflag) {
-		if (Hflag)
-			fts_options |= FTS_COMFOLLOW;
-		if (Lflag) {
-			fts_options &= ~FTS_PHYSICAL;
-			fts_options |= FTS_LOGICAL;
-		}
-	} else if (!Pflag) {
-		fts_options &= ~FTS_PHYSICAL;
-		fts_options |= FTS_LOGICAL | FTS_COMFOLLOW;
-	}
-
-	myuid = getuid();
-
-	/* Copy the umask for explicit mode setting. */
-	myumask = umask(0);
-	(void)umask(myumask);
-
-	/* Save the target base in "to". */
-	target = argv[--argc];
-	if (strlcpy(to.p_path, target, sizeof(to.p_path)) >= sizeof(to.p_path))
-		errx(EXIT_FAILURE, "%s: name too long", target);
-	to.p_end = to.p_path + strlen(to.p_path);
-	have_trailing_slash = (to.p_end[-1] == '/');
-	if (have_trailing_slash)
-		STRIP_TRAILING_SLASH(to);
-	to.target_end = to.p_end;
-
-	/* Set end of argument list for fts(3). */
-	argv[argc] = NULL;     
-	
-	(void)signal(SIGINFO, progress);
-	
-	/*
-	 * Cp has two distinct cases:
-	 *
-	 * cp [-R] source target
-	 * cp [-R] source1 ... sourceN directory
-	 *
-	 * In both cases, source can be either a file or a directory.
-	 *
-	 * In (1), the target becomes a copy of the source. That is, if the
-	 * source is a file, the target will be a file, and likewise for
-	 * directories.
-	 *
-	 * In (2), the real target is not directory, but "directory/source".
-	 */
-	if (Pflag)
-		r = lstat(to.p_path, &to_stat);
-	else
-		r = stat(to.p_path, &to_stat);
-	if (r == -1 && errno != ENOENT) {
-		err(EXIT_FAILURE, "%s", to.p_path);
-		/* NOTREACHED */
-	}
-	if (r == -1 || !S_ISDIR(to_stat.st_mode)) {
-		/*
-		 * Case (1).  Target is not a directory.
-		 */ 
-		if (argc > 1)
-			usage();
-		/*
-		 * Need to detect the case:
-		 *	cp -R dir foo
-		 * Where dir is a directory and foo does not exist, where
-		 * we want pathname concatenations turned on but not for
-		 * the initial mkdir().
-		 */
-		if (r == -1) {
-			if (rflag || (Rflag && (Lflag || Hflag)))
-				r = stat(*argv, &tmp_stat);
-			else
-				r = lstat(*argv, &tmp_stat);
-			if (r == -1) {
-				err(EXIT_FAILURE, "%s", *argv);
-				/* NOTREACHED */
-			}
-			
-			if (S_ISDIR(tmp_stat.st_mode) && (Rflag || rflag))
-				type = DIR_TO_DNE;
-			else
-				type = FILE_TO_FILE;
-		} else
-			type = FILE_TO_FILE;
-
-		if (have_trailing_slash && type == FILE_TO_FILE) {
-			if (r == -1)
-				errx(1, "directory %s does not exist",
-				     to.p_path);
-			else
-				errx(1, "%s is not a directory", to.p_path);
-		}
-	} else {
-		/*
-		 * Case (2).  Target is a directory.
-		 */
-		type = FILE_TO_DIR;
-	}
-
-	/*
-	 * make "cp -rp src/ dst" behave like "cp -rp src dst" not
-	 * like "cp -rp src/. dst"
-	 */
-	for (src = argv; *src; src++) {
-		size_t len = strlen(*src);
-		while (len-- > 1 && (*src)[len] == '/')
-			(*src)[len] = '\0';
-	}
-
-	exit(copy(argv, type, fts_options));
-	/* NOTREACHED */
-}
-
-static int dnestack[MAXPATHLEN]; /* unlikely we'll have more nested dirs */
-static ssize_t dnesp;
-static void
-pushdne(int dne)
-{
-
-	dnestack[dnesp++] = dne;
-	assert(dnesp < MAXPATHLEN);
-}
-
-static int
-popdne(void)
-{
-	int rv;
-
-	rv = dnestack[--dnesp];
-	assert(dnesp >= 0);
-	return rv;
-}
-
-static int
-copy(char *argv[], enum op type, int fts_options)
-{
-	struct stat to_stat;
-	FTS *ftsp;
-	FTSENT *curr;
-	int base, dne, sval;
-	int this_failed, any_failed;
-	size_t nlen;
-	char *p, *target_mid;
-
-	base = 0;	/* XXX gcc -Wuninitialized (see comment below) */
-
-	if ((ftsp = fts_open(argv, fts_options, NULL)) == NULL)
-		err(EXIT_FAILURE, "%s", argv[0]);
-		/* NOTREACHED */
-	for (any_failed = 0; (curr = fts_read(ftsp)) != NULL;) {
-		this_failed = 0;
-		switch (curr->fts_info) {
-		case FTS_NS:
-		case FTS_DNR:
-		case FTS_ERR:
-			warnx("%s: %s", curr->fts_path,
-					strerror(curr->fts_errno));
-			this_failed = any_failed = 1;
-			continue;
-		case FTS_DC:			/* Warn, continue. */
-			warnx("%s: directory causes a cycle", curr->fts_path);
-			this_failed = any_failed = 1;
-			continue;
-		}
-
-		/*
-		 * If we are in case (2) or (3) above, we need to append the 
-                 * source name to the target name.  
-                 */
-		if (type != FILE_TO_FILE) {
-			if ((curr->fts_namelen +
-			    to.target_end - to.p_path + 1) > MAXPATHLEN) {
-				warnx("%s/%s: name too long (not copied)",
-						to.p_path, curr->fts_name);
-				this_failed = any_failed = 1;
-				continue;
-			}
-
-			/*
-			 * Need to remember the roots of traversals to create
-			 * correct pathnames.  If there's a directory being
-			 * copied to a non-existent directory, e.g.
-			 *	cp -R a/dir noexist
-			 * the resulting path name should be noexist/foo, not
-			 * noexist/dir/foo (where foo is a file in dir), which
-			 * is the case where the target exists.
-			 *
-			 * Also, check for "..".  This is for correct path
-			 * concatentation for paths ending in "..", e.g.
-			 *	cp -R .. /tmp
-			 * Paths ending in ".." are changed to ".".  This is
-			 * tricky, but seems the easiest way to fix the problem.
-			 *
-			 * XXX
-			 * Since the first level MUST be FTS_ROOTLEVEL, base
-			 * is always initialized.
-			 */
-			if (curr->fts_level == FTS_ROOTLEVEL) {
-				if (type != DIR_TO_DNE) {
-					p = strrchr(curr->fts_path, '/');
-					base = (p == NULL) ? 0 : 
-					    (int)(p - curr->fts_path + 1);
-
-					if (!strcmp(&curr->fts_path[base], 
-					    ".."))
-						base += 1;
-				} else
-					base = curr->fts_pathlen;
-			}
-
-			p = &curr->fts_path[base];
-			nlen = curr->fts_pathlen - base;
-			target_mid = to.target_end;
-			if (*p != '/' && target_mid[-1] != '/')
-				*target_mid++ = '/';
-			*target_mid = 0;
-
-			if (target_mid - to.p_path + nlen >= PATH_MAX) {
-				warnx("%s%s: name too long (not copied)",
-				    to.p_path, p);
-				this_failed = any_failed = 1;
-				continue;
-			}
-			(void)strncat(target_mid, p, nlen);
-			to.p_end = target_mid + nlen;
-			*to.p_end = 0;
-			STRIP_TRAILING_SLASH(to);
-		}
-
-		sval = Pflag ? lstat(to.p_path, &to_stat) : stat(to.p_path, &to_stat);
-		/* Not an error but need to remember it happened */
-		if (sval == -1)
-			dne = 1;
-		else {
-			if (to_stat.st_dev == curr->fts_statp->st_dev &&
-			    to_stat.st_ino == curr->fts_statp->st_ino) {
-				warnx("%s and %s are identical (not copied).",
-				    to.p_path, curr->fts_path);
-				this_failed = any_failed = 1;
-				if (S_ISDIR(curr->fts_statp->st_mode))
-					(void)fts_set(ftsp, curr, FTS_SKIP);
-				continue;
-			}
-			if (!S_ISDIR(curr->fts_statp->st_mode) &&
-			    S_ISDIR(to_stat.st_mode)) {
-		warnx("cannot overwrite directory %s with non-directory %s",
-				    to.p_path, curr->fts_path);
-				this_failed = any_failed = 1;
-				continue;
-			}
-			dne = 0;
-		}
-
-		switch (curr->fts_statp->st_mode & S_IFMT) {
-		case S_IFLNK:
-			/* Catch special case of a non dangling symlink */
-			if((fts_options & FTS_LOGICAL) ||
-			   ((fts_options & FTS_COMFOLLOW) && curr->fts_level == 0)) {
-				if (copy_file(curr, dne))
-					this_failed = any_failed = 1;
-			} else {	
-				if (copy_link(curr, !dne))
-					this_failed = any_failed = 1;
-			}
-			break;
-		case S_IFDIR:
-			if (!Rflag && !rflag) {
-				if (curr->fts_info == FTS_D)
-					warnx("%s is a directory (not copied).",
-					    curr->fts_path);
-				(void)fts_set(ftsp, curr, FTS_SKIP);
-				this_failed = any_failed = 1;
-				break;
-			}
-
-                        /*
-                         * Directories get noticed twice:
-                         *  In the first pass, create it if needed.
-                         *  In the second pass, after the children have been copied, set the permissions.
-                         */
-			if (curr->fts_info == FTS_D) /* First pass */
-			{
-				/*
-				 * If the directory doesn't exist, create the new
-				 * one with the from file mode plus owner RWX bits,
-				 * modified by the umask.  Trade-off between being
-				 * able to write the directory (if from directory is
-				 * 555) and not causing a permissions race.  If the
-				 * umask blocks owner writes, we fail..
-				 */
-				pushdne(dne);
-				if (dne) {
-					if (mkdir(to.p_path, 
-					    curr->fts_statp->st_mode | S_IRWXU) < 0)
-						err(EXIT_FAILURE, "%s",
-						    to.p_path);
-						/* NOTREACHED */
-				} else if (!S_ISDIR(to_stat.st_mode)) {
-					errno = ENOTDIR;
-					err(EXIT_FAILURE, "%s",
-						to.p_path);
-					/* NOTREACHED */
-				}
-			}
-			else if (curr->fts_info == FTS_DP) /* Second pass */
-			{
-	                        /*
-				 * If not -p and directory didn't exist, set it to be
-				 * the same as the from directory, umodified by the 
-                        	 * umask; arguably wrong, but it's been that way 
-                        	 * forever.
-				 */
-				if (pflag && setfile(curr->fts_statp, 0))
-					this_failed = any_failed = 1;
-				else if ((dne = popdne()))
-					(void)chmod(to.p_path, 
-					    curr->fts_statp->st_mode);
-			}
-			else
-			{
-				warnx("directory %s encountered when not expected.",
-				    curr->fts_path);
-				this_failed = any_failed = 1;
-				break;
-			}
-
-			break;
-		case S_IFBLK:
-		case S_IFCHR:
-			if (Rflag) {
-				if (copy_special(curr->fts_statp, !dne))
-					this_failed = any_failed = 1;
-			} else
-				if (copy_file(curr, dne))
-					this_failed = any_failed = 1;
-			break;
-		case S_IFIFO:
-			if (Rflag) {
-				if (copy_fifo(curr->fts_statp, !dne))
-					this_failed = any_failed = 1;
-			} else 
-				if (copy_file(curr, dne))
-					this_failed = any_failed = 1;
-			break;
-		default:
-			if (copy_file(curr, dne))
-				this_failed = any_failed = 1;
-			break;
-		}
-		if (vflag && !this_failed)
-			(void)printf("%s -> %s\n", curr->fts_path, to.p_path);
-	}
-	if (errno) {
-		err(EXIT_FAILURE, "fts_read");
-		/* NOTREACHED */
-	}
-	(void)fts_close(ftsp);
-	return (any_failed);
-}
diff --git a/toolbox/upstream-netbsd/bin/cp/extern.h b/toolbox/upstream-netbsd/bin/cp/extern.h
deleted file mode 100644
index e393844..0000000
--- a/toolbox/upstream-netbsd/bin/cp/extern.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/* $NetBSD: extern.h,v 1.17 2012/01/04 15:58:37 christos Exp $ */
-
-/*-
- * Copyright (c) 1991, 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.
- *
- *	@(#)extern.h	8.2 (Berkeley) 4/1/94
- */
-
-#ifndef _EXTERN_H_
-#define _EXTERN_H_
-
-typedef struct {
-	char *p_end;			/* pointer to NULL at end of path */
-	char *target_end;		/* pointer to end of target base */
-	char p_path[MAXPATHLEN + 1];	/* pointer to the start of a path */
-} PATH_T;
-
-extern PATH_T to;
-extern uid_t myuid;
-extern int Rflag, rflag, Hflag, Lflag, Pflag, fflag, iflag, lflag, pflag, Nflag;
-extern mode_t myumask;
-extern sig_atomic_t pinfo;
-
-#include <sys/cdefs.h>
-
-__BEGIN_DECLS
-int	copy_fifo(struct stat *, int);
-int	copy_file(FTSENT *, int);
-int	copy_link(FTSENT *, int);
-int	copy_special(struct stat *, int);
-int	set_utimes(const char *, struct stat *);
-int	setfile(struct stat *, int);
-void	usage(void) __attribute__((__noreturn__));
-__END_DECLS
-
-#endif /* !_EXTERN_H_ */
diff --git a/toolbox/upstream-netbsd/bin/cp/utils.c b/toolbox/upstream-netbsd/bin/cp/utils.c
deleted file mode 100644
index d8f900a..0000000
--- a/toolbox/upstream-netbsd/bin/cp/utils.c
+++ /dev/null
@@ -1,444 +0,0 @@
-/* $NetBSD: utils.c,v 1.42 2013/12/11 06:00:11 dholland Exp $ */
-
-/*-
- * Copyright (c) 1991, 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.
- */
-
-#include <sys/cdefs.h>
-#ifndef lint
-#if 0
-static char sccsid[] = "@(#)utils.c	8.3 (Berkeley) 4/1/94";
-#else
-__RCSID("$NetBSD: utils.c,v 1.42 2013/12/11 06:00:11 dholland Exp $");
-#endif
-#endif /* not lint */
-
-#include <sys/mman.h>
-#include <sys/param.h>
-#include <sys/stat.h>
-#include <sys/time.h>
-#include <sys/extattr.h>
-
-#include <err.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <fts.h>
-#include <stdbool.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include "extern.h"
-
-#define	MMAP_MAX_SIZE	(8 * 1048576)
-#define	MMAP_MAX_WRITE	(64 * 1024)
-
-int
-set_utimes(const char *file, struct stat *fs)
-{
-    static struct timeval tv[2];
-
-#ifdef __ANDROID__
-    tv[0].tv_sec = fs->st_atime;
-    tv[0].tv_usec = 0;
-    tv[1].tv_sec = fs->st_mtime;
-    tv[1].tv_usec = 0;
-
-    if (utimes(file, tv)) {
-        warn("utimes: %s", file);
-        return 1;
-    }
-#else
-    TIMESPEC_TO_TIMEVAL(&tv[0], &fs->st_atimespec);
-    TIMESPEC_TO_TIMEVAL(&tv[1], &fs->st_mtimespec);
-
-    if (lutimes(file, tv)) {
-	warn("lutimes: %s", file);
-	return (1);
-    }
-#endif
-    return (0);
-}
-
-struct finfo {
-	const char *from;
-	const char *to;
-	size_t size;
-};
-
-static void
-progress(const struct finfo *fi, size_t written)
-{
-	int pcent = (int)((100.0 * written) / fi->size);
-
-	pinfo = 0;
-	(void)fprintf(stderr, "%s => %s %zu/%zu bytes %d%% written\n",
-	    fi->from, fi->to, written, fi->size, pcent);
-}
-
-int
-copy_file(FTSENT *entp, int dne)
-{
-	static char buf[MAXBSIZE];
-	struct stat to_stat, *fs;
-	int ch, checkch, from_fd, rcount, rval, to_fd, tolnk, wcount;
-	char *p;
-	size_t ptotal = 0;
-	
-	if ((from_fd = open(entp->fts_path, O_RDONLY, 0)) == -1) {
-		warn("%s", entp->fts_path);
-		return (1);
-	}
-
-	to_fd = -1;
-	fs = entp->fts_statp;
-	tolnk = ((Rflag && !(Lflag || Hflag)) || Pflag);
-
-	/*
-	 * If the file exists and we're interactive, verify with the user.
-	 * If the file DNE, set the mode to be the from file, minus setuid
-	 * bits, modified by the umask; arguably wrong, but it makes copying
-	 * executables work right and it's been that way forever.  (The
-	 * other choice is 666 or'ed with the execute bits on the from file
-	 * modified by the umask.)
-	 */
-	if (!dne) {
-		struct stat sb;
-		int sval;
-
-		if (iflag) {
-			(void)fprintf(stderr, "overwrite %s? ", to.p_path);
-			checkch = ch = getchar();
-			while (ch != '\n' && ch != EOF)
-				ch = getchar();
-			if (checkch != 'y' && checkch != 'Y') {
-				(void)close(from_fd);
-				return (0);
-			}
-		}
-
-		sval = tolnk ?
-			lstat(to.p_path, &sb) : stat(to.p_path, &sb);
-		if (sval == -1) {
-			warn("stat: %s", to.p_path);
-			(void)close(from_fd);
-			return (1);
-		}
-
-		if (!(tolnk && S_ISLNK(sb.st_mode)))
-			to_fd = open(to.p_path, O_WRONLY | O_TRUNC, 0);
-	} else
-		to_fd = open(to.p_path, O_WRONLY | O_TRUNC | O_CREAT,
-		    fs->st_mode & ~(S_ISUID | S_ISGID));
-
-	if (to_fd == -1 && (fflag || tolnk)) {
-		/*
-		 * attempt to remove existing destination file name and
-		 * create a new file
-		 */
-		(void)unlink(to.p_path);
-		to_fd = open(to.p_path, O_WRONLY | O_TRUNC | O_CREAT,
-			     fs->st_mode & ~(S_ISUID | S_ISGID));
-	}
-
-	if (to_fd == -1) {
-		warn("%s", to.p_path);
-		(void)close(from_fd);
-		return (1);
-	}
-
-	rval = 0;
-
-	/* if hard linking then simply close the open fds, link and return */
-	if (lflag) {
-		(void)close(from_fd);
-		(void)close(to_fd);
-		(void)unlink(to.p_path);
-		if (link(entp->fts_path, to.p_path)) {
-			warn("%s", to.p_path);
-			return (1);
-		}
-		return (0);
-	}
-
-	/*
-	 * There's no reason to do anything other than close the file
-	 * now if it's empty, so let's not bother.
-	 */
-#ifndef __ANDROID__ // Files in /proc report length 0. mmap will fail but we'll fall back to read.
-	if (fs->st_size > 0) {
-#endif
-		struct finfo fi;
-
-		fi.from = entp->fts_path;
-		fi.to = to.p_path;
-		fi.size = (size_t)fs->st_size;
-
-		/*
-		 * Mmap and write if less than 8M (the limit is so
-		 * we don't totally trash memory on big files).
-		 * This is really a minor hack, but it wins some CPU back.
-		 */
-		bool use_read;
-
-		use_read = true;
-		if (fs->st_size <= MMAP_MAX_SIZE) {
-			size_t fsize = (size_t)fs->st_size;
-			p = mmap(NULL, fsize, PROT_READ, MAP_FILE|MAP_SHARED,
-			    from_fd, (off_t)0);
-			if (p != MAP_FAILED) {
-				size_t remainder;
-
-				use_read = false;
-
-				(void) madvise(p, (size_t)fs->st_size,
-				     MADV_SEQUENTIAL);
-
-				/*
-				 * Write out the data in small chunks to
-				 * avoid locking the output file for a
-				 * long time if the reading the data from
-				 * the source is slow.
-				 */
-				remainder = fsize;
-				do {
-					ssize_t chunk;
-
-					chunk = (remainder > MMAP_MAX_WRITE) ?
-					    MMAP_MAX_WRITE : remainder;
-					if (write(to_fd, &p[fsize - remainder],
-					    chunk) != chunk) {
-						warn("%s", to.p_path);
-						rval = 1;
-						break;
-					}
-					remainder -= chunk;
-					ptotal += chunk;
-					if (pinfo)
-						progress(&fi, ptotal);
-				} while (remainder > 0);
-
-				if (munmap(p, fsize) < 0) {
-					warn("%s", entp->fts_path);
-					rval = 1;
-				}
-			}
-		}
-
-		if (use_read) {
-			while ((rcount = read(from_fd, buf, MAXBSIZE)) > 0) {
-				wcount = write(to_fd, buf, (size_t)rcount);
-				if (rcount != wcount || wcount == -1) {
-					warn("%s", to.p_path);
-					rval = 1;
-					break;
-				}
-				ptotal += wcount;
-				if (pinfo)
-					progress(&fi, ptotal);
-			}
-			if (rcount < 0) {
-				warn("%s", entp->fts_path);
-				rval = 1;
-			}
-		}
-#ifndef __ANDROID__
-	}
-#endif
-
-#ifndef __ANDROID__
-	if (pflag && (fcpxattr(from_fd, to_fd) != 0))
-		warn("%s: error copying extended attributes", to.p_path);
-#endif
-
-	(void)close(from_fd);
-
-	if (rval == 1) {
-		(void)close(to_fd);
-		return (1);
-	}
-
-	if (pflag && setfile(fs, to_fd))
-		rval = 1;
-	/*
-	 * If the source was setuid or setgid, lose the bits unless the
-	 * copy is owned by the same user and group.
-	 */
-#define	RETAINBITS \
-	(S_ISUID | S_ISGID | S_ISVTX | S_IRWXU | S_IRWXG | S_IRWXO)
-	if (!pflag && dne
-	    && fs->st_mode & (S_ISUID | S_ISGID) && fs->st_uid == myuid) {
-		if (fstat(to_fd, &to_stat)) {
-			warn("%s", to.p_path);
-			rval = 1;
-		} else if (fs->st_gid == to_stat.st_gid &&
-		    fchmod(to_fd, fs->st_mode & RETAINBITS & ~myumask)) {
-			warn("%s", to.p_path);
-			rval = 1;
-		}
-	}
-	if (close(to_fd)) {
-		warn("%s", to.p_path);
-		rval = 1;
-	}
-	/* set the mod/access times now after close of the fd */
-	if (pflag && set_utimes(to.p_path, fs)) { 
-	    rval = 1;
-	}
-	return (rval);
-}
-
-int
-copy_link(FTSENT *p, int exists)
-{
-	int len;
-	char target[MAXPATHLEN];
-
-	if ((len = readlink(p->fts_path, target, sizeof(target)-1)) == -1) {
-		warn("readlink: %s", p->fts_path);
-		return (1);
-	}
-	target[len] = '\0';
-	if (exists && unlink(to.p_path)) {
-		warn("unlink: %s", to.p_path);
-		return (1);
-	}
-	if (symlink(target, to.p_path)) {
-		warn("symlink: %s", target);
-		return (1);
-	}
-	return (pflag ? setfile(p->fts_statp, 0) : 0);
-}
-
-int
-copy_fifo(struct stat *from_stat, int exists)
-{
-	if (exists && unlink(to.p_path)) {
-		warn("unlink: %s", to.p_path);
-		return (1);
-	}
-	if (mkfifo(to.p_path, from_stat->st_mode)) {
-		warn("mkfifo: %s", to.p_path);
-		return (1);
-	}
-	return (pflag ? setfile(from_stat, 0) : 0);
-}
-
-int
-copy_special(struct stat *from_stat, int exists)
-{
-	if (exists && unlink(to.p_path)) {
-		warn("unlink: %s", to.p_path);
-		return (1);
-	}
-	if (mknod(to.p_path, from_stat->st_mode, from_stat->st_rdev)) {
-		warn("mknod: %s", to.p_path);
-		return (1);
-	}
-	return (pflag ? setfile(from_stat, 0) : 0);
-}
-
-
-/*
- * Function: setfile
- *
- * Purpose:
- *   Set the owner/group/permissions for the "to" file to the information
- *   in the stat structure.  If fd is zero, also call set_utimes() to set
- *   the mod/access times.  If fd is non-zero, the caller must do a utimes
- *   itself after close(fd).
- */
-int
-setfile(struct stat *fs, int fd)
-{
-	int rval, islink;
-
-	rval = 0;
-	islink = S_ISLNK(fs->st_mode);
-	fs->st_mode &= S_ISUID | S_ISGID | S_IRWXU | S_IRWXG | S_IRWXO;
-
-	/*
-	 * Changing the ownership probably won't succeed, unless we're root
-	 * or POSIX_CHOWN_RESTRICTED is not set.  Set uid/gid before setting
-	 * the mode; current BSD behavior is to remove all setuid bits on
-	 * chown.  If chown fails, lose setuid/setgid bits.
-	 */
-	if (fd ? fchown(fd, fs->st_uid, fs->st_gid) :
-	    lchown(to.p_path, fs->st_uid, fs->st_gid)) {
-		if (errno != EPERM) {
-			warn("chown: %s", to.p_path);
-			rval = 1;
-		}
-		fs->st_mode &= ~(S_ISUID | S_ISGID);
-	}
-#ifdef __ANDROID__
-	if (fd ? fchmod(fd, fs->st_mode) : chmod(to.p_path, fs->st_mode)) {
-#else
-	if (fd ? fchmod(fd, fs->st_mode) : lchmod(to.p_path, fs->st_mode)) {
-#endif
-		warn("chmod: %s", to.p_path);
-		rval = 1;
-	}
-
-#ifndef __ANDROID__
-	if (!islink && !Nflag) {
-		unsigned long fflags = fs->st_flags;
-		/*
-		 * XXX
-		 * NFS doesn't support chflags; ignore errors unless
-		 * there's reason to believe we're losing bits.
-		 * (Note, this still won't be right if the server
-		 * supports flags and we were trying to *remove* flags
-		 * on a file that we copied, i.e., that we didn't create.)
-		 */
-		errno = 0;
-		if ((fd ? fchflags(fd, fflags) :
-		    chflags(to.p_path, fflags)) == -1)
-			if (errno != EOPNOTSUPP || fs->st_flags != 0) {
-				warn("chflags: %s", to.p_path);
-				rval = 1;
-			}
-	}
-#endif
-	/* if fd is non-zero, caller must call set_utimes() after close() */
-	if (fd == 0 && set_utimes(to.p_path, fs))
-	    rval = 1;
-	return (rval);
-}
-
-void
-usage(void)
-{
-	(void)fprintf(stderr,
-	    "usage: %s [-R [-H | -L | -P]] [-f | -i] [-alNpv] src target\n"
-	    "       %s [-R [-H | -L | -P]] [-f | -i] [-alNpv] src1 ... srcN directory\n",
-	    getprogname(), getprogname());
-	exit(1);
-	/* NOTREACHED */
-}
diff --git a/toolbox/upstream-netbsd/bin/ln/ln.c b/toolbox/upstream-netbsd/bin/ln/ln.c
deleted file mode 100644
index 9127477..0000000
--- a/toolbox/upstream-netbsd/bin/ln/ln.c
+++ /dev/null
@@ -1,230 +0,0 @@
-/* $NetBSD: ln.c,v 1.35 2011/08/29 14:38:30 joerg Exp $ */
-
-/*
- * Copyright (c) 1987, 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.
- */
-
-#include <sys/cdefs.h>
-#ifndef lint
-__COPYRIGHT("@(#) Copyright (c) 1987, 1993, 1994\
- The Regents of the University of California.  All rights reserved.");
-#endif /* not lint */
-
-#ifndef lint
-#if 0
-static char sccsid[] = "@(#)ln.c	8.2 (Berkeley) 3/31/94";
-#else
-__RCSID("$NetBSD: ln.c,v 1.35 2011/08/29 14:38:30 joerg Exp $");
-#endif
-#endif /* not lint */
-
-#include <sys/param.h>
-#include <sys/stat.h>
-
-#include <err.h>
-#include <errno.h>
-#include <locale.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-static int	fflag;				/* Unlink existing files. */
-static int	hflag;				/* Check new name for symlink first. */
-static int	iflag;				/* Interactive mode. */
-static int	sflag;				/* Symbolic, not hard, link. */
-static int	vflag;                          /* Verbose output */
-
-					/* System link call. */
-static int (*linkf)(const char *, const char *);
-static char   linkch;
-
-static int	linkit(const char *, const char *, int);
-__dead static void	usage(void);
-
-int
-main(int argc, char *argv[])
-{
-	struct stat sb;
-	int ch, exitval;
-	char *sourcedir;
-
-	setprogname(argv[0]);
-	(void)setlocale(LC_ALL, "");
-
-	while ((ch = getopt(argc, argv, "fhinsv")) != -1)
-		switch (ch) {
-		case 'f':
-			fflag = 1;
-			iflag = 0;
-			break;
-		case 'h':
-		case 'n':
-			hflag = 1;
-			break;
-		case 'i':
-			iflag = 1;
-			fflag = 0;
-			break;
-		case 's':
-			sflag = 1;
-			break;
-		case 'v':               
-			vflag = 1;
-			break;
-		case '?':
-		default:
-			usage();
-			/* NOTREACHED */
-		}
-
-	argv += optind;
-	argc -= optind;
-
-	if (sflag) {
-		linkf  = symlink;
-		linkch = '-';
-	} else {
-		linkf  = link;
-		linkch = '=';
-	}
-
-	switch(argc) {
-	case 0:
-		usage();
-		/* NOTREACHED */
-	case 1:				/* ln target */
-		exit(linkit(argv[0], ".", 1));
-		/* NOTREACHED */
-	case 2:				/* ln target source */
-		exit(linkit(argv[0], argv[1], 0));
-		/* NOTREACHED */
-	}
-
-					/* ln target1 target2 directory */
-	sourcedir = argv[argc - 1];
-	if (hflag && lstat(sourcedir, &sb) == 0 && S_ISLNK(sb.st_mode)) {
-		/* we were asked not to follow symlinks, but found one at
-		   the target--simulate "not a directory" error */
-		errno = ENOTDIR;
-		err(EXIT_FAILURE, "%s", sourcedir);
-		/* NOTREACHED */
-	}
-	if (stat(sourcedir, &sb)) {
-		err(EXIT_FAILURE, "%s", sourcedir);
-		/* NOTREACHED */
-	}
-	if (!S_ISDIR(sb.st_mode)) {
-		usage();
-		/* NOTREACHED */
-	}
-	for (exitval = 0; *argv != sourcedir; ++argv)
-		exitval |= linkit(*argv, sourcedir, 1);
-	exit(exitval);
-	/* NOTREACHED */
-}
-
-static int
-linkit(const char *target, const char *source, int isdir)
-{
-	struct stat sb;
-	const char *p;
-	char path[MAXPATHLEN];
-	int ch, exists, first;
-
-	if (!sflag) {
-		/* If target doesn't exist, quit now. */
-		if (stat(target, &sb)) {
-			warn("%s", target);
-			return (1);
-		}
-	}
-
-	/* If the source is a directory (and not a symlink if hflag),
-	   append the target's name. */
-	if (isdir ||
-	    (!lstat(source, &sb) && S_ISDIR(sb.st_mode)) ||
-	    (!hflag && !stat(source, &sb) && S_ISDIR(sb.st_mode))) {
-		if ((p = strrchr(target, '/')) == NULL)
-			p = target;
-		else
-			++p;
-		(void)snprintf(path, sizeof(path), "%s/%s", source, p);
-		source = path;
-	}
-
-	exists = !lstat(source, &sb);
-
-	/*
-	 * If the file exists, then unlink it forcibly if -f was specified
-	 * and interactively if -i was specified.
-	 */
-	if (fflag && exists) {
-		if (unlink(source)) {
-			warn("%s", source);
-			return (1);
-		}
-	} else if (iflag && exists) {
-		fflush(stdout);
-		(void)fprintf(stderr, "replace %s? ", source);
-
-		first = ch = getchar();
-		while (ch != '\n' && ch != EOF)
-			ch = getchar();
-		if (first != 'y' && first != 'Y') {
-			(void)fprintf(stderr, "not replaced\n");
-			return (1);
-		}
-
-		if (unlink(source)) {
-			warn("%s", source);
-			return (1);
-		}
-	}
-
-	/* Attempt the link. */
-	if ((*linkf)(target, source)) {
-		warn("%s", source);
-		return (1);
-	}
-	if (vflag)
-		(void)printf("%s %c> %s\n", source, linkch, target);
-
-	return (0);
-}
-
-static void
-usage(void)
-{
-
-	(void)fprintf(stderr,
-	    "usage:\t%s [-fhinsv] file1 file2\n\t%s [-fhinsv] file ... directory\n",
-	    getprogname(), getprogname());
-	exit(1);
-	/* NOTREACHED */
-}
diff --git a/toolbox/upstream-netbsd/bin/mv/mv.c b/toolbox/upstream-netbsd/bin/mv/mv.c
deleted file mode 100644
index 4be6c30..0000000
--- a/toolbox/upstream-netbsd/bin/mv/mv.c
+++ /dev/null
@@ -1,396 +0,0 @@
-/* $NetBSD: mv.c,v 1.43 2011/08/29 14:46:54 joerg Exp $ */
-
-/*
- * 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
- * Ken Smith of The State University of New York at Buffalo.
- *
- * 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.
- */
-
-#include <sys/cdefs.h>
-#ifndef lint
-__COPYRIGHT("@(#) Copyright (c) 1989, 1993, 1994\
- The Regents of the University of California.  All rights reserved.");
-#endif /* not lint */
-
-#ifndef lint
-#if 0
-static char sccsid[] = "@(#)mv.c	8.2 (Berkeley) 4/2/94";
-#else
-__RCSID("$NetBSD: mv.c,v 1.43 2011/08/29 14:46:54 joerg Exp $");
-#endif
-#endif /* not lint */
-
-#include <sys/param.h>
-#include <sys/time.h>
-#include <sys/wait.h>
-#include <sys/stat.h>
-#include <sys/extattr.h>
-
-#include <err.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <grp.h>
-#include <locale.h>
-#include <pwd.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include "pathnames.h"
-
-static int fflg, iflg, vflg;
-static int stdin_ok;
-
-static int	copy(char *, char *);
-static int	do_move(char *, char *);
-static int	fastcopy(char *, char *, struct stat *);
-__dead static void	usage(void);
-
-int
-main(int argc, char *argv[])
-{
-	int ch, len, rval;
-	char *p, *endp;
-	struct stat sb;
-	char path[MAXPATHLEN + 1];
-	size_t baselen;
-
-	setprogname(argv[0]);
-	(void)setlocale(LC_ALL, "");
-
-	while ((ch = getopt(argc, argv, "ifv")) != -1)
-		switch (ch) {
-		case 'i':
-			fflg = 0;
-			iflg = 1;
-			break;
-		case 'f':
-			iflg = 0;
-			fflg = 1;
-			break;
-		case 'v':
-			vflg = 1;
-			break;
-		default:
-			usage();
-		}
-	argc -= optind;
-	argv += optind;
-
-	if (argc < 2)
-		usage();
-
-	stdin_ok = isatty(STDIN_FILENO);
-
-	/*
-	 * If the stat on the target fails or the target isn't a directory,
-	 * try the move.  More than 2 arguments is an error in this case.
-	 */
-	if (stat(argv[argc - 1], &sb) || !S_ISDIR(sb.st_mode)) {
-		if (argc > 2)
-			usage();
-		exit(do_move(argv[0], argv[1]));
-	}
-
-	/* It's a directory, move each file into it. */
-	baselen = strlcpy(path, argv[argc - 1], sizeof(path));
-	if (baselen >= sizeof(path))
-		errx(1, "%s: destination pathname too long", argv[argc - 1]);
-	endp = &path[baselen];
-	if (!baselen || *(endp - 1) != '/') {
-		*endp++ = '/';
-		++baselen;
-	}
-	for (rval = 0; --argc; ++argv) {
-		p = *argv + strlen(*argv) - 1;
-		while (*p == '/' && p != *argv)
-			*p-- = '\0';
-		if ((p = strrchr(*argv, '/')) == NULL)
-			p = *argv;
-		else
-			++p;
-
-		if ((baselen + (len = strlen(p))) >= MAXPATHLEN) {
-			warnx("%s: destination pathname too long", *argv);
-			rval = 1;
-		} else {
-			memmove(endp, p, len + 1);
-			if (do_move(*argv, path))
-				rval = 1;
-		}
-	}
-	exit(rval);
-	/* NOTREACHED */
-}
-
-static int
-do_move(char *from, char *to)
-{
-	struct stat sb;
-	char modep[15];
-
-	/*
-	 * (1)	If the destination path exists, the -f option is not specified
-	 *	and either of the following conditions are true:
-	 *
-	 *	(a) The permissions of the destination path do not permit
-	 *	    writing and the standard input is a terminal.
-	 *	(b) The -i option is specified.
-	 *
-	 *	the mv utility shall write a prompt to standard error and
-	 *	read a line from standard input.  If the response is not
-	 *	affirmative, mv shall do nothing more with the current
-	 *	source file...
-	 */
-	if (!fflg && !access(to, F_OK)) {
-		int ask = 1;
-		int ch;
-
-		if (iflg) {
-			if (access(from, F_OK)) {
-				warn("rename %s", from);
-				return (1);
-			}
-			(void)fprintf(stderr, "overwrite %s? ", to);
-		} else if (stdin_ok && access(to, W_OK) && !stat(to, &sb)) {
-			if (access(from, F_OK)) {
-				warn("rename %s", from);
-				return (1);
-			}
-			strmode(sb.st_mode, modep);
-			(void)fprintf(stderr, "override %s%s%s/%s for %s? ",
-			    modep + 1, modep[9] == ' ' ? "" : " ",
-			    user_from_uid(sb.st_uid, 0),
-			    group_from_gid(sb.st_gid, 0), to);
-		} else
-			ask = 0;
-		if (ask) {
-			if ((ch = getchar()) != EOF && ch != '\n') {
-				int ch2;
-				while ((ch2 = getchar()) != EOF && ch2 != '\n')
-					continue;
-			}
-			if (ch != 'y' && ch != 'Y')
-				return (0);
-		}
-	}
-
-	/*
-	 * (2)	If rename() succeeds, mv shall do nothing more with the
-	 *	current source file.  If it fails for any other reason than
-	 *	EXDEV, mv shall write a diagnostic message to the standard
-	 *	error and do nothing more with the current source file.
-	 *
-	 * (3)	If the destination path exists, and it is a file of type
-	 *	directory and source_file is not a file of type directory,
-	 *	or it is a file not of type directory, and source file is
-	 *	a file of type directory, mv shall write a diagnostic
-	 *	message to standard error, and do nothing more with the
-	 *	current source file...
-	 */
-	if (!rename(from, to)) {
-		if (vflg)
-			printf("%s -> %s\n", from, to);
-		return (0);
-	}
-
-	if (errno != EXDEV) {
-		warn("rename %s to %s", from, to);
-		return (1);
-	}
-
-	/*
-	 * (4)	If the destination path exists, mv shall attempt to remove it.
-	 *	If this fails for any reason, mv shall write a diagnostic
-	 *	message to the standard error and do nothing more with the
-	 *	current source file...
-	 */
-	if (!lstat(to, &sb)) {
-		if ((S_ISDIR(sb.st_mode)) ? rmdir(to) : unlink(to)) {
-			warn("can't remove %s", to);
-			return (1);
-		}
-	}
-
-	/*
-	 * (5)	The file hierarchy rooted in source_file shall be duplicated
-	 *	as a file hierarchy rooted in the destination path...
-	 */
-	if (lstat(from, &sb)) {
-		warn("%s", from);
-		return (1);
-	}
-
-	return (S_ISREG(sb.st_mode) ?
-	    fastcopy(from, to, &sb) : copy(from, to));
-}
-
-static int
-fastcopy(char *from, char *to, struct stat *sbp)
-{
-	struct timeval tval[2];
-	static blksize_t blen;
-	static char *bp;
-	int nread, from_fd, to_fd;
-
-	if ((from_fd = open(from, O_RDONLY, 0)) < 0) {
-		warn("%s", from);
-		return (1);
-	}
-	if ((to_fd =
-	    open(to, O_CREAT | O_TRUNC | O_WRONLY, sbp->st_mode)) < 0) {
-		warn("%s", to);
-		(void)close(from_fd);
-		return (1);
-	}
-	if (!blen && !(bp = malloc(blen = sbp->st_blksize))) {
-		warn(NULL);
-		blen = 0;
-		(void)close(from_fd);
-		(void)close(to_fd);
-		return (1);
-	}
-	while ((nread = read(from_fd, bp, blen)) > 0)
-		if (write(to_fd, bp, nread) != nread) {
-			warn("%s", to);
-			goto err;
-		}
-	if (nread < 0) {
-		warn("%s", from);
-err:		if (unlink(to))
-			warn("%s: remove", to);
-		(void)close(from_fd);
-		(void)close(to_fd);
-		return (1);
-	}
-
-#ifndef __ANDROID__
-	if (fcpxattr(from_fd, to_fd) == -1)
-		warn("%s: error copying extended attributes", to);
-#endif
-
-	(void)close(from_fd);
-#ifdef BSD4_4
-	TIMESPEC_TO_TIMEVAL(&tval[0], &sbp->st_atimespec);
-	TIMESPEC_TO_TIMEVAL(&tval[1], &sbp->st_mtimespec);
-#else
-	tval[0].tv_sec = sbp->st_atime;
-	tval[1].tv_sec = sbp->st_mtime;
-	tval[0].tv_usec = 0;
-	tval[1].tv_usec = 0;
-#endif
-#ifdef __SVR4
-	if (utimes(to, tval))
-#else
-	if (futimes(to_fd, tval))
-#endif
-		warn("%s: set times", to);
-	if (fchown(to_fd, sbp->st_uid, sbp->st_gid)) {
-		if (errno != EPERM)
-			warn("%s: set owner/group", to);
-		sbp->st_mode &= ~(S_ISUID | S_ISGID);
-	}
-	if (fchmod(to_fd, sbp->st_mode))
-		warn("%s: set mode", to);
-#ifndef __ANDROID__
-	if (fchflags(to_fd, sbp->st_flags) && (errno != EOPNOTSUPP))
-		warn("%s: set flags (was: 0%07o)", to, sbp->st_flags);
-#endif
-
-	if (close(to_fd)) {
-		warn("%s", to);
-		return (1);
-	}
-
-	if (unlink(from)) {
-		warn("%s: remove", from);
-		return (1);
-	}
-
-	if (vflg)
-		printf("%s -> %s\n", from, to);
-
-	return (0);
-}
-
-static int
-copy(char *from, char *to)
-{
-	pid_t pid;
-	int status;
-
-	if ((pid = vfork()) == 0) {
-		execl(_PATH_CP, "mv", vflg ? "-PRpv" : "-PRp", "--", from, to, NULL);
-		warn("%s", _PATH_CP);
-		_exit(1);
-	}
-	if (waitpid(pid, &status, 0) == -1) {
-		warn("%s: waitpid", _PATH_CP);
-		return (1);
-	}
-	if (!WIFEXITED(status)) {
-		warnx("%s: did not terminate normally", _PATH_CP);
-		return (1);
-	}
-	if (WEXITSTATUS(status)) {
-		warnx("%s: terminated with %d (non-zero) status",
-		    _PATH_CP, WEXITSTATUS(status));
-		return (1);
-	}
-	if (!(pid = vfork())) {
-		execl(_PATH_RM, "mv", "-rf", "--", from, NULL);
-		warn("%s", _PATH_RM);
-		_exit(1);
-	}
-	if (waitpid(pid, &status, 0) == -1) {
-		warn("%s: waitpid", _PATH_RM);
-		return (1);
-	}
-	if (!WIFEXITED(status)) {
-		warnx("%s: did not terminate normally", _PATH_RM);
-		return (1);
-	}
-	if (WEXITSTATUS(status)) {
-		warnx("%s: terminated with %d (non-zero) status",
-		    _PATH_RM, WEXITSTATUS(status));
-		return (1);
-	}
-	return (0);
-}
-
-static void
-usage(void)
-{
-	(void)fprintf(stderr, "usage: %s [-fiv] source target\n"
-	    "       %s [-fiv] source ... directory\n", getprogname(),
-	    getprogname());
-	exit(1);
-	/* NOTREACHED */
-}
diff --git a/toolbox/upstream-netbsd/bin/mv/pathnames.h b/toolbox/upstream-netbsd/bin/mv/pathnames.h
deleted file mode 100644
index 7838946..0000000
--- a/toolbox/upstream-netbsd/bin/mv/pathnames.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*	$NetBSD: pathnames.h,v 1.8 2004/08/19 22:26:07 christos Exp $	*/
-
-/*
- * 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.
- *
- *	@(#)pathnames.h	8.1 (Berkeley) 5/31/93
- */
-
-#ifdef __ANDROID__
-#define	_PATH_RM	"/system/bin/rm"
-#define	_PATH_CP	"/system/bin/cp"
-#else
-#ifdef RESCUEDIR
-#define	_PATH_RM	RESCUEDIR "/rm"
-#define	_PATH_CP	RESCUEDIR "/cp"
-#else
-#define	_PATH_RM	"/bin/rm"
-#define	_PATH_CP	"/bin/cp"
-#endif
-#endif
diff --git a/toolbox/upstream-netbsd/bin/rm/rm.c b/toolbox/upstream-netbsd/bin/rm/rm.c
deleted file mode 100644
index f183810..0000000
--- a/toolbox/upstream-netbsd/bin/rm/rm.c
+++ /dev/null
@@ -1,625 +0,0 @@
-/* $NetBSD: rm.c,v 1.53 2013/04/26 18:43:22 christos Exp $ */
-
-/*-
- * Copyright (c) 1990, 1993, 1994, 2003
- *	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.
- */
-
-#include <sys/cdefs.h>
-#ifndef lint
-__COPYRIGHT("@(#) Copyright (c) 1990, 1993, 1994\
- The Regents of the University of California.  All rights reserved.");
-#endif /* not lint */
-
-#ifndef lint
-#if 0
-static char sccsid[] = "@(#)rm.c	8.8 (Berkeley) 4/27/95";
-#else
-__RCSID("$NetBSD: rm.c,v 1.53 2013/04/26 18:43:22 christos Exp $");
-#endif
-#endif /* not lint */
-
-#include <sys/param.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-
-#include <err.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <fts.h>
-#include <grp.h>
-#include <locale.h>
-#include <pwd.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-static int dflag, eval, fflag, iflag, Pflag, stdin_ok, vflag, Wflag;
-static int xflag;
-static sig_atomic_t pinfo;
-
-static int	check(char *, char *, struct stat *);
-static void	checkdot(char **);
-static void	progress(int);
-static void	rm_file(char **);
-static int	rm_overwrite(char *, struct stat *);
-static void	rm_tree(char **);
-__dead static void	usage(void);
-
-/*
- * For the sake of the `-f' flag, check whether an error number indicates the
- * failure of an operation due to an non-existent file, either per se (ENOENT)
- * or because its filename argument was illegal (ENAMETOOLONG, ENOTDIR).
- */
-#define NONEXISTENT(x) \
-    ((x) == ENOENT || (x) == ENAMETOOLONG || (x) == ENOTDIR)
-
-/*
- * rm --
- *	This rm is different from historic rm's, but is expected to match
- *	POSIX 1003.2 behavior.  The most visible difference is that -f
- *	has two specific effects now, ignore non-existent files and force
- * 	file removal.
- */
-int
-main(int argc, char *argv[])
-{
-	int ch, rflag;
-
-	setprogname(argv[0]);
-	(void)setlocale(LC_ALL, "");
-
-	Pflag = rflag = xflag = 0;
-	while ((ch = getopt(argc, argv, "dfiPRrvWx")) != -1)
-		switch (ch) {
-		case 'd':
-			dflag = 1;
-			break;
-		case 'f':
-			fflag = 1;
-			iflag = 0;
-			break;
-		case 'i':
-			fflag = 0;
-			iflag = 1;
-			break;
-		case 'P':
-			Pflag = 1;
-			break;
-		case 'R':
-		case 'r':			/* Compatibility. */
-			rflag = 1;
-			break;
-		case 'v':
-			vflag = 1;
-			break;
-		case 'x':
-			xflag = 1;
-			break;
-#ifndef __ANDROID__
-		case 'W':
-			Wflag = 1;
-			break;
-#endif
-		case '?':
-		default:
-			usage();
-		}
-	argc -= optind;
-	argv += optind;
-
-	if (argc < 1) {
-		if (fflag)
-			return 0;
-		usage();
-	}
-
-	(void)signal(SIGINFO, progress);
-
-	checkdot(argv);
-
-	if (*argv) {
-		stdin_ok = isatty(STDIN_FILENO);
-
-		if (rflag)
-			rm_tree(argv);
-		else
-			rm_file(argv);
-	}
-
-	exit(eval);
-	/* NOTREACHED */
-}
-
-static void
-rm_tree(char **argv)
-{
-	FTS *fts;
-	FTSENT *p;
-	int flags, needstat, rval;
-			
-	/*
-	 * Remove a file hierarchy.  If forcing removal (-f), or interactive
-	 * (-i) or can't ask anyway (stdin_ok), don't stat the file.
-	 */
-	needstat = !fflag && !iflag && stdin_ok;
-
-	/*
-	 * If the -i option is specified, the user can skip on the pre-order
-	 * visit.  The fts_number field flags skipped directories.
-	 */
-#define	SKIPPED	1
-
-	flags = FTS_PHYSICAL;
-	if (!needstat)
-		flags |= FTS_NOSTAT;
-#ifndef __ANDROID__
-	if (Wflag)
-		flags |= FTS_WHITEOUT;
-#endif
-	if (xflag)
-		flags |= FTS_XDEV;
-	if ((fts = fts_open(argv, flags, NULL)) == NULL)
-		err(1, "fts_open failed");
-	while ((p = fts_read(fts)) != NULL) {
-	
-		switch (p->fts_info) {
-		case FTS_DNR:
-			if (!fflag || p->fts_errno != ENOENT) {
-				warnx("%s: %s", p->fts_path,
-						strerror(p->fts_errno));
-				eval = 1;
-			}
-			continue;
-		case FTS_ERR:
-			errx(EXIT_FAILURE, "%s: %s", p->fts_path,
-					strerror(p->fts_errno));
-			/* NOTREACHED */
-		case FTS_NS:
-			/*
-			 * FTS_NS: assume that if can't stat the file, it
-			 * can't be unlinked.
-			 */
-			if (fflag && NONEXISTENT(p->fts_errno))
-				continue;
-			if (needstat) {
-				warnx("%s: %s", p->fts_path,
-						strerror(p->fts_errno));
-				eval = 1;
-				continue;
-			}
-			break;
-		case FTS_D:
-			/* Pre-order: give user chance to skip. */
-			if (!fflag && !check(p->fts_path, p->fts_accpath,
-			    p->fts_statp)) {
-				(void)fts_set(fts, p, FTS_SKIP);
-				p->fts_number = SKIPPED;
-			}
-			continue;
-		case FTS_DP:
-			/* Post-order: see if user skipped. */
-			if (p->fts_number == SKIPPED)
-				continue;
-			break;
-		default:
-			if (!fflag &&
-			    !check(p->fts_path, p->fts_accpath, p->fts_statp))
-				continue;
-		}
-
-		rval = 0;
-		/*
-		 * If we can't read or search the directory, may still be
-		 * able to remove it.  Don't print out the un{read,search}able
-		 * message unless the remove fails.
-		 */
-		switch (p->fts_info) {
-		case FTS_DP:
-		case FTS_DNR:
-			rval = rmdir(p->fts_accpath);
-			if (rval != 0 && fflag && errno == ENOENT)
-				continue;
-			break;
-
-#ifndef __ANDROID__
-		case FTS_W:
-			rval = undelete(p->fts_accpath);
-			if (rval != 0 && fflag && errno == ENOENT)
-				continue;
-			break;
-#endif
-
-		default:
-			if (Pflag) {
-				if (rm_overwrite(p->fts_accpath, NULL))
-					continue;
-			}
-			rval = unlink(p->fts_accpath);
-			if (rval != 0 && fflag && NONEXISTENT(errno))
-				continue;
-			break;
-		}
-		if (rval != 0) {
-			warn("%s", p->fts_path);
-			eval = 1;
-		} else if (vflag || pinfo) {
-			pinfo = 0;
-			(void)printf("%s\n", p->fts_path);
-		}
-	}
-	if (errno)
-		err(1, "fts_read");
-	fts_close(fts);
-}
-
-static void
-rm_file(char **argv)
-{
-	struct stat sb;
-	int rval;
-	char *f;
-
-	/*
-	 * Remove a file.  POSIX 1003.2 states that, by default, attempting
-	 * to remove a directory is an error, so must always stat the file.
-	 */
-	while ((f = *argv++) != NULL) {
-		/* Assume if can't stat the file, can't unlink it. */
-		if (lstat(f, &sb)) {
-#ifndef __ANDROID__
-			if (Wflag) {
-				sb.st_mode = S_IFWHT|S_IWUSR|S_IRUSR;
-			} else {
-#endif
-				if (!fflag || !NONEXISTENT(errno)) {
-					warn("%s", f);
-					eval = 1;
-				}
-				continue;
-#ifndef __ANDROID__
-			}
-		} else if (Wflag) {
-			warnx("%s: %s", f, strerror(EEXIST));
-			eval = 1;
-			continue;
-#endif
-		}
-
-		if (S_ISDIR(sb.st_mode) && !dflag) {
-			warnx("%s: is a directory", f);
-			eval = 1;
-			continue;
-		}
-		if (!fflag && !S_ISWHT(sb.st_mode) && !check(f, f, &sb))
-			continue;
-#ifndef __ANDROID__
-		if (S_ISWHT(sb.st_mode))
-			rval = undelete(f);
-		else if (S_ISDIR(sb.st_mode))
-#else
-		if (S_ISDIR(sb.st_mode))
-#endif
-			rval = rmdir(f);
-		else {
-			if (Pflag) {
-				if (rm_overwrite(f, &sb))
-					continue;
-			}
-			rval = unlink(f);
-		}
-		if (rval && (!fflag || !NONEXISTENT(errno))) {
-			warn("%s", f);
-			eval = 1;
-		}
-		if (vflag && rval == 0)
-			(void)printf("%s\n", f);
-	}
-}
-
-/*
- * rm_overwrite --
- *	Overwrite the file 3 times with varying bit patterns.
- *
- * This is an expensive way to keep people from recovering files from your
- * non-snapshotted FFS filesystems using fsdb(8).  Really.  No more.  Only
- * regular files are deleted, directories (and therefore names) will remain.
- * Also, this assumes a fixed-block file system (like FFS, or a V7 or a
- * System V file system).  In a logging file system, you'll have to have
- * kernel support.
- *
- * A note on standards:  U.S. DoD 5220.22-M "National Industrial Security
- * Program Operating Manual" ("NISPOM") is often cited as a reference
- * for clearing and sanitizing magnetic media.  In fact, a matrix of
- * "clearing" and "sanitization" methods for various media was given in
- * Chapter 8 of the original 1995 version of NISPOM.  However, that
- * matrix was *removed from the document* when Chapter 8 was rewritten
- * in Change 2 to the document in 2001.  Recently, the Defense Security
- * Service has made a revised clearing and sanitization matrix available
- * in Microsoft Word format on the DSS web site.  The standardization
- * status of this matrix is unclear.  Furthermore, one must be very
- * careful when referring to this matrix: it is intended for the "clearing"
- * prior to reuse or "sanitization" prior to disposal of *entire media*,
- * not individual files and the only non-physically-destructive method of
- * "sanitization" that is permitted for magnetic disks of any kind is
- * specifically noted to be prohibited for media that have contained
- * Top Secret data.
- *
- * It is impossible to actually conform to the exact procedure given in
- * the matrix if one is overwriting a file, not an entire disk, because
- * the procedure requires examination and comparison of the disk's defect
- * lists.  Any program that claims to securely erase *files* while 
- * conforming to the standard, then, is not correct.  We do as much of
- * what the standard requires as can actually be done when erasing a
- * file, rather than an entire disk; but that does not make us conformant.
- *
- * Furthermore, the presence of track caches, disk and controller write
- * caches, and so forth make it extremely difficult to ensure that data
- * have actually been written to the disk, particularly when one tries
- * to repeatedly overwrite the same sectors in quick succession.  We call
- * fsync(), but controllers with nonvolatile cache, as well as IDE disks
- * that just plain lie about the stable storage of data, will defeat this.
- *
- * Finally, widely respected research suggests that the given procedure
- * is nowhere near sufficient to prevent the recovery of data using special
- * forensic equipment and techniques that are well-known.  This is 
- * presumably one reason that the matrix requires physical media destruction,
- * rather than any technique of the sort attempted here, for secret data.
- *
- * Caveat Emptor.
- *
- * rm_overwrite will return 0 on success.
- */
-
-static int
-rm_overwrite(char *file, struct stat *sbp)
-{
-	struct stat sb, sb2;
-	int fd, randint;
-	char randchar;
-
-	fd = -1;
-	if (sbp == NULL) {
-		if (lstat(file, &sb))
-			goto err;
-		sbp = &sb;
-	}
-	if (!S_ISREG(sbp->st_mode))
-		return 0;
-
-	/* flags to try to defeat hidden caching by forcing seeks */
-	if ((fd = open(file, O_RDWR|O_SYNC|O_RSYNC|O_NOFOLLOW, 0)) == -1)
-		goto err;
-
-	if (fstat(fd, &sb2)) {
-		goto err;
-	}
-
-	if (sb2.st_dev != sbp->st_dev || sb2.st_ino != sbp->st_ino ||
-	    !S_ISREG(sb2.st_mode)) {
-		errno = EPERM;
-		goto err;
-	}
-
-#define RAND_BYTES	1
-#define THIS_BYTE	0
-
-#define	WRITE_PASS(mode, byte) do {					\
-	off_t len;							\
-	size_t wlen, i;							\
-	char buf[8 * 1024];						\
-									\
-	if (fsync(fd) || lseek(fd, (off_t)0, SEEK_SET))			\
-		goto err;						\
-									\
-	if (mode == THIS_BYTE)						\
-		memset(buf, byte, sizeof(buf));				\
-	for (len = sbp->st_size; len > 0; len -= wlen) {		\
-		if (mode == RAND_BYTES) {				\
-			for (i = 0; i < sizeof(buf); 			\
-			    i+= sizeof(u_int32_t))			\
-				*(int *)(buf + i) = arc4random();	\
-		}							\
-		wlen = len < (off_t)sizeof(buf) ? (size_t)len : sizeof(buf); \
-		if ((size_t)write(fd, buf, wlen) != wlen)		\
-			goto err;					\
-	}								\
-	sync();		/* another poke at hidden caches */		\
-} while (/* CONSTCOND */ 0)
-
-#define READ_PASS(byte) do {						\
-	off_t len;							\
-	size_t rlen;							\
-	char pattern[8 * 1024];						\
-	char buf[8 * 1024];						\
-									\
-	if (fsync(fd) || lseek(fd, (off_t)0, SEEK_SET))			\
-		goto err;						\
-									\
-	memset(pattern, byte, sizeof(pattern));				\
-	for(len = sbp->st_size; len > 0; len -= rlen) {			\
-		rlen = len < (off_t)sizeof(buf) ? (size_t)len : sizeof(buf); \
-		if((size_t)read(fd, buf, rlen) != rlen)			\
-			goto err;					\
-		if(memcmp(buf, pattern, rlen))				\
-			goto err;					\
-	}								\
-	sync();		/* another poke at hidden caches */		\
-} while (/* CONSTCOND */ 0)
-
-	/*
-	 * DSS sanitization matrix "clear" for magnetic disks: 
-	 * option 'c' "Overwrite all addressable locations with a single 
-	 * character."
-	 */
-	randint = arc4random();
-	randchar = *(char *)&randint;
-	WRITE_PASS(THIS_BYTE, randchar);
-
-	/*
-	 * DSS sanitization matrix "sanitize" for magnetic disks: 
-	 * option 'd', sub 2 "Overwrite all addressable locations with a
-	 * character, then its complement.  Verify "complement" character
-	 * was written successfully to all addressable locations, then
-	 * overwrite all addressable locations with random characters; or
-	 * verify third overwrite of random characters."  The rest of the
-	 * text in d-sub-2 specifies requirements for overwriting spared
-	 * sectors; we cannot conform to it when erasing only a file, thus
-	 * we do not conform to the standard.
-	 */
-
-	/* 1. "a character" */
-	WRITE_PASS(THIS_BYTE, 0xff);
-
-	/* 2. "its complement" */
-	WRITE_PASS(THIS_BYTE, 0x00);
-
-	/* 3. "Verify 'complement' character" */
-	READ_PASS(0x00);
-
-	/* 4. "overwrite all addressable locations with random characters" */
-
-	WRITE_PASS(RAND_BYTES, 0x00);
-
-	/*
-	 * As the file might be huge, and we note that this revision of
-	 * the matrix says "random characters", not "a random character"
-	 * as the original did, we do not verify the random-character
-	 * write; the "or" in the standard allows this.
-	 */
-
-	if (close(fd) == -1) {
-		fd = -1;
-		goto err;
-	}
-
-	return 0;
-
-err:	eval = 1;
-	warn("%s", file);
-	if (fd != -1)
-		close(fd);
-	return 1;
-}
-
-static int
-check(char *path, char *name, struct stat *sp)
-{
-	int ch, first;
-	char modep[15];
-
-	/* Check -i first. */
-	if (iflag)
-		(void)fprintf(stderr, "remove '%s'? ", path);
-	else {
-		/*
-		 * If it's not a symbolic link and it's unwritable and we're
-		 * talking to a terminal, ask.  Symbolic links are excluded
-		 * because their permissions are meaningless.  Check stdin_ok
-		 * first because we may not have stat'ed the file.
-		 */
-		if (!stdin_ok || S_ISLNK(sp->st_mode) ||
-		    !(access(name, W_OK) && (errno != ETXTBSY)))
-			return (1);
-		strmode(sp->st_mode, modep);
-		if (Pflag) {
-			warnx(
-			    "%s: -P was specified but file could not"
-			    " be overwritten", path);
-			return 0;
-		}
-		(void)fprintf(stderr, "override %s%s%s:%s for '%s'? ",
-		    modep + 1, modep[9] == ' ' ? "" : " ",
-		    user_from_uid(sp->st_uid, 0),
-		    group_from_gid(sp->st_gid, 0), path);
-	}
-	(void)fflush(stderr);
-
-	first = ch = getchar();
-	while (ch != '\n' && ch != EOF)
-		ch = getchar();
-	return (first == 'y' || first == 'Y');
-}
-
-/*
- * POSIX.2 requires that if "." or ".." are specified as the basename
- * portion of an operand, a diagnostic message be written to standard
- * error and nothing more be done with such operands.
- *
- * Since POSIX.2 defines basename as the final portion of a path after
- * trailing slashes have been removed, we'll remove them here.
- */
-#define ISDOT(a) ((a)[0] == '.' && (!(a)[1] || ((a)[1] == '.' && !(a)[2])))
-static void
-checkdot(char **argv)
-{
-	char *p, **save, **t;
-	int complained;
-
-	complained = 0;
-	for (t = argv; *t;) {
-		/* strip trailing slashes */
-		p = strrchr(*t, '\0');
-		while (--p > *t && *p == '/')
-			*p = '\0';
-
-		/* extract basename */
-		if ((p = strrchr(*t, '/')) != NULL)
-			++p;
-		else
-			p = *t;
-
-		if (ISDOT(p)) {
-			if (!complained++)
-				warnx("\".\" and \"..\" may not be removed");
-			eval = 1;
-			for (save = t; (t[0] = t[1]) != NULL; ++t)
-				continue;
-			t = save;
-		} else
-			++t;
-	}
-}
-
-static void
-usage(void)
-{
-
-	(void)fprintf(stderr, "usage: %s [-f|-i] [-dPRrvWx] file ...\n",
-	    getprogname());
-	exit(1);
-	/* NOTREACHED */
-}
-
-static void
-progress(int sig __unused)
-{
-	
-	pinfo++;
-}
diff --git a/toolbox/upstream-netbsd/bin/rmdir/rmdir.c b/toolbox/upstream-netbsd/bin/rmdir/rmdir.c
deleted file mode 100644
index 03261ce..0000000
--- a/toolbox/upstream-netbsd/bin/rmdir/rmdir.c
+++ /dev/null
@@ -1,121 +0,0 @@
-/* $NetBSD: rmdir.c,v 1.26 2011/08/29 14:49:38 joerg Exp $ */
-
-/*-
- * Copyright (c) 1992, 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.
- */
-
-#include <sys/cdefs.h>
-#ifndef lint
-__COPYRIGHT("@(#) Copyright (c) 1992, 1993, 1994\
- The Regents of the University of California.  All rights reserved.");
-#endif /* not lint */
-
-#ifndef lint
-#if 0
-static char sccsid[] = "@(#)rmdir.c	8.3 (Berkeley) 4/2/94";
-#else
-__RCSID("$NetBSD: rmdir.c,v 1.26 2011/08/29 14:49:38 joerg Exp $");
-#endif
-#endif /* not lint */
-
-#include <sys/param.h>
-
-#include <err.h>
-#include <locale.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-static int	rm_path(char *);
-__dead static void	usage(void);
-
-int
-main(int argc, char *argv[])
-{
-	int ch, errors, pflag;
-
-	setprogname(argv[0]);
-	(void)setlocale(LC_ALL, "");
-
-	pflag = 0;
-	while ((ch = getopt(argc, argv, "p")) != -1)
-		switch(ch) {
-		case 'p':
-			pflag = 1;
-			break;
-		case '?':
-		default:
-			usage();
-		}
-	argc -= optind;
-	argv += optind;
-
-	if (argc == 0)
-		usage();
-
-	for (errors = 0; *argv; argv++) {
-		/* We rely on the kernel to ignore trailing '/' characters. */
-		if (rmdir(*argv) < 0) {
-			warn("%s", *argv);
-			errors = 1;
-		} else if (pflag)
-			errors |= rm_path(*argv);
-	}
-
-	exit(errors);
-	/* NOTREACHED */
-}
-
-static int
-rm_path(char *path)
-{
-	char *p;
-
-	while ((p = strrchr(path, '/')) != NULL) {
-		*p = 0;
-		if (p[1] == 0)
-			/* Ignore trailing '/' on deleted name */
-			continue;
-
-		if (rmdir(path) < 0) {
-			warn("%s", path);
-			return (1);
-		}
-	}
-
-	return (0);
-}
-
-static void
-usage(void)
-{
-	(void)fprintf(stderr, "usage: %s [-p] directory ...\n", getprogname());
-	exit(1);
-	/* NOTREACHED */
-}
diff --git a/toolbox/upstream-netbsd/sbin/chown/chown.c b/toolbox/upstream-netbsd/sbin/chown/chown.c
deleted file mode 100644
index ee46eee..0000000
--- a/toolbox/upstream-netbsd/sbin/chown/chown.c
+++ /dev/null
@@ -1,302 +0,0 @@
-/*	$NetBSD: chown.c,v 1.8 2012/10/24 01:12:51 enami Exp $	*/
-
-/*
- * Copyright (c) 1988, 1993, 1994, 2003
- *	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.
- */
-
-#include <sys/cdefs.h>
-#ifndef lint
-__COPYRIGHT("@(#) Copyright (c) 1988, 1993, 1994, 2003\
- The Regents of the University of California.  All rights reserved.");
-#endif /* not lint */
-
-#ifndef lint
-#if 0
-static char sccsid[] = "@(#)chown.c	8.8 (Berkeley) 4/4/94";
-#else
-__RCSID("$NetBSD: chown.c,v 1.8 2012/10/24 01:12:51 enami Exp $");
-#endif
-#endif /* not lint */
-
-#include <sys/types.h>
-#include <sys/stat.h>
-
-#include <ctype.h>
-#include <dirent.h>
-#include <err.h>
-#include <errno.h>
-#include <locale.h>
-#include <fts.h>
-#include <grp.h>
-#include <pwd.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <getopt.h>
-
-static void	a_gid(const char *);
-static void	a_uid(const char *);
-static id_t	id(const char *, const char *);
-__dead static void	usage(void);
-
-static uid_t uid;
-static gid_t gid;
-static int ischown;
-static const char *myname;
-
-struct option chown_longopts[] = {
-	{ "reference",		required_argument,	0,
-						1 },
-	{ NULL,			0,			0,
-						0 },
-};
-
-int
-main(int argc, char **argv)
-{
-	FTS *ftsp;
-	FTSENT *p;
-	int Hflag, Lflag, Rflag, ch, fflag, fts_options, hflag, rval, vflag;
-	char *cp, *reference;
-	int (*change_owner)(const char *, uid_t, gid_t);
-
-	setprogname(*argv);
-
-	(void)setlocale(LC_ALL, "");
-
-	myname = getprogname();
-	ischown = (myname[2] == 'o');
-	reference = NULL;
-
-	Hflag = Lflag = Rflag = fflag = hflag = vflag = 0;
-	while ((ch = getopt_long(argc, argv, "HLPRfhv",
-	    chown_longopts, NULL)) != -1)
-		switch (ch) {
-		case 1:
-			reference = optarg;
-			break;
-		case 'H':
-			Hflag = 1;
-			Lflag = 0;
-			break;
-		case 'L':
-			Lflag = 1;
-			Hflag = 0;
-			break;
-		case 'P':
-			Hflag = Lflag = 0;
-			break;
-		case 'R':
-			Rflag = 1;
-			break;
-		case 'f':
-			fflag = 1;
-			break;
-		case 'h':
-			/*
-			 * In System V the -h option causes chown/chgrp to
-			 * change the owner/group of the symbolic link.
-			 * 4.4BSD's symbolic links didn't have owners/groups,
-			 * so it was an undocumented noop.
-			 * In NetBSD 1.3, lchown(2) is introduced.
-			 */
-			hflag = 1;
-			break;
-		case 'v':
-			vflag = 1;
-			break;
-		case '?':
-		default:
-			usage();
-		}
-	argv += optind;
-	argc -= optind;
-
-	if (argc == 0 || (argc == 1 && reference == NULL))
-		usage();
-
-	fts_options = FTS_PHYSICAL;
-	if (Rflag) {
-		if (Hflag)
-			fts_options |= FTS_COMFOLLOW;
-		if (Lflag) {
-			if (hflag)
-				errx(EXIT_FAILURE,
-				    "the -L and -h options "
-				    "may not be specified together.");
-			fts_options &= ~FTS_PHYSICAL;
-			fts_options |= FTS_LOGICAL;
-		}
-	} else if (!hflag)
-		fts_options |= FTS_COMFOLLOW;
-
-	uid = (uid_t)-1;
-	gid = (gid_t)-1;
-	if (reference == NULL) {
-		if (ischown) {
-			if ((cp = strchr(*argv, ':')) != NULL) {
-				*cp++ = '\0';
-				a_gid(cp);
-			}
-#ifdef SUPPORT_DOT
-			else if ((cp = strrchr(*argv, '.')) != NULL) {
-				if (uid_from_user(*argv, &uid) == -1) {
-					*cp++ = '\0';
-					a_gid(cp);
-				}
-			}
-#endif
-			a_uid(*argv);
-		} else
-			a_gid(*argv);
-		argv++;
-	} else {
-		struct stat st;
-
-		if (stat(reference, &st) == -1)
-			err(EXIT_FAILURE, "Cannot stat `%s'", reference);
-		if (ischown)
-			uid = st.st_uid;
-		gid = st.st_gid;
-	}
-
-	if ((ftsp = fts_open(argv, fts_options, NULL)) == NULL)
-		err(EXIT_FAILURE, "fts_open");
-
-	for (rval = EXIT_SUCCESS; (p = fts_read(ftsp)) != NULL;) {
-		change_owner = chown;
-		switch (p->fts_info) {
-		case FTS_D:
-			if (!Rflag)		/* Change it at FTS_DP. */
-				fts_set(ftsp, p, FTS_SKIP);
-			continue;
-		case FTS_DNR:			/* Warn, chown, continue. */
-			warnx("%s: %s", p->fts_path, strerror(p->fts_errno));
-			rval = EXIT_FAILURE;
-			break;
-		case FTS_ERR:			/* Warn, continue. */
-		case FTS_NS:
-			warnx("%s: %s", p->fts_path, strerror(p->fts_errno));
-			rval = EXIT_FAILURE;
-			continue;
-		case FTS_SL:			/* Ignore unless -h. */
-			/*
-			 * All symlinks we found while doing a physical
-			 * walk end up here.
-			 */
-			if (!hflag)
-				continue;
-			/*
-			 * Note that if we follow a symlink, fts_info is
-			 * not FTS_SL but FTS_F or whatever.  And we should
-			 * use lchown only for FTS_SL and should use chown
-			 * for others.
-			 */
-			change_owner = lchown;
-			break;
-		case FTS_SLNONE:		/* Ignore. */
-			/*
-			 * The only symlinks that end up here are ones that
-			 * don't point to anything.  Note that if we are
-			 * doing a phisycal walk, we never reach here unless
-			 * we asked to follow explicitly.
-			 */
-			continue;
-		default:
-			break;
-		}
-
-		if ((*change_owner)(p->fts_accpath, uid, gid) && !fflag) {
-			warn("%s", p->fts_path);
-			rval = EXIT_FAILURE;
-		} else {
-			if (vflag)
-				printf("%s\n", p->fts_path);
-		}
-	}
-	if (errno)
-		err(EXIT_FAILURE, "fts_read");
-	exit(rval);
-	/* NOTREACHED */
-}
-
-static void
-a_gid(const char *s)
-{
-	struct group *gr;
-
-	if (*s == '\0')			/* Argument was "uid[:.]". */
-		return;
-	gr = *s == '#' ? NULL : getgrnam(s);
-	if (gr == NULL)
-		gid = id(s, "group");
-	else
-		gid = gr->gr_gid;
-	return;
-}
-
-static void
-a_uid(const char *s)
-{
-	if (*s == '\0')			/* Argument was "[:.]gid". */
-		return;
-	if (*s == '#' || uid_from_user(s, &uid) == -1) {
-		uid = id(s, "user");
-	}
-	return;
-}
-
-static id_t
-id(const char *name, const char *type)
-{
-	id_t val;
-	char *ep;
-
-	errno = 0;
-	if (*name == '#')
-		name++;
-	val = (id_t)strtoul(name, &ep, 10);
-	if (errno)
-		err(EXIT_FAILURE, "%s", name);
-	if (*ep != '\0')
-		errx(EXIT_FAILURE, "%s: invalid %s name", name, type);
-	return (val);
-}
-
-static void
-usage(void)
-{
-
-	(void)fprintf(stderr,
-	    "Usage: %s [-R [-H | -L | -P]] [-fhv] %s file ...\n"
-	    "\t%s [-R [-H | -L | -P]] [-fhv] --reference=rfile file ...\n",
-	    myname, ischown ? "owner:group|owner|:group" : "group",
-	    myname);
-	exit(EXIT_FAILURE);
-}
diff --git a/toolbox/uptime.c b/toolbox/uptime.c
index 3fb4606..2dd8084 100644
--- a/toolbox/uptime.c
+++ b/toolbox/uptime.c
@@ -36,7 +36,7 @@
 #include <fcntl.h>
 #include <stdio.h>
 #include <time.h>
-
+#include <unistd.h>
 
 static void format_time(int time, char* buffer) {
     int seconds, minutes, hours, days;