Merge "adb: Fix 'adb forward --no-rebind'."
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/adb/file_sync_client.c b/adb/file_sync_client.c
index 7fb3e3b..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;
 
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/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/debuggerd/Android.mk b/debuggerd/Android.mk
index 0cf2818..fbaac39 100644
--- a/debuggerd/Android.mk
+++ b/debuggerd/Android.mk
@@ -22,6 +22,10 @@
     -Wunused \
     -Werror \
 
+ifeq ($(TARGET_IS_64_BIT),true)
+LOCAL_CPPFLAGS += -DTARGET_IS_64_BIT
+endif
+
 LOCAL_SHARED_LIBRARIES := \
     libbacktrace \
     libcutils \
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/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/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/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/Mutex.h b/include/utils/Mutex.h
index 4fdd27f..a3b594d 100644
--- a/include/utils/Mutex.h
+++ b/include/utils/Mutex.h
@@ -131,8 +131,8 @@
 #if HAVE_ANDROID_OS
 inline status_t Mutex::timedLock(nsecs_t timeoutNs) {
     const struct timespec ts = {
-        /* .tv_sec = */ timeoutNs / 1000000000,
-        /* .tv_nsec = */ timeoutNs % 1000000000,
+        /* .tv_sec = */ static_cast<time_t>(timeoutNs / 1000000000),
+        /* .tv_nsec = */ static_cast<long>(timeoutNs % 1000000000),
     };
     return -pthread_mutex_timedlock(&mMutex, &ts);
 }
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/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/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/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/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/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/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/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 a48906a..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 */
diff --git a/toolbox/Android.mk b/toolbox/Android.mk
index ebe94d5..f0eec68 100644
--- a/toolbox/Android.mk
+++ b/toolbox/Android.mk
@@ -13,20 +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/dd/args.c \
     upstream-netbsd/bin/dd/conv.c \
@@ -62,21 +48,15 @@
 include $(CLEAR_VARS)
 
 BSD_TOOLS := \
-    cat \
-    chown \
     dd \
     du \
     grep \
 
 OUR_TOOLS := \
-    cmp \
-    date \
     df \
     getevent \
     getprop \
     getsebool \
-    id \
-    ifconfig \
     iftop \
     ioctl \
     ionice \
@@ -87,7 +67,6 @@
     mount \
     nandread \
     newfs_msdos \
-    notify \
     ps \
     renice \
     restorecon \
@@ -116,7 +95,6 @@
     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 \
 
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/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/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/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/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/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/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);
-}