Merge "RefBase: make Renamer destructor virtual"
diff --git a/adb/Android.mk b/adb/Android.mk
index 50e28a6..80c1f9c 100644
--- a/adb/Android.mk
+++ b/adb/Android.mk
@@ -24,6 +24,7 @@
   USB_SRCS := usb_osx.c
   EXTRA_SRCS := get_my_path_darwin.c
   LOCAL_LDLIBS += -lpthread -framework CoreFoundation -framework IOKit -framework Carbon
+  LOCAL_CFLAGS += -Wno-sizeof-pointer-memaccess -Wno-unused-parameter
 endif
 
 ifeq ($(HOST_OS),freebsd)
@@ -102,7 +103,6 @@
 
 LOCAL_SRC_FILES := \
 	adb.c \
-	backup_service.c \
 	fdevent.c \
 	transport.c \
 	transport_local.c \
diff --git a/adb/adb.c b/adb/adb.c
index 90bdbaa..10a1e0d 100644
--- a/adb/adb.c
+++ b/adb/adb.c
@@ -37,8 +37,8 @@
 #include <cutils/properties.h>
 #include <private/android_filesystem_config.h>
 #include <sys/capability.h>
-#include <linux/prctl.h>
 #include <sys/mount.h>
+#include <sys/prctl.h>
 #include <getopt.h>
 #include <selinux/selinux.h>
 #else
@@ -1670,11 +1670,6 @@
         /* we don't even need to send a reply */
         return 0;
     }
-#endif // ADB_HOST
-
-    int ret = handle_forward_request(service, ttype, serial, reply_fd);
-    if (ret >= 0)
-      return ret - 1;
 
     if(!strncmp(service,"get-state",strlen("get-state"))) {
         transport = acquire_one_transport(CS_ANY, ttype, serial, NULL);
@@ -1682,6 +1677,11 @@
         send_msg_with_okay(reply_fd, state, strlen(state));
         return 0;
     }
+#endif // ADB_HOST
+
+    int ret = handle_forward_request(service, ttype, serial, reply_fd);
+    if (ret >= 0)
+      return ret - 1;
     return -1;
 }
 
diff --git a/adb/adb.h b/adb/adb.h
index 2504f99..4704abb 100644
--- a/adb/adb.h
+++ b/adb/adb.h
@@ -326,11 +326,6 @@
 int handle_forward_request(const char* service, transport_type ttype, char* serial, int reply_fd);
 
 #if !ADB_HOST
-typedef enum {
-    BACKUP,
-    RESTORE
-} BackupOperation;
-int backup_service(BackupOperation operation, char* args);
 void framebuffer_service(int fd, void *cookie);
 void remount_service(int fd, void *cookie);
 #endif
@@ -418,7 +413,7 @@
 #  define  D(...)          ((void)0)
 #  define  DR(...)         ((void)0)
 #  define  ADB_TRACING     0
-#endif
+#endif /* ADB_TRACE */
 
 
 #if !DEBUG_PACKETS
@@ -476,6 +471,11 @@
 extern int HOST;
 extern int SHELL_EXIT_NOTIFY_FD;
 
+typedef enum {
+    SUBPROC_PTY = 0,
+    SUBPROC_RAW = 1,
+} subproc_mode;
+
 #define CHUNK_SIZE (64*1024)
 
 #if !ADB_HOST
diff --git a/adb/adb_auth_client.c b/adb/adb_auth_client.c
index f8d7306..8409c63 100644
--- a/adb/adb_auth_client.c
+++ b/adb/adb_auth_client.c
@@ -57,7 +57,7 @@
     char *sep;
     int ret;
 
-    f = fopen(file, "r");
+    f = fopen(file, "re");
     if (!f) {
         D("Can't open '%s'\n", file);
         return;
@@ -126,7 +126,7 @@
     FILE *f;
     int ret;
 
-    f = fopen("/dev/urandom", "r");
+    f = fopen("/dev/urandom", "re");
     if (!f)
         return 0;
 
@@ -257,6 +257,7 @@
         D("Failed to get adbd socket\n");
         return;
     }
+    fcntl(fd, F_SETFD, FD_CLOEXEC);
 
     ret = listen(fd, 4);
     if (ret < 0) {
diff --git a/adb/backup_service.c b/adb/backup_service.c
deleted file mode 100644
index 654e0f3..0000000
--- a/adb/backup_service.c
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- * Copyright (C) 2011 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 <unistd.h>
-#include <stdio.h>
-
-#include "sysdeps.h"
-
-#define TRACE_TAG  TRACE_ADB
-#include "adb.h"
-
-typedef struct {
-    pid_t pid;
-    int fd;
-} backup_harvest_params;
-
-// socketpair but do *not* mark as close_on_exec
-static int backup_socketpair(int sv[2]) {
-    int rc = unix_socketpair( AF_UNIX, SOCK_STREAM, 0, sv );
-    if (rc < 0)
-        return -1;
-
-    return 0;
-}
-
-// harvest the child process then close the read end of the socketpair
-static void* backup_child_waiter(void* args) {
-    int status;
-    backup_harvest_params* params = (backup_harvest_params*) args;
-
-    waitpid(params->pid, &status, 0);
-    adb_close(params->fd);
-    free(params);
-    return NULL;
-}
-
-/* returns the data socket passing the backup data here for forwarding */
-int backup_service(BackupOperation op, char* args) {
-    pid_t pid;
-    int s[2];
-    char* operation;
-
-    // Command string depends on our invocation
-    if (op == BACKUP) {
-        operation = "backup";
-    } else {
-        operation = "restore";
-    }
-
-    D("backup_service(%s, %s)\n", operation, args);
-
-    // set up the pipe from the subprocess to here
-    // parent will read s[0]; child will write s[1]
-    if (backup_socketpair(s)) {
-        D("can't create backup/restore socketpair\n");
-        fprintf(stderr, "unable to create backup/restore socketpair\n");
-        return -1;
-    }
-
-    D("Backup/restore socket pair: (send=%d, receive=%d)\n", s[1], s[0]);
-    close_on_exec(s[0]);    // only the side we hold on to
-
-    // spin off the child process to run the backup command
-    pid = fork();
-    if (pid < 0) {
-        // failure
-        D("can't fork for %s\n", operation);
-        fprintf(stderr, "unable to fork for %s\n", operation);
-        adb_close(s[0]);
-        adb_close(s[1]);
-        return -1;
-    }
-
-    // Great, we're off and running.
-    if (pid == 0) {
-        // child -- actually run the backup here
-        char* p;
-        int argc;
-        char portnum[16];
-        char** bu_args;
-
-        // fixed args:  [0] is 'bu', [1] is the port number, [2] is the 'operation' string
-        argc = 3;
-        for (p = (char*)args; p && *p; ) {
-            argc++;
-            while (*p && *p != ':') p++;
-            if (*p == ':') p++;
-        }
-
-        bu_args = (char**) alloca(argc*sizeof(char*) + 1);
-
-        // run through again to build the argv array
-        argc = 0;
-        bu_args[argc++] = "bu";
-        snprintf(portnum, sizeof(portnum), "%d", s[1]);
-        bu_args[argc++] = portnum;
-        bu_args[argc++] = operation;
-        for (p = (char*)args; p && *p; ) {
-            bu_args[argc++] = p;
-            while (*p && *p != ':') p++;
-            if (*p == ':') {
-                *p = 0;
-                p++;
-            }
-        }
-        bu_args[argc] = NULL;
-
-        // Close the half of the socket that we don't care about, route 'bu's console
-        // to the output socket, and off we go
-        adb_close(s[0]);
-
-        // off we go
-        execvp("/system/bin/bu", (char * const *)bu_args);
-        // oops error - close up shop and go home
-        fprintf(stderr, "Unable to exec 'bu', bailing\n");
-        exit(-1);
-    } else {
-        adb_thread_t t;
-        backup_harvest_params* params;
-
-        // parent, i.e. adbd -- close the sending half of the socket
-        D("fork() returned pid %d\n", pid);
-        adb_close(s[1]);
-
-        // spin a thread to harvest the child process
-        params = (backup_harvest_params*) malloc(sizeof(backup_harvest_params));
-        params->pid = pid;
-        params->fd = s[0];
-        if (adb_thread_create(&t, backup_child_waiter, params)) {
-            adb_close(s[0]);
-            free(params);
-            D("Unable to create child harvester\n");
-            return -1;
-        }
-    }
-
-    // we'll be reading from s[0] as the data is sent by the child process
-    return s[0];
-}
diff --git a/adb/commandline.c b/adb/commandline.c
index 18dc6e0..356c0db 100644
--- a/adb/commandline.c
+++ b/adb/commandline.c
@@ -110,9 +110,10 @@
         "  adb push [-p] <local> <remote>\n"
         "                               - copy file/dir to device\n"
         "                                 ('-p' to display the transfer progress)\n"
-        "  adb pull [-p] <remote> [<local>]\n"
+        "  adb pull [-p] [-a] <remote> [<local>]\n"
         "                               - copy file/dir from device\n"
         "                                 ('-p' to display the transfer progress)\n"
+        "                                 ('-a' means copy timestamp and mode)\n"
         "  adb sync [ <directory> ]     - copy host->device only if changed\n"
         "                                 (-l means list but don't copy)\n"
         "                                 (see 'adb help all')\n"
@@ -285,8 +286,17 @@
     long total = 0;
 
     D("copy_to_file(%d -> %d)\n", inFd, outFd);
+#ifdef HAVE_TERMIO_H
+    if (inFd == STDIN_FILENO) {
+        stdin_raw_init(STDIN_FILENO);
+    }
+#endif
     for (;;) {
-        len = adb_read(inFd, buf, BUFSIZE);
+        if (inFd == STDIN_FILENO) {
+            len = unix_read(inFd, buf, BUFSIZE);
+        } else {
+            len = adb_read(inFd, buf, BUFSIZE);
+        }
         if (len == 0) {
             D("copy_to_file() : read 0 bytes; exiting\n");
             break;
@@ -299,9 +309,19 @@
             D("copy_to_file() : error %d\n", errno);
             break;
         }
-        adb_write(outFd, buf, len);
+        if (outFd == STDOUT_FILENO) {
+            fwrite(buf, 1, len, stdout);
+            fflush(stdout);
+        } else {
+            adb_write(outFd, buf, len);
+        }
         total += len;
     }
+#ifdef HAVE_TERMIO_H
+    if (inFd == STDIN_FILENO) {
+        stdin_raw_restore(STDIN_FILENO);
+    }
+#endif
     D("copy_to_file() finished after %lu bytes\n", total);
     free(buf);
 }
@@ -524,39 +544,40 @@
     }
 }
 
-/** duplicate string and quote all \ " ( ) chars + space character. */
-static char *
-dupAndQuote(const char *s)
+/** Duplicate and escape given argument. */
+static char *escape_arg(const char *s)
 {
     const char *ts;
     size_t alloc_len;
     char *ret;
     char *dest;
 
-    ts = s;
-
     alloc_len = 0;
-
-    for( ;*ts != '\0'; ts++) {
+    for (ts = s; *ts != '\0'; ts++) {
         alloc_len++;
         if (*ts == ' ' || *ts == '"' || *ts == '\\' || *ts == '(' || *ts == ')') {
             alloc_len++;
         }
     }
 
-    ret = (char *)malloc(alloc_len + 1);
+    if (alloc_len == 0) {
+        // Preserve empty arguments
+        ret = (char *) malloc(3);
+        ret[0] = '\"';
+        ret[1] = '\"';
+        ret[2] = '\0';
+        return ret;
+    }
 
-    ts = s;
+    ret = (char *) malloc(alloc_len + 1);
     dest = ret;
 
-    for ( ;*ts != '\0'; ts++) {
+    for (ts = s; *ts != '\0'; ts++) {
         if (*ts == ' ' || *ts == '"' || *ts == '\\' || *ts == '(' || *ts == ')') {
             *dest++ = '\\';
         }
-
         *dest++ = *ts;
     }
-
     *dest++ = '\0';
 
     return ret;
@@ -663,30 +684,24 @@
     char buf[4096];
 
     char *log_tags;
-    char *quoted_log_tags;
+    char *quoted;
 
     log_tags = getenv("ANDROID_LOG_TAGS");
-    quoted_log_tags = dupAndQuote(log_tags == NULL ? "" : log_tags);
-
+    quoted = escape_arg(log_tags == NULL ? "" : log_tags);
     snprintf(buf, sizeof(buf),
-        "shell:export ANDROID_LOG_TAGS=\"\%s\" ; exec logcat",
-        quoted_log_tags);
+            "shell:export ANDROID_LOG_TAGS=\"%s\"; exec logcat", quoted);
+    free(quoted);
 
-    free(quoted_log_tags);
-
-    if (!strcmp(argv[0],"longcat")) {
-        strncat(buf, " -v long", sizeof(buf)-1);
+    if (!strcmp(argv[0], "longcat")) {
+        strncat(buf, " -v long", sizeof(buf) - 1);
     }
 
     argc -= 1;
     argv += 1;
     while(argc-- > 0) {
-        char *quoted;
-
-        quoted = dupAndQuote (*argv++);
-
-        strncat(buf, " ", sizeof(buf)-1);
-        strncat(buf, quoted, sizeof(buf)-1);
+        quoted = escape_arg(*argv++);
+        strncat(buf, " ", sizeof(buf) - 1);
+        strncat(buf, quoted, sizeof(buf) - 1);
         free(quoted);
     }
 
@@ -938,13 +953,19 @@
     return path_buf;
 }
 
-
-static void parse_push_pull_args(char** arg, int narg, char const** path1, char const** path2,
-                                 int* show_progress) {
+static void parse_push_pull_args(char **arg, int narg, char const **path1, char const **path2,
+                                 int *show_progress, int *copy_attrs) {
     *show_progress = 0;
+    *copy_attrs = 0;
 
-    if ((narg > 0) && !strcmp(*arg, "-p")) {
-        *show_progress = 1;
+    while (narg > 0) {
+        if (!strcmp(*arg, "-p")) {
+            *show_progress = 1;
+        } else if (!strcmp(*arg, "-a")) {
+            *copy_attrs = 1;
+        } else {
+            break;
+        }
         ++arg;
         --narg;
     }
@@ -968,7 +989,6 @@
     int is_server = 0;
     int persist = 0;
     int r;
-    int quote;
     transport_type ttype = kTransportAny;
     char* serial = NULL;
     char* server_port_str = NULL;
@@ -1189,19 +1209,14 @@
             return r;
         }
 
-        snprintf(buf, sizeof buf, "shell:%s", argv[1]);
+        snprintf(buf, sizeof(buf), "shell:%s", argv[1]);
         argc -= 2;
         argv += 2;
-        while(argc-- > 0) {
-            strcat(buf, " ");
-
-            /* quote empty strings and strings with spaces */
-            quote = (**argv == 0 || strchr(*argv, ' '));
-            if (quote)
-                strcat(buf, "\"");
-            strcat(buf, *argv++);
-            if (quote)
-                strcat(buf, "\"");
+        while (argc-- > 0) {
+            char *quoted = escape_arg(*argv++);
+            strncat(buf, " ", sizeof(buf) - 1);
+            strncat(buf, quoted, sizeof(buf) - 1);
+            free(quoted);
         }
 
         for(;;) {
@@ -1233,6 +1248,36 @@
         }
     }
 
+    if (!strcmp(argv[0], "exec-in") || !strcmp(argv[0], "exec-out")) {
+        int exec_in = !strcmp(argv[0], "exec-in");
+        int fd;
+
+        snprintf(buf, sizeof buf, "exec:%s", argv[1]);
+        argc -= 2;
+        argv += 2;
+        while (argc-- > 0) {
+            char *quoted = escape_arg(*argv++);
+            strncat(buf, " ", sizeof(buf) - 1);
+            strncat(buf, quoted, sizeof(buf) - 1);
+            free(quoted);
+        }
+
+        fd = adb_connect(buf);
+        if (fd < 0) {
+            fprintf(stderr, "error: %s\n", adb_error());
+            return -1;
+        }
+
+        if (exec_in) {
+            copy_to_file(STDIN_FILENO, fd);
+        } else {
+            copy_to_file(fd, STDOUT_FILENO);
+        }
+
+        adb_close(fd);
+        return 0;
+    }
+
     if(!strcmp(argv[0], "kill-server")) {
         int fd;
         fd = _adb_connect("host:kill");
@@ -1415,9 +1460,10 @@
 
     if(!strcmp(argv[0], "push")) {
         int show_progress = 0;
+        int copy_attrs = 0; // unused
         const char* lpath = NULL, *rpath = NULL;
 
-        parse_push_pull_args(&argv[1], argc - 1, &lpath, &rpath, &show_progress);
+        parse_push_pull_args(&argv[1], argc - 1, &lpath, &rpath, &show_progress, &copy_attrs);
 
         if ((lpath != NULL) && (rpath != NULL)) {
             return do_sync_push(lpath, rpath, 0 /* no verify APK */, show_progress);
@@ -1428,12 +1474,13 @@
 
     if(!strcmp(argv[0], "pull")) {
         int show_progress = 0;
+        int copy_attrs = 0;
         const char* rpath = NULL, *lpath = ".";
 
-        parse_push_pull_args(&argv[1], argc - 1, &rpath, &lpath, &show_progress);
+        parse_push_pull_args(&argv[1], argc - 1, &rpath, &lpath, &show_progress, &copy_attrs);
 
         if (rpath != NULL) {
-            return do_sync_pull(rpath, lpath, show_progress);
+            return do_sync_pull(rpath, lpath, show_progress, copy_attrs);
         }
 
         return usage();
@@ -1555,9 +1602,10 @@
     return 1;
 }
 
+#define MAX_ARGV_LENGTH 16
 static int do_cmd(transport_type ttype, char* serial, char *cmd, ...)
 {
-    char *argv[16];
+    char *argv[MAX_ARGV_LENGTH];
     int argc;
     va_list ap;
 
@@ -1574,7 +1622,9 @@
     }
 
     argv[argc++] = cmd;
-    while((argv[argc] = va_arg(ap, char*)) != 0) argc++;
+    while(argc < MAX_ARGV_LENGTH &&
+        (argv[argc] = va_arg(ap, char*)) != 0) argc++;
+    assert(argc < MAX_ARGV_LENGTH);
     va_end(ap);
 
 #if 0
@@ -1634,12 +1684,9 @@
     snprintf(buf, sizeof(buf), "shell:pm");
 
     while(argc-- > 0) {
-        char *quoted;
-
-        quoted = dupAndQuote(*argv++);
-
-        strncat(buf, " ", sizeof(buf)-1);
-        strncat(buf, quoted, sizeof(buf)-1);
+        char *quoted = escape_arg(*argv++);
+        strncat(buf, " ", sizeof(buf) - 1);
+        strncat(buf, quoted, sizeof(buf) - 1);
         free(quoted);
     }
 
@@ -1671,7 +1718,7 @@
     char* quoted;
 
     snprintf(buf, sizeof(buf), "shell:rm ");
-    quoted = dupAndQuote(filename);
+    quoted = escape_arg(filename);
     strncat(buf, quoted, sizeof(buf)-1);
     free(quoted);
 
diff --git a/adb/file_sync_client.c b/adb/file_sync_client.c
index dc4e77f..d3cb113 100644
--- a/adb/file_sync_client.c
+++ b/adb/file_sync_client.c
@@ -25,6 +25,7 @@
 #include <limits.h>
 #include <sys/types.h>
 #include <zipfile/zipfile.h>
+#include <utime.h>
 
 #include "sysdeps.h"
 #include "adb.h"
@@ -139,7 +140,8 @@
 
 static syncsendbuf send_buffer;
 
-int sync_readtime(int fd, const char *path, unsigned *timestamp)
+int sync_readtime(int fd, const char *path, unsigned int *timestamp,
+                  unsigned int *mode)
 {
     syncmsg msg;
     int len = strlen(path);
@@ -161,6 +163,7 @@
     }
 
     *timestamp = ltohl(msg.stat.time);
+    *mode = ltohl(msg.stat.mode);
     return 0;
 }
 
@@ -237,7 +240,7 @@
     if (show_progress) {
         // Determine local file size.
         struct stat st;
-        if (lstat(path, &st)) {
+        if (fstat(lfd, &st)) {
             fprintf(stderr,"cannot stat '%s': %s\n", path, strerror(errno));
             return -1;
         }
@@ -931,8 +934,21 @@
     return 0;
 }
 
+static int set_time_and_mode(const char *lpath, unsigned int time, unsigned int mode)
+{
+    struct utimbuf times = { time, time };
+    int r1 = utime(lpath, &times);
+
+    /* use umask for permissions */
+    mode_t mask=umask(0000);
+    umask(mask);
+    int r2 = chmod(lpath, mode & ~mask);
+
+    return r1 ? : r2;
+}
+
 static int copy_remote_dir_local(int fd, const char *rpath, const char *lpath,
-                                 int checktimestamps)
+                                 int copy_attrs)
 {
     copyinfo *filelist = 0;
     copyinfo *ci, *next;
@@ -962,26 +978,6 @@
         return -1;
     }
 
-#if 0
-    if (checktimestamps) {
-        for (ci = filelist; ci != 0; ci = ci->next) {
-            if (sync_start_readtime(fd, ci->dst)) {
-                return 1;
-            }
-        }
-        for (ci = filelist; ci != 0; ci = ci->next) {
-            unsigned int timestamp, mode, size;
-            if (sync_finish_readtime(fd, &timestamp, &mode, &size))
-                return 1;
-            if (size == ci->size) {
-                /* for links, we cannot update the atime/mtime */
-                if ((S_ISREG(ci->mode & mode) && timestamp == ci->time) ||
-                    (S_ISLNK(ci->mode & mode) && timestamp >= ci->time))
-                    ci->flag = 1;
-            }
-        }
-    }
-#endif
     for (ci = filelist; ci != 0; ci = next) {
         next = ci->next;
         if (ci->flag == 0) {
@@ -989,6 +985,10 @@
             if (sync_recv(fd, ci->src, ci->dst, 0 /* no show progress */)) {
                 return 1;
             }
+
+            if (copy_attrs && set_time_and_mode(ci->dst, ci->time, ci->mode)) {
+               return 1;
+            }
             pulled++;
         } else {
             skipped++;
@@ -1003,9 +1003,9 @@
     return 0;
 }
 
-int do_sync_pull(const char *rpath, const char *lpath, int show_progress)
+int do_sync_pull(const char *rpath, const char *lpath, int show_progress, int copy_attrs)
 {
-    unsigned mode;
+    unsigned mode, time;
     struct stat st;
 
     int fd;
@@ -1016,7 +1016,7 @@
         return 1;
     }
 
-    if(sync_readmode(fd, rpath, &mode)) {
+    if(sync_readtime(fd, rpath, &time, &mode)) {
         return 1;
     }
     if(mode == 0) {
@@ -1047,13 +1047,15 @@
         if (sync_recv(fd, rpath, lpath, show_progress)) {
             return 1;
         } else {
+            if (copy_attrs && set_time_and_mode(lpath, time, mode))
+                return 1;
             END();
             sync_quit(fd);
             return 0;
         }
     } else if(S_ISDIR(mode)) {
         BEGIN();
-        if (copy_remote_dir_local(fd, rpath, lpath, 0)) {
+        if (copy_remote_dir_local(fd, rpath, lpath, copy_attrs)) {
             return 1;
         } else {
             END();
diff --git a/adb/file_sync_service.c b/adb/file_sync_service.c
index 1d80d26..b297552 100644
--- a/adb/file_sync_service.c
+++ b/adb/file_sync_service.c
@@ -178,18 +178,18 @@
     unsigned int timestamp = 0;
     int fd;
 
-    fd = adb_open_mode(path, O_WRONLY | O_CREAT | O_EXCL, mode);
+    fd = adb_open_mode(path, O_WRONLY | O_CREAT | O_EXCL | O_CLOEXEC, mode);
     if(fd < 0 && errno == ENOENT) {
         if(mkdirs(path) != 0) {
             if(fail_errno(s))
                 return -1;
             fd = -1;
         } else {
-            fd = adb_open_mode(path, O_WRONLY | O_CREAT | O_EXCL, mode);
+            fd = adb_open_mode(path, O_WRONLY | O_CREAT | O_EXCL | O_CLOEXEC, mode);
         }
     }
     if(fd < 0 && errno == EEXIST) {
-        fd = adb_open_mode(path, O_WRONLY, mode);
+        fd = adb_open_mode(path, O_WRONLY | O_CLOEXEC, mode);
     }
     if(fd < 0) {
         if(fail_errno(s))
@@ -383,7 +383,7 @@
     syncmsg msg;
     int fd, r;
 
-    fd = adb_open(path, O_RDONLY);
+    fd = adb_open(path, O_RDONLY | O_CLOEXEC);
     if(fd < 0) {
         if(fail_errno(s)) return -1;
         return 0;
diff --git a/adb/file_sync_service.h b/adb/file_sync_service.h
index 3e7e096..8ea239e 100644
--- a/adb/file_sync_service.h
+++ b/adb/file_sync_service.h
@@ -80,7 +80,7 @@
 int do_sync_ls(const char *path);
 int do_sync_push(const char *lpath, const char *rpath, int verifyApk, int show_progress);
 int do_sync_sync(const char *lpath, const char *rpath, int listonly);
-int do_sync_pull(const char *rpath, const char *lpath, int show_progress);
+int do_sync_pull(const char *rpath, const char *lpath, int show_progress, int pullTime);
 
 #define SYNC_DATA_MAX (64*1024)
 
diff --git a/adb/remount_service.c b/adb/remount_service.c
index d3a649b..3a4535e 100644
--- a/adb/remount_service.c
+++ b/adb/remount_service.c
@@ -39,7 +39,7 @@
     const char delims[] = "\n";
     char buf[4096];
 
-    fd = unix_open("/proc/mounts", O_RDONLY);
+    fd = unix_open("/proc/mounts", O_RDONLY | O_CLOEXEC);
     if (fd < 0)
         return NULL;
 
@@ -83,7 +83,7 @@
     if (!dev)
         return -1;
 
-    fd = unix_open(dev, O_RDONLY);
+    fd = unix_open(dev, O_RDONLY | O_CLOEXEC);
     if (fd < 0)
         return -1;
 
diff --git a/adb/services.c b/adb/services.c
index 7b809da..2c20b81 100644
--- a/adb/services.c
+++ b/adb/services.c
@@ -184,25 +184,38 @@
 }
 
 #if !ADB_HOST
-static int create_subprocess(const char *cmd, const char *arg0, const char *arg1, pid_t *pid)
+
+static void init_subproc_child()
 {
+    setsid();
+
+    // Set OOM score adjustment to prevent killing
+    int fd = adb_open("/proc/self/oom_score_adj", O_WRONLY | O_CLOEXEC);
+    if (fd >= 0) {
+        adb_write(fd, "0", 1);
+        adb_close(fd);
+    } else {
+       D("adb: unable to update oom_score_adj\n");
+    }
+}
+
+static int create_subproc_pty(const char *cmd, const char *arg0, const char *arg1, pid_t *pid)
+{
+    D("create_subproc_pty(cmd=%s, arg0=%s, arg1=%s)\n", cmd, arg0, arg1);
 #ifdef HAVE_WIN32_PROC
-    D("create_subprocess(cmd=%s, arg0=%s, arg1=%s)\n", cmd, arg0, arg1);
-    fprintf(stderr, "error: create_subprocess not implemented on Win32 (%s %s %s)\n", cmd, arg0, arg1);
+    fprintf(stderr, "error: create_subproc_pty not implemented on Win32 (%s %s %s)\n", cmd, arg0, arg1);
     return -1;
 #else /* !HAVE_WIN32_PROC */
-    char *devname;
     int ptm;
 
-    ptm = unix_open("/dev/ptmx", O_RDWR); // | O_NOCTTY);
+    ptm = unix_open("/dev/ptmx", O_RDWR | O_CLOEXEC); // | O_NOCTTY);
     if(ptm < 0){
         printf("[ cannot open /dev/ptmx - %s ]\n",strerror(errno));
         return -1;
     }
-    fcntl(ptm, F_SETFD, FD_CLOEXEC);
 
-    if(grantpt(ptm) || unlockpt(ptm) ||
-       ((devname = (char*) ptsname(ptm)) == 0)){
+    char devname[64];
+    if(grantpt(ptm) || unlockpt(ptm) || ptsname_r(ptm, devname, sizeof(devname)) != 0) {
         printf("[ trouble with /dev/ptmx - %s ]\n", strerror(errno));
         adb_close(ptm);
         return -1;
@@ -215,47 +228,74 @@
         return -1;
     }
 
-    if(*pid == 0){
-        int pts;
+    if (*pid == 0) {
+        init_subproc_child();
 
-        setsid();
-
-        pts = unix_open(devname, O_RDWR);
-        if(pts < 0) {
+        int pts = unix_open(devname, O_RDWR | O_CLOEXEC);
+        if (pts < 0) {
             fprintf(stderr, "child failed to open pseudo-term slave: %s\n", devname);
             exit(-1);
         }
 
-        dup2(pts, 0);
-        dup2(pts, 1);
-        dup2(pts, 2);
+        dup2(pts, STDIN_FILENO);
+        dup2(pts, STDOUT_FILENO);
+        dup2(pts, STDERR_FILENO);
 
         adb_close(pts);
         adb_close(ptm);
 
-        // set OOM adjustment to zero
-        char text[64];
-        snprintf(text, sizeof text, "/proc/%d/oom_adj", getpid());
-        int fd = adb_open(text, O_WRONLY);
-        if (fd >= 0) {
-            adb_write(fd, "0", 1);
-            adb_close(fd);
-        } else {
-           D("adb: unable to open %s\n", text);
-        }
         execl(cmd, cmd, arg0, arg1, NULL);
         fprintf(stderr, "- exec '%s' failed: %s (%d) -\n",
                 cmd, strerror(errno), errno);
         exit(-1);
     } else {
-        // Don't set child's OOM adjustment to zero.
-        // Let the child do it itself, as sometimes the parent starts
-        // running before the child has a /proc/pid/oom_adj.
-        // """adb: unable to open /proc/644/oom_adj""" seen in some logs.
         return ptm;
     }
 #endif /* !HAVE_WIN32_PROC */
 }
+
+static int create_subproc_raw(const char *cmd, const char *arg0, const char *arg1, pid_t *pid)
+{
+    D("create_subproc_raw(cmd=%s, arg0=%s, arg1=%s)\n", cmd, arg0, arg1);
+#ifdef HAVE_WIN32_PROC
+    fprintf(stderr, "error: create_subproc_raw not implemented on Win32 (%s %s %s)\n", cmd, arg0, arg1);
+    return -1;
+#else /* !HAVE_WIN32_PROC */
+
+    // 0 is parent socket, 1 is child socket
+    int sv[2];
+    if (unix_socketpair(AF_UNIX, SOCK_STREAM, 0, sv) < 0) {
+        printf("[ cannot create socket pair - %s ]\n", strerror(errno));
+        return -1;
+    }
+
+    *pid = fork();
+    if (*pid < 0) {
+        printf("- fork failed: %s -\n", strerror(errno));
+        adb_close(sv[0]);
+        adb_close(sv[1]);
+        return -1;
+    }
+
+    if (*pid == 0) {
+        adb_close(sv[0]);
+        init_subproc_child();
+
+        // Only hook up stdin/stdout; drop stderr
+        dup2(sv[1], STDIN_FILENO);
+        dup2(sv[1], STDOUT_FILENO);
+        adb_close(sv[1]);
+
+        execl(cmd, cmd, arg0, arg1, NULL);
+        fprintf(stderr, "- exec '%s' failed: %s (%d) -\n",
+                cmd, strerror(errno), errno);
+        exit(-1);
+    } else {
+        adb_close(sv[1]);
+        return sv[0];
+    }
+#endif /* !HAVE_WIN32_PROC */
+}
 #endif  /* !ABD_HOST */
 
 #if ADB_HOST
@@ -296,18 +336,32 @@
     }
 }
 
-static int create_subproc_thread(const char *name)
+static int create_subproc_thread(const char *name, const subproc_mode mode)
 {
     stinfo *sti;
     adb_thread_t t;
     int ret_fd;
-    pid_t pid;
-    if(name) {
-        ret_fd = create_subprocess(SHELL_COMMAND, "-c", name, &pid);
+    pid_t pid = -1;
+
+    const char *arg0, *arg1;
+    if (name == 0 || *name == 0) {
+        arg0 = "-"; arg1 = 0;
     } else {
-        ret_fd = create_subprocess(SHELL_COMMAND, "-", 0, &pid);
+        arg0 = "-c"; arg1 = name;
     }
-    D("create_subprocess() ret_fd=%d pid=%d\n", ret_fd, pid);
+
+    switch (mode) {
+    case SUBPROC_PTY:
+        ret_fd = create_subproc_pty(SHELL_COMMAND, arg0, arg1, &pid);
+        break;
+    case SUBPROC_RAW:
+        ret_fd = create_subproc_raw(SHELL_COMMAND, arg0, arg1, &pid);
+        break;
+    default:
+        fprintf(stderr, "invalid subproc_mode %d\n", mode);
+        return -1;
+    }
+    D("create_subproc ret_fd=%d pid=%d\n", ret_fd, pid);
 
     sti = malloc(sizeof(stinfo));
     if(sti == 0) fatal("cannot allocate stinfo");
@@ -315,14 +369,14 @@
     sti->cookie = (void*) (uintptr_t) pid;
     sti->fd = ret_fd;
 
-    if(adb_thread_create( &t, service_bootstrap_func, sti)){
+    if (adb_thread_create(&t, service_bootstrap_func, sti)) {
         free(sti);
         adb_close(ret_fd);
-        printf("cannot create service thread\n");
+        fprintf(stderr, "cannot create service thread\n");
         return -1;
     }
 
-    D("service thread started, fd=%d pid=%d\n",ret_fd, pid);
+    D("service thread started, fd=%d pid=%d\n", ret_fd, pid);
     return ret_fd;
 }
 #endif
@@ -361,33 +415,41 @@
 #endif
 #if !ADB_HOST
     } else if(!strncmp("dev:", name, 4)) {
-        ret = unix_open(name + 4, O_RDWR);
+        ret = unix_open(name + 4, O_RDWR | O_CLOEXEC);
     } else if(!strncmp(name, "framebuffer:", 12)) {
         ret = create_service_thread(framebuffer_service, 0);
     } else if (!strncmp(name, "jdwp:", 5)) {
         ret = create_jdwp_connection_fd(atoi(name+5));
     } else if(!HOST && !strncmp(name, "shell:", 6)) {
-        if(name[6]) {
-            ret = create_subproc_thread(name + 6);
-        } else {
-            ret = create_subproc_thread(0);
-        }
+        ret = create_subproc_thread(name + 6, SUBPROC_PTY);
+    } else if(!HOST && !strncmp(name, "exec:", 5)) {
+        ret = create_subproc_thread(name + 5, SUBPROC_RAW);
     } else if(!strncmp(name, "sync:", 5)) {
         ret = create_service_thread(file_sync_service, NULL);
     } else if(!strncmp(name, "remount:", 8)) {
         ret = create_service_thread(remount_service, NULL);
     } else if(!strncmp(name, "reboot:", 7)) {
         void* arg = strdup(name + 7);
-        if(arg == 0) return -1;
+        if (arg == NULL) return -1;
         ret = create_service_thread(reboot_service, arg);
     } else if(!strncmp(name, "root:", 5)) {
         ret = create_service_thread(restart_root_service, NULL);
     } else if(!strncmp(name, "backup:", 7)) {
-        char* arg = strdup(name+7);
+        char* arg = strdup(name + 7);
         if (arg == NULL) return -1;
-        ret = backup_service(BACKUP, arg);
+        char* c = arg;
+        for (; *c != '\0'; c++) {
+            if (*c == ':')
+                *c = ' ';
+        }
+        char* cmd;
+        if (asprintf(&cmd, "/system/bin/bu backup %s", arg) != -1) {
+            ret = create_subproc_thread(cmd, SUBPROC_RAW);
+            free(cmd);
+        }
+        free(arg);
     } else if(!strncmp(name, "restore:", 8)) {
-        ret = backup_service(RESTORE, NULL);
+        ret = create_subproc_thread("/system/bin/bu restore", SUBPROC_RAW);
     } else if(!strncmp(name, "tcpip:", 6)) {
         int port;
         if (sscanf(name + 6, "%d", &port) == 0) {
diff --git a/adb/sockets.c b/adb/sockets.c
index de14a22..faa9564 100644
--- a/adb/sockets.c
+++ b/adb/sockets.c
@@ -23,6 +23,10 @@
 
 #include "sysdeps.h"
 
+#if !ADB_HOST
+#include <cutils/properties.h>
+#endif
+
 #define  TRACE_TAG  TRACE_SOCKETS
 #include "adb.h"
 
@@ -428,6 +432,9 @@
 {
     asocket *s;
     int fd;
+#if !ADB_HOST
+    char debug[PROPERTY_VALUE_MAX];
+#endif
 
 #if !ADB_HOST
     if (!strcmp(name,"jdwp")) {
@@ -444,7 +451,11 @@
     D("LS(%d): bound to '%s' via %d\n", s->id, name, fd);
 
 #if !ADB_HOST
-    if ((!strncmp(name, "root:", 5) && getuid() != 0)
+    if (!strncmp(name, "root:", 5))
+        property_get("ro.debuggable", debug, "");
+
+    if ((!strncmp(name, "root:", 5) && getuid() != 0
+        && strcmp(debug, "1") == 0)
         || !strncmp(name, "usb:", 4)
         || !strncmp(name, "tcpip:", 6)) {
         D("LS(%d): enabling exit_on_close\n", s->id);
diff --git a/adb/usb_linux.c b/adb/usb_linux.c
index 8ff753e..f16bdd0 100644
--- a/adb/usb_linux.c
+++ b/adb/usb_linux.c
@@ -170,7 +170,7 @@
             }
 
 //            DBGX("[ scanning %s ]\n", devname);
-            if((fd = unix_open(devname, O_RDONLY)) < 0) {
+            if((fd = unix_open(devname, O_RDONLY | O_CLOEXEC)) < 0) {
                 continue;
             }
 
@@ -597,10 +597,10 @@
     usb->mark = 1;
     usb->reaper_thread = 0;
 
-    usb->desc = unix_open(usb->fname, O_RDWR);
+    usb->desc = unix_open(usb->fname, O_RDWR | O_CLOEXEC);
     if(usb->desc < 0) {
         /* if we fail, see if have read-only access */
-        usb->desc = unix_open(usb->fname, O_RDONLY);
+        usb->desc = unix_open(usb->fname, O_RDONLY | O_CLOEXEC);
         if(usb->desc < 0) goto fail;
         usb->writeable = 0;
         D("[ usb open read-only %s fd = %d]\n", usb->fname, usb->desc);
diff --git a/adb/usb_vendors.c b/adb/usb_vendors.c
index 957e5db..6288155 100755
--- a/adb/usb_vendors.c
+++ b/adb/usb_vendors.c
@@ -164,6 +164,8 @@
 #define VENDOR_ID_SK_TELESYS    0x1F53
 // Smartisan's USB Vendor ID
 #define VENDOR_ID_SMARTISAN     0x29a9
+// Sonim Tech's USB Vendor ID
+#define VENDOR_ID_SONIM_TECH    0x1d9c
 // Sony's USB Vendor ID
 #define VENDOR_ID_SONY          0x054C
 // Sony Ericsson's USB Vendor ID
@@ -261,6 +263,7 @@
     VENDOR_ID_SHARP,
     VENDOR_ID_SK_TELESYS,
     VENDOR_ID_SMARTISAN,
+    VENDOR_ID_SONIM_TECH,
     VENDOR_ID_SONY,
     VENDOR_ID_SONY_ERICSSON,
     VENDOR_ID_T_AND_A,
diff --git a/debuggerd/Android.mk b/debuggerd/Android.mk
index e4d7ecc..c33b263 100644
--- a/debuggerd/Android.mk
+++ b/debuggerd/Android.mk
@@ -22,13 +22,6 @@
     -Wunused \
     -Werror \
 
-ifeq ($(ARCH_ARM_HAVE_VFP),true)
-LOCAL_CFLAGS_arm += -DWITH_VFP
-endif # ARCH_ARM_HAVE_VFP
-ifeq ($(ARCH_ARM_HAVE_VFP_D32),true)
-LOCAL_CFLAGS_arm += -DWITH_VFP_D32
-endif # ARCH_ARM_HAVE_VFP_D32
-
 LOCAL_SHARED_LIBRARIES := \
     libbacktrace \
     libcutils \
@@ -45,6 +38,8 @@
 
 include $(BUILD_EXECUTABLE)
 
+
+
 include $(CLEAR_VARS)
 LOCAL_SRC_FILES := crasher.c
 LOCAL_SRC_FILES_arm    := arm/crashglue.S
@@ -59,36 +54,14 @@
 #LOCAL_FORCE_STATIC_EXECUTABLE := true
 LOCAL_SHARED_LIBRARIES := libcutils liblog libc
 
+# The arm emulator has VFP but not VFPv3-D32.
+ifeq ($(ARCH_ARM_HAVE_VFP_D32),true)
+LOCAL_ASFLAGS_arm += -DHAS_VFP_D32
+endif
+
 LOCAL_MODULE := crasher
 LOCAL_MODULE_STEM_32 := crasher
 LOCAL_MODULE_STEM_64 := crasher64
 LOCAL_MULTILIB := both
 
 include $(BUILD_EXECUTABLE)
-
-include $(CLEAR_VARS)
-
-ifeq ($(ARCH_ARM_HAVE_VFP),true)
-LOCAL_MODULE_TARGET_ARCH += arm
-LOCAL_SRC_FILES_arm := arm/vfp.S
-LOCAL_CFLAGS_arm += -DWITH_VFP
-ifeq ($(ARCH_ARM_HAVE_VFP_D32),true)
-LOCAL_CFLAGS_arm += -DWITH_VFP_D32
-endif # ARCH_ARM_HAVE_VFP_D32
-endif # ARCH_ARM_HAVE_VFP == true
-LOCAL_CFLAGS += -Werror
-
-LOCAL_SRC_FILES_arm64 := arm64/vfp.S
-LOCAL_MODULE_TARGET_ARCH += arm64
-
-LOCAL_SRC_FILES := vfp-crasher.c
-LOCAL_MODULE := vfp-crasher
-LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES)
-LOCAL_MODULE_TAGS := optional
-LOCAL_SHARED_LIBRARIES := libcutils liblog libc
-
-LOCAL_MODULE_STEM_32 := vfp-crasher
-LOCAL_MODULE_STEM_64 := vfp-crasher64
-LOCAL_MULTILIB := both
-
-include $(BUILD_EXECUTABLE)
diff --git a/debuggerd/arm/crashglue.S b/debuggerd/arm/crashglue.S
index eb9d0e3..4fbfd6e 100644
--- a/debuggerd/arm/crashglue.S
+++ b/debuggerd/arm/crashglue.S
@@ -1,8 +1,5 @@
 .globl crash1
 .type crash1, %function
-.globl crashnostack
-.type crashnostack, %function
-
 crash1:
 	ldr r0, =0xa5a50000
 	ldr r1, =0xa5a50001
@@ -18,11 +15,48 @@
 	ldr r11, =0xa5a50011
 	ldr r12, =0xa5a50012
 
+
+	fconstd   d0, #0
+	fconstd   d1, #1
+	fconstd   d2, #2
+	fconstd   d3, #3
+	fconstd   d4, #4
+	fconstd   d5, #5
+	fconstd   d6, #6
+	fconstd   d7, #7
+	fconstd   d8, #8
+	fconstd   d9, #9
+	fconstd   d10, #10
+	fconstd   d11, #11
+	fconstd   d12, #12
+	fconstd   d13, #13
+	fconstd   d14, #14
+	fconstd   d15, #15
+#if defined(HAS_VFP_D32)
+	fconstd   d16, #16
+	fconstd   d17, #17
+	fconstd   d18, #18
+	fconstd   d19, #19
+	fconstd   d20, #20
+	fconstd   d21, #21
+	fconstd   d22, #22
+	fconstd   d23, #23
+	fconstd   d24, #24
+	fconstd   d25, #25
+	fconstd   d26, #26
+	fconstd   d27, #27
+	fconstd   d28, #28
+	fconstd   d29, #29
+	fconstd   d30, #30
+	fconstd   d31, #31
+#endif
+
 	mov lr, #0
 	ldr lr, [lr]
 	b .
 
-
+.globl crashnostack
+.type crashnostack, %function
 crashnostack:
 	mov sp, #0
 	mov r0, #0
diff --git a/debuggerd/arm/machine.cpp b/debuggerd/arm/machine.cpp
index 839d47a..50e78c5 100644
--- a/debuggerd/arm/machine.cpp
+++ b/debuggerd/arm/machine.cpp
@@ -27,21 +27,8 @@
 #include "../utility.h"
 #include "../machine.h"
 
-// enable to dump memory pointed to by every register
-#define DUMP_MEMORY_FOR_ALL_REGISTERS 1
-
-#ifdef WITH_VFP
-#ifdef WITH_VFP_D32
-#define NUM_VFP_REGS 32
-#else
-#define NUM_VFP_REGS 16
-#endif
-#endif
-
-// If configured to do so, dump memory around *all* registers
-// for the crashing thread.
 void dump_memory_and_code(log_t* log, pid_t tid) {
-  struct pt_regs regs;
+  pt_regs regs;
   if (ptrace(PTRACE_GETREGS, tid, 0, &regs)) {
     return;
   }
@@ -73,7 +60,7 @@
 }
 
 void dump_registers(log_t* log, pid_t tid) {
-  struct pt_regs r;
+  pt_regs r;
   if (ptrace(PTRACE_GETREGS, tid, 0, &r)) {
     _LOG(log, logtype::REGISTERS, "cannot get registers: %s\n", strerror(errno));
     return;
@@ -93,19 +80,15 @@
        static_cast<uint32_t>(r.ARM_lr), static_cast<uint32_t>(r.ARM_pc),
        static_cast<uint32_t>(r.ARM_cpsr));
 
-#ifdef WITH_VFP
-  struct user_vfp vfp_regs;
-  int i;
-
+  user_vfp vfp_regs;
   if (ptrace(PTRACE_GETVFPREGS, tid, 0, &vfp_regs)) {
-    _LOG(log, logtype::REGISTERS, "cannot get registers: %s\n", strerror(errno));
+    _LOG(log, logtype::FP_REGISTERS, "cannot get FP registers: %s\n", strerror(errno));
     return;
   }
 
-  for (i = 0; i < NUM_VFP_REGS; i += 2) {
-    _LOG(log, logtype::REGISTERS, "    d%-2d %016llx  d%-2d %016llx\n",
+  for (size_t i = 0; i < 32; i += 2) {
+    _LOG(log, logtype::FP_REGISTERS, "    d%-2d %016llx  d%-2d %016llx\n",
          i, vfp_regs.fpregs[i], i+1, vfp_regs.fpregs[i+1]);
   }
-  _LOG(log, logtype::REGISTERS, "    scr %08lx\n", vfp_regs.fpscr);
-#endif
+  _LOG(log, logtype::FP_REGISTERS, "    scr %08lx\n", vfp_regs.fpscr);
 }
diff --git a/debuggerd/arm/vfp.S b/debuggerd/arm/vfp.S
deleted file mode 100644
index 9744f6f..0000000
--- a/debuggerd/arm/vfp.S
+++ /dev/null
@@ -1,43 +0,0 @@
-    .text
-    .align 2
-    .global crash
-    .type crash, %function
-crash:
-    fconstd   d0, #0
-    fconstd   d1, #1
-    fconstd   d2, #2
-    fconstd   d3, #3
-    fconstd   d4, #4
-    fconstd   d5, #5
-    fconstd   d6, #6
-    fconstd   d7, #7
-    fconstd   d8, #8
-    fconstd   d9, #9
-    fconstd   d10, #10
-    fconstd   d11, #11
-    fconstd   d12, #12
-    fconstd   d13, #13
-    fconstd   d14, #14
-    fconstd   d15, #15
-#ifdef WITH_VFP_D32
-    fconstd   d16, #16
-    fconstd   d17, #17
-    fconstd   d18, #18
-    fconstd   d19, #19
-    fconstd   d20, #20
-    fconstd   d21, #21
-    fconstd   d22, #22
-    fconstd   d23, #23
-    fconstd   d24, #24
-    fconstd   d25, #25
-    fconstd   d26, #26
-    fconstd   d27, #27
-    fconstd   d28, #28
-    fconstd   d29, #29
-    fconstd   d30, #30
-    fconstd   d31, #31
-#endif
-    mov       r0, #0
-    str       r0, [r0]
-    bx        lr
-
diff --git a/debuggerd/arm64/crashglue.S b/debuggerd/arm64/crashglue.S
index b06b67c..e58b542 100644
--- a/debuggerd/arm64/crashglue.S
+++ b/debuggerd/arm64/crashglue.S
@@ -1,8 +1,5 @@
 .globl crash1
 .type crash1, %function
-.globl crashnostack
-.type crashnostack, %function
-
 crash1:
 	ldr x0, =0xa5a50000
 	ldr x1, =0xa5a50001
@@ -35,11 +32,46 @@
 	ldr x28, =0xa5a50028
 	ldr x29, =0xa5a50029
 
+	fmov   d0, -1.0  // -1 is more convincing than 0.
+	fmov   d1, 1.0
+	fmov   d2, 2.0
+	fmov   d3, 3.0
+	fmov   d4, 4.0
+	fmov   d5, 5.0
+	fmov   d6, 6.0
+	fmov   d7, 7.0
+	fmov   d8, 8.0
+	fmov   d9, 9.0
+	fmov   d10, 10.0
+	fmov   d11, 11.0
+	fmov   d12, 12.0
+	fmov   d13, 13.0
+	fmov   d14, 14.0
+	fmov   d15, 15.0
+	fmov   d16, 16.0
+	fmov   d17, 17.0
+	fmov   d18, 18.0
+	fmov   d19, 19.0
+	fmov   d20, 20.0
+	fmov   d21, 21.0
+	fmov   d22, 22.0
+	fmov   d23, 23.0
+	fmov   d24, 24.0
+	fmov   d25, 25.0
+	fmov   d26, 26.0
+	fmov   d27, 27.0
+	fmov   d28, 28.0
+	fmov   d29, 29.0
+	fmov   d30, 30.0
+	fmov   d31, 31.0
+
 	mov x30, xzr
 	ldr x30, [x30]
 	b .
 
 
+.globl crashnostack
+.type crashnostack, %function
 crashnostack:
 	mov x0, xzr
 	add sp, x0, xzr
diff --git a/debuggerd/arm64/machine.cpp b/debuggerd/arm64/machine.cpp
index 48308c3..8b17d53 100644
--- a/debuggerd/arm64/machine.cpp
+++ b/debuggerd/arm64/machine.cpp
@@ -15,28 +15,18 @@
  * limitations under the License.
  */
 
-#include <stddef.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <stdio.h>
+#include <elf.h>
 #include <errno.h>
+#include <inttypes.h>
+#include <string.h>
 #include <sys/types.h>
 #include <sys/ptrace.h>
 #include <sys/user.h>
 #include <sys/uio.h>
-#include <linux/elf.h>
 
 #include "../utility.h"
 #include "../machine.h"
 
-/* enable to dump memory pointed to by every register */
-#define DUMP_MEMORY_FOR_ALL_REGISTERS 1
-
-/*
- * If configured to do so, dump memory around *all* registers
- * for the crashing thread.
- */
 void dump_memory_and_code(log_t* log, pid_t tid) {
     struct user_pt_regs regs;
     struct iovec io;
@@ -86,19 +76,18 @@
 
   for (int i = 0; i < 28; i += 4) {
     _LOG(log, logtype::REGISTERS,
-         "    x%-2d  %016lx  x%-2d  %016lx  x%-2d  %016lx  x%-2d  %016lx\n",
-         i, (uint64_t)r.regs[i],
-         i+1, (uint64_t)r.regs[i+1],
-         i+2, (uint64_t)r.regs[i+2],
-         i+3, (uint64_t)r.regs[i+3]);
+         "    x%-2d  %016llx  x%-2d  %016llx  x%-2d  %016llx  x%-2d  %016llx\n",
+         i, r.regs[i],
+         i+1, r.regs[i+1],
+         i+2, r.regs[i+2],
+         i+3, r.regs[i+3]);
   }
 
-  _LOG(log, logtype::REGISTERS, "    x28  %016lx  x29  %016lx  x30  %016lx\n",
-       (uint64_t)r.regs[28], (uint64_t)r.regs[29], (uint64_t)r.regs[30]);
+  _LOG(log, logtype::REGISTERS, "    x28  %016llx  x29  %016llx  x30  %016llx\n",
+       r.regs[28], r.regs[29], r.regs[30]);
 
-  _LOG(log, logtype::REGISTERS, "    sp   %016lx  pc   %016lx\n",
-       (uint64_t)r.sp, (uint64_t)r.pc);
-
+  _LOG(log, logtype::REGISTERS, "    sp   %016llx  pc   %016llx  pstate %016llx\n",
+       r.sp, r.pc, r.pstate);
 
   struct user_fpsimd_state f;
   io.iov_base = &f;
@@ -109,11 +98,15 @@
     return;
   }
 
-  for (int i = 0; i < 32; i += 4) {
-    _LOG(log, logtype::REGISTERS, "    v%-2d  %016lx  v%-2d  %016lx  v%-2d  %016lx  v%-2d  %016lx\n",
-         i, (uint64_t)f.vregs[i],
-         i+1, (uint64_t)f.vregs[i+1],
-         i+2, (uint64_t)f.vregs[i+2],
-         i+3, (uint64_t)f.vregs[i+3]);
+  for (int i = 0; i < 32; i += 2) {
+    _LOG(log, logtype::FP_REGISTERS,
+         "    v%-2d  %016" PRIx64 "%016" PRIx64 "  v%-2d  %016" PRIx64 "%016" PRIx64 "\n",
+         i,
+         static_cast<uint64_t>(f.vregs[i] >> 64),
+         static_cast<uint64_t>(f.vregs[i]),
+         i+1,
+         static_cast<uint64_t>(f.vregs[i+1] >> 64),
+         static_cast<uint64_t>(f.vregs[i+1]));
   }
+  _LOG(log, logtype::FP_REGISTERS, "    fpsr %08x  fpcr %08x\n", f.fpsr, f.fpcr);
 }
diff --git a/debuggerd/arm64/vfp.S b/debuggerd/arm64/vfp.S
deleted file mode 100644
index bf12c22..0000000
--- a/debuggerd/arm64/vfp.S
+++ /dev/null
@@ -1,42 +0,0 @@
-    .text
-    .align 2
-    .global crash
-    .type crash, %function
-crash:
-    fmov   d0, XZR
-    fmov   d1, 1.0
-    fmov   d2, 2.0
-    fmov   d3, 3.0
-    fmov   d4, 4.0
-    fmov   d5, 5.0
-    fmov   d6, 6.0
-    fmov   d7, 7.0
-    fmov   d8, 8.0
-    fmov   d9, 9.0
-    fmov   d10, 10.0
-    fmov   d11, 11.0
-    fmov   d12, 12.0
-    fmov   d13, 13.0
-    fmov   d14, 14.0
-    fmov   d15, 15.0
-    fmov   d16, 16.0
-    fmov   d17, 17.0
-    fmov   d18, 18.0
-    fmov   d19, 19.0
-    fmov   d20, 20.0
-    fmov   d21, 21.0
-    fmov   d22, 22.0
-    fmov   d23, 23.0
-    fmov   d24, 24.0
-    fmov   d25, 25.0
-    fmov   d26, 26.0
-    fmov   d27, 27.0
-    fmov   d28, 28.0
-    fmov   d29, 29.0
-    fmov   d30, 30.0
-    fmov   d31, 31.0
-
-    mov       x0, xzr
-    str       x0, [x0]
-    br        x30
-
diff --git a/debuggerd/crasher.c b/debuggerd/crasher.c
index e11d9af..d315ee5 100644
--- a/debuggerd/crasher.c
+++ b/debuggerd/crasher.c
@@ -7,6 +7,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <sys/cdefs.h>
+#include <sys/mman.h>
 #include <sys/ptrace.h>
 #include <sys/socket.h>
 #include <sys/wait.h>
@@ -140,11 +141,14 @@
     } else if (!strcmp(arg, "assert")) {
         __assert("some_file.c", 123, "false");
     } else if (!strcmp(arg, "assert2")) {
-      __assert2("some_file.c", 123, "some_function", "false");
+        __assert2("some_file.c", 123, "some_function", "false");
     } else if (!strcmp(arg, "LOG_ALWAYS_FATAL")) {
         LOG_ALWAYS_FATAL("hello %s", "world");
     } else if (!strcmp(arg, "LOG_ALWAYS_FATAL_IF")) {
         LOG_ALWAYS_FATAL_IF(true, "hello %s", "world");
+    } else if (!strcmp(arg, "SIGFPE")) {
+        raise(SIGFPE);
+        return EXIT_SUCCESS;
     } else if (!strcmp(arg, "SIGPIPE")) {
         int pipe_fds[2];
         pipe(pipe_fds);
@@ -156,6 +160,10 @@
         return EXIT_SUCCESS;
     } else if (!strcmp(arg, "heap-usage")) {
         abuse_heap();
+    } else if (!strcmp(arg, "SIGSEGV-unmapped")) {
+        char* map = mmap(NULL, sizeof(int), PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
+        munmap(map, sizeof(int));
+        map[0] = '8';
     }
 
     fprintf(stderr, "%s OP\n", __progname);
@@ -172,9 +180,11 @@
     fprintf(stderr, "  assert2               call assert() with a function\n");
     fprintf(stderr, "  LOG_ALWAYS_FATAL      call LOG_ALWAYS_FATAL\n");
     fprintf(stderr, "  LOG_ALWAYS_FATAL_IF   call LOG_ALWAYS_FATAL\n");
+    fprintf(stderr, "  SIGFPE                cause a SIGFPE\n");
     fprintf(stderr, "  SIGPIPE               cause a SIGPIPE\n");
     fprintf(stderr, "  SIGSEGV               cause a SIGSEGV at address 0x0 (synonym: crash)\n");
     fprintf(stderr, "  SIGSEGV-non-null      cause a SIGSEGV at a non-zero address\n");
+    fprintf(stderr, "  SIGSEGV-unmapped      mmap/munmap a region of memory and then attempt to access it\n");
     fprintf(stderr, "  SIGTRAP               cause a SIGTRAP\n");
     fprintf(stderr, "prefix any of the above with 'thread-' to not run\n");
     fprintf(stderr, "on the process' main thread.\n");
diff --git a/debuggerd/debuggerd.cpp b/debuggerd/debuggerd.cpp
index 61805c9..03d7e49 100644
--- a/debuggerd/debuggerd.cpp
+++ b/debuggerd/debuggerd.cpp
@@ -30,6 +30,8 @@
 #include <sys/stat.h>
 #include <sys/poll.h>
 
+#include <selinux/android.h>
+
 #include <log/logger.h>
 
 #include <cutils/sockets.h>
@@ -124,6 +126,53 @@
   return fields == 7 ? 0 : -1;
 }
 
+static int selinux_enabled;
+
+/*
+ * Corresponds with debugger_action_t enum type in
+ * include/cutils/debugger.h.
+ */
+static const char *debuggerd_perms[] = {
+  NULL, /* crash is only used on self, no check applied */
+  "dump_tombstone",
+  "dump_backtrace"
+};
+
+static bool selinux_action_allowed(int s, pid_t tid, debugger_action_t action)
+{
+  char *scon = NULL, *tcon = NULL;
+  const char *tclass = "debuggerd";
+  const char *perm;
+  bool allowed = false;
+
+  if (selinux_enabled <= 0)
+    return true;
+
+  if (action <= 0 || action >= (sizeof(debuggerd_perms)/sizeof(debuggerd_perms[0]))) {
+    ALOGE("SELinux:  No permission defined for debugger action %d", action);
+    return false;
+  }
+
+  perm = debuggerd_perms[action];
+
+  if (getpeercon(s, &scon) < 0) {
+    ALOGE("Cannot get peer context from socket\n");
+    goto out;
+  }
+
+  if (getpidcon(tid, &tcon) < 0) {
+    ALOGE("Cannot get context for tid %d\n", tid);
+    goto out;
+  }
+
+  allowed = (selinux_check_access(scon, tcon, tclass, perm, NULL) == 0);
+
+out:
+   freecon(scon);
+   freecon(tcon);
+   return allowed;
+}
+
 static int read_request(int fd, debugger_request_t* out_request) {
   ucred cr;
   socklen_t len = sizeof(cr);
@@ -186,6 +235,9 @@
       ALOGE("tid %d does not exist. ignoring explicit dump request\n", out_request->tid);
       return -1;
     }
+
+    if (!selinux_action_allowed(fd, out_request->tid, out_request->action))
+      return -1;
   } else {
     // No one else is allowed to dump arbitrary processes.
     return -1;
@@ -434,7 +486,11 @@
 }
 
 int main(int argc, char** argv) {
+  union selinux_callback cb;
   if (argc == 1) {
+    selinux_enabled = is_selinux_enabled();
+    cb.func_log = selinux_log_callback;
+    selinux_set_callback(SELINUX_CB_LOG, cb);
     return do_server();
   }
 
diff --git a/debuggerd/tombstone.cpp b/debuggerd/tombstone.cpp
index dea016d..2b9d093 100755
--- a/debuggerd/tombstone.cpp
+++ b/debuggerd/tombstone.cpp
@@ -210,6 +210,12 @@
       }
     }
   }
+  // Blacklist logd, logd.reader, logd.writer, logd.auditd, logd.control ...
+  static const char logd[] = "logd";
+  if (!strncmp(threadname, logd, sizeof(logd) - 1)
+      && (!threadname[sizeof(logd) - 1] || (threadname[sizeof(logd) - 1] == '.'))) {
+    log->should_retrieve_logcat = false;
+  }
 
   char procnamebuf[1024];
   char* procname = NULL;
@@ -329,10 +335,11 @@
 }
 
 static void dump_map(log_t* log, const backtrace_map_t* map, bool fault_addr) {
-  _LOG(log, logtype::MAPS, "%s%" PRIPTR "-%" PRIPTR " %c%c%c %s\n",
-         (fault_addr? "--->" : "    "), map->start, map->end,
+  _LOG(log, logtype::MAPS, "%s%" PRIPTR "-%" PRIPTR " %c%c%c  %7" PRIdPTR "  %s\n",
+         (fault_addr? "--->" : "    "), map->start, map->end - 1,
          (map->flags & PROT_READ) ? 'r' : '-', (map->flags & PROT_WRITE) ? 'w' : '-',
-         (map->flags & PROT_EXEC) ? 'x' : '-', map->name.c_str());
+         (map->flags & PROT_EXEC) ? 'x' : '-',
+         (map->end - map->start), map->name.c_str());
 }
 
 static void dump_nearby_maps(BacktraceMap* map, log_t* log, pid_t tid) {
@@ -342,28 +349,31 @@
     _LOG(log, logtype::MAPS, "cannot get siginfo for %d: %s\n", tid, strerror(errno));
     return;
   }
-  if (!signal_has_si_addr(si.si_signo)) {
-    return;
-  }
 
+  bool is_running = (si.si_code == SI_USER);
   uintptr_t addr = reinterpret_cast<uintptr_t>(si.si_addr);
   addr &= ~0xfff;     // round to 4K page boundary
-  if (addr == 0) {    // null-pointer deref
+  if (!is_running && addr == 0) {    // null-pointer deref
     return;
   }
 
-  _LOG(log, logtype::MAPS, "\nmemory map: (fault address prefixed with --->)\n");
+  _LOG(log, logtype::MAPS, "\nmemory map: %s\n", is_running? "" : "(fault address prefixed with --->)");
 
-  bool found_map = false;
-  for (BacktraceMap::const_iterator it = map->begin(); it != map->end(); ++it) {
-    bool in_map = addr >= (*it).start && addr < (*it).end;
-    dump_map(log, &*it, in_map);
-    if(in_map) {
-      found_map = true;
-    }
+  if(!is_running && (addr < map->begin()->start)) {
+    _LOG(log, logtype::MAPS, "--->Fault address falls at %" PRIPTR " before any mapped regions\n", addr);
   }
-  if(!found_map) {
-    _LOG(log, logtype::ERROR, "\nFault address was not in any map!");
+
+  BacktraceMap::const_iterator prev = map->begin();
+  for (BacktraceMap::const_iterator it = map->begin(); it != map->end(); ++it) {
+    if (addr >= (*prev).end && addr < (*it).start) {
+      _LOG(log, logtype::MAPS, "--->Fault address falls at %" PRIPTR " between mapped regions\n", addr);
+    }
+    prev = it;
+    bool in_map = !is_running && (addr >= (*it).start) && (addr < (*it).end);
+    dump_map(log, &*it, in_map);
+  }
+  if (!is_running && (addr >= (*prev).end)) {
+    _LOG(log, logtype::MAPS, "--->Fault address falls at %" PRIPTR " after any mapped regions\n", addr);
   }
 }
 
@@ -446,6 +456,10 @@
   bool first = true;
   struct logger_list* logger_list;
 
+  if (!log->should_retrieve_logcat) {
+    return;
+  }
+
   logger_list = android_logger_list_open(
       android_name_to_log_id(filename), O_RDONLY | O_NONBLOCK, tail, pid);
 
diff --git a/debuggerd/utility.cpp b/debuggerd/utility.cpp
index a163344..9a30fe3 100644
--- a/debuggerd/utility.cpp
+++ b/debuggerd/utility.cpp
@@ -59,6 +59,8 @@
 void _LOG(log_t* log, enum logtype ltype, const char* fmt, ...) {
   bool write_to_tombstone = (log->tfd != -1);
   bool write_to_logcat = is_allowed_in_logcat(ltype)
+                      && log->crashed_tid != -1
+                      && log->current_tid != -1
                       && (log->crashed_tid == log->current_tid);
   bool write_to_activitymanager = (log->amfd != -1);
 
diff --git a/debuggerd/utility.h b/debuggerd/utility.h
index f2e2d29..82413b8 100644
--- a/debuggerd/utility.h
+++ b/debuggerd/utility.h
@@ -2,16 +2,16 @@
 **
 ** Copyright 2008, 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 
+** 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 
+**     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 
+** 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.
 */
 
@@ -37,7 +37,7 @@
 #endif
 
 
-typedef struct {
+struct log_t{
     /* tombstone file descriptor */
     int tfd;
     /* Activity Manager socket file descriptor */
@@ -46,7 +46,12 @@
     pid_t crashed_tid;
     // The tid of the thread we are currently working with.
     pid_t current_tid;
-} log_t;
+    // logd daemon crash, can block asking for logcat data, allow suppression.
+    bool should_retrieve_logcat;
+
+    log_t()
+        : tfd(-1), amfd(-1), crashed_tid(-1), current_tid(-1), should_retrieve_logcat(true) {}
+};
 
 // List of types of logs to simplify the logging decision in _LOG
 enum logtype {
@@ -54,6 +59,7 @@
   HEADER,
   THREAD,
   REGISTERS,
+  FP_REGISTERS,
   BACKTRACE,
   MAPS,
   MEMORY,
diff --git a/debuggerd/vfp-crasher.c b/debuggerd/vfp-crasher.c
deleted file mode 100644
index 7a19cdd..0000000
--- a/debuggerd/vfp-crasher.c
+++ /dev/null
@@ -1,7 +0,0 @@
-int main()
-{
-  extern void crash(void);
-
-  crash();
-  return 0;
-}
diff --git a/fastboot/Android.mk b/fastboot/Android.mk
index 73794a0..112bd02 100644
--- a/fastboot/Android.mk
+++ b/fastboot/Android.mk
@@ -31,6 +31,7 @@
   LOCAL_SRC_FILES += usb_osx.c util_osx.c
   LOCAL_LDLIBS += -lpthread -framework CoreFoundation -framework IOKit \
 	-framework Carbon
+  LOCAL_CFLAGS += -Wno-unused-parameter
 endif
 
 ifeq ($(HOST_OS),windows)
diff --git a/fastboot/fs.h b/fastboot/fs.h
index 8388629..8444081 100644
--- a/fastboot/fs.h
+++ b/fastboot/fs.h
@@ -1,5 +1,5 @@
 #ifndef _FS_H_
-#define _FH_H_
+#define _FS_H_
 
 #include <stdint.h>
 
diff --git a/fastboot/usb_linux.c b/fastboot/usb_linux.c
index a45f9f8..fabbd51 100644
--- a/fastboot/usb_linux.c
+++ b/fastboot/usb_linux.c
@@ -100,12 +100,12 @@
 
 static int check(void *_desc, int len, unsigned type, int size)
 {
-    unsigned char *desc = _desc;
+    struct usb_descriptor_header *hdr = (struct usb_descriptor_header *)_desc;
 
     if(len < size) return -1;
-    if(desc[0] < size) return -1;
-    if(desc[0] > len) return -1;
-    if(desc[1] != type) return -1;
+    if(hdr->bLength < size) return -1;
+    if(hdr->bLength > len) return -1;
+    if(hdr->bDescriptorType != type) return -1;
 
     return 0;
 }
@@ -125,15 +125,15 @@
     unsigned i;
     unsigned e;
     
-    if(check(ptr, len, USB_DT_DEVICE, USB_DT_DEVICE_SIZE))
+    if (check(ptr, len, USB_DT_DEVICE, USB_DT_DEVICE_SIZE))
         return -1;
-    dev = (void*) ptr;
+    dev = (struct usb_device_descriptor *)ptr;
     len -= dev->bLength;
     ptr += dev->bLength;
 
-    if(check(ptr, len, USB_DT_CONFIG, USB_DT_CONFIG_SIZE))
+    if (check(ptr, len, USB_DT_CONFIG, USB_DT_CONFIG_SIZE))
         return -1;
-    cfg = (void*) ptr;
+    cfg = (struct usb_config_descriptor *)ptr;
     len -= cfg->bLength;
     ptr += cfg->bLength;
 
@@ -177,9 +177,19 @@
     }
 
     for(i = 0; i < cfg->bNumInterfaces; i++) {
-        if(check(ptr, len, USB_DT_INTERFACE, USB_DT_INTERFACE_SIZE))
+
+        while (len > 0) {
+	        struct usb_descriptor_header *hdr = (struct usb_descriptor_header *)ptr;
+            if (check(hdr, len, USB_DT_INTERFACE, USB_DT_INTERFACE_SIZE) == 0)
+                break;
+            len -= hdr->bLength;
+            ptr += hdr->bLength;
+        }
+
+        if (len <= 0)
             return -1;
-        ifc = (void*) ptr;
+
+        ifc = (struct usb_interface_descriptor *)ptr;
         len -= ifc->bLength;
         ptr += ifc->bLength;
 
@@ -190,16 +200,25 @@
         info.ifc_protocol = ifc->bInterfaceProtocol;
 
         for(e = 0; e < ifc->bNumEndpoints; e++) {
-            if(check(ptr, len, USB_DT_ENDPOINT, USB_DT_ENDPOINT_SIZE))
-                return -1;
-            ept = (void*) ptr;
+            while (len > 0) {
+	            struct usb_descriptor_header *hdr = (struct usb_descriptor_header *)ptr;
+                if (check(hdr, len, USB_DT_ENDPOINT, USB_DT_ENDPOINT_SIZE) == 0)
+                    break;
+                len -= hdr->bLength;
+                ptr += hdr->bLength;
+            }
+            if (len < 0) {
+                break;
+            }
+
+            ept = (struct usb_endpoint_descriptor *)ptr;
             len -= ept->bLength;
             ptr += ept->bLength;
 
-            if((ept->bmAttributes & 0x03) != 0x02)
+            if((ept->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_BULK)
                 continue;
 
-            if(ept->bEndpointAddress & 0x80) {
+            if(ept->bEndpointAddress & USB_ENDPOINT_DIR_MASK) {
                 in = ept->bEndpointAddress;
             } else {
                 out = ept->bEndpointAddress;
diff --git a/healthd/BatteryMonitor.cpp b/healthd/BatteryMonitor.cpp
index 688c7ff..fa87274 100644
--- a/healthd/BatteryMonitor.cpp
+++ b/healthd/BatteryMonitor.cpp
@@ -37,7 +37,7 @@
 namespace android {
 
 struct sysfsStringEnumMap {
-    char* s;
+    const char* s;
     int val;
 };
 
diff --git a/include/backtrace/BacktraceMap.h b/include/backtrace/BacktraceMap.h
index c717f09..4ed23a8 100644
--- a/include/backtrace/BacktraceMap.h
+++ b/include/backtrace/BacktraceMap.h
@@ -41,7 +41,10 @@
 
 class BacktraceMap {
 public:
-  static BacktraceMap* Create(pid_t pid);
+  // If uncached is true, then parse the current process map as of the call.
+  // Passing a map created with uncached set to true to Backtrace::Create()
+  // is unsupported.
+  static BacktraceMap* Create(pid_t pid, bool uncached = false);
 
   virtual ~BacktraceMap();
 
diff --git a/include/cutils/atomic.h b/include/cutils/atomic.h
index 1787e34..b9b18c4 100644
--- a/include/cutils/atomic.h
+++ b/include/cutils/atomic.h
@@ -25,8 +25,20 @@
 #endif
 
 /*
- * A handful of basic atomic operations.  The appropriate pthread
- * functions should be used instead of these whenever possible.
+ * A handful of basic atomic operations.
+ * THESE ARE HERE FOR LEGACY REASONS ONLY.  AVOID.
+ *
+ * PREFERRED ALTERNATIVES:
+ * - Use C++/C/pthread locks/mutexes whenever there is not a
+ *   convincing reason to do otherwise.  Note that very clever and
+ *   complicated, but correct, lock-free code is often slower than
+ *   using locks, especially where nontrivial data structures
+ *   are involved.
+ * - C11 stdatomic.h.
+ * - Where supported, C++11 std::atomic<T> .
+ *
+ * PLEASE STOP READING HERE UNLESS YOU ARE TRYING TO UNDERSTAND
+ * OR UPDATE OLD CODE.
  *
  * The "acquire" and "release" terms can be defined intuitively in terms
  * of the placement of memory barriers in a simple lock implementation:
@@ -74,6 +86,17 @@
 /*
  * Perform an atomic load with "acquire" or "release" ordering.
  *
+ * Note that the notion of a "release" ordering for a load does not
+ * really fit into the C11 or C++11 memory model.  The extra ordering
+ * is normally observable only by code using memory_order_relaxed
+ * atomics, or data races.  In the rare cases in which such ordering
+ * is called for, use memory_order_relaxed atomics and a leading
+ * atomic_thread_fence (typically with memory_order_acquire,
+ * not memory_order_release!) instead.  If you do not understand
+ * this comment, you are in the vast majority, and should not be
+ * using release loads or replacing them with anything other than
+ * locks or default sequentially consistent atomics.
+ *
  * This is only necessary if you need the memory barrier.  A 32-bit read
  * from a 32-bit aligned address is atomic on all supported platforms.
  */
@@ -88,6 +111,14 @@
 /*
  * Perform an atomic store with "acquire" or "release" ordering.
  *
+ * Note that the notion of a "acquire" ordering for a store does not
+ * really fit into the C11 or C++11 memory model.  The extra ordering
+ * is normally observable only by code using memory_order_relaxed
+ * atomics, or data races.  In the rare cases in which such ordering
+ * is called for, use memory_order_relaxed atomics and a trailing
+ * atomic_thread_fence (typically with memory_order_release,
+ * not memory_order_acquire!) instead.
+ *
  * This is only necessary if you need the memory barrier.  A 32-bit write
  * to a 32-bit aligned address is atomic on all supported platforms.
  */
diff --git a/include/cutils/jstring.h b/include/cutils/jstring.h
index ee0018f..a342608 100644
--- a/include/cutils/jstring.h
+++ b/include/cutils/jstring.h
@@ -24,7 +24,10 @@
 extern "C" {
 #endif
 
-typedef uint16_t char16_t;
+#if __STDC_VERSION__ < 201112L && __cplusplus < 201103L
+  typedef uint16_t char16_t;
+#endif
+  // otherwise char16_t is a keyword with the right semantics
 
 extern char * strndup16to8 (const char16_t* s, size_t n);
 extern size_t strnlen16to8 (const char16_t* s, size_t n);
diff --git a/include/cutils/tztime.h b/include/cutils/tztime.h
deleted file mode 100644
index dbdbd60..0000000
--- a/include/cutils/tztime.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright (C) 2006 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_TZTIME_H
-#define _CUTILS_TZTIME_H
-
-// TODO: fix both callers to just include <bionic_time.h> themselves.
-#include <bionic_time.h>
-
-#endif /* __CUTILS_TZTIME_H */ 
-
diff --git a/include/private/pixelflinger/ggl_fixed.h b/include/private/pixelflinger/ggl_fixed.h
index d0493f3..787f620 100644
--- a/include/private/pixelflinger/ggl_fixed.h
+++ b/include/private/pixelflinger/ggl_fixed.h
@@ -190,7 +190,7 @@
         );
     return res;
 }
-#elif defined(__mips__)
+#elif defined(__mips__) && __mips_isa_rev < 6
 
 /*inline MIPS implementations*/
 inline GGLfixed gglMulx(GGLfixed a, GGLfixed b, int shift) CONST;
diff --git a/init/bootchart.c b/init/bootchart.c
index f72fcaa..a514261 100644
--- a/init/bootchart.c
+++ b/init/bootchart.c
@@ -119,6 +119,18 @@
     }
 }
 
+static long long
+get_uptime_jiffies()
+{
+    char       buff[64];
+    long long  jiffies = 0;
+
+    if (proc_read("/proc/uptime", buff, sizeof(buff)) > 0)
+        jiffies = 100LL*strtod(buff,NULL);
+
+    return jiffies;
+}
+
 static void
 log_header(void)
 {
@@ -185,22 +197,11 @@
 do_log_uptime(FileBuff  log)
 {
     char  buff[65];
-    int   fd, ret, len;
+    int   len;
 
-    fd = open("/proc/uptime",O_RDONLY);
-    if (fd >= 0) {
-        int  ret;
-        ret = unix_read(fd, buff, 64);
-        close(fd);
-        buff[64] = 0;
-        if (ret >= 0) {
-            long long  jiffies = 100LL*strtod(buff,NULL);
-            int        len;
-            snprintf(buff,sizeof(buff),"%lld\n",jiffies);
-            len = strlen(buff);
-            file_buff_write(log, buff, len);
-        }
-    }
+    snprintf(buff,sizeof(buff),"%lld\n",get_uptime_jiffies());
+    len = strlen(buff);
+    file_buff_write(log, buff, len);
 }
 
 static void
@@ -376,3 +377,9 @@
     file_buff_done(log_procs);
     acct(NULL);
 }
+
+/* called to get time (in ms) used by bootchart */
+long long  bootchart_gettime( void )
+{
+    return 10LL*get_uptime_jiffies();
+}
diff --git a/init/bootchart.h b/init/bootchart.h
index 39d2d4f..ed65e8a 100644
--- a/init/bootchart.h
+++ b/init/bootchart.h
@@ -26,6 +26,7 @@
 extern int   bootchart_init(void);
 extern int   bootchart_step(void);
 extern void  bootchart_finish(void);
+extern long long  bootchart_gettime(void);
 
 # define BOOTCHART_POLLING_MS   200   /* polling period in ms */
 # define BOOTCHART_DEFAULT_TIME_SEC    (2*60)  /* default polling time in seconds */
diff --git a/init/builtins.c b/init/builtins.c
index b32981e..c474198 100644
--- a/init/builtins.c
+++ b/init/builtins.c
@@ -48,7 +48,7 @@
 
 #include <private/android_filesystem_config.h>
 
-void add_environment(const char *name, const char *value);
+int add_environment(const char *name, const char *value);
 
 extern int init_module(void *, unsigned long, const char *);
 
@@ -261,8 +261,7 @@
 
 int do_export(int nargs, char **args)
 {
-    add_environment(args[1], args[2]);
-    return 0;
+    return add_environment(args[1], args[2]);
 }
 
 int do_hostname(int nargs, char **args)
diff --git a/init/init.c b/init/init.c
index e4ac1cf..99474e6 100644
--- a/init/init.c
+++ b/init/init.c
@@ -65,6 +65,7 @@
 
 #if BOOTCHART
 static int   bootchart_count;
+static long long bootchart_time = 0;
 #endif
 
 static char console[32];
@@ -96,11 +97,24 @@
 /* add_environment - add "key=value" to the current environment */
 int add_environment(const char *key, const char *val)
 {
-    int n;
+    size_t n;
+    size_t key_len = strlen(key);
 
-    for (n = 0; n < 31; n++) {
-        if (!ENV[n]) {
-            size_t len = strlen(key) + strlen(val) + 2;
+    /* The last environment entry is reserved to terminate the list */
+    for (n = 0; n < (ARRAY_SIZE(ENV) - 1); n++) {
+
+        /* Delete any existing entry for this key */
+        if (ENV[n] != NULL) {
+            size_t entry_key_len = strcspn(ENV[n], "=");
+            if ((entry_key_len == key_len) && (strncmp(ENV[n], key, entry_key_len) == 0)) {
+                free((char*)ENV[n]);
+                ENV[n] = NULL;
+            }
+        }
+
+        /* Add entry if a free slot is available */
+        if (ENV[n] == NULL) {
+            size_t len = key_len + strlen(val) + 2;
             char *entry = malloc(len);
             snprintf(entry, len, "%s=%s", key, val);
             ENV[n] = entry;
@@ -108,7 +122,9 @@
         }
     }
 
-    return 1;
+    ERROR("No env. room to store: '%s':'%s'\n", key, val);
+
+    return -1;
 }
 
 static void zap_stdio(void)
@@ -802,27 +818,21 @@
      * that /data/local.prop cannot interfere with them.
      */
     start_property_service();
+    if (get_property_set_fd() < 0) {
+        ERROR("start_property_service() failed\n");
+        exit(1);
+    }
+
     return 0;
 }
 
 static int signal_init_action(int nargs, char **args)
 {
     signal_init();
-    return 0;
-}
-
-static int check_startup_action(int nargs, char **args)
-{
-    /* make sure we actually have all the pieces we need */
-    if ((get_property_set_fd() < 0) ||
-        (get_signal_fd() < 0)) {
-        ERROR("init startup failure\n");
+    if (get_signal_fd() < 0) {
+        ERROR("signal_init() failed\n");
         exit(1);
     }
-
-        /* signal that we hit this point */
-    unlink("/dev/.booting");
-
     return 0;
 }
 
@@ -1083,7 +1093,6 @@
     queue_builtin_action(mix_hwrng_into_linux_rng_action, "mix_hwrng_into_linux_rng");
     queue_builtin_action(property_service_init_action, "property_service_init");
     queue_builtin_action(signal_init_action, "signal_init");
-    queue_builtin_action(check_startup_action, "check_startup");
 
     /* Don't mount filesystems or start core system services if in charger mode. */
     if (is_charger) {
@@ -1092,7 +1101,7 @@
         action_for_each_trigger("late-init", action_add_queue_tail);
     }
 
-        /* run all property triggers based on current state of the properties */
+    /* run all property triggers based on current state of the properties */
     queue_builtin_action(queue_property_triggers_action, "queue_property_triggers");
 
 
@@ -1139,11 +1148,29 @@
 
 #if BOOTCHART
         if (bootchart_count > 0) {
-            if (timeout < 0 || timeout > BOOTCHART_POLLING_MS)
-                timeout = BOOTCHART_POLLING_MS;
-            if (bootchart_step() < 0 || --bootchart_count == 0) {
-                bootchart_finish();
-                bootchart_count = 0;
+            long long current_time;
+            int elapsed_time, remaining_time;
+
+            current_time = bootchart_gettime();
+            elapsed_time = current_time - bootchart_time;
+
+            if (elapsed_time >= BOOTCHART_POLLING_MS) {
+                /* count missed samples */
+                while (elapsed_time >= BOOTCHART_POLLING_MS) {
+                    elapsed_time -= BOOTCHART_POLLING_MS;
+                    bootchart_count--;
+                }
+                /* count may be negative, take a sample anyway */
+                bootchart_time = current_time;
+                if (bootchart_step() < 0 || bootchart_count <= 0) {
+                    bootchart_finish();
+                    bootchart_count = 0;
+                }
+            }
+            if (bootchart_count > 0) {
+                remaining_time = BOOTCHART_POLLING_MS - elapsed_time;
+                if (timeout < 0 || timeout > remaining_time)
+                    timeout = remaining_time;
             }
         }
 #endif
diff --git a/init/readme.txt b/init/readme.txt
index 613a9e9..26be536 100644
--- a/init/readme.txt
+++ b/init/readme.txt
@@ -257,9 +257,9 @@
   or the timeout has been reached. If timeout is not specified it
   currently defaults to five seconds.
 
-write <path> <string> [ <string> ]*
-   Open the file at <path> and write one or more strings
-   to it with write(2)
+write <path> <string>
+   Open the file at <path> and write a string to it with write(2)
+   without appending.
 
 
 Properties
diff --git a/libbacktrace/Android.build.mk b/libbacktrace/Android.build.mk
index 2f55645..2685380 100644
--- a/libbacktrace/Android.build.mk
+++ b/libbacktrace/Android.build.mk
@@ -73,6 +73,7 @@
 ifeq ($(build_type),host)
   # Only build if host builds are supported.
   ifeq ($(build_host),true)
+    LOCAL_CFLAGS += -Wno-extern-c-compat
     ifneq ($($(module)_libc++),)
       include external/libcxx/libcxx.mk
     endif
diff --git a/libbacktrace/BacktraceMap.cpp b/libbacktrace/BacktraceMap.cpp
index 0056f4b..f38e484 100644
--- a/libbacktrace/BacktraceMap.cpp
+++ b/libbacktrace/BacktraceMap.cpp
@@ -137,7 +137,7 @@
 #if defined(__APPLE__)
 // Corkscrew and libunwind don't compile on the mac, so create a generic
 // map object.
-BacktraceMap* BacktraceMap::Create(pid_t pid) {
+BacktraceMap* BacktraceMap::Create(pid_t pid, bool uncached) {
   BacktraceMap* map = new BacktraceMap(pid);
   if (!map->Build()) {
     delete map;
diff --git a/libbacktrace/UnwindMap.cpp b/libbacktrace/UnwindMap.cpp
index 4f9831b..387d768 100644
--- a/libbacktrace/UnwindMap.cpp
+++ b/libbacktrace/UnwindMap.cpp
@@ -130,9 +130,13 @@
 //-------------------------------------------------------------------------
 // BacktraceMap create function.
 //-------------------------------------------------------------------------
-BacktraceMap* BacktraceMap::Create(pid_t pid) {
+BacktraceMap* BacktraceMap::Create(pid_t pid, bool uncached) {
   BacktraceMap* map;
-  if (pid == getpid()) {
+
+  if (uncached) {
+    // Force use of the base class to parse the maps when this call is made.
+    map = new BacktraceMap(pid);
+  } else if (pid == getpid()) {
     map = new UnwindMapLocal();
   } else {
     map = new UnwindMap(pid);
diff --git a/libcutils/Android.mk b/libcutils/Android.mk
index 933a77b..12a3bf9 100644
--- a/libcutils/Android.mk
+++ b/libcutils/Android.mk
@@ -86,19 +86,6 @@
 include $(BUILD_HOST_STATIC_LIBRARY)
 
 
-# Static library for host, 64-bit
-# ========================================================
-include $(CLEAR_VARS)
-LOCAL_MODULE := lib64cutils
-LOCAL_SRC_FILES := $(commonSources) $(commonHostSources) dlmalloc_stubs.c
-LOCAL_STATIC_LIBRARIES := lib64log
-LOCAL_CFLAGS += $(hostSmpFlag) -m64
-ifneq ($(HOST_OS),windows)
-LOCAL_CFLAGS += -Werror
-endif
-LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
-include $(BUILD_HOST_STATIC_LIBRARY)
-
 # Tests for host
 # ========================================================
 include $(CLEAR_VARS)
@@ -137,9 +124,17 @@
 LOCAL_SRC_FILES_arm64 += \
         arch-arm64/android_memset.S \
 
+ifndef ARCH_MIPS_REV6
 LOCAL_SRC_FILES_mips += \
         arch-mips/android_memset.c \
 
+LOCAL_CFLAGS_mips += -DHAVE_MEMSET16 -DHAVE_MEMSET32
+endif
+
+# TODO: switch mips64 back to using arch-mips/android_memset.c
+LOCAL_SRC_FILES_mips64 += \
+#       arch-mips/android_memset.c \
+
 LOCAL_SRC_FILES_x86 += \
         arch-x86/android_memset16.S \
         arch-x86/android_memset32.S \
@@ -150,7 +145,7 @@
 
 LOCAL_CFLAGS_arm += -DHAVE_MEMSET16 -DHAVE_MEMSET32
 LOCAL_CFLAGS_arm64 += -DHAVE_MEMSET16 -DHAVE_MEMSET32
-LOCAL_CFLAGS_mips += -DHAVE_MEMSET16 -DHAVE_MEMSET32
+#LOCAL_CFLAGS_mips64 += -DHAVE_MEMSET16 -DHAVE_MEMSET32
 LOCAL_CFLAGS_x86 += -DHAVE_MEMSET16 -DHAVE_MEMSET32
 LOCAL_CFLAGS_x86_64 += -DHAVE_MEMSET16 -DHAVE_MEMSET32
 
diff --git a/liblog/Android.mk b/liblog/Android.mk
index a7eead9..a4e5f5e 100644
--- a/liblog/Android.mk
+++ b/liblog/Android.mk
@@ -71,14 +71,6 @@
 include $(BUILD_HOST_SHARED_LIBRARY)
 
 
-# Static library for host, 64-bit
-# ========================================================
-include $(CLEAR_VARS)
-LOCAL_MODULE := lib64log
-LOCAL_SRC_FILES := $(liblog_host_sources)
-LOCAL_CFLAGS := -DFAKE_LOG_DEVICE=1 -m64 -Werror
-include $(BUILD_HOST_STATIC_LIBRARY)
-
 # Shared and static library for target
 # ========================================================
 include $(CLEAR_VARS)
diff --git a/libpixelflinger/Android.mk b/libpixelflinger/Android.mk
index 484cf50..6a3a58f 100644
--- a/libpixelflinger/Android.mk
+++ b/libpixelflinger/Android.mk
@@ -44,11 +44,13 @@
 	arch-arm64/col32cb16blend.S \
 	arch-arm64/t32cb16blend.S \
 
+ifndef ARCH_MIPS_REV6
 PIXELFLINGER_SRC_FILES_mips := \
 	codeflinger/MIPSAssembler.cpp \
 	codeflinger/mips_disassem.c \
 	arch-mips/t32cb16blend.S \
 
+endif
 #
 # Shared library
 #
diff --git a/libpixelflinger/scanline.cpp b/libpixelflinger/scanline.cpp
index 26b9a3e..3d14531 100644
--- a/libpixelflinger/scanline.cpp
+++ b/libpixelflinger/scanline.cpp
@@ -39,7 +39,7 @@
 #include "codeflinger/ARMAssembler.h"
 #elif defined(__aarch64__)
 #include "codeflinger/Arm64Assembler.h"
-#elif defined(__mips__) && !defined(__LP64__)
+#elif defined(__mips__) && !defined(__LP64__) && __mips_isa_rev < 6
 #include "codeflinger/MIPSAssembler.h"
 #endif
 //#include "codeflinger/ARMAssemblerOptimizer.h"
@@ -59,7 +59,7 @@
 #   define ANDROID_CODEGEN      ANDROID_CODEGEN_GENERATED
 #endif
 
-#if defined(__arm__) || (defined(__mips__) && !defined(__LP64__)) || defined(__aarch64__)
+#if defined(__arm__) || (defined(__mips__) && !defined(__LP64__) && __mips_isa_rev < 6) || defined(__aarch64__)
 #   define ANDROID_ARM_CODEGEN  1
 #else
 #   define ANDROID_ARM_CODEGEN  0
@@ -73,7 +73,7 @@
  */
 #define DEBUG_NEEDS  0
 
-#if defined( __mips__) && !defined(__LP64__)
+#if defined( __mips__) && !defined(__LP64__) && __mips_isa_rev < 6
 #define ASSEMBLY_SCRATCH_SIZE   4096
 #elif defined(__aarch64__)
 #define ASSEMBLY_SCRATCH_SIZE   8192
@@ -134,7 +134,7 @@
 #elif defined(__aarch64__)
 extern "C" void scanline_t32cb16blend_arm64(uint16_t*, uint32_t*, size_t);
 extern "C" void scanline_col32cb16blend_arm64(uint16_t *dst, uint32_t col, size_t ct);
-#elif defined(__mips__)  && !defined(__LP64__)
+#elif defined(__mips__) && !defined(__LP64__) && __mips_isa_rev < 6
 extern "C" void scanline_t32cb16blend_mips(uint16_t*, uint32_t*, size_t);
 #endif
 
@@ -286,7 +286,7 @@
 
 #if ANDROID_ARM_CODEGEN
 
-#if defined(__mips__)
+#if defined(__mips__) && !defined(__LP64__) && __mips_isa_rev < 6
 static CodeCache gCodeCache(32 * 1024);
 #elif defined(__aarch64__)
 static CodeCache gCodeCache(48 * 1024);
@@ -2175,7 +2175,7 @@
 
 void scanline_t32cb16blend(context_t* c)
 {
-#if ((ANDROID_CODEGEN >= ANDROID_CODEGEN_ASM) && (defined(__arm__) || (defined(__mips__) && !defined(__LP64__)) || defined(__aarch64__)))
+#if ((ANDROID_CODEGEN >= ANDROID_CODEGEN_ASM) && (defined(__arm__) || (defined(__mips__) && !defined(__LP64__) && __mips_isa_rev < 6) || defined(__aarch64__)))
     int32_t x = c->iterators.xl;
     size_t ct = c->iterators.xr - x;
     int32_t y = c->iterators.y;
diff --git a/libpixelflinger/tests/codegen/codegen.cpp b/libpixelflinger/tests/codegen/codegen.cpp
index 46c1ccc..148b6f4 100644
--- a/libpixelflinger/tests/codegen/codegen.cpp
+++ b/libpixelflinger/tests/codegen/codegen.cpp
@@ -9,16 +9,18 @@
 #include "codeflinger/CodeCache.h"
 #include "codeflinger/GGLAssembler.h"
 #include "codeflinger/ARMAssembler.h"
+#if defined(__mips__) && !defined(__LP64__) && __mips_isa_rev < 6
 #include "codeflinger/MIPSAssembler.h"
+#endif
 #include "codeflinger/Arm64Assembler.h"
 
-#if defined(__arm__) || defined(__mips__) || defined(__aarch64__)
+#if defined(__arm__) || (defined(__mips__) && !defined(__LP64__) && __mips_isa_rev < 6) || defined(__aarch64__)
 #   define ANDROID_ARM_CODEGEN  1
 #else
 #   define ANDROID_ARM_CODEGEN  0
 #endif
 
-#if defined (__mips__)
+#if defined(__mips__) && !defined(__LP64__) && __mips_isa_rev < 6
 #define ASSEMBLY_SCRATCH_SIZE   4096
 #elif defined(__aarch64__)
 #define ASSEMBLY_SCRATCH_SIZE   8192
@@ -52,7 +54,7 @@
     GGLAssembler assembler( new ARMAssembler(a) );
 #endif
 
-#if defined(__mips__) && !defined(__LP64__)
+#if defined(__mips__) && !defined(__LP64__) && __mips_isa_rev < 6
     GGLAssembler assembler( new ArmToMipsAssembler(a) );
 #endif
 
diff --git a/libutils/Android.mk b/libutils/Android.mk
index 9a50147..0c8625c 100644
--- a/libutils/Android.mk
+++ b/libutils/Android.mk
@@ -66,6 +66,9 @@
 ifeq ($(HOST_OS), linux)
 LOCAL_SRC_FILES += Looper.cpp
 endif
+ifeq ($(HOST_OS),darwin)
+LOCAL_CFLAGS += -Wno-unused-parameter
+endif
 LOCAL_MODULE:= libutils
 LOCAL_STATIC_LIBRARIES := liblog
 LOCAL_CFLAGS += $(host_commonCflags)
@@ -73,19 +76,6 @@
 include $(BUILD_HOST_STATIC_LIBRARY)
 
 
-# For the host, 64-bit
-# =====================================================
-include $(CLEAR_VARS)
-LOCAL_SRC_FILES:= $(commonSources)
-ifeq ($(HOST_OS), linux)
-LOCAL_SRC_FILES += Looper.cpp
-endif
-LOCAL_MODULE:= lib64utils
-LOCAL_STATIC_LIBRARIES := liblog
-LOCAL_CFLAGS += $(host_commonCflags) -m64
-include $(BUILD_HOST_STATIC_LIBRARY)
-
-
 # For the device, static
 # =====================================================
 include $(CLEAR_VARS)
@@ -103,7 +93,7 @@
 LOCAL_CFLAGS += -Werror
 
 LOCAL_C_INCLUDES += \
-		bionic/libc/private \
+		bionic/libc \
 		external/zlib
 
 LOCAL_STATIC_LIBRARIES := \
diff --git a/libutils/Threads.cpp b/libutils/Threads.cpp
index cc7fe89..b09d510 100644
--- a/libutils/Threads.cpp
+++ b/libutils/Threads.cpp
@@ -29,7 +29,7 @@
 # include <sched.h>
 # include <sys/resource.h>
 #ifdef HAVE_ANDROID_OS
-# include <bionic_pthread.h>
+# include <private/bionic_pthread.h>
 #endif
 #elif defined(HAVE_WIN32_THREADS)
 # include <windows.h>
diff --git a/libziparchive/Android.mk b/libziparchive/Android.mk
index 705caa5..d96bc63 100644
--- a/libziparchive/Android.mk
+++ b/libziparchive/Android.mk
@@ -63,7 +63,8 @@
 LOCAL_CFLAGS += \
     -DGTEST_OS_LINUX \
     -DGTEST_HAS_STD_STRING \
-    -Werror
+    -Werror \
+    -Wno-unnamed-type-template-args
 LOCAL_SRC_FILES := zip_archive_test.cc
 LOCAL_STATIC_LIBRARIES := libziparchive-host \
 	libz \
diff --git a/libziparchive/zip_archive.cc b/libziparchive/zip_archive.cc
index 128bad4..6ec8f0d 100644
--- a/libziparchive/zip_archive.cc
+++ b/libziparchive/zip_archive.cc
@@ -287,7 +287,7 @@
  */
 struct ZipArchive {
   /* open Zip archive */
-  int fd;
+  const int fd;
 
   /* mapped central directory area */
   off64_t directory_offset;
@@ -304,6 +304,25 @@
    */
   uint32_t hash_table_size;
   ZipEntryName* hash_table;
+
+  ZipArchive(const int fd) :
+      fd(fd),
+      directory_offset(0),
+      directory_map(NULL),
+      num_entries(0),
+      hash_table_size(0),
+      hash_table(NULL) {}
+
+  ~ZipArchive() {
+    if (fd >= 0) {
+      close(fd);
+    }
+
+    if (directory_map != NULL) {
+      directory_map->release();
+    }
+    free(hash_table);
+  }
 };
 
 // Returns 0 on success and negative values on failure.
@@ -661,28 +680,20 @@
 
 int32_t OpenArchiveFd(int fd, const char* debug_file_name,
                       ZipArchiveHandle* handle) {
-  ZipArchive* archive = (ZipArchive*) malloc(sizeof(ZipArchive));
-  memset(archive, 0, sizeof(*archive));
+  ZipArchive* archive = new ZipArchive(fd);
   *handle = archive;
-
-  archive->fd = fd;
-
   return OpenArchiveInternal(archive, debug_file_name);
 }
 
 int32_t OpenArchive(const char* fileName, ZipArchiveHandle* handle) {
-  ZipArchive* archive = (ZipArchive*) malloc(sizeof(ZipArchive));
-  memset(archive, 0, sizeof(*archive));
+  const int fd = open(fileName, O_RDONLY | O_BINARY, 0);
+  ZipArchive* archive = new ZipArchive(fd);
   *handle = archive;
 
-  const int fd = open(fileName, O_RDONLY | O_BINARY, 0);
   if (fd < 0) {
     ALOGW("Unable to open '%s': %s", fileName, strerror(errno));
     return kIoError;
-  } else {
-    archive->fd = fd;
   }
-
   return OpenArchiveInternal(archive, fileName);
 }
 
@@ -692,16 +703,7 @@
 void CloseArchive(ZipArchiveHandle handle) {
   ZipArchive* archive = (ZipArchive*) handle;
   ALOGV("Closing archive %p", archive);
-
-  if (archive->fd >= 0) {
-    close(archive->fd);
-  }
-
-  if (archive->directory_map != NULL) {
-    archive->directory_map->release();
-  }
-  free(archive->hash_table);
-  free(archive);
+  delete archive;
 }
 
 static int32_t UpdateEntryFromDataDescriptor(int fd,
diff --git a/libziparchive/zip_archive_test.cc b/libziparchive/zip_archive_test.cc
index 875b6de..813a87f 100644
--- a/libziparchive/zip_archive_test.cc
+++ b/libziparchive/zip_archive_test.cc
@@ -26,6 +26,7 @@
 
 static std::string test_data_dir;
 
+static const std::string kMissingZip = "missing.zip";
 static const std::string kValidZip = "valid.zip";
 
 static const uint8_t kATxtContents[] = {
@@ -58,6 +59,14 @@
   CloseArchive(handle);
 }
 
+TEST(ziparchive, OpenMissing) {
+  ZipArchiveHandle handle;
+  ASSERT_NE(0, OpenArchiveWrapper(kMissingZip, &handle));
+
+  // Confirm the file descriptor is not going to be mistaken for a valid one.
+  ASSERT_EQ(-1, GetFileDescriptor(handle));
+}
+
 TEST(ziparchive, Iteration) {
   ZipArchiveHandle handle;
   ASSERT_EQ(0, OpenArchiveWrapper(kValidZip, &handle));
diff --git a/logcat/tests/logcat_test.cpp b/logcat/tests/logcat_test.cpp
index 9b316d1..85756d5 100644
--- a/logcat/tests/logcat_test.cpp
+++ b/logcat/tests/logcat_test.cpp
@@ -284,21 +284,21 @@
 
     while (fgets(buffer, sizeof(buffer), fp)) {
         int size, consumed, max, payload;
-        char size_mult, consumed_mult;
+        char size_mult[2], consumed_mult[2];
         long full_size, full_consumed;
 
         size = consumed = max = payload = 0;
         // NB: crash log can be very small, not hit a Kb of consumed space
         //     doubly lucky we are not including it.
-        if (6 != sscanf(buffer, "%*s ring buffer is %d%cb (%d%cb consumed),"
+        if (6 != sscanf(buffer, "%*s ring buffer is %d%2s (%d%2s consumed),"
                                 " max entry is %db, max payload is %db",
-                                &size, &size_mult, &consumed, &consumed_mult,
+                                &size, size_mult, &consumed, consumed_mult,
                                 &max, &payload)) {
             fprintf(stderr, "WARNING: Parse error: %s", buffer);
             continue;
         }
         full_size = size;
-        switch(size_mult) {
+        switch(size_mult[0]) {
         case 'G':
             full_size *= 1024;
             /* FALLTHRU */
@@ -307,10 +307,12 @@
             /* FALLTHRU */
         case 'K':
             full_size *= 1024;
+            /* FALLTHRU */
+        case 'b':
             break;
         }
         full_consumed = consumed;
-        switch(consumed_mult) {
+        switch(consumed_mult[0]) {
         case 'G':
             full_consumed *= 1024;
             /* FALLTHRU */
@@ -319,6 +321,8 @@
             /* FALLTHRU */
         case 'K':
             full_consumed *= 1024;
+            /* FALLTHRU */
+        case 'b':
             break;
         }
         EXPECT_GT((full_size * 9) / 4, full_consumed);
@@ -477,6 +481,45 @@
     EXPECT_EQ(1, signals);
 }
 
+TEST(logcat, logrotate) {
+    static const char form[] = "/data/local/tmp/logcat.logrotate.XXXXXX";
+    char buf[sizeof(form)];
+    ASSERT_TRUE(NULL != mkdtemp(strcpy(buf, form)));
+
+    static const char comm[] = "logcat -b radio -b events -b system -b main"
+                                     " -d -f %s/log.txt -n 7 -r 1";
+    char command[sizeof(buf) + sizeof(comm)];
+    sprintf(command, comm, buf);
+
+    int ret;
+    EXPECT_FALSE((ret = system(command)));
+    if (!ret) {
+        sprintf(command, "ls -s %s 2>/dev/null", buf);
+
+        FILE *fp;
+        EXPECT_TRUE(NULL != (fp = popen(command, "r")));
+        if (fp) {
+            char buffer[5120];
+            int count = 0;
+
+            while (fgets(buffer, sizeof(buffer), fp)) {
+                static const char match[] = "4 log.txt";
+                static const char total[] = "total ";
+
+                if (!strncmp(buffer, match, sizeof(match) - 1)) {
+                    ++count;
+                } else if (strncmp(buffer, total, sizeof(total) - 1)) {
+                    fprintf(stderr, "WARNING: Parse error: %s", buffer);
+                }
+            }
+            pclose(fp);
+            EXPECT_TRUE(count == 7 || count == 8);
+        }
+    }
+    sprintf(command, "rm -rf %s", buf);
+    EXPECT_FALSE(system(command));
+}
+
 static void caught_blocking_clear(int /*signum*/)
 {
     unsigned long long v = 0xDEADBEEFA55C0000ULL;
diff --git a/logd/main.cpp b/logd/main.cpp
index ece5a3a..1e1a718 100644
--- a/logd/main.cpp
+++ b/logd/main.cpp
@@ -22,12 +22,11 @@
 #include <stdlib.h>
 #include <string.h>
 #include <sys/capability.h>
+#include <sys/prctl.h>
 #include <sys/stat.h>
 #include <sys/types.h>
 #include <unistd.h>
 
-#include <linux/prctl.h>
-
 #include <cutils/properties.h>
 
 #include "private/android_filesystem_config.h"
diff --git a/logd/tests/logd_test.cpp b/logd/tests/logd_test.cpp
index 957fdb5..4bea4be 100644
--- a/logd/tests/logd_test.cpp
+++ b/logd/tests/logd_test.cpp
@@ -503,13 +503,11 @@
             (user_logger_content)     ? yes : no,
             (kernel_logger_available) ? yes : no,
             (kernel_logger_content)   ? yes : no,
-            (user_logger_available && kernel_logger_available) ? "WARNING" : "ok",
+            (user_logger_available && kernel_logger_available) ? "ERROR" : "ok",
             (user_logger_content && kernel_logger_content) ? "ERROR" : "ok");
 
-    if (user_logger_available && kernel_logger_available) {
-        printf("WARNING: kernel & user logger; both consuming resources!!!\n");
-    }
-
+    EXPECT_EQ(0, user_logger_available && kernel_logger_available);
+    EXPECT_EQ(0, !user_logger_available && !kernel_logger_available);
     EXPECT_EQ(0, user_logger_content && kernel_logger_content);
     EXPECT_EQ(0, !user_logger_content && !kernel_logger_content);
 }
diff --git a/logwrapper/logwrap.c b/logwrapper/logwrap.c
index d47c9b5..3a6276e 100644
--- a/logwrapper/logwrap.c
+++ b/logwrapper/logwrap.c
@@ -477,7 +477,6 @@
     pid_t pid;
     int parent_ptty;
     int child_ptty;
-    char *child_devname = NULL;
     struct sigaction intact;
     struct sigaction quitact;
     sigset_t blockset;
@@ -498,8 +497,9 @@
         goto err_open;
     }
 
+    char child_devname[64];
     if (grantpt(parent_ptty) || unlockpt(parent_ptty) ||
-            ((child_devname = (char*)ptsname(parent_ptty)) == 0)) {
+            ptsname_r(parent_ptty, child_devname, sizeof(child_devname)) != 0) {
         ERROR("Problem with /dev/ptmx\n");
         rc = -1;
         goto err_ptty;
diff --git a/rootdir/init.rc b/rootdir/init.rc
index a2c9c0f..3644219 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -164,6 +164,10 @@
 on load_all_props_action
     load_all_props
 
+# Indicate to fw loaders that the relevant mounts are up.
+on firmware_mounts_complete
+    rm /dev/.booting
+
 # Mount filesystems and start core system services.
 on late-init
     trigger early-fs
@@ -176,9 +180,13 @@
     # issued fs triggers have completed.
     trigger load_all_props_action
 
+    # Remove a file to wake up anything waiting for firmware.
+    trigger firmware_mounts_complete
+
     trigger early-boot
     trigger boot
 
+
 on post-fs
     # once everything is setup, no need to modify /
     mount rootfs rootfs / ro remount
@@ -189,13 +197,11 @@
     chown system cache /cache
     chmod 0770 /cache
     # We restorecon /cache in case the cache partition has been reset.
-    restorecon /cache
+    restorecon_recursive /cache
 
     # This may have been created by the recovery system with odd permissions
     chown system cache /cache/recovery
     chmod 0770 /cache/recovery
-    # This may have been created by the recovery system with the wrong context.
-    restorecon /cache/recovery
 
     #change permissions on vmallocinfo so we can grab it from bugreports
     chown root log /proc/vmallocinfo
@@ -251,6 +257,7 @@
     mkdir /data/misc/bluetooth 0770 system system
     mkdir /data/misc/keystore 0700 keystore keystore
     mkdir /data/misc/keychain 0771 system system
+    mkdir /data/misc/net 0750 root shell
     mkdir /data/misc/radio 0770 system radio
     mkdir /data/misc/sms 0770 system radio
     mkdir /data/misc/zoneinfo 0775 system system
@@ -276,8 +283,6 @@
     mkdir /data/app-lib 0771 system system
     mkdir /data/app 0771 system system
     mkdir /data/property 0700 root root
-    mkdir /data/ssh 0750 root shell
-    mkdir /data/ssh/empty 0700 root root
 
     # create dalvik-cache, so as to enforce our permissions
     mkdir /data/dalvik-cache 0771 system system
@@ -609,10 +614,6 @@
     disabled
     oneshot
 
-service sshd /system/bin/start-ssh
-    class main
-    disabled
-
 service mdnsd /system/bin/mdnsd
     class main
     user mdnsr
diff --git a/sdcard/sdcard.c b/sdcard/sdcard.c
index 7baad63..9b55b33 100644
--- a/sdcard/sdcard.c
+++ b/sdcard/sdcard.c
@@ -14,10 +14,13 @@
  * limitations under the License.
  */
 
+#define LOG_TAG "sdcard"
+
 #include <ctype.h>
 #include <dirent.h>
 #include <errno.h>
 #include <fcntl.h>
+#include <inttypes.h>
 #include <limits.h>
 #include <linux/fuse.h>
 #include <pthread.h>
@@ -35,6 +38,7 @@
 
 #include <cutils/fs.h>
 #include <cutils/hashmap.h>
+#include <cutils/log.h>
 #include <cutils/multiuser.h>
 
 #include <private/android_filesystem_config.h>
@@ -90,12 +94,12 @@
 #define FUSE_TRACE 0
 
 #if FUSE_TRACE
-#define TRACE(x...) fprintf(stderr,x)
+#define TRACE(x...) ALOGD(x)
 #else
 #define TRACE(x...) do {} while (0)
 #endif
 
-#define ERROR(x...) fprintf(stderr,x)
+#define ERROR(x...) ALOGE(x)
 
 #define FUSE_UNKNOWN_INO 0xffffffff
 
@@ -818,7 +822,7 @@
     pthread_mutex_lock(&fuse->lock);
     parent_node = lookup_node_and_path_by_id_locked(fuse, hdr->nodeid,
             parent_path, sizeof(parent_path));
-    TRACE("[%d] LOOKUP %s @ %llx (%s)\n", handler->token, name, hdr->nodeid,
+    TRACE("[%d] LOOKUP %s @ %"PRIx64" (%s)\n", handler->token, name, hdr->nodeid,
         parent_node ? parent_node->name : "?");
     pthread_mutex_unlock(&fuse->lock);
 
@@ -840,7 +844,7 @@
 
     pthread_mutex_lock(&fuse->lock);
     node = lookup_node_by_id_locked(fuse, hdr->nodeid);
-    TRACE("[%d] FORGET #%lld @ %llx (%s)\n", handler->token, req->nlookup,
+    TRACE("[%d] FORGET #%"PRIu64" @ %"PRIx64" (%s)\n", handler->token, req->nlookup,
             hdr->nodeid, node ? node->name : "?");
     if (node) {
         __u64 n = req->nlookup;
@@ -860,7 +864,7 @@
 
     pthread_mutex_lock(&fuse->lock);
     node = lookup_node_and_path_by_id_locked(fuse, hdr->nodeid, path, sizeof(path));
-    TRACE("[%d] GETATTR flags=%x fh=%llx @ %llx (%s)\n", handler->token,
+    TRACE("[%d] GETATTR flags=%x fh=%"PRIx64" @ %"PRIx64" (%s)\n", handler->token,
             req->getattr_flags, req->fh, hdr->nodeid, node ? node->name : "?");
     pthread_mutex_unlock(&fuse->lock);
 
@@ -885,7 +889,7 @@
     pthread_mutex_lock(&fuse->lock);
     has_rw = get_caller_has_rw_locked(fuse, hdr);
     node = lookup_node_and_path_by_id_locked(fuse, hdr->nodeid, path, sizeof(path));
-    TRACE("[%d] SETATTR fh=%llx valid=%x @ %llx (%s)\n", handler->token,
+    TRACE("[%d] SETATTR fh=%"PRIx64" valid=%x @ %"PRIx64" (%s)\n", handler->token,
             req->fh, req->valid, hdr->nodeid, node ? node->name : "?");
     pthread_mutex_unlock(&fuse->lock);
 
@@ -899,7 +903,7 @@
     /* XXX: incomplete implementation on purpose.
      * chmod/chown should NEVER be implemented.*/
 
-    if ((req->valid & FATTR_SIZE) && truncate(path, req->size) < 0) {
+    if ((req->valid & FATTR_SIZE) && truncate64(path, req->size) < 0) {
         return -errno;
     }
 
@@ -950,7 +954,7 @@
     has_rw = get_caller_has_rw_locked(fuse, hdr);
     parent_node = lookup_node_and_path_by_id_locked(fuse, hdr->nodeid,
             parent_path, sizeof(parent_path));
-    TRACE("[%d] MKNOD %s 0%o @ %llx (%s)\n", handler->token,
+    TRACE("[%d] MKNOD %s 0%o @ %"PRIx64" (%s)\n", handler->token,
             name, req->mode, hdr->nodeid, parent_node ? parent_node->name : "?");
     pthread_mutex_unlock(&fuse->lock);
 
@@ -981,7 +985,7 @@
     has_rw = get_caller_has_rw_locked(fuse, hdr);
     parent_node = lookup_node_and_path_by_id_locked(fuse, hdr->nodeid,
             parent_path, sizeof(parent_path));
-    TRACE("[%d] MKDIR %s 0%o @ %llx (%s)\n", handler->token,
+    TRACE("[%d] MKDIR %s 0%o @ %"PRIx64" (%s)\n", handler->token,
             name, req->mode, hdr->nodeid, parent_node ? parent_node->name : "?");
     pthread_mutex_unlock(&fuse->lock);
 
@@ -1030,7 +1034,7 @@
     has_rw = get_caller_has_rw_locked(fuse, hdr);
     parent_node = lookup_node_and_path_by_id_locked(fuse, hdr->nodeid,
             parent_path, sizeof(parent_path));
-    TRACE("[%d] UNLINK %s @ %llx (%s)\n", handler->token,
+    TRACE("[%d] UNLINK %s @ %"PRIx64" (%s)\n", handler->token,
             name, hdr->nodeid, parent_node ? parent_node->name : "?");
     pthread_mutex_unlock(&fuse->lock);
 
@@ -1059,7 +1063,7 @@
     has_rw = get_caller_has_rw_locked(fuse, hdr);
     parent_node = lookup_node_and_path_by_id_locked(fuse, hdr->nodeid,
             parent_path, sizeof(parent_path));
-    TRACE("[%d] RMDIR %s @ %llx (%s)\n", handler->token,
+    TRACE("[%d] RMDIR %s @ %"PRIx64" (%s)\n", handler->token,
             name, hdr->nodeid, parent_node ? parent_node->name : "?");
     pthread_mutex_unlock(&fuse->lock);
 
@@ -1097,7 +1101,7 @@
             old_parent_path, sizeof(old_parent_path));
     new_parent_node = lookup_node_and_path_by_id_locked(fuse, req->newdir,
             new_parent_path, sizeof(new_parent_path));
-    TRACE("[%d] RENAME %s->%s @ %llx (%s) -> %llx (%s)\n", handler->token,
+    TRACE("[%d] RENAME %s->%s @ %"PRIx64" (%s) -> %"PRIx64" (%s)\n", handler->token,
             old_name, new_name,
             hdr->nodeid, old_parent_node ? old_parent_node->name : "?",
             req->newdir, new_parent_node ? new_parent_node->name : "?");
@@ -1181,7 +1185,7 @@
     pthread_mutex_lock(&fuse->lock);
     has_rw = get_caller_has_rw_locked(fuse, hdr);
     node = lookup_node_and_path_by_id_locked(fuse, hdr->nodeid, path, sizeof(path));
-    TRACE("[%d] OPEN 0%o @ %llx (%s)\n", handler->token,
+    TRACE("[%d] OPEN 0%o @ %"PRIx64" (%s)\n", handler->token,
             req->flags, hdr->nodeid, node ? node->name : "?");
     pthread_mutex_unlock(&fuse->lock);
 
@@ -1223,8 +1227,8 @@
      * overlaps the request buffer and will clobber data in the request.  This
      * saves us 128KB per request handler thread at the cost of this scary comment. */
 
-    TRACE("[%d] READ %p(%d) %u@%llu\n", handler->token,
-            h, h->fd, size, offset);
+    TRACE("[%d] READ %p(%d) %u@%"PRIu64"\n", handler->token,
+            h, h->fd, size, (uint64_t) offset);
     if (size > MAX_READ) {
         return -EINVAL;
     }
@@ -1250,7 +1254,7 @@
         buffer = (const __u8*) aligned_buffer;
     }
 
-    TRACE("[%d] WRITE %p(%d) %u@%llu\n", handler->token,
+    TRACE("[%d] WRITE %p(%d) %u@%"PRIu64"\n", handler->token,
             h, h->fd, req->size, req->offset);
     res = pwrite64(h->fd, buffer, req->size, req->offset);
     if (res < 0) {
@@ -1306,14 +1310,23 @@
 static int handle_fsync(struct fuse* fuse, struct fuse_handler* handler,
         const struct fuse_in_header* hdr, const struct fuse_fsync_in* req)
 {
-    int is_data_sync = req->fsync_flags & 1;
-    struct handle *h = id_to_ptr(req->fh);
-    int res;
+    bool is_dir = (hdr->opcode == FUSE_FSYNCDIR);
+    bool is_data_sync = req->fsync_flags & 1;
 
-    TRACE("[%d] FSYNC %p(%d) is_data_sync=%d\n", handler->token,
-            h, h->fd, is_data_sync);
-    res = is_data_sync ? fdatasync(h->fd) : fsync(h->fd);
-    if (res < 0) {
+    int fd = -1;
+    if (is_dir) {
+      struct dirhandle *dh = id_to_ptr(req->fh);
+      fd = dirfd(dh->d);
+    } else {
+      struct handle *h = id_to_ptr(req->fh);
+      fd = h->fd;
+    }
+
+    TRACE("[%d] %s %p(%d) is_data_sync=%d\n", handler->token,
+            is_dir ? "FSYNCDIR" : "FSYNC",
+            id_to_ptr(req->fh), fd, is_data_sync);
+    int res = is_data_sync ? fdatasync(fd) : fsync(fd);
+    if (res == -1) {
         return -errno;
     }
     return 0;
@@ -1336,7 +1349,7 @@
 
     pthread_mutex_lock(&fuse->lock);
     node = lookup_node_and_path_by_id_locked(fuse, hdr->nodeid, path, sizeof(path));
-    TRACE("[%d] OPENDIR @ %llx (%s)\n", handler->token,
+    TRACE("[%d] OPENDIR @ %"PRIx64" (%s)\n", handler->token,
             hdr->nodeid, node ? node->name : "?");
     pthread_mutex_unlock(&fuse->lock);
 
@@ -1537,7 +1550,7 @@
     }
 
     default: {
-        TRACE("[%d] NOTIMPL op=%d uniq=%llx nid=%llx\n",
+        TRACE("[%d] NOTIMPL op=%d uniq=%"PRIx64" nid=%"PRIx64"\n",
                 handler->token, hdr->opcode, hdr->unique, hdr->nodeid);
         return -ENOSYS;
     }
@@ -1640,7 +1653,7 @@
         }
     }
 
-    TRACE("read_package_list: found %d packages, %d with write_gid\n",
+    TRACE("read_package_list: found %zu packages, %zu with write_gid\n",
             hashmapSize(fuse->package_to_appid),
             hashmapSize(fuse->appid_with_rw));
     fclose(file);
@@ -1837,6 +1850,7 @@
     bool split_perms = false;
     int i;
     struct rlimit rlim;
+    int fs_version;
 
     int opt;
     while ((opt = getopt(argc, argv, "u:g:w:t:dls")) != -1) {
@@ -1911,6 +1925,11 @@
         ERROR("Error setting RLIMIT_NOFILE, errno = %d\n", errno);
     }
 
+    while ((fs_read_atomic_int("/data/.layout_version", &fs_version) == -1) || (fs_version < 3)) {
+        ERROR("installd fs upgrade not yet complete. Waiting...\n");
+        sleep(1);
+    }
+
     res = run(source_path, dest_path, uid, gid, write_gid, num_threads, derive, split_perms);
     return res < 0 ? 1 : 0;
 }
diff --git a/toolbox/Android.mk b/toolbox/Android.mk
index c53f17d..d8d397e 100644
--- a/toolbox/Android.mk
+++ b/toolbox/Android.mk
@@ -1,104 +1,221 @@
 LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
 
-TOOLS := \
-	cat \
-	chcon \
-	chmod \
-	chown \
-	clear \
-	cmp \
-	date \
-	dd \
-	df \
-	dmesg \
-	du \
-	getenforce \
-	getevent \
-	getprop \
-	getsebool \
-	hd \
-	id \
-	ifconfig \
-	iftop \
-	insmod \
-	ioctl \
-	ionice \
-	kill \
-	ln \
-	load_policy \
-	log \
-	ls \
-	lsmod \
-	lsof \
-	md5 \
-	mkdir \
-	mknod \
-	mkswap \
-	mount \
-	mv \
-	nandread \
-	netstat \
-	newfs_msdos \
-	nohup \
-	notify \
-	printenv \
-	ps \
-	readlink \
-	renice \
-	restorecon \
-	rm \
-	rmdir \
-	rmmod \
-	route \
-	runcon \
-	schedtop \
-	sendevent \
-	setenforce \
-	setprop \
-	setsebool \
-	sleep \
-	smd \
-	start \
-	stop \
-	swapoff \
-	swapon \
-	sync \
-	top \
-	touch \
-	umount \
-	uptime \
-	vmstat \
-	watchprops \
-	wipe \
 
-ifneq (,$(filter userdebug eng,$(TARGET_BUILD_VARIANT)))
-TOOLS += r
-endif
-
-ALL_TOOLS = $(TOOLS)
-ALL_TOOLS += \
-	cp \
-	grep
-
-LOCAL_SRC_FILES := \
-	cp/cp.c \
-	cp/utils.c \
-	dynarray.c \
-	grep/fastgrep.c \
-	grep/file.c \
-	grep/grep.c \
-	grep/queue.c \
-	grep/util.c \
-	$(patsubst %,%.c,$(TOOLS)) \
-	toolbox.c \
-	uid_from_user.c \
-
-LOCAL_CFLAGS += \
+common_cflags := \
     -std=gnu99 \
     -Werror -Wno-unused-parameter \
+    -I$(LOCAL_PATH)/upstream-netbsd/include/ \
     -include bsd-compatibility.h \
 
+
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES := upstream-netbsd/bin/cat/cat.c
+LOCAL_CFLAGS += $(common_cflags) -Dmain=cat_main
+LOCAL_MODULE := libtoolbox_cat
+LOCAL_ADDITIONAL_DEPENDENCIES += $(LOCAL_PATH)/Android.mk
+include $(BUILD_STATIC_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES := upstream-netbsd/sbin/chown/chown.c
+LOCAL_CFLAGS += $(common_cflags) -Dmain=chown_main
+LOCAL_MODULE := libtoolbox_chown
+LOCAL_ADDITIONAL_DEPENDENCIES += $(LOCAL_PATH)/Android.mk
+include $(BUILD_STATIC_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES := \
+    upstream-netbsd/bin/cp/cp.c \
+    upstream-netbsd/bin/cp/utils.c
+LOCAL_CFLAGS += $(common_cflags) -Dmain=cp_main
+LOCAL_MODULE := libtoolbox_cp
+LOCAL_ADDITIONAL_DEPENDENCIES += $(LOCAL_PATH)/Android.mk
+include $(BUILD_STATIC_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES := \
+    upstream-netbsd/bin/dd/args.c \
+    upstream-netbsd/bin/dd/conv.c \
+    upstream-netbsd/bin/dd/dd.c \
+    upstream-netbsd/bin/dd/dd_hostops.c \
+    upstream-netbsd/bin/dd/misc.c \
+    upstream-netbsd/bin/dd/position.c
+LOCAL_CFLAGS += $(common_cflags) -Dmain=dd_main -DNO_CONV
+LOCAL_MODULE := libtoolbox_dd
+LOCAL_ADDITIONAL_DEPENDENCIES += $(LOCAL_PATH)/Android.mk
+include $(BUILD_STATIC_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES := upstream-netbsd/usr.bin/du/du.c
+LOCAL_CFLAGS += $(common_cflags) -Dmain=du_main
+LOCAL_MODULE := libtoolbox_du
+LOCAL_ADDITIONAL_DEPENDENCIES += $(LOCAL_PATH)/Android.mk
+include $(BUILD_STATIC_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES := \
+    upstream-netbsd/usr.bin/grep/fastgrep.c \
+    upstream-netbsd/usr.bin/grep/file.c \
+    upstream-netbsd/usr.bin/grep/grep.c \
+    upstream-netbsd/usr.bin/grep/queue.c \
+    upstream-netbsd/usr.bin/grep/util.c
+LOCAL_CFLAGS += $(common_cflags) -Dmain=grep_main
+LOCAL_MODULE := libtoolbox_grep
+LOCAL_ADDITIONAL_DEPENDENCIES += $(LOCAL_PATH)/Android.mk
+include $(BUILD_STATIC_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES := upstream-netbsd/bin/kill/kill.c
+LOCAL_CFLAGS += $(common_cflags) -Dmain=kill_main
+LOCAL_MODULE := libtoolbox_kill
+LOCAL_ADDITIONAL_DEPENDENCIES += $(LOCAL_PATH)/Android.mk
+include $(BUILD_STATIC_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES := upstream-netbsd/bin/ln/ln.c
+LOCAL_CFLAGS += $(common_cflags) -Dmain=ln_main
+LOCAL_MODULE := libtoolbox_ln
+LOCAL_ADDITIONAL_DEPENDENCIES += $(LOCAL_PATH)/Android.mk
+include $(BUILD_STATIC_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES := upstream-netbsd/bin/mv/mv.c
+LOCAL_CFLAGS += $(common_cflags) -Dmain=mv_main -D__SVR4
+LOCAL_MODULE := libtoolbox_mv
+LOCAL_ADDITIONAL_DEPENDENCIES += $(LOCAL_PATH)/Android.mk
+include $(BUILD_STATIC_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES := upstream-netbsd/usr.bin/printenv/printenv.c
+LOCAL_CFLAGS += $(common_cflags) -Dmain=printenv_main
+LOCAL_MODULE := libtoolbox_printenv
+LOCAL_ADDITIONAL_DEPENDENCIES += $(LOCAL_PATH)/Android.mk
+include $(BUILD_STATIC_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES := upstream-netbsd/bin/rm/rm.c
+LOCAL_CFLAGS += $(common_cflags) -Dmain=rm_main
+LOCAL_MODULE := libtoolbox_rm
+LOCAL_ADDITIONAL_DEPENDENCIES += $(LOCAL_PATH)/Android.mk
+include $(BUILD_STATIC_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES := upstream-netbsd/bin/rmdir/rmdir.c
+LOCAL_CFLAGS += $(common_cflags) -Dmain=rmdir_main
+LOCAL_MODULE := libtoolbox_rmdir
+LOCAL_ADDITIONAL_DEPENDENCIES += $(LOCAL_PATH)/Android.mk
+include $(BUILD_STATIC_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES := upstream-netbsd/bin/sleep/sleep.c
+LOCAL_CFLAGS += $(common_cflags) -Dmain=sleep_main
+LOCAL_MODULE := libtoolbox_sleep
+LOCAL_ADDITIONAL_DEPENDENCIES += $(LOCAL_PATH)/Android.mk
+include $(BUILD_STATIC_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES := upstream-netbsd/bin/sync/sync.c
+LOCAL_CFLAGS += $(common_cflags) -Dmain=sync_main
+LOCAL_MODULE := libtoolbox_sync
+LOCAL_ADDITIONAL_DEPENDENCIES += $(LOCAL_PATH)/Android.mk
+include $(BUILD_STATIC_LIBRARY)
+
+
+include $(CLEAR_VARS)
+
+BSD_TOOLS := \
+    cat \
+    chown \
+    cp \
+    dd \
+    du \
+    grep \
+    kill \
+    ln \
+    mv \
+    printenv \
+    rm \
+    rmdir \
+    sleep \
+    sync \
+
+OUR_TOOLS := \
+    chcon \
+    chmod \
+    clear \
+    cmp \
+    date \
+    df \
+    dmesg \
+    getenforce \
+    getevent \
+    getprop \
+    getsebool \
+    hd \
+    id \
+    ifconfig \
+    iftop \
+    insmod \
+    ioctl \
+    ionice \
+    load_policy \
+    log \
+    ls \
+    lsmod \
+    lsof \
+    md5 \
+    mkdir \
+    mknod \
+    mkswap \
+    mount \
+    nandread \
+    netstat \
+    newfs_msdos \
+    nohup \
+    notify \
+    ps \
+    readlink \
+    renice \
+    restorecon \
+    rmmod \
+    route \
+    runcon \
+    schedtop \
+    sendevent \
+    setenforce \
+    setprop \
+    setsebool \
+    smd \
+    start \
+    stop \
+    swapoff \
+    swapon \
+    top \
+    touch \
+    umount \
+    uptime \
+    vmstat \
+    watchprops \
+    wipe \
+
+ifneq (,$(filter userdebug eng,$(TARGET_BUILD_VARIANT)))
+OUR_TOOLS += r
+endif
+
+ALL_TOOLS = $(BSD_TOOLS) $(OUR_TOOLS)
+
+LOCAL_SRC_FILES := \
+    upstream-netbsd/lib/libc/gen/getbsize.c \
+    upstream-netbsd/lib/libc/gen/humanize_number.c \
+    upstream-netbsd/lib/libc/stdlib/strsuftoll.c \
+    upstream-netbsd/lib/libc/string/swab.c \
+    upstream-netbsd/lib/libutil/raise_default_signal.c \
+    dynarray.c \
+    pwcache.c \
+    $(patsubst %,%.c,$(OUR_TOOLS)) \
+    toolbox.c \
+
+LOCAL_CFLAGS += $(common_cflags)
+
 LOCAL_C_INCLUDES += external/openssl/include
 
 LOCAL_SHARED_LIBRARIES := \
@@ -111,6 +228,8 @@
 LOCAL_STATIC_LIBRARIES := \
     libusbhost \
 
+LOCAL_WHOLE_STATIC_LIBRARIES := $(patsubst %,libtoolbox_%,$(BSD_TOOLS))
+
 LOCAL_MODULE := toolbox
 LOCAL_ADDITIONAL_DEPENDENCIES += $(LOCAL_PATH)/Android.mk
 
diff --git a/toolbox/NOTICE b/toolbox/NOTICE
index 895b49a..e9ab58d 100644
--- a/toolbox/NOTICE
+++ b/toolbox/NOTICE
@@ -1,5 +1,20 @@
+Copyright (C) 2010 The Android Open Source Project
 
-Copyright (c) 2010, 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.
+
+-------------------------------------------------------------------
+
+Copyright (C) 2014, The Android Open Source Project
 All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
@@ -9,12 +24,8 @@
    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 
+   the documentation and/or other materials provided with the
    distribution.
- * Neither the name of The Android Open Source Project nor the names
-   of its contributors may be used to endorse or promote products
-   derived from this software without specific prior written
-   permission.
 
 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
@@ -23,86 +34,16 @@
 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 
+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.
 
+-------------------------------------------------------------------
 
-Copyright (c) 2009, The Android Open Source Project.
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
- * Redistributions of source code must retain the above copyright
-   notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright
-   notice, this list of conditions and the following disclaimer in
-   the documentation and/or other materials provided with the 
-   distribution.
- * Neither the name of The Android Open Source Project nor the names
-   of its contributors may be used to endorse or promote products
-   derived from this software without specific prior written
-   permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
-COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
-OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 
-AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
-OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
-
-Copyright (c) 2008, The Android Open Source Project.
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
- * Redistributions of source code must retain the above copyright
-   notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright
-   notice, this list of conditions and the following disclaimer in
-   the documentation and/or other materials provided with the 
-   distribution.
- * Neither the name of The Android Open Source Project nor the names
-   of its contributors may be used to endorse or promote products
-   derived from this software without specific prior written
-   permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
-COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
-OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 
-AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
-OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
-
-Copyright (c) 1998 Robert Nordier
-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.
-This code is derived from software contributed to Berkeley by
-Keith Muller of the University of California, San Diego and Lance
-Visser of Convex Computer Corporation.
-This code is derived from software contributed to Berkeley by
-Mike Muuss.
+Copyright (c) 1987, 1993
+   The Regents of the University of California.  All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions
@@ -128,66 +69,919 @@
 OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 SUCH DAMAGE.
 
+-------------------------------------------------------------------
 
- Copyright (c) 1989, 1993
-	The Regents of the University of California.  All rights reserved.
+Copyright (c) 1987, 1993, 1994
+   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.
 
- 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.
 
- 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.
+-------------------------------------------------------------------
 
+Copyright (c) 1988, 1993
+   The Regents of the University of California.  All rights reserved.
 
- Copyright (c) 1991, 1993, 1994
-	The Regents of the University of California.  All rights reserved.
+This code is derived from software contributed to Berkeley by
+Jeffrey Mogul.
 
- This code is derived from software contributed to Berkeley by
- Keith Muller of the University of California, San Diego and Lance
- Visser of Convex Computer Corporation.
+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.
 
- 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.
 
- 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.
+-------------------------------------------------------------------
+
+Copyright (c) 1988, 1993, 1994
+   The Regents of the University of California.  All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+3. Neither the name of the University nor the names of its contributors
+   may be used to endorse or promote products derived from this software
+   without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
+
+-------------------------------------------------------------------
+
+Copyright (c) 1988, 1993, 1994
+   The Regents of the University of California.  All rights reserved.
+
+This code is derived from software contributed to Berkeley by
+David Hitz of Auspex Systems Inc.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+3. Neither the name of the University nor the names of its contributors
+   may be used to endorse or promote products derived from this software
+   without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
+
+-------------------------------------------------------------------
+
+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.
+
+-------------------------------------------------------------------
+
+Copyright (c) 1989, 1993
+   The Regents of the University of California.  All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+3. Neither the name of the University nor the names of its contributors
+   may be used to endorse or promote products derived from this software
+   without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
+
+-------------------------------------------------------------------
+
+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.
+
+-------------------------------------------------------------------
+
+Copyright (c) 1989, 1993, 1994
+   The Regents of the University of California.  All rights reserved.
+
+This code is derived from software contributed to Berkeley by
+Chris Newcomb.
+
+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.
+
+-------------------------------------------------------------------
+
+Copyright (c) 1989, 1993, 1994
+   The Regents of the University of California.  All rights reserved.
+
+This code is derived from software contributed to Berkeley by
+Ken Smith of The State University of New York at Buffalo.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+3. Neither the name of the University nor the names of its contributors
+   may be used to endorse or promote products derived from this software
+   without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
+
+-------------------------------------------------------------------
+
+Copyright (c) 1990, 1993, 1994, 2003
+   The Regents of the University of California.  All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+3. Neither the name of the University nor the names of its contributors
+   may be used to endorse or promote products derived from this software
+   without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
+
+-------------------------------------------------------------------
+
+Copyright (c) 1991, 1993
+   The Regents of the University of California.  All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+3. Neither the name of the University nor the names of its contributors
+   may be used to endorse or promote products derived from this software
+   without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
+
+-------------------------------------------------------------------
+
+Copyright (c) 1991, 1993, 1994
+   The Regents of the University of California.  All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+3. Neither the name of the University nor the names of its contributors
+   may be used to endorse or promote products derived from this software
+   without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
+
+-------------------------------------------------------------------
+
+Copyright (c) 1991, 1993, 1994
+   The Regents of the University of California.  All rights reserved.
+
+This code is derived from software contributed to Berkeley by
+Keith Muller of the University of California, San Diego and Lance
+Visser of Convex Computer Corporation.
+
+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.
+
+-------------------------------------------------------------------
+
+Copyright (c) 1992, 1993, 1994
+   The Regents of the University of California.  All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+3. Neither the name of the University nor the names of its contributors
+   may be used to endorse or promote products derived from this software
+   without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
+
+-------------------------------------------------------------------
+
+Copyright (c) 1997, 1998, 1999, 2002 The NetBSD Foundation, Inc.
+All rights reserved.
+
+This code is derived from software contributed to The NetBSD Foundation
+by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
+NASA Ames Research Center, by Luke Mewburn and by Tomas Svensson.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+
+-------------------------------------------------------------------
+
+Copyright (c) 1998 Robert Nordier
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in
+   the documentation and/or other materials provided with the
+   distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS
+OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR(S) 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.
+
+-------------------------------------------------------------------
+
+Copyright (c) 1999 James Howard and Dag-Erling Coïdan Smørgrav
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+
+-------------------------------------------------------------------
+
+Copyright (c) 1999 James Howard and Dag-Erling Coïdan Smørgrav
+Copyright (C) 2008 Gabor Kovesdan <gabor@FreeBSD.org>
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+
+-------------------------------------------------------------------
+
+Copyright (c) 1999 James Howard and Dag-Erling Coïdan Smørgrav
+Copyright (C) 2008-2009 Gabor Kovesdan <gabor@FreeBSD.org>
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+
+-------------------------------------------------------------------
+
+Copyright (c) 1999 James Howard and Dag-Erling Coïdan Smørgrav
+Copyright (C) 2008-2010 Gabor Kovesdan <gabor@FreeBSD.org>
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+
+-------------------------------------------------------------------
+
+Copyright (c) 1999 James Howard and Dag-Erling Coïdan Smørgrav
+Copyright (C) 2008-2010 Gabor Kovesdan <gabor@FreeBSD.org>
+Copyright (C) 2010 Dimitry Andric <dimitry@andric.com>
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+
+-------------------------------------------------------------------
+
+Copyright (c) 1999 James Howard and Dag-Erling Coïdan Smørgrav
+Copyright (c) 2008-2009 Gabor Kovesdan <gabor@FreeBSD.org>
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+
+-------------------------------------------------------------------
+
+Copyright (c) 2001-2002,2004 The NetBSD Foundation, Inc.
+All rights reserved.
+
+This code is derived from software contributed to The NetBSD Foundation
+by Luke Mewburn.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+
+-------------------------------------------------------------------
+
+Copyright (c) 2007 The NetBSD Foundation, Inc.
+All rights reserved.
+
+This code is derived from software contributed to The NetBSD Foundation
+by Luke Mewburn.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+
+-------------------------------------------------------------------
+
+Copyright (c) 2008, The Android Open Source Project
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+ * Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in
+   the documentation and/or other materials provided with the
+   distribution.
+ * Neither the name of Google, Inc. nor the names of its contributors
+   may be used to endorse or promote products derived from this
+   software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
+
+-------------------------------------------------------------------
+
+Copyright (c) 2009, The Android Open Source Project
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+ * Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in
+   the documentation and/or other materials provided with the
+   distribution.
+ * Neither the name of Google, Inc. nor the names of its contributors
+   may be used to endorse or promote products derived from this
+   software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
+
+-------------------------------------------------------------------
+
+Copyright (c) 2010 The NetBSD Foundation, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+
+-------------------------------------------------------------------
+
+Copyright (c) 2010, The Android Open Source Project
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+ * Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in
+   the documentation and/or other materials provided with the
+   distribution.
+ * Neither the name of Google, Inc. nor the names of its contributors
+   may be used to endorse or promote products derived from this
+   software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
+
+-------------------------------------------------------------------
+
+Copyright (c) 2012, The Android Open Source Project
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+ * Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in
+   the documentation and/or other materials provided with the
+   distribution.
+ * Neither the name of Google, Inc. nor the names of its contributors
+   may be used to endorse or promote products derived from this
+   software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
+
+-------------------------------------------------------------------
+
+Copyright (c) 2013, The Android Open Source Project
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+ * Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in
+   the documentation and/or other materials provided with the
+   distribution.
+ * Neither the name of Google, Inc. nor the names of its contributors
+   may be used to endorse or promote products derived from this
+   software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
+
+-------------------------------------------------------------------
+
+Copyright (c) 2014, The Android Open Source Project
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+ * Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in
+   the documentation and/or other materials provided with the
+   distribution.
+ * Neither the name of Google, Inc. nor the names of its contributors
+   may be used to endorse or promote products derived from this
+   software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
+
+-------------------------------------------------------------------
 
diff --git a/toolbox/bsd-compatibility.h b/toolbox/bsd-compatibility.h
index a304631..9c6c34a 100644
--- a/toolbox/bsd-compatibility.h
+++ b/toolbox/bsd-compatibility.h
@@ -26,13 +26,67 @@
  * SUCH DAMAGE.
  */
 
+#include <stdbool.h>
 #include <sys/types.h>
 
 /* We want chown to support user.group as well as user:group. */
 #define SUPPORT_DOT
 
+/* We don't localize /system/bin! */
+#define WITHOUT_NLS
+
+// NetBSD uses _DIAGASSERT to null-check arguments and the like.
+#include <assert.h>
+#define _DIAGASSERT(e) ((e) ? (void) 0 : __assert2(__FILE__, __LINE__, __func__, #e))
+
+// TODO: update our <sys/cdefs.h> to support this properly.
+#define __type_fit(t, a) (0 == 0)
+
+// TODO: should this be in our <sys/cdefs.h>?
+#define __arraycount(a) (sizeof(a) / sizeof(a[0]))
+
+// This at least matches GNU dd(1) behavior.
+#define SIGINFO SIGUSR1
+
+#define S_ISWHT(x) false
+
+// TODO: should this be in bionic? (glibc does this, even though it's not quite right.)
+#define O_RSYNC O_SYNC
+
 __BEGIN_DECLS
 
-extern int uid_from_user(const char* name, uid_t* uid);
+/* 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
+#define HN_B                    0x04
+#define HN_DIVISOR_1000         0x08
+#define HN_GETSCALE             0x10
+#define HN_AUTOSCALE            0x20
+int	humanize_number(char *, size_t, int64_t, const char *, int, int);
+int	dehumanize_number(const char *, int64_t *);
+char	*getbsize(int *, long *);
+long long strsuftoll(const char *, const char *, long long, long long);
+long long strsuftollx(const char *, const char *, long long, long long,
+			char *, size_t);
+
+/* From NetBSD <string.h>. */
+void strmode(mode_t, char*);
+
+/* From NetBSD <sys/param.h>. */
+#define MAXBSIZE 65536
+
+/* From NetBSD <sys/stat.h>. */
+#define DEFFILEMODE (S_IRUSR | S_IWUSR)
+
+/* From NetBSD <unistd.h>. */
+void	swab(const void * __restrict, void * __restrict, ssize_t);
+
+/* From NetBSD <util.h>. */
+int		raise_default_signal(int);
 
 __END_DECLS
diff --git a/toolbox/dd.c b/toolbox/dd.c
deleted file mode 100644
index 408a496..0000000
--- a/toolbox/dd.c
+++ /dev/null
@@ -1,1313 +0,0 @@
-/*	$NetBSD: dd.c,v 1.37 2004/01/17 21:00:16 dbj Exp $	*/
-
-/*-
- * Copyright (c) 1991, 1993, 1994
- *	The Regents of the University of California.  All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Keith Muller of the University of California, San Diego and Lance
- * Visser of Convex Computer Corporation.
- *
- * 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) 1991, 1993, 1994\n\
-	The Regents of the University of California.  All rights reserved.\n");
-#endif /* not lint */
-
-#ifndef lint
-#if 0
-static char sccsid[] = "@(#)dd.c	8.5 (Berkeley) 4/2/94";
-#else
-__RCSID("$NetBSD: dd.c,v 1.37 2004/01/17 21:00:16 dbj Exp $");
-#endif
-#endif /* not lint */
-
-#include <sys/param.h>
-#include <sys/stat.h>
-#include <sys/ioctl.h>
-#include <sys/time.h>
-
-#include <ctype.h>
-#include <err.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include "dd.h"
-
-//#define NO_CONV
-
-//#include "extern.h"
-void block(void);
-void block_close(void);
-void dd_out(int);
-void def(void);
-void def_close(void);
-void jcl(char **);
-void pos_in(void);
-void pos_out(void);
-void summary(void);
-void summaryx(int);
-void terminate(int);
-void unblock(void);
-void unblock_close(void);
-ssize_t bwrite(int, const void *, size_t);
-
-extern IO		in, out;
-extern STAT		st;
-extern void		(*cfunc)(void);
-extern uint64_t		cpy_cnt;
-extern uint64_t		cbsz;
-extern u_int		ddflags;
-extern u_int		files_cnt;
-extern int		progress;
-extern const u_char	*ctab;
-
-#define DEFFILEMODE (S_IRUSR | S_IWUSR)
-
-static void dd_close(void);
-static void dd_in(void);
-static void getfdtype(IO *);
-static int redup_clean_fd(int);
-static void setup(void);
-
-
-IO		in, out;		/* input/output state */
-STAT		st;			/* statistics */
-void		(*cfunc)(void);		/* conversion function */
-uint64_t	cpy_cnt;		/* # of blocks to copy */
-static off_t	pending = 0;		/* pending seek if sparse */
-u_int		ddflags;		/* conversion options */
-uint64_t	cbsz;			/* conversion block size */
-u_int		files_cnt = 1;		/* # of files to copy */
-int		progress = 0;		/* display sign of life */
-const u_char	*ctab;			/* conversion table */
-sigset_t	infoset;		/* a set blocking SIGINFO */
-
-int
-dd_main(int argc, char *argv[])
-{
-	int ch;
-
-	while ((ch = getopt(argc, argv, "")) != -1) {
-		switch (ch) {
-		default:
-			fprintf(stderr, "usage: dd [operand ...]\n");
-			exit(1);
-			/* NOTREACHED */
-		}
-	}
-	argc -= (optind - 1);
-	argv += (optind - 1);
-
-	jcl(argv);
-	setup();
-
-//	(void)signal(SIGINFO, summaryx);
-	(void)signal(SIGINT, terminate);
-	(void)sigemptyset(&infoset);
-//	(void)sigaddset(&infoset, SIGINFO);
-
-	(void)atexit(summary);
-
-	while (files_cnt--)
-		dd_in();
-
-	dd_close();
-	exit(0);
-	/* NOTREACHED */
-}
-
-static void
-setup(void)
-{
-
-	if (in.name == NULL) {
-		in.name = "stdin";
-		in.fd = STDIN_FILENO;
-	} else {
-		in.fd = open(in.name, O_RDONLY, 0);
-		if (in.fd < 0) {
-			fprintf(stderr, "%s: cannot open for read: %s\n",
-				in.name, strerror(errno));
-			exit(1);
-			/* NOTREACHED */
-		}
-
-		/* Ensure in.fd is outside the stdio descriptor range */
-		in.fd = redup_clean_fd(in.fd);
-	}
-
-	getfdtype(&in);
-
-	if (files_cnt > 1 && !(in.flags & ISTAPE)) {
-		fprintf(stderr,
-			"files is not supported for non-tape devices\n");
-		exit(1);
-		/* NOTREACHED */
-	}
-
-	if (out.name == NULL) {
-		/* No way to check for read access here. */
-		out.fd = STDOUT_FILENO;
-		out.name = "stdout";
-	} else {
-#define	OFLAGS \
-    (O_CREAT | (ddflags & (C_SEEK | C_NOTRUNC) ? 0 : O_TRUNC))
-		out.fd = open(out.name, O_RDWR | OFLAGS, DEFFILEMODE);
-		/*
-		 * May not have read access, so try again with write only.
-		 * Without read we may have a problem if output also does
-		 * not support seeks.
-		 */
-		if (out.fd < 0) {
-			out.fd = open(out.name, O_WRONLY | OFLAGS, DEFFILEMODE);
-			out.flags |= NOREAD;
-		}
-		if (out.fd < 0) {
-			fprintf(stderr, "%s: cannot open for write: %s\n",
-				out.name, strerror(errno));
-			exit(1);
-			/* NOTREACHED */
-		}
-
-		/* Ensure out.fd is outside the stdio descriptor range */
-		out.fd = redup_clean_fd(out.fd);
-	}
-
-	getfdtype(&out);
-
-	/*
-	 * Allocate space for the input and output buffers.  If not doing
-	 * record oriented I/O, only need a single buffer.
-	 */
-	if (!(ddflags & (C_BLOCK|C_UNBLOCK))) {
-		if ((in.db = malloc(out.dbsz + in.dbsz - 1)) == NULL) {
-			exit(1);
-			/* NOTREACHED */
-		}
-		out.db = in.db;
-	} else if ((in.db =
-	    malloc((u_int)(MAX(in.dbsz, cbsz) + cbsz))) == NULL ||
-	    (out.db = malloc((u_int)(out.dbsz + cbsz))) == NULL) {
-		exit(1);
-		/* NOTREACHED */
-	}
-	in.dbp = in.db;
-	out.dbp = out.db;
-
-	/* Position the input/output streams. */
-	if (in.offset)
-		pos_in();
-	if (out.offset)
-		pos_out();
-
-	/*
-	 * Truncate the output file; ignore errors because it fails on some
-	 * kinds of output files, tapes, for example.
-	 */
-	if ((ddflags & (C_OF | C_SEEK | C_NOTRUNC)) == (C_OF | C_SEEK))
-		(void)ftruncate(out.fd, (off_t)out.offset * out.dbsz);
-
-	(void)gettimeofday(&st.start, NULL);	/* Statistics timestamp. */
-}
-
-static void
-getfdtype(IO *io)
-{
-//	struct mtget mt;
-	struct stat sb;
-
-	if (fstat(io->fd, &sb)) {
-		fprintf(stderr, "%s: cannot fstat: %s\n",
-			io->name, strerror(errno));
-		exit(1);
-		/* NOTREACHED */
-	}
-	if (S_ISCHR(sb.st_mode))
-		io->flags |= /*ioctl(io->fd, MTIOCGET, &mt) ? ISCHR : ISTAPE; */ ISCHR;
-	else if (lseek(io->fd, (off_t)0, SEEK_CUR) == -1 && errno == ESPIPE)
-		io->flags |= ISPIPE;		/* XXX fixed in 4.4BSD */
-}
-
-/*
- * Move the parameter file descriptor to a descriptor that is outside the
- * stdio descriptor range, if necessary.  This is required to avoid
- * accidentally outputting completion or error messages into the
- * output file that were intended for the tty.
- */
-static int
-redup_clean_fd(int fd)
-{
-	int newfd;
-
-	if (fd != STDIN_FILENO && fd != STDOUT_FILENO &&
-	    fd != STDERR_FILENO)
-		/* File descriptor is ok, return immediately. */
-		return fd;
-
-	/*
-	 * 3 is the first descriptor greater than STD*_FILENO.  Any
-	 * free descriptor valued 3 or above is acceptable...
-	 */
-	newfd = fcntl(fd, F_DUPFD, 3);
-	if (newfd < 0) {
-		fprintf(stderr, "dupfd IO: %s\n", strerror(errno));
-		exit(1);
-		/* NOTREACHED */
-	}
-
-	close(fd);
-
-	return newfd;
-}
-
-static void
-dd_in(void)
-{
-	int flags;
-	int64_t n;
-
-	for (flags = ddflags;;) {
-		if (cpy_cnt && (st.in_full + st.in_part) >= cpy_cnt)
-			return;
-
-		/*
-		 * Clear the buffer first if doing "sync" on input.
-		 * If doing block operations use spaces.  This will
-		 * affect not only the C_NOERROR case, but also the
-		 * last partial input block which should be padded
-		 * with zero and not garbage.
-		 */
-		if (flags & C_SYNC) {
-			if (flags & (C_BLOCK|C_UNBLOCK))
-				(void)memset(in.dbp, ' ', in.dbsz);
-			else
-				(void)memset(in.dbp, 0, in.dbsz);
-		}
-
-		n = read(in.fd, in.dbp, in.dbsz);
-		if (n == 0) {
-			in.dbrcnt = 0;
-			return;
-		}
-
-		/* Read error. */
-		if (n < 0) {
-
-			/*
-			 * If noerror not specified, die.  POSIX requires that
-			 * the warning message be followed by an I/O display.
-			 */
-			fprintf(stderr, "%s: read error: %s\n",
-				in.name, strerror(errno));
-			if (!(flags & C_NOERROR)) {
-				exit(1);
-				/* NOTREACHED */
-			}
-			summary();
-
-			/*
-			 * If it's not a tape drive or a pipe, seek past the
-			 * error.  If your OS doesn't do the right thing for
-			 * raw disks this section should be modified to re-read
-			 * in sector size chunks.
-			 */
-			if (!(in.flags & (ISPIPE|ISTAPE)) &&
-			    lseek(in.fd, (off_t)in.dbsz, SEEK_CUR))
-				fprintf(stderr, "%s: seek error: %s\n",
-					in.name, strerror(errno));
-
-			/* If sync not specified, omit block and continue. */
-			if (!(ddflags & C_SYNC))
-				continue;
-
-			/* Read errors count as full blocks. */
-			in.dbcnt += in.dbrcnt = in.dbsz;
-			++st.in_full;
-
-		/* Handle full input blocks. */
-		} else if (n == (int64_t)in.dbsz) {
-			in.dbcnt += in.dbrcnt = n;
-			++st.in_full;
-
-		/* Handle partial input blocks. */
-		} else {
-			/* If sync, use the entire block. */
-			if (ddflags & C_SYNC)
-				in.dbcnt += in.dbrcnt = in.dbsz;
-			else
-				in.dbcnt += in.dbrcnt = n;
-			++st.in_part;
-		}
-
-		/*
-		 * POSIX states that if bs is set and no other conversions
-		 * than noerror, notrunc or sync are specified, the block
-		 * is output without buffering as it is read.
-		 */
-		if (ddflags & C_BS) {
-			out.dbcnt = in.dbcnt;
-			dd_out(1);
-			in.dbcnt = 0;
-			continue;
-		}
-
-/*		if (ddflags & C_SWAB) {
-			if ((n = in.dbrcnt) & 1) {
-				++st.swab;
-				--n;
-			}
-			swab(in.dbp, in.dbp, n);
-		}
-*/
-		in.dbp += in.dbrcnt;
-		(*cfunc)();
-	}
-}
-
-/*
- * Cleanup any remaining I/O and flush output.  If necesssary, output file
- * is truncated.
- */
-static void
-dd_close(void)
-{
-
-	if (cfunc == def)
-		def_close();
-	else if (cfunc == block)
-		block_close();
-	else if (cfunc == unblock)
-		unblock_close();
-	if (ddflags & C_OSYNC && out.dbcnt < out.dbsz) {
-		(void)memset(out.dbp, 0, out.dbsz - out.dbcnt);
-		out.dbcnt = out.dbsz;
-	}
-	/* If there are pending sparse blocks, make sure
-	 * to write out the final block un-sparse
-	 */
-	if ((out.dbcnt == 0) && pending) {
-		memset(out.db, 0, out.dbsz);
-		out.dbcnt = out.dbsz;
-		out.dbp = out.db + out.dbcnt;
-		pending -= out.dbsz;
-	}
-	if (out.dbcnt)
-		dd_out(1);
-
-	/*
-	 * Reporting nfs write error may be defered until next
-	 * write(2) or close(2) system call.  So, we need to do an
-	 * extra check.  If an output is stdout, the file structure
-	 * may be shared among with other processes and close(2) just
-	 * decreases the reference count.
-	 */
-	if (out.fd == STDOUT_FILENO && fsync(out.fd) == -1 && errno != EINVAL) {
-		fprintf(stderr, "fsync stdout: %s\n", strerror(errno));
-		exit(1);
-		/* NOTREACHED */
-	}
-	if (close(out.fd) == -1) {
-		fprintf(stderr, "close: %s\n", strerror(errno));
-		exit(1);
-		/* NOTREACHED */
-	}
-}
-
-void
-dd_out(int force)
-{
-	static int warned;
-	int64_t cnt, n, nw;
-	u_char *outp;
-
-	/*
-	 * Write one or more blocks out.  The common case is writing a full
-	 * output block in a single write; increment the full block stats.
-	 * Otherwise, we're into partial block writes.  If a partial write,
-	 * and it's a character device, just warn.  If a tape device, quit.
-	 *
-	 * The partial writes represent two cases.  1: Where the input block
-	 * was less than expected so the output block was less than expected.
-	 * 2: Where the input block was the right size but we were forced to
-	 * write the block in multiple chunks.  The original versions of dd(1)
-	 * never wrote a block in more than a single write, so the latter case
-	 * never happened.
-	 *
-	 * One special case is if we're forced to do the write -- in that case
-	 * we play games with the buffer size, and it's usually a partial write.
-	 */
-	outp = out.db;
-	for (n = force ? out.dbcnt : out.dbsz;; n = out.dbsz) {
-		for (cnt = n;; cnt -= nw) {
-
-			if (!force && ddflags & C_SPARSE) {
-				int sparse, i;
-				sparse = 1;	/* Is buffer sparse? */
-				for (i = 0; i < cnt; i++)
-					if (outp[i] != 0) {
-						sparse = 0;
-						break;
-					}
-				if (sparse) {
-					pending += cnt;
-					outp += cnt;
-					nw = 0;
-					break;
-				}
-			}
-			if (pending != 0) {
-				if (lseek(out.fd, pending, SEEK_CUR) ==
-				    -1) {
-					fprintf(stderr,
-						"%s: seek error creating "
-						"sparse file: %s\n",
-						out.name, strerror(errno));
-					exit(1);
-				}
-			}
-			nw = bwrite(out.fd, outp, cnt);
-			if (nw <= 0) {
-				if (nw == 0) {
-					fprintf(stderr, "%s: end of device\n",
-						out.name);
-					exit(1);
-					/* NOTREACHED */
-				}
-				if (errno != EINTR) {
-					fprintf(stderr, "%s: write error: %s\n",
-						out.name, strerror(errno));
-					/* NOTREACHED */
-					exit(1);
-				}
-				nw = 0;
-			}
-			if (pending) {
-				st.bytes += pending;
-				st.sparse += pending/out.dbsz;
-				st.out_full += pending/out.dbsz;
-				pending = 0;
-			}
-			outp += nw;
-			st.bytes += nw;
-			if (nw == n) {
-				if (n != (int64_t)out.dbsz)
-					++st.out_part;
-				else
-					++st.out_full;
-				break;
-			}
-			++st.out_part;
-			if (nw == cnt)
-				break;
-			if (out.flags & ISCHR && !warned) {
-				warned = 1;
-				fprintf(stderr, "%s: short write on character "
-					"device\n", out.name);
-			}
-			if (out.flags & ISTAPE) {
-				fprintf(stderr,
-					"%s: short write on tape device",
-					out.name);
-				exit(1);
-				/* NOTREACHED */
-			}
-		}
-		if ((out.dbcnt -= n) < out.dbsz)
-			break;
-	}
-
-	/* Reassemble the output block. */
-	if (out.dbcnt)
-		(void)memmove(out.db, out.dbp - out.dbcnt, out.dbcnt);
-	out.dbp = out.db + out.dbcnt;
-
-	if (progress)
-		(void)write(STDERR_FILENO, ".", 1);
-}
-
-/*
- * A protected against SIGINFO write
- */
-ssize_t
-bwrite(int fd, const void *buf, size_t len)
-{
-	sigset_t oset;
-	ssize_t rv;
-	int oerrno;
-
-	(void)sigprocmask(SIG_BLOCK, &infoset, &oset);
-	rv = write(fd, buf, len);
-	oerrno = errno;
-	(void)sigprocmask(SIG_SETMASK, &oset, NULL);
-	errno = oerrno;
-	return (rv);
-}
-
-/*
- * Position input/output data streams before starting the copy.  Device type
- * dependent.  Seekable devices use lseek, and the rest position by reading.
- * Seeking past the end of file can cause null blocks to be written to the
- * output.
- */
-void
-pos_in(void)
-{
-	int bcnt, cnt, nr, warned;
-
-	/* If not a pipe or tape device, try to seek on it. */
-	if (!(in.flags & (ISPIPE|ISTAPE))) {
-		if (lseek64(in.fd,
-		    (off64_t)in.offset * (off64_t)in.dbsz, SEEK_CUR) == -1) {
-			fprintf(stderr, "%s: seek error: %s",
-				in.name, strerror(errno));
-			exit(1);
-			/* NOTREACHED */
-		}
-		return;
-		/* NOTREACHED */
-	}
-
-	/*
-	 * Read the data.  If a pipe, read until satisfy the number of bytes
-	 * being skipped.  No differentiation for reading complete and partial
-	 * blocks for other devices.
-	 */
-	for (bcnt = in.dbsz, cnt = in.offset, warned = 0; cnt;) {
-		if ((nr = read(in.fd, in.db, bcnt)) > 0) {
-			if (in.flags & ISPIPE) {
-				if (!(bcnt -= nr)) {
-					bcnt = in.dbsz;
-					--cnt;
-				}
-			} else
-				--cnt;
-			continue;
-		}
-
-		if (nr == 0) {
-			if (files_cnt > 1) {
-				--files_cnt;
-				continue;
-			}
-			fprintf(stderr, "skip reached end of input\n");
-			exit(1);
-			/* NOTREACHED */
-		}
-
-		/*
-		 * Input error -- either EOF with no more files, or I/O error.
-		 * If noerror not set die.  POSIX requires that the warning
-		 * message be followed by an I/O display.
-		 */
-		if (ddflags & C_NOERROR) {
-			if (!warned) {
-
-				fprintf(stderr, "%s: error occurred\n",
-					in.name);
-				warned = 1;
-				summary();
-			}
-			continue;
-		}
-		fprintf(stderr, "%s: read error: %s", in.name, strerror(errno));
-		exit(1);
-		/* NOTREACHED */
-	}
-}
-
-void
-pos_out(void)
-{
-/*	struct mtop t_op;        */
-	int64_t cnt, n;
-
-	/*
-	 * If not a tape, try seeking on the file.  Seeking on a pipe is
-	 * going to fail, but don't protect the user -- they shouldn't
-	 * have specified the seek operand.
-	 */
-	if (!(out.flags & ISTAPE)) {
-		if (lseek64(out.fd,
-		    (off64_t)out.offset * (off64_t)out.dbsz, SEEK_SET) == -1) {
-			fprintf(stderr, "%s: seek error: %s\n",
-				out.name, strerror(errno));
-			exit(1);
-			/* NOTREACHED */
-		}
-		return;
-	}
-
-	/* If no read access, try using mtio. */
-	if (out.flags & NOREAD) {
-/*		t_op.mt_op = MTFSR;
-		t_op.mt_count = out.offset;
-
-		if (ioctl(out.fd, MTIOCTOP, &t_op) < 0)*/
-			fprintf(stderr, "%s: cannot read", out.name);
-			exit(1);
-			/* NOTREACHED */
-		return;
-	}
-
-	/* Read it. */
-	for (cnt = 0; cnt < (int64_t)out.offset; ++cnt) {
-		if ((n = read(out.fd, out.db, out.dbsz)) > 0)
-			continue;
-
-		if (n < 0) {
-			fprintf(stderr, "%s: cannot position by reading: %s\n",
-				out.name, strerror(errno));
-			exit(1);
-			/* NOTREACHED */
-		}
-
-		/*
-		 * If reach EOF, fill with NUL characters; first, back up over
-		 * the EOF mark.  Note, cnt has not yet been incremented, so
-		 * the EOF read does not count as a seek'd block.
-		 */
-/*		t_op.mt_op = MTBSR;
-		t_op.mt_count = 1;
-		if (ioctl(out.fd, MTIOCTOP, &t_op) == -1) */ {
-			fprintf(stderr, "%s: cannot position\n", out.name);
-			exit(1);
-			/* NOTREACHED */
-		}
-
-		while (cnt++ < (int64_t)out.offset)
-			if ((n = bwrite(out.fd, out.db, out.dbsz)) != (int64_t)out.dbsz) {
-				fprintf(stderr, "%s: cannot position "
-					"by writing: %s\n",
-					out.name, strerror(errno));
-				exit(1);
-				/* NOTREACHED */
-			}
-		break;
-	}
-}
-
-/*
- * def --
- * Copy input to output.  Input is buffered until reaches obs, and then
- * output until less than obs remains.  Only a single buffer is used.
- * Worst case buffer calculation is (ibs + obs - 1).
- */
-void
-def(void)
-{
-	uint64_t cnt;
-	u_char *inp;
-	const u_char *t;
-
-	if ((t = ctab) != NULL)
-		for (inp = in.dbp - (cnt = in.dbrcnt); cnt--; ++inp)
-			*inp = t[*inp];
-
-	/* Make the output buffer look right. */
-	out.dbp = in.dbp;
-	out.dbcnt = in.dbcnt;
-
-	if (in.dbcnt >= out.dbsz) {
-		/* If the output buffer is full, write it. */
-		dd_out(0);
-
-		/*
-		 * Ddout copies the leftover output to the beginning of
-		 * the buffer and resets the output buffer.  Reset the
-		 * input buffer to match it.
-	 	 */
-		in.dbp = out.dbp;
-		in.dbcnt = out.dbcnt;
-	}
-}
-
-void
-def_close(void)
-{
-	if (ddflags & C_FDATASYNC) {
-		fdatasync(out.fd);
-	}
-
-	/* Just update the count, everything is already in the buffer. */
-	if (in.dbcnt)
-		out.dbcnt = in.dbcnt;
-}
-
-#ifdef	NO_CONV
-/* Build a smaller version (i.e. for a miniroot) */
-/* These can not be called, but just in case...  */
-static const char no_block[] = "unblock and -DNO_CONV?\n";
-void block(void)		{ fprintf(stderr, "%s", no_block + 2); exit(1); }
-void block_close(void)		{ fprintf(stderr, "%s", no_block + 2); exit(1); }
-void unblock(void)		{ fprintf(stderr, "%s", no_block); exit(1); }
-void unblock_close(void)	{ fprintf(stderr, "%s", no_block); exit(1); }
-#else	/* NO_CONV */
-
-/*
- * Copy variable length newline terminated records with a max size cbsz
- * bytes to output.  Records less than cbs are padded with spaces.
- *
- * max in buffer:  MAX(ibs, cbsz)
- * max out buffer: obs + cbsz
- */
-void
-block(void)
-{
-	static int intrunc;
-	int ch = 0;	/* pacify gcc */
-	uint64_t cnt, maxlen;
-	u_char *inp, *outp;
-	const u_char *t;
-
-	/*
-	 * Record truncation can cross block boundaries.  If currently in a
-	 * truncation state, keep tossing characters until reach a newline.
-	 * Start at the beginning of the buffer, as the input buffer is always
-	 * left empty.
-	 */
-	if (intrunc) {
-		for (inp = in.db, cnt = in.dbrcnt;
-		    cnt && *inp++ != '\n'; --cnt);
-		if (!cnt) {
-			in.dbcnt = 0;
-			in.dbp = in.db;
-			return;
-		}
-		intrunc = 0;
-		/* Adjust the input buffer numbers. */
-		in.dbcnt = cnt - 1;
-		in.dbp = inp + cnt - 1;
-	}
-
-	/*
-	 * Copy records (max cbsz size chunks) into the output buffer.  The
-	 * translation is done as we copy into the output buffer.
-	 */
-	for (inp = in.dbp - in.dbcnt, outp = out.dbp; in.dbcnt;) {
-		maxlen = MIN(cbsz, in.dbcnt);
-		if ((t = ctab) != NULL)
-			for (cnt = 0;
-			    cnt < maxlen && (ch = *inp++) != '\n'; ++cnt)
-				*outp++ = t[ch];
-		else
-			for (cnt = 0;
-			    cnt < maxlen && (ch = *inp++) != '\n'; ++cnt)
-				*outp++ = ch;
-		/*
-		 * Check for short record without a newline.  Reassemble the
-		 * input block.
-		 */
-		if (ch != '\n' && in.dbcnt < cbsz) {
-			(void)memmove(in.db, in.dbp - in.dbcnt, in.dbcnt);
-			break;
-		}
-
-		/* Adjust the input buffer numbers. */
-		in.dbcnt -= cnt;
-		if (ch == '\n')
-			--in.dbcnt;
-
-		/* Pad short records with spaces. */
-		if (cnt < cbsz)
-			(void)memset(outp, ctab ? ctab[' '] : ' ', cbsz - cnt);
-		else {
-			/*
-			 * If the next character wouldn't have ended the
-			 * block, it's a truncation.
-			 */
-			if (!in.dbcnt || *inp != '\n')
-				++st.trunc;
-
-			/* Toss characters to a newline. */
-			for (; in.dbcnt && *inp++ != '\n'; --in.dbcnt);
-			if (!in.dbcnt)
-				intrunc = 1;
-			else
-				--in.dbcnt;
-		}
-
-		/* Adjust output buffer numbers. */
-		out.dbp += cbsz;
-		if ((out.dbcnt += cbsz) >= out.dbsz)
-			dd_out(0);
-		outp = out.dbp;
-	}
-	in.dbp = in.db + in.dbcnt;
-}
-
-void
-block_close(void)
-{
-
-	/*
-	 * Copy any remaining data into the output buffer and pad to a record.
-	 * Don't worry about truncation or translation, the input buffer is
-	 * always empty when truncating, and no characters have been added for
-	 * translation.  The bottom line is that anything left in the input
-	 * buffer is a truncated record.  Anything left in the output buffer
-	 * just wasn't big enough.
-	 */
-	if (in.dbcnt) {
-		++st.trunc;
-		(void)memmove(out.dbp, in.dbp - in.dbcnt, in.dbcnt);
-		(void)memset(out.dbp + in.dbcnt,
-		    ctab ? ctab[' '] : ' ', cbsz - in.dbcnt);
-		out.dbcnt += cbsz;
-	}
-}
-
-/*
- * Convert fixed length (cbsz) records to variable length.  Deletes any
- * trailing blanks and appends a newline.
- *
- * max in buffer:  MAX(ibs, cbsz) + cbsz
- * max out buffer: obs + cbsz
- */
-void
-unblock(void)
-{
-	uint64_t cnt;
-	u_char *inp;
-	const u_char *t;
-
-	/* Translation and case conversion. */
-	if ((t = ctab) != NULL)
-		for (cnt = in.dbrcnt, inp = in.dbp - 1; cnt--; inp--)
-			*inp = t[*inp];
-	/*
-	 * Copy records (max cbsz size chunks) into the output buffer.  The
-	 * translation has to already be done or we might not recognize the
-	 * spaces.
-	 */
-	for (inp = in.db; in.dbcnt >= cbsz; inp += cbsz, in.dbcnt -= cbsz) {
-		for (t = inp + cbsz - 1; t >= inp && *t == ' '; --t);
-		if (t >= inp) {
-			cnt = t - inp + 1;
-			(void)memmove(out.dbp, inp, cnt);
-			out.dbp += cnt;
-			out.dbcnt += cnt;
-		}
-		++out.dbcnt;
-		*out.dbp++ = '\n';
-		if (out.dbcnt >= out.dbsz)
-			dd_out(0);
-	}
-	if (in.dbcnt)
-		(void)memmove(in.db, in.dbp - in.dbcnt, in.dbcnt);
-	in.dbp = in.db + in.dbcnt;
-}
-
-void
-unblock_close(void)
-{
-	uint64_t cnt;
-	u_char *t;
-
-	if (in.dbcnt) {
-		warnx("%s: short input record", in.name);
-		for (t = in.db + in.dbcnt - 1; t >= in.db && *t == ' '; --t);
-		if (t >= in.db) {
-			cnt = t - in.db + 1;
-			(void)memmove(out.dbp, in.db, cnt);
-			out.dbp += cnt;
-			out.dbcnt += cnt;
-		}
-		++out.dbcnt;
-		*out.dbp++ = '\n';
-	}
-}
-
-#endif	/* NO_CONV */
-
-#define	tv2mS(tv) ((tv).tv_sec * 1000LL + ((tv).tv_usec + 500) / 1000)
-
-void
-summary(void)
-{
-	char buf[100];
-	int64_t mS;
-	struct timeval tv;
-
-	if (progress)
-		(void)write(STDERR_FILENO, "\n", 1);
-
-	(void)gettimeofday(&tv, NULL);
-	mS = tv2mS(tv) - tv2mS(st.start);
-	if (mS == 0)
-		mS = 1;
-	/* Use snprintf(3) so that we don't reenter stdio(3). */
-	(void)snprintf(buf, sizeof(buf),
-	    "%llu+%llu records in\n%llu+%llu records out\n",
-	    (unsigned long long)st.in_full,  (unsigned long long)st.in_part,
-	    (unsigned long long)st.out_full, (unsigned long long)st.out_part);
-	(void)write(STDERR_FILENO, buf, strlen(buf));
-	if (st.swab) {
-		(void)snprintf(buf, sizeof(buf), "%llu odd length swab %s\n",
-		    (unsigned long long)st.swab,
-		    (st.swab == 1) ? "block" : "blocks");
-		(void)write(STDERR_FILENO, buf, strlen(buf));
-	}
-	if (st.trunc) {
-		(void)snprintf(buf, sizeof(buf), "%llu truncated %s\n",
-		    (unsigned long long)st.trunc,
-		    (st.trunc == 1) ? "block" : "blocks");
-		(void)write(STDERR_FILENO, buf, strlen(buf));
-	}
-	if (st.sparse) {
-		(void)snprintf(buf, sizeof(buf), "%llu sparse output %s\n",
-		    (unsigned long long)st.sparse,
-		    (st.sparse == 1) ? "block" : "blocks");
-		(void)write(STDERR_FILENO, buf, strlen(buf));
-	}
-	(void)snprintf(buf, sizeof(buf),
-	    "%llu bytes transferred in %lu.%03d secs (%llu bytes/sec)\n",
-	    (unsigned long long) st.bytes,
-	    (long) (mS / 1000),
-	    (int) (mS % 1000),
-	    (unsigned long long) (st.bytes * 1000LL / mS));
-	(void)write(STDERR_FILENO, buf, strlen(buf));
-}
-
-void
-terminate(int notused)
-{
-
-	exit(0);
-	/* NOTREACHED */
-}
-
-static int	c_arg(const void *, const void *);
-#ifndef	NO_CONV
-static int	c_conv(const void *, const void *);
-#endif
-static void	f_bs(char *);
-static void	f_cbs(char *);
-static void	f_conv(char *);
-static void	f_count(char *);
-static void	f_files(char *);
-static void	f_ibs(char *);
-static void	f_if(char *);
-static void	f_obs(char *);
-static void	f_of(char *);
-static void	f_seek(char *);
-static void	f_skip(char *);
-static void	f_progress(char *);
-
-static const struct arg {
-	const char *name;
-	void (*f)(char *);
-	u_int set, noset;
-} args[] = {
-     /* the array needs to be sorted by the first column so
-	bsearch() can be used to find commands quickly */
-	{ "bs",		f_bs,		C_BS,	 C_BS|C_IBS|C_OBS|C_OSYNC },
-	{ "cbs",	f_cbs,		C_CBS,	 C_CBS },
-	{ "conv",	f_conv,		0,	 0 },
-	{ "count",	f_count,	C_COUNT, C_COUNT },
-	{ "files",	f_files,	C_FILES, C_FILES },
-	{ "ibs",	f_ibs,		C_IBS,	 C_BS|C_IBS },
-	{ "if",		f_if,		C_IF,	 C_IF },
-	{ "obs",	f_obs,		C_OBS,	 C_BS|C_OBS },
-	{ "of",		f_of,		C_OF,	 C_OF },
-	{ "progress",	f_progress,	0,	 0 },
-	{ "seek",	f_seek,		C_SEEK,	 C_SEEK },
-	{ "skip",	f_skip,		C_SKIP,	 C_SKIP },
-};
-
-/*
- * args -- parse JCL syntax of dd.
- */
-void
-jcl(char **argv)
-{
-	struct arg *ap, tmp;
-	char *oper, *arg;
-
-	in.dbsz = out.dbsz = 512;
-
-	while ((oper = *++argv) != NULL) {
-		if ((arg = strchr(oper, '=')) == NULL) {
-			fprintf(stderr, "unknown operand %s\n", oper);
-			exit(1);
-			/* NOTREACHED */
-		}
-		*arg++ = '\0';
-		if (!*arg) {
-			fprintf(stderr, "no value specified for %s\n", oper);
-			exit(1);
-			/* NOTREACHED */
-		}
-		tmp.name = oper;
-		if (!(ap = (struct arg *)bsearch(&tmp, args,
-		    sizeof(args)/sizeof(struct arg), sizeof(struct arg),
-		    c_arg))) {
-			fprintf(stderr, "unknown operand %s\n", tmp.name);
-			exit(1);
-			/* NOTREACHED */
-		}
-		if (ddflags & ap->noset) {
-			fprintf(stderr,
-			    "%s: illegal argument combination or already set\n",
-			    tmp.name);
-			exit(1);
-			/* NOTREACHED */
-		}
-		ddflags |= ap->set;
-		ap->f(arg);
-	}
-
-	/* Final sanity checks. */
-
-	if (ddflags & C_BS) {
-		/*
-		 * Bs is turned off by any conversion -- we assume the user
-		 * just wanted to set both the input and output block sizes
-		 * and didn't want the bs semantics, so we don't warn.
-		 */
-		if (ddflags & (C_BLOCK | C_LCASE | C_SWAB | C_UCASE |
-		    C_UNBLOCK | C_OSYNC | C_ASCII | C_EBCDIC | C_SPARSE)) {
-			ddflags &= ~C_BS;
-			ddflags |= C_IBS|C_OBS;
-		}
-
-		/* Bs supersedes ibs and obs. */
-		if (ddflags & C_BS && ddflags & (C_IBS|C_OBS))
-			fprintf(stderr, "bs supersedes ibs and obs\n");
-	}
-
-	/*
-	 * Ascii/ebcdic and cbs implies block/unblock.
-	 * Block/unblock requires cbs and vice-versa.
-	 */
-	if (ddflags & (C_BLOCK|C_UNBLOCK)) {
-		if (!(ddflags & C_CBS)) {
-			fprintf(stderr, "record operations require cbs\n");
-			exit(1);
-			/* NOTREACHED */
-		}
-		cfunc = ddflags & C_BLOCK ? block : unblock;
-	} else if (ddflags & C_CBS) {
-		if (ddflags & (C_ASCII|C_EBCDIC)) {
-			if (ddflags & C_ASCII) {
-				ddflags |= C_UNBLOCK;
-				cfunc = unblock;
-			} else {
-				ddflags |= C_BLOCK;
-				cfunc = block;
-			}
-		} else {
-			fprintf(stderr,
-			    "cbs meaningless if not doing record operations\n");
-			exit(1);
-			/* NOTREACHED */
-		}
-	} else
-		cfunc = def;
-
-	/* Read, write and seek calls take off_t as arguments.
-	 *
-	 * The following check is not done because an off_t is a quad
-	 *  for current NetBSD implementations.
-	 *
-	 * if (in.offset > INT_MAX/in.dbsz || out.offset > INT_MAX/out.dbsz)
-	 *	errx(1, "seek offsets cannot be larger than %d", INT_MAX);
-	 */
-}
-
-static int
-c_arg(const void *a, const void *b)
-{
-
-	return (strcmp(((const struct arg *)a)->name,
-	    ((const struct arg *)b)->name));
-}
-
-static long long strsuftoll(const char* name, const char* arg, int def, unsigned long long max)
-{
-	long long result;
-	
-	if (sscanf(arg, "%lld", &result) == 0)
-		result = def;
-	return result;
-}
-
-static void
-f_bs(char *arg)
-{
-
-	in.dbsz = out.dbsz = strsuftoll("block size", arg, 1, UINT_MAX);
-}
-
-static void
-f_cbs(char *arg)
-{
-
-	cbsz = strsuftoll("conversion record size", arg, 1, UINT_MAX);
-}
-
-static void
-f_count(char *arg)
-{
-
-	cpy_cnt = (uint64_t)strsuftoll("block count", arg, 0, 0xFFFFFFFFFFFFFFFFULL);
-	if (!cpy_cnt)
-		terminate(0);
-}
-
-static void
-f_files(char *arg)
-{
-
-	files_cnt = (u_int)strsuftoll("file count", arg, 0, UINT_MAX);
-	if (!files_cnt)
-		terminate(0);
-}
-
-static void
-f_ibs(char *arg)
-{
-
-	if (!(ddflags & C_BS))
-		in.dbsz = strsuftoll("input block size", arg, 1, UINT_MAX);
-}
-
-static void
-f_if(char *arg)
-{
-
-	in.name = arg;
-}
-
-static void
-f_obs(char *arg)
-{
-
-	if (!(ddflags & C_BS))
-		out.dbsz = strsuftoll("output block size", arg, 1, UINT_MAX);
-}
-
-static void
-f_of(char *arg)
-{
-
-	out.name = arg;
-}
-
-static void
-f_seek(char *arg)
-{
-
-	out.offset = (uint64_t)strsuftoll("seek blocks", arg, 0, 0xFFFFFFFFFFFFFFFFULL);
-}
-
-static void
-f_skip(char *arg)
-{
-
-	in.offset = (uint64_t)strsuftoll("skip blocks", arg, 0, 0xFFFFFFFFFFFFFFFFULL);
-}
-
-static void
-f_progress(char *arg)
-{
-
-	if (*arg != '0')
-		progress = 1;
-}
-
-#ifdef	NO_CONV
-/* Build a small version (i.e. for a ramdisk root) */
-static void
-f_conv(char *arg)
-{
-
-	fprintf(stderr, "conv option disabled\n");
-	exit(1);
-	/* NOTREACHED */
-}
-#else	/* NO_CONV */
-
-static const struct conv {
-	const char *name;
-	u_int set, noset;
-	const u_char *ctab;
-} clist[] = {
-	{ "block",	C_BLOCK,	C_UNBLOCK,	NULL },
-	{ "fdatasync",	C_FDATASYNC,	0,		NULL },
-	{ "noerror",	C_NOERROR,	0,		NULL },
-	{ "notrunc",	C_NOTRUNC,	0,		NULL },
-	{ "osync",	C_OSYNC,	C_BS,		NULL },
-	{ "sparse",	C_SPARSE,	0,		NULL },
-	{ "swab",	C_SWAB,		0,		NULL },
-	{ "sync",	C_SYNC,		0,		NULL },
-	{ "unblock",	C_UNBLOCK,	C_BLOCK,	NULL },
-	/* If you add items to this table, be sure to add the
-	 * conversions to the C_BS check in the jcl routine above.
-	 */
-};
-
-static void
-f_conv(char *arg)
-{
-	struct conv *cp, tmp;
-
-	while (arg != NULL) {
-		tmp.name = strsep(&arg, ",");
-		if (!(cp = (struct conv *)bsearch(&tmp, clist,
-		    sizeof(clist)/sizeof(struct conv), sizeof(struct conv),
-		    c_conv))) {
-			errx(EXIT_FAILURE, "unknown conversion %s", tmp.name);
-			/* NOTREACHED */
-		}
-		if (ddflags & cp->noset) {
-			errx(EXIT_FAILURE, "%s: illegal conversion combination", tmp.name);
-			/* NOTREACHED */
-		}
-		ddflags |= cp->set;
-		if (cp->ctab)
-			ctab = cp->ctab;
-	}
-}
-
-static int
-c_conv(const void *a, const void *b)
-{
-
-	return (strcmp(((const struct conv *)a)->name,
-	    ((const struct conv *)b)->name));
-}
-
-#endif	/* NO_CONV */
-
-
diff --git a/toolbox/kill.c b/toolbox/kill.c
deleted file mode 100644
index fa2f649..0000000
--- a/toolbox/kill.c
+++ /dev/null
@@ -1,148 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <errno.h>
-
-#include <sys/types.h>
-#include <signal.h>
-
-static struct {
-    unsigned int number;
-    char *name;
-} signals[] = {
-#define _SIG(name) {SIG##name, #name}
-    /* Single Unix Specification signals */
-    _SIG(ABRT),
-    _SIG(ALRM),
-    _SIG(FPE),
-    _SIG(HUP),
-    _SIG(ILL),
-    _SIG(INT),
-    _SIG(KILL),
-    _SIG(PIPE),
-    _SIG(QUIT),
-    _SIG(SEGV),
-    _SIG(TERM),
-    _SIG(USR1),
-    _SIG(USR2),
-    _SIG(CHLD),
-    _SIG(CONT),
-    _SIG(STOP),
-    _SIG(TSTP),
-    _SIG(TTIN),
-    _SIG(TTOU),
-    _SIG(BUS),
-    _SIG(POLL),
-    _SIG(PROF),
-    _SIG(SYS),
-    _SIG(TRAP),
-    _SIG(URG),
-    _SIG(VTALRM),
-    _SIG(XCPU),
-    _SIG(XFSZ),
-    /* non-SUS signals */
-    _SIG(IO),
-    _SIG(PWR),
-#ifdef SIGSTKFLT
-    _SIG(STKFLT),
-#endif
-    _SIG(WINCH),
-#undef _SIG
-};
-
-/* To indicate a matching signal was not found */
-static const unsigned int SENTINEL = (unsigned int) -1;
-
-void list_signals()
-{
-    unsigned int sorted_signals[_NSIG];
-    unsigned int i;
-    unsigned int num;
-
-    memset(sorted_signals, SENTINEL, sizeof(sorted_signals));
-
-    // Sort the signals
-    for (i = 0; i < sizeof(signals)/sizeof(signals[0]); i++) {
-        sorted_signals[signals[i].number] = i;
-    }
-
-    num = 0;
-    for (i = 1; i < _NSIG; i++) {
-        unsigned int index = sorted_signals[i];
-        if (index == SENTINEL) {
-            continue;
-        }
-
-        fprintf(stderr, "%2d) SIG%-9s ", i, signals[index].name);
-
-        if ((num++ % 4) == 3) {
-            fprintf(stderr, "\n");
-        }
-    }
-
-    if ((num % 4) == 3) {
-        fprintf(stderr, "\n");
-    }
-}
-
-unsigned int name_to_signal(const char* name)
-{
-    unsigned int i;
-
-    for (i = 1; i < sizeof(signals) / sizeof(signals[0]); i++) {
-        if (!strcasecmp(name, signals[i].name)) {
-            return signals[i].number;
-        }
-    }
-
-    return SENTINEL;
-}
-
-int kill_main(int argc, char **argv)
-{
-    unsigned int sig = SIGTERM;
-    int result = 0;
-
-    argc--;
-    argv++;
-
-    if (argc >= 1 && argv[0][0] == '-') {
-        char *endptr;
-        size_t arg_len = strlen(argv[0]);
-        if (arg_len < 2) {
-            fprintf(stderr, "invalid argument: -\n");
-            return -1;
-        }
-
-        char* arg = argv[0] + 1;
-        if (arg_len == 2 && *arg == 'l') {
-            list_signals();
-            return 0;
-        }
-
-        sig = strtol(arg, &endptr, 10);
-        if (*endptr != '\0') {
-            sig = name_to_signal(arg);
-            if (sig == SENTINEL) {
-                fprintf(stderr, "invalid signal name: %s\n", arg);
-                return -1;
-            }
-        }
-
-        argc--;
-        argv++;
-    }
-
-    while(argc > 0){
-        int pid = atoi(argv[0]);
-        int err = kill(pid, sig);
-        if (err < 0) {
-            result = err;
-            fprintf(stderr, "could not kill pid %d: %s\n", pid, strerror(errno));
-        }
-
-        argc--;
-        argv++;
-    }
-
-    return result;
-}
diff --git a/toolbox/ln.c b/toolbox/ln.c
deleted file mode 100644
index dcd5e3a..0000000
--- a/toolbox/ln.c
+++ /dev/null
@@ -1,34 +0,0 @@
-#include <stdio.h>
-#include <unistd.h>
-#include <string.h>
-#include <errno.h>
-
-static int usage()
-{
-    fprintf(stderr,"ln [-s] <target> <name>\n");
-    return -1;
-}
-
-int ln_main(int argc, char *argv[])
-{
-    int symbolic = 0;
-    int ret;
-    if(argc < 2) return usage();
-    
-    if(!strcmp(argv[1],"-s")) {
-        symbolic = 1;
-        argc--;
-        argv++;
-    }
-
-    if(argc < 3) return usage();
-
-    if(symbolic) {
-        ret = symlink(argv[1], argv[2]);
-    } else {
-        ret = link(argv[1], argv[2]);
-    }
-    if(ret < 0)
-        fprintf(stderr, "link failed %s\n", strerror(errno));
-    return ret;
-}
diff --git a/toolbox/ls.c b/toolbox/ls.c
index 011f7b5..963fcb5 100644
--- a/toolbox/ls.c
+++ b/toolbox/ls.c
@@ -33,7 +33,7 @@
 // fwd
 static int listpath(const char *name, int flags);
 
-static char mode2kind(unsigned mode)
+static char mode2kind(mode_t mode)
 {
     switch(mode & S_IFMT){
     case S_IFSOCK: return 's';
@@ -47,7 +47,7 @@
     }
 }
 
-static void mode2str(unsigned mode, char *out)
+void strmode(mode_t mode, char *out)
 {
     *out++ = mode2kind(mode);
 
@@ -180,7 +180,7 @@
         name++;
     }
 
-    mode2str(s->st_mode, mode);
+    strmode(s->st_mode, mode);
     if (flags & LIST_LONG_NUMERIC) {
         snprintf(user, sizeof(user), "%u", s->st_uid);
         snprintf(group, sizeof(group), "%u", s->st_gid);
@@ -260,7 +260,7 @@
         return -1;
     }
 
-    mode2str(s->st_mode, mode);
+    strmode(s->st_mode, mode);
     user2str(s->st_uid, user, sizeof(user));
     group2str(s->st_gid, group, sizeof(group));
 
diff --git a/toolbox/mv.c b/toolbox/mv.c
deleted file mode 100644
index a5bc225..0000000
--- a/toolbox/mv.c
+++ /dev/null
@@ -1,59 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <limits.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-
-
-int mv_main(int argc, char *argv[])
-{
-    const char* dest;
-    struct stat st;
-    int i;
-
-    if (argc < 3) {
-        fprintf(stderr,"USAGE: %s <source...> <destination>\n", argv[0]);
-        return -1;
-    }
-
-    /* check if destination exists */
-    dest = argv[argc - 1];
-    if (stat(dest, &st)) {
-        /* an error, unless the destination was missing */
-        if (errno != ENOENT) {
-            fprintf(stderr, "failed on %s - %s\n", dest, strerror(errno));
-            return -1;
-        }
-        st.st_mode = 0;
-    }
-
-    for (i = 1; i < argc - 1; i++) {
-        const char *source = argv[i];
-        char fullDest[PATH_MAX + 1 + PATH_MAX + 1];
-        /* assume we build "dest/source", and let rename() fail on pathsize */
-        if (strlen(dest) + 1 + strlen(source) + 1 > sizeof(fullDest)) {
-            fprintf(stderr, "path too long\n");
-            return -1;
-        }
-        strcpy(fullDest, dest);
-
-        /* if destination is a directory, concat the source file name */
-        if (S_ISDIR(st.st_mode)) {
-            const char *fileName = strrchr(source, '/');
-            if (fullDest[strlen(fullDest)-1] != '/') {
-                strcat(fullDest, "/");
-            }
-            strcat(fullDest, fileName ? fileName + 1 : source);
-        }
-
-        /* attempt to move it */
-        if (rename(source, fullDest)) {
-            fprintf(stderr, "failed on '%s' - %s\n", source, strerror(errno));
-            return -1;
-        }
-    }
-
-    return 0;
-}
-
diff --git a/toolbox/printenv.c b/toolbox/printenv.c
deleted file mode 100644
index d5ea531..0000000
--- a/toolbox/printenv.c
+++ /dev/null
@@ -1,29 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-
-extern char** environ;
-
-int printenv_main (int argc, char **argv)
-{
-    char** e;
-    char* v;
-    int i;
-   
-    if (argc == 1) {
-        e = environ;
-        while (*e) {
-            printf("%s\n", *e);
-            e++;
-        }
-    } else {
-        for (i=1; i<argc; i++) {
-            v = getenv(argv[i]);
-            if (v) {
-                printf("%s\n", v);
-            }
-        }
-    }
-
-    return 0;
-}
-
diff --git a/toolbox/uid_from_user.c b/toolbox/pwcache.c
similarity index 75%
rename from toolbox/uid_from_user.c
rename to toolbox/pwcache.c
index fd48d3c..9d81981 100644
--- a/toolbox/uid_from_user.c
+++ b/toolbox/pwcache.c
@@ -26,7 +26,9 @@
  * 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) {
@@ -37,3 +39,23 @@
   *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/rm.c b/toolbox/rm.c
deleted file mode 100644
index 957b586..0000000
--- a/toolbox/rm.c
+++ /dev/null
@@ -1,126 +0,0 @@
-#include <stdio.h>
-#include <unistd.h>
-#include <string.h>
-#include <errno.h>
-#include <dirent.h>
-#include <limits.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-
-#define OPT_RECURSIVE 1
-#define OPT_FORCE     2
-
-static int usage()
-{
-    fprintf(stderr,"Usage: rm [-rR] [-f] <target>\n");
-    return -1;
-}
-
-/* return -1 on failure, with errno set to the first error */
-static int unlink_recursive(const char* name, int flags)
-{
-    struct stat st;
-    DIR *dir;
-    struct dirent *de;
-    int fail = 0;
-
-    /* is it a file or directory? */
-    if (lstat(name, &st) < 0)
-        return ((flags & OPT_FORCE) && errno == ENOENT) ? 0 : -1;
-
-    /* a file, so unlink it */
-    if (!S_ISDIR(st.st_mode))
-        return unlink(name);
-
-    /* a directory, so open handle */
-    dir = opendir(name);
-    if (dir == NULL)
-        return -1;
-
-    /* recurse over components */
-    errno = 0;
-    while ((de = readdir(dir)) != NULL) {
-        char dn[PATH_MAX];
-        if (!strcmp(de->d_name, "..") || !strcmp(de->d_name, "."))
-            continue;
-        sprintf(dn, "%s/%s", name, de->d_name);
-        if (unlink_recursive(dn, flags) < 0) {
-            if (!(flags & OPT_FORCE)) {
-                fail = 1;
-                break;
-            }
-        }
-        errno = 0;
-    }
-    /* in case readdir or unlink_recursive failed */
-    if (fail || errno < 0) {
-        int save = errno;
-        closedir(dir);
-        errno = save;
-        return -1;
-    }
-
-    /* close directory handle */
-    if (closedir(dir) < 0)
-        return -1;
-
-    /* delete target directory */
-    return rmdir(name);
-}
-
-int rm_main(int argc, char *argv[])
-{
-    int ret;
-    int i, c;
-    int flags = 0;
-    int something_failed = 0;
-
-    if (argc < 2)
-        return usage();
-
-    /* check flags */
-    do {
-        c = getopt(argc, argv, "frR");
-        if (c == EOF)
-            break;
-        switch (c) {
-        case 'f':
-            flags |= OPT_FORCE;
-            break;
-        case 'r':
-        case 'R':
-            flags |= OPT_RECURSIVE;
-            break;
-        }
-    } while (1);
-
-    if (optind < 1 || optind >= argc) {
-        usage();
-        return -1;
-    }
-
-    /* loop over the file/directory args */
-    for (i = optind; i < argc; i++) {
-
-        if (flags & OPT_RECURSIVE) {
-            ret = unlink_recursive(argv[i], flags);
-        } else {
-            ret = unlink(argv[i]);
-            if (ret < 0 && errno == ENOENT && (flags & OPT_FORCE)) {
-                continue;
-            }
-        }
-
-        if (ret < 0) {
-            fprintf(stderr, "rm failed for %s, %s\n", argv[i], strerror(errno));
-            if (!(flags & OPT_FORCE)) {
-                return -1;
-            } else {
-                something_failed = 1;
-            }
-        }
-    }
-
-    return something_failed;
-}
-
diff --git a/toolbox/rmdir.c b/toolbox/rmdir.c
deleted file mode 100644
index 749fec8..0000000
--- a/toolbox/rmdir.c
+++ /dev/null
@@ -1,28 +0,0 @@
-#include <stdio.h>
-#include <unistd.h>
-#include <string.h>
-#include <errno.h>
-
-static int usage()
-{
-    fprintf(stderr,"rmdir <directory>\n");
-    return -1;
-}
-
-int rmdir_main(int argc, char *argv[])
-{
-    int ret;
-    if(argc < 2) return usage();
-
-    while(argc > 1) {
-        argc--;
-        argv++;
-        ret = rmdir(argv[0]);
-        if(ret < 0) {
-            fprintf(stderr, "rmdir failed for %s, %s\n", argv[0], strerror(errno));
-            return ret;
-        }
-    }
-    
-    return 0;
-}
diff --git a/toolbox/sleep.c b/toolbox/sleep.c
deleted file mode 100644
index c09ae03..0000000
--- a/toolbox/sleep.c
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (c) 2008, The Android Open Source Project
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *  * Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *  * Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the 
- *    distribution.
- *  * Neither the name of Google, Inc. nor the names of its contributors
- *    may be used to endorse or promote products derived from this
- *    software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <stdio.h>
-#include <unistd.h>
-#include <stdlib.h>
-
-static void
-usage(const char *s)
-{
-    fprintf(stderr, "USAGE: %s SECONDS\n", s);
-    exit(-1);
-}
-
-int sleep_main(int argc, char *argv[])
-{
-    unsigned long seconds;
-    char *endptr;
-
-    if (argc != 2) {
-        usage(argv[0]);
-    }
-
-    seconds = strtoul(argv[1], &endptr, 10);
-
-    if (endptr == argv[1]) {
-        usage(argv[0]);
-    }
-
-
-    sleep((unsigned int)seconds);
-   
-    return 0;
-}
-
-
diff --git a/toolbox/start.c b/toolbox/start.c
index 0941e64..6c8a3f2 100644
--- a/toolbox/start.c
+++ b/toolbox/start.c
@@ -11,6 +11,7 @@
         property_set("ctl.start", argv[1]);
     } else {
         /* defaults to starting the common services stopped by stop.c */
+        property_set("ctl.start", "netd");
         property_set("ctl.start", "surfaceflinger");
         property_set("ctl.start", "zygote");
         property_set("ctl.start", "zygote_secondary");
diff --git a/toolbox/stop.c b/toolbox/stop.c
index ed9a293..5e3ce3c 100644
--- a/toolbox/stop.c
+++ b/toolbox/stop.c
@@ -12,6 +12,7 @@
         property_set("ctl.stop", "zygote_secondary");
         property_set("ctl.stop", "zygote");
         property_set("ctl.stop", "surfaceflinger");
+        property_set("ctl.stop", "netd");
     }
 
     return 0;
diff --git a/toolbox/swapon.c b/toolbox/swapon.c
index 21d2287..150701a 100644
--- a/toolbox/swapon.c
+++ b/toolbox/swapon.c
@@ -4,13 +4,13 @@
 #include <getopt.h>
 #include <sys/swap.h>
 
-void usage(char *name)
+static void usage(char *name)
 {
     fprintf(stderr, "Usage: %s [-p prio] <filename>\n"
         "        prio must be between 0 and %d\n", name, SWAP_FLAG_PRIO_MASK);
 }
 
-int parse_prio(char *prio_str)
+static int parse_prio(char *prio_str)
 {
     unsigned long p = strtoul(prio_str, NULL, 10);
 
diff --git a/toolbox/sync.c b/toolbox/sync.c
deleted file mode 100644
index 8284276..0000000
--- a/toolbox/sync.c
+++ /dev/null
@@ -1,7 +0,0 @@
-#include <unistd.h>
-
-int sync_main(int argc, char **argv)
-{
-	sync();
-	return 0;
-}
diff --git a/toolbox/cat.c b/toolbox/upstream-netbsd/bin/cat/cat.c
similarity index 67%
rename from toolbox/cat.c
rename to toolbox/upstream-netbsd/bin/cat/cat.c
index 6ac31f8..cca8cf5 100644
--- a/toolbox/cat.c
+++ b/toolbox/upstream-netbsd/bin/cat/cat.c
@@ -1,4 +1,4 @@
-/* $NetBSD: cat.c,v 1.43 2004/01/04 03:31:28 jschauma Exp $	*/
+/* $NetBSD: cat.c,v 1.54 2013/12/08 08:32:13 spz Exp $	*/
 
 /*
  * Copyright (c) 1989, 1993
@@ -32,208 +32,59 @@
  * 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>
 
-#define CAT_BUFSIZ (4096)
-
 static int bflag, eflag, fflag, lflag, nflag, sflag, tflag, vflag;
+static size_t bsize;
 static int rval;
 static const char *filename;
 
-static void
-cook_buf(FILE *fp)
-{
-	int ch, gobble, line, prev;
-	int stdout_err = 0;
-
-	line = gobble = 0;
-	for (prev = '\n'; (ch = getc(fp)) != EOF; prev = ch) {
-		if (prev == '\n') {
-			if (ch == '\n') {
-				if (sflag) {
-					if (!gobble && putchar(ch) == EOF)
-						break;
-					gobble = 1;
-					continue;
-				}
-				if (nflag) {
-					if (!bflag) {
-						if (fprintf(stdout,
-						    "%6d\t", ++line) < 0) {
-							stdout_err++;
-							break;
-						}
-					} else if (eflag) {
-						if (fprintf(stdout,
-						    "%6s\t", "") < 0) {
-							stdout_err++;
-							break;
-						}
-					}
-				}
-			} else if (nflag) {
-				if (fprintf(stdout, "%6d\t", ++line) < 0) {
-					stdout_err++;
-					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 = (ch) & 0x7f;
-			}
-			if (iscntrl(ch)) {
-				if (putchar('^') == EOF ||
-				    putchar(ch == '\177' ? '?' :
-				    ch | 0100) == EOF)
-					break;
-				continue;
-			}
-		}
-		if (putchar(ch) == EOF)
-			break;
-	}
-	if (stdout_err) {
-		perror(filename);
-		rval = 1;
-	}
-}
-
-static 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) {
-				perror("fopen");
-				rval = 1;
-				++argv;
-				continue;
-			}
-			filename = *argv++;
-		}
-		cook_buf(fp);
-		if (fp != stdin)
-			fclose(fp);
-	} while (*argv);
-}
-
-static void
-raw_cat(int rfd)
-{
-	static char *buf;
-	static char fb_buf[CAT_BUFSIZ];
-	static size_t bsize;
-
-	struct stat sbuf;
-	ssize_t nr, nw, off;
-	int wfd;
-
-	wfd = fileno(stdout);
-	if (buf == NULL) {
-		if (fstat(wfd, &sbuf) == 0) {
-			bsize = sbuf.st_blksize > CAT_BUFSIZ ?
-			    sbuf.st_blksize : CAT_BUFSIZ;
-			buf = malloc(bsize);
-		}
-		if (buf == NULL) {
-			buf = fb_buf;
-			bsize = CAT_BUFSIZ;
-		}
-	}
-	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)
-			{
-				perror("write");
-				exit(EXIT_FAILURE);
-			}
-	if (nr < 0) {
-		fprintf(stderr,"%s: invalid length\n", filename);
-		rval = 1;
-	}
-}
-
-static void
-raw_args(char **argv)
-{
-	int fd;
-
-	fd = fileno(stdin);
-	filename = "stdin";
-	do {
-		if (*argv) {
-			if (!strcmp(*argv, "-"))
-				fd = fileno(stdin);
-			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);
-					errno = EINVAL;
-					goto skipnomsg;
-				}
-			}
-			else if ((fd = open(*argv, O_RDONLY, 0)) < 0) {
-skip:
-				perror(*argv);
-skipnomsg:
-				rval = 1;
-				++argv;
-				continue;
-			}
-			filename = *argv++;
-		}
-		raw_cat(fd);
-		if (fd != fileno(stdin))
-			close(fd);
-	} while (*argv);
-}
+void cook_args(char *argv[]);
+void cook_buf(FILE *);
+void raw_args(char *argv[]);
+void raw_cat(int);
 
 int
-cat_main(int argc, char *argv[])
+main(int argc, char *argv[])
 {
 	int ch;
 	struct flock stdout_lock;
 
-	while ((ch = getopt(argc, argv, "beflnstv")) != -1)
+	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;
@@ -255,14 +106,18 @@
 		case 't':
 			tflag = vflag = 1;	/* -t implies -v */
 			break;
+		case 'u':
+			setbuf(stdout, NULL);
+			break;
 		case 'v':
 			vflag = 1;
 			break;
 		default:
 		case '?':
-			fprintf(stderr,
-				"usage: cat [-beflnstv] [-] [file ...]\n");
-			exit(EXIT_FAILURE);
+			(void)fprintf(stderr,
+			    "Usage: %s [-beflnstuv] [-B bsize] [-] "
+			    "[file ...]\n", getprogname());
+			return EXIT_FAILURE;
 		}
 	argv += optind;
 
@@ -272,10 +127,7 @@
 		stdout_lock.l_type = F_WRLCK;
 		stdout_lock.l_whence = SEEK_SET;
 		if (fcntl(STDOUT_FILENO, F_SETLKW, &stdout_lock) == -1)
-		{
-			perror("fcntl");
-			exit(EXIT_FAILURE);
-		}
+			err(EXIT_FAILURE, "stdout");
 	}
 
 	if (bflag || eflag || nflag || sflag || tflag || vflag)
@@ -283,9 +135,195 @@
 	else
 		raw_args(argv);
 	if (fclose(stdout))
-	{
-		perror("fclose");
-		exit(EXIT_FAILURE);
+		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;
 	}
-	exit(rval);
+	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/cp/cp.c b/toolbox/upstream-netbsd/bin/cp/cp.c
similarity index 95%
rename from toolbox/cp/cp.c
rename to toolbox/upstream-netbsd/bin/cp/cp.c
index e666453..4bbe1b7 100644
--- a/toolbox/cp/cp.c
+++ b/toolbox/upstream-netbsd/bin/cp/cp.c
@@ -49,11 +49,11 @@
 
 /*
  * Cp copies source files to target files.
- *
+ * 
  * The global PATH_T structure "to" always contains the path to the
  * current target file.  Since fts(3) does not change directories,
  * this path can be either absolute or dot-relative.
- *
+ * 
  * The basic algorithm is to initialize "to" and use fts(3) to traverse
  * the file hierarchy rooted in the argument list.  A trivial case is the
  * case of 'cp file1 file2'.  The more interesting case is the case of
@@ -95,30 +95,26 @@
 
 static int copy(char *[], enum op, int);
 
-#ifndef ANDROID
 static void
 progress(int sig __unused)
 {
 
 	pinfo++;
 }
-#endif
 
 int
-cp_main(int argc, char *argv[])
+main(int argc, char *argv[])
 {
 	struct stat to_stat, tmp_stat;
 	enum op type;
 	int ch, fts_options, r, have_trailing_slash;
 	char *target, **src;
 
-#ifndef ANDROID
 	setprogname(argv[0]);
-#endif
 	(void)setlocale(LC_ALL, "");
 
 	Hflag = Lflag = Pflag = Rflag = 0;
-	while ((ch = getopt(argc, argv, "HLNPRfailprv")) != -1)
+	while ((ch = getopt(argc, argv, "HLNPRfailprv")) != -1) 
 		switch (ch) {
 		case 'H':
 			Hflag = 1;
@@ -166,14 +162,14 @@
 			break;
 		case '?':
 		default:
-			cp_usage();
+			usage();
 			/* NOTREACHED */
 		}
 	argc -= optind;
 	argv += optind;
 
 	if (argc < 2)
-		cp_usage();
+		usage();
 
 	fts_options = FTS_NOCHDIR | FTS_PHYSICAL;
 	if (rflag) {
@@ -220,12 +216,10 @@
 	to.target_end = to.p_end;
 
 	/* Set end of argument list for fts(3). */
-	argv[argc] = NULL;
-
-#ifndef ANDROID
+	argv[argc] = NULL;     
+	
 	(void)signal(SIGINFO, progress);
-#endif
-
+	
 	/*
 	 * Cp has two distinct cases:
 	 *
@@ -251,9 +245,9 @@
 	if (r == -1 || !S_ISDIR(to_stat.st_mode)) {
 		/*
 		 * Case (1).  Target is not a directory.
-		 */
+		 */ 
 		if (argc > 1)
-			cp_usage();
+			usage();
 		/*
 		 * Need to detect the case:
 		 *	cp -R dir foo
@@ -270,7 +264,7 @@
 				err(EXIT_FAILURE, "%s", *argv);
 				/* NOTREACHED */
 			}
-
+			
 			if (S_ISDIR(tmp_stat.st_mode) && (Rflag || rflag))
 				type = DIR_TO_DNE;
 			else
@@ -359,8 +353,8 @@
 		}
 
 		/*
-		 * If we are in case (2) or (3) above, we need to append the
-                 * source name to the target name.
+		 * If we are in case (2) or (3) above, we need to append the 
+                 * source name to the target name.  
                  */
 		if (type != FILE_TO_FILE) {
 			if ((curr->fts_namelen +
@@ -393,10 +387,10 @@
 			if (curr->fts_level == FTS_ROOTLEVEL) {
 				if (type != DIR_TO_DNE) {
 					p = strrchr(curr->fts_path, '/');
-					base = (p == NULL) ? 0 :
+					base = (p == NULL) ? 0 : 
 					    (int)(p - curr->fts_path + 1);
 
-					if (!strcmp(&curr->fts_path[base],
+					if (!strcmp(&curr->fts_path[base], 
 					    ".."))
 						base += 1;
 				} else
@@ -453,7 +447,7 @@
 			   ((fts_options & FTS_COMFOLLOW) && curr->fts_level == 0)) {
 				if (copy_file(curr, dne))
 					this_failed = any_failed = 1;
-			} else {
+			} else {	
 				if (copy_link(curr, !dne))
 					this_failed = any_failed = 1;
 			}
@@ -485,7 +479,7 @@
 				 */
 				pushdne(dne);
 				if (dne) {
-					if (mkdir(to.p_path,
+					if (mkdir(to.p_path, 
 					    curr->fts_statp->st_mode | S_IRWXU) < 0)
 						err(EXIT_FAILURE, "%s",
 						    to.p_path);
@@ -501,14 +495,14 @@
 			{
 	                        /*
 				 * If not -p and directory didn't exist, set it to be
-				 * the same as the from directory, umodified by the
-				 * umask; arguably wrong, but it's been that way
-				 * forever.
+				 * the same as the from directory, umodified by the 
+                        	 * umask; arguably wrong, but it's been that way 
+                        	 * forever.
 				 */
 				if (pflag && setfile(curr->fts_statp, 0))
 					this_failed = any_failed = 1;
 				else if ((dne = popdne()))
-					(void)chmod(to.p_path,
+					(void)chmod(to.p_path, 
 					    curr->fts_statp->st_mode);
 			}
 			else
@@ -533,7 +527,7 @@
 			if (Rflag) {
 				if (copy_fifo(curr->fts_statp, !dne))
 					this_failed = any_failed = 1;
-			} else
+			} else 
 				if (copy_file(curr, dne))
 					this_failed = any_failed = 1;
 			break;
diff --git a/toolbox/cp/extern.h b/toolbox/upstream-netbsd/bin/cp/extern.h
similarity index 97%
rename from toolbox/cp/extern.h
rename to toolbox/upstream-netbsd/bin/cp/extern.h
index ffbadf7..e393844 100644
--- a/toolbox/cp/extern.h
+++ b/toolbox/upstream-netbsd/bin/cp/extern.h
@@ -55,7 +55,7 @@
 int	copy_special(struct stat *, int);
 int	set_utimes(const char *, struct stat *);
 int	setfile(struct stat *, int);
-void cp_usage(void) __attribute__((__noreturn__));
+void	usage(void) __attribute__((__noreturn__));
 __END_DECLS
 
 #endif /* !_EXTERN_H_ */
diff --git a/toolbox/cp/utils.c b/toolbox/upstream-netbsd/bin/cp/utils.c
similarity index 92%
rename from toolbox/cp/utils.c
rename to toolbox/upstream-netbsd/bin/cp/utils.c
index 9d0390f..d8f900a 100644
--- a/toolbox/cp/utils.c
+++ b/toolbox/upstream-netbsd/bin/cp/utils.c
@@ -1,4 +1,4 @@
-/* $NetBSD: utils.c,v 1.41 2012/01/04 15:58:37 christos Exp $ */
+/* $NetBSD: utils.c,v 1.42 2013/12/11 06:00:11 dholland Exp $ */
 
 /*-
  * Copyright (c) 1991, 1993, 1994
@@ -34,7 +34,7 @@
 #if 0
 static char sccsid[] = "@(#)utils.c	8.3 (Berkeley) 4/1/94";
 #else
-__RCSID("$NetBSD: utils.c,v 1.41 2012/01/04 15:58:37 christos Exp $");
+__RCSID("$NetBSD: utils.c,v 1.42 2013/12/11 06:00:11 dholland Exp $");
 #endif
 #endif /* not lint */
 
@@ -42,9 +42,7 @@
 #include <sys/param.h>
 #include <sys/stat.h>
 #include <sys/time.h>
-#ifndef ANDROID
 #include <sys/extattr.h>
-#endif
 
 #include <err.h>
 #include <errno.h>
@@ -58,10 +56,6 @@
 
 #include "extern.h"
 
-#ifdef ANDROID
-#define MAXBSIZE 65536
-#endif
-
 #define	MMAP_MAX_SIZE	(8 * 1048576)
 #define	MMAP_MAX_WRITE	(64 * 1024)
 
@@ -70,7 +64,7 @@
 {
     static struct timeval tv[2];
 
-#ifdef ANDROID
+#ifdef __ANDROID__
     tv[0].tv_sec = fs->st_atime;
     tv[0].tv_usec = 0;
     tv[1].tv_sec = fs->st_mtime;
@@ -85,8 +79,8 @@
     TIMESPEC_TO_TIMEVAL(&tv[1], &fs->st_mtimespec);
 
     if (lutimes(file, tv)) {
-    warn("lutimes: %s", file);
-    return (1);
+	warn("lutimes: %s", file);
+	return (1);
     }
 #endif
     return (0);
@@ -116,7 +110,7 @@
 	int ch, checkch, from_fd, rcount, rval, to_fd, tolnk, wcount;
 	char *p;
 	size_t ptotal = 0;
-
+	
 	if ((from_fd = open(entp->fts_path, O_RDONLY, 0)) == -1) {
 		warn("%s", entp->fts_path);
 		return (1);
@@ -192,13 +186,14 @@
 		}
 		return (0);
 	}
-	/* NOTREACHED */
 
 	/*
 	 * There's no reason to do anything other than close the file
 	 * now if it's empty, so let's not bother.
 	 */
+#ifndef __ANDROID__ // Files in /proc report length 0. mmap will fail but we'll fall back to read.
 	if (fs->st_size > 0) {
+#endif
 		struct finfo fi;
 
 		fi.from = entp->fts_path;
@@ -273,9 +268,11 @@
 				rval = 1;
 			}
 		}
+#ifndef __ANDROID__
 	}
+#endif
 
-#ifndef ANDROID
+#ifndef __ANDROID__
 	if (pflag && (fcpxattr(from_fd, to_fd) != 0))
 		warn("%s: error copying extended attributes", to.p_path);
 #endif
@@ -311,7 +308,7 @@
 		rval = 1;
 	}
 	/* set the mod/access times now after close of the fd */
-	if (pflag && set_utimes(to.p_path, fs)) {
+	if (pflag && set_utimes(to.p_path, fs)) { 
 	    rval = 1;
 	}
 	return (rval);
@@ -380,11 +377,10 @@
 int
 setfile(struct stat *fs, int fd)
 {
-	int rval = 0;
-#ifndef ANDROID
-	int islink = S_ISLNK(fs->st_mode);
-#endif
+	int rval, islink;
 
+	rval = 0;
+	islink = S_ISLNK(fs->st_mode);
 	fs->st_mode &= S_ISUID | S_ISGID | S_IRWXU | S_IRWXG | S_IRWXO;
 
 	/*
@@ -401,16 +397,16 @@
 		}
 		fs->st_mode &= ~(S_ISUID | S_ISGID);
 	}
-#ifdef ANDROID
-        if (fd ? fchmod(fd, fs->st_mode) : chmod(to.p_path, fs->st_mode)) {
+#ifdef __ANDROID__
+	if (fd ? fchmod(fd, fs->st_mode) : chmod(to.p_path, fs->st_mode)) {
 #else
-        if (fd ? fchmod(fd, fs->st_mode) : lchmod(to.p_path, fs->st_mode)) {
+	if (fd ? fchmod(fd, fs->st_mode) : lchmod(to.p_path, fs->st_mode)) {
 #endif
-                warn("chmod: %s", to.p_path);
-                rval = 1;
-        }
+		warn("chmod: %s", to.p_path);
+		rval = 1;
+	}
 
-#ifndef ANDROID
+#ifndef __ANDROID__
 	if (!islink && !Nflag) {
 		unsigned long fflags = fs->st_flags;
 		/*
@@ -437,11 +433,12 @@
 }
 
 void
-cp_usage(void)
+usage(void)
 {
 	(void)fprintf(stderr,
-	    "usage: cp [-R [-H | -L | -P]] [-f | -i] [-alNpv] src target\n"
-	    "       cp [-R [-H | -L | -P]] [-f | -i] [-alNpv] src1 ... srcN directory\n");
+	    "usage: %s [-R [-H | -L | -P]] [-f | -i] [-alNpv] src target\n"
+	    "       %s [-R [-H | -L | -P]] [-f | -i] [-alNpv] src1 ... srcN directory\n",
+	    getprogname(), getprogname());
 	exit(1);
 	/* NOTREACHED */
 }
diff --git a/toolbox/upstream-netbsd/bin/dd/args.c b/toolbox/upstream-netbsd/bin/dd/args.c
new file mode 100644
index 0000000..207e300
--- /dev/null
+++ b/toolbox/upstream-netbsd/bin/dd/args.c
@@ -0,0 +1,391 @@
+/*	$NetBSD: args.c,v 1.38 2013/07/17 12:55:48 christos Exp $	*/
+
+/*-
+ * Copyright (c) 1991, 1993, 1994
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Keith Muller of the University of California, San Diego and Lance
+ * Visser of Convex Computer Corporation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)args.c	8.3 (Berkeley) 4/2/94";
+#else
+__RCSID("$NetBSD: args.c,v 1.38 2013/07/17 12:55:48 christos Exp $");
+#endif
+#endif /* not lint */
+
+#include <sys/types.h>
+#include <sys/time.h>
+
+#include <err.h>
+#include <errno.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "dd.h"
+#include "extern.h"
+
+static int	c_arg(const void *, const void *);
+
+#ifdef NO_MSGFMT
+static void	f_msgfmt(char *) __dead;
+#else
+static void	f_msgfmt(char *);
+#endif /* NO_MSGFMT */
+
+#ifdef NO_CONV
+static void	f_conv(char *) __dead;
+#else
+static void	f_conv(char *);
+static int	c_conv(const void *, const void *);
+#endif /* NO_CONV */
+
+static void	f_bs(char *);
+static void	f_cbs(char *);
+static void	f_count(char *);
+static void	f_files(char *);
+static void	f_ibs(char *);
+static void	f_if(char *);
+static void	f_obs(char *);
+static void	f_of(char *);
+static void	f_seek(char *);
+static void	f_skip(char *);
+static void	f_progress(char *);
+
+static const struct arg {
+	const char *name;
+	void (*f)(char *);
+	u_int set, noset;
+} args[] = {
+     /* the array needs to be sorted by the first column so
+	bsearch() can be used to find commands quickly */
+	{ "bs",		f_bs,		C_BS,	 C_BS|C_IBS|C_OBS|C_OSYNC },
+	{ "cbs",	f_cbs,		C_CBS,	 C_CBS },
+	{ "conv",	f_conv,		0,	 0 },
+	{ "count",	f_count,	C_COUNT, C_COUNT },
+	{ "files",	f_files,	C_FILES, C_FILES },
+	{ "ibs",	f_ibs,		C_IBS,	 C_BS|C_IBS },
+	{ "if",		f_if,		C_IF,	 C_IF },
+	{ "iseek",	f_skip,		C_SKIP,	 C_SKIP },
+	{ "msgfmt",	f_msgfmt,	0,	 0 },
+	{ "obs",	f_obs,		C_OBS,	 C_BS|C_OBS },
+	{ "of",		f_of,		C_OF,	 C_OF },
+	{ "oseek",	f_seek,		C_SEEK,	 C_SEEK },
+	{ "progress",	f_progress,	0,	 0 },
+	{ "seek",	f_seek,		C_SEEK,	 C_SEEK },
+	{ "skip",	f_skip,		C_SKIP,	 C_SKIP },
+};
+
+/*
+ * args -- parse JCL syntax of dd.
+ */
+void
+jcl(char **argv)
+{
+	struct arg *ap, tmp;
+	char *oper, *arg;
+
+	in.dbsz = out.dbsz = 512;
+
+	while ((oper = *++argv) != NULL) {
+		if ((oper = strdup(oper)) == NULL) {
+			errx(EXIT_FAILURE,
+			    "unable to allocate space for the argument %s",
+			    *argv);
+			/* NOTREACHED */
+		}
+		if ((arg = strchr(oper, '=')) == NULL) {
+			errx(EXIT_FAILURE, "unknown operand %s", oper);
+			/* NOTREACHED */
+		}
+		*arg++ = '\0';
+		if (!*arg) {
+			errx(EXIT_FAILURE, "no value specified for %s", oper);
+			/* NOTREACHED */
+		}
+		tmp.name = oper;
+		if (!(ap = bsearch(&tmp, args,
+		    __arraycount(args), sizeof(*args), c_arg))) {
+			errx(EXIT_FAILURE, "unknown operand %s", tmp.name);
+			/* NOTREACHED */
+		}
+		if (ddflags & ap->noset) {
+			errx(EXIT_FAILURE,
+			    "%s: illegal argument combination or already set",
+			    tmp.name);
+			/* NOTREACHED */
+		}
+		ddflags |= ap->set;
+		ap->f(arg);
+	}
+
+	/* Final sanity checks. */
+
+	if (ddflags & C_BS) {
+		/*
+		 * Bs is turned off by any conversion -- we assume the user
+		 * just wanted to set both the input and output block sizes
+		 * and didn't want the bs semantics, so we don't warn.
+		 */
+		if (ddflags & (C_BLOCK | C_LCASE | C_SWAB | C_UCASE |
+		    C_UNBLOCK | C_OSYNC | C_ASCII | C_EBCDIC | C_SPARSE)) {
+			ddflags &= ~C_BS;
+			ddflags |= C_IBS|C_OBS;
+		}
+
+		/* Bs supersedes ibs and obs. */
+		if (ddflags & C_BS && ddflags & (C_IBS|C_OBS))
+			warnx("bs supersedes ibs and obs");
+	}
+
+	/*
+	 * Ascii/ebcdic and cbs implies block/unblock.
+	 * Block/unblock requires cbs and vice-versa.
+	 */
+	if (ddflags & (C_BLOCK|C_UNBLOCK)) {
+		if (!(ddflags & C_CBS)) {
+			errx(EXIT_FAILURE, "record operations require cbs");
+			/* NOTREACHED */
+		}
+		cfunc = ddflags & C_BLOCK ? block : unblock;
+	} else if (ddflags & C_CBS) {
+		if (ddflags & (C_ASCII|C_EBCDIC)) {
+			if (ddflags & C_ASCII) {
+				ddflags |= C_UNBLOCK;
+				cfunc = unblock;
+			} else {
+				ddflags |= C_BLOCK;
+				cfunc = block;
+			}
+		} else {
+			errx(EXIT_FAILURE,
+			    "cbs meaningless if not doing record operations");
+			/* NOTREACHED */
+		}
+	} else
+		cfunc = def;
+
+	/* Read, write and seek calls take off_t as arguments.
+	 *
+	 * The following check is not done because an off_t is a quad
+	 *  for current NetBSD implementations.
+	 *
+	 * if (in.offset > INT_MAX/in.dbsz || out.offset > INT_MAX/out.dbsz)
+	 *	errx(1, "seek offsets cannot be larger than %d", INT_MAX);
+	 */
+}
+
+static int
+c_arg(const void *a, const void *b)
+{
+
+	return (strcmp(((const struct arg *)a)->name,
+	    ((const struct arg *)b)->name));
+}
+
+static void
+f_bs(char *arg)
+{
+
+	in.dbsz = out.dbsz = strsuftoll("block size", arg, 1, UINT_MAX);
+}
+
+static void
+f_cbs(char *arg)
+{
+
+	cbsz = strsuftoll("conversion record size", arg, 1, UINT_MAX);
+}
+
+static void
+f_count(char *arg)
+{
+
+	cpy_cnt = strsuftoll("block count", arg, 0, LLONG_MAX);
+	if (!cpy_cnt)
+		terminate(0);
+}
+
+static void
+f_files(char *arg)
+{
+
+	files_cnt = (u_int)strsuftoll("file count", arg, 0, UINT_MAX);
+	if (!files_cnt)
+		terminate(0);
+}
+
+static void
+f_ibs(char *arg)
+{
+
+	if (!(ddflags & C_BS))
+		in.dbsz = strsuftoll("input block size", arg, 1, UINT_MAX);
+}
+
+static void
+f_if(char *arg)
+{
+
+	in.name = arg;
+}
+
+#ifdef NO_MSGFMT
+/* Build a small version (i.e. for a ramdisk root) */
+static void
+f_msgfmt(char *arg)
+{
+
+	errx(EXIT_FAILURE, "msgfmt option disabled");
+	/* NOTREACHED */
+}
+#else	/* NO_MSGFMT */
+static void
+f_msgfmt(char *arg)
+{
+
+	/*
+	 * If the format string is not valid, dd_write_msg() will print
+	 * an error and exit.
+	 */
+	dd_write_msg(arg, 0);
+
+	msgfmt = arg;
+}
+#endif	/* NO_MSGFMT */
+
+static void
+f_obs(char *arg)
+{
+
+	if (!(ddflags & C_BS))
+		out.dbsz = strsuftoll("output block size", arg, 1, UINT_MAX);
+}
+
+static void
+f_of(char *arg)
+{
+
+	out.name = arg;
+}
+
+static void
+f_seek(char *arg)
+{
+
+	out.offset = strsuftoll("seek blocks", arg, 0, LLONG_MAX);
+}
+
+static void
+f_skip(char *arg)
+{
+
+	in.offset = strsuftoll("skip blocks", arg, 0, LLONG_MAX);
+}
+
+static void
+f_progress(char *arg)
+{
+
+	progress = strsuftoll("progress blocks", arg, 0, LLONG_MAX);
+}
+
+#ifdef	NO_CONV
+/* Build a small version (i.e. for a ramdisk root) */
+static void
+f_conv(char *arg)
+{
+
+	errx(EXIT_FAILURE, "conv option disabled");
+	/* NOTREACHED */
+}
+#else	/* NO_CONV */
+
+static const struct conv {
+	const char *name;
+	u_int set, noset;
+	const u_char *ctab;
+} clist[] = {
+	{ "ascii",	C_ASCII,	C_EBCDIC,	e2a_POSIX },
+	{ "block",	C_BLOCK,	C_UNBLOCK,	NULL },
+	{ "ebcdic",	C_EBCDIC,	C_ASCII,	a2e_POSIX },
+	{ "ibm",	C_EBCDIC,	C_ASCII,	a2ibm_POSIX },
+	{ "lcase",	C_LCASE,	C_UCASE,	NULL },
+	{ "noerror",	C_NOERROR,	0,		NULL },
+	{ "notrunc",	C_NOTRUNC,	0,		NULL },
+	{ "oldascii",	C_ASCII,	C_EBCDIC,	e2a_32V },
+	{ "oldebcdic",	C_EBCDIC,	C_ASCII,	a2e_32V },
+	{ "oldibm",	C_EBCDIC,	C_ASCII,	a2ibm_32V },
+	{ "osync",	C_OSYNC,	C_BS,		NULL },
+	{ "sparse",	C_SPARSE,	0,		NULL },
+	{ "swab",	C_SWAB,		0,		NULL },
+	{ "sync",	C_SYNC,		0,		NULL },
+	{ "ucase",	C_UCASE,	C_LCASE,	NULL },
+	{ "unblock",	C_UNBLOCK,	C_BLOCK,	NULL },
+	/* If you add items to this table, be sure to add the
+	 * conversions to the C_BS check in the jcl routine above.
+	 */
+};
+
+static void
+f_conv(char *arg)
+{
+	struct conv *cp, tmp;
+
+	while (arg != NULL) {
+		tmp.name = strsep(&arg, ",");
+		if (!(cp = bsearch(&tmp, clist,
+		    __arraycount(clist), sizeof(*clist), c_conv))) {
+			errx(EXIT_FAILURE, "unknown conversion %s", tmp.name);
+			/* NOTREACHED */
+		}
+		if (ddflags & cp->noset) {
+			errx(EXIT_FAILURE,
+			    "%s: illegal conversion combination", tmp.name);
+			/* NOTREACHED */
+		}
+		ddflags |= cp->set;
+		if (cp->ctab)
+			ctab = cp->ctab;
+	}
+}
+
+static int
+c_conv(const void *a, const void *b)
+{
+
+	return (strcmp(((const struct conv *)a)->name,
+	    ((const struct conv *)b)->name));
+}
+
+#endif	/* NO_CONV */
diff --git a/toolbox/upstream-netbsd/bin/dd/conv.c b/toolbox/upstream-netbsd/bin/dd/conv.c
new file mode 100644
index 0000000..d4a8a09
--- /dev/null
+++ b/toolbox/upstream-netbsd/bin/dd/conv.c
@@ -0,0 +1,283 @@
+/*	$NetBSD: conv.c,v 1.17 2003/08/07 09:05:10 agc Exp $	*/
+
+/*-
+ * Copyright (c) 1991, 1993, 1994
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Keith Muller of the University of California, San Diego and Lance
+ * Visser of Convex Computer Corporation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)conv.c	8.3 (Berkeley) 4/2/94";
+#else
+__RCSID("$NetBSD: conv.c,v 1.17 2003/08/07 09:05:10 agc Exp $");
+#endif
+#endif /* not lint */
+
+#include <sys/param.h>
+#include <sys/time.h>
+
+#include <err.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "dd.h"
+#include "extern.h"
+
+/*
+ * def --
+ * Copy input to output.  Input is buffered until reaches obs, and then
+ * output until less than obs remains.  Only a single buffer is used.
+ * Worst case buffer calculation is (ibs + obs - 1).
+ */
+void
+def(void)
+{
+	uint64_t cnt;
+	u_char *inp;
+	const u_char *t;
+
+	if ((t = ctab) != NULL)
+		for (inp = in.dbp - (cnt = in.dbrcnt); cnt--; ++inp)
+			*inp = t[*inp];
+
+	/* Make the output buffer look right. */
+	out.dbp = in.dbp;
+	out.dbcnt = in.dbcnt;
+
+	if (in.dbcnt >= out.dbsz) {
+		/* If the output buffer is full, write it. */
+		dd_out(0);
+
+		/*
+		 * Ddout copies the leftover output to the beginning of
+		 * the buffer and resets the output buffer.  Reset the
+		 * input buffer to match it.
+	 	 */
+		in.dbp = out.dbp;
+		in.dbcnt = out.dbcnt;
+	}
+}
+
+void
+def_close(void)
+{
+
+	/* Just update the count, everything is already in the buffer. */
+	if (in.dbcnt)
+		out.dbcnt = in.dbcnt;
+}
+
+#ifdef	NO_CONV
+/* Build a smaller version (i.e. for a miniroot) */
+/* These can not be called, but just in case...  */
+static const char no_block[] = "unblock and -DNO_CONV?";
+void block(void)		{ errx(EXIT_FAILURE, "%s", no_block + 2); }
+void block_close(void)		{ errx(EXIT_FAILURE, "%s", no_block + 2); }
+void unblock(void)		{ errx(EXIT_FAILURE, "%s", no_block); }
+void unblock_close(void)	{ errx(EXIT_FAILURE, "%s", no_block); }
+#else	/* NO_CONV */
+
+/*
+ * Copy variable length newline terminated records with a max size cbsz
+ * bytes to output.  Records less than cbs are padded with spaces.
+ *
+ * max in buffer:  MAX(ibs, cbsz)
+ * max out buffer: obs + cbsz
+ */
+void
+block(void)
+{
+	static int intrunc;
+	int ch = 0;	/* pacify gcc */
+	uint64_t cnt, maxlen;
+	u_char *inp, *outp;
+	const u_char *t;
+
+	/*
+	 * Record truncation can cross block boundaries.  If currently in a
+	 * truncation state, keep tossing characters until reach a newline.
+	 * Start at the beginning of the buffer, as the input buffer is always
+	 * left empty.
+	 */
+	if (intrunc) {
+		for (inp = in.db, cnt = in.dbrcnt;
+		    cnt && *inp++ != '\n'; --cnt);
+		if (!cnt) {
+			in.dbcnt = 0;
+			in.dbp = in.db;
+			return;
+		}
+		intrunc = 0;
+		/* Adjust the input buffer numbers. */
+		in.dbcnt = cnt - 1;
+		in.dbp = inp + cnt - 1;
+	}
+
+	/*
+	 * Copy records (max cbsz size chunks) into the output buffer.  The
+	 * translation is done as we copy into the output buffer.
+	 */
+	for (inp = in.dbp - in.dbcnt, outp = out.dbp; in.dbcnt;) {
+		maxlen = MIN(cbsz, in.dbcnt);
+		if ((t = ctab) != NULL)
+			for (cnt = 0;
+			    cnt < maxlen && (ch = *inp++) != '\n'; ++cnt)
+				*outp++ = t[ch];
+		else
+			for (cnt = 0;
+			    cnt < maxlen && (ch = *inp++) != '\n'; ++cnt)
+				*outp++ = ch;
+		/*
+		 * Check for short record without a newline.  Reassemble the
+		 * input block.
+		 */
+		if (ch != '\n' && in.dbcnt < cbsz) {
+			(void)memmove(in.db, in.dbp - in.dbcnt, in.dbcnt);
+			break;
+		}
+
+		/* Adjust the input buffer numbers. */
+		in.dbcnt -= cnt;
+		if (ch == '\n')
+			--in.dbcnt;
+
+		/* Pad short records with spaces. */
+		if (cnt < cbsz)
+			(void)memset(outp, ctab ? ctab[' '] : ' ', cbsz - cnt);
+		else {
+			/*
+			 * If the next character wouldn't have ended the
+			 * block, it's a truncation.
+			 */
+			if (!in.dbcnt || *inp != '\n')
+				++st.trunc;
+
+			/* Toss characters to a newline. */
+			for (; in.dbcnt && *inp++ != '\n'; --in.dbcnt);
+			if (!in.dbcnt)
+				intrunc = 1;
+			else
+				--in.dbcnt;
+		}
+
+		/* Adjust output buffer numbers. */
+		out.dbp += cbsz;
+		if ((out.dbcnt += cbsz) >= out.dbsz)
+			dd_out(0);
+		outp = out.dbp;
+	}
+	in.dbp = in.db + in.dbcnt;
+}
+
+void
+block_close(void)
+{
+
+	/*
+	 * Copy any remaining data into the output buffer and pad to a record.
+	 * Don't worry about truncation or translation, the input buffer is
+	 * always empty when truncating, and no characters have been added for
+	 * translation.  The bottom line is that anything left in the input
+	 * buffer is a truncated record.  Anything left in the output buffer
+	 * just wasn't big enough.
+	 */
+	if (in.dbcnt) {
+		++st.trunc;
+		(void)memmove(out.dbp, in.dbp - in.dbcnt, in.dbcnt);
+		(void)memset(out.dbp + in.dbcnt,
+		    ctab ? ctab[' '] : ' ', cbsz - in.dbcnt);
+		out.dbcnt += cbsz;
+	}
+}
+
+/*
+ * Convert fixed length (cbsz) records to variable length.  Deletes any
+ * trailing blanks and appends a newline.
+ *
+ * max in buffer:  MAX(ibs, cbsz) + cbsz
+ * max out buffer: obs + cbsz
+ */
+void
+unblock(void)
+{
+	uint64_t cnt;
+	u_char *inp;
+	const u_char *t;
+
+	/* Translation and case conversion. */
+	if ((t = ctab) != NULL)
+		for (cnt = in.dbrcnt, inp = in.dbp - 1; cnt--; inp--)
+			*inp = t[*inp];
+	/*
+	 * Copy records (max cbsz size chunks) into the output buffer.  The
+	 * translation has to already be done or we might not recognize the
+	 * spaces.
+	 */
+	for (inp = in.db; in.dbcnt >= cbsz; inp += cbsz, in.dbcnt -= cbsz) {
+		for (t = inp + cbsz - 1; t >= inp && *t == ' '; --t);
+		if (t >= inp) {
+			cnt = t - inp + 1;
+			(void)memmove(out.dbp, inp, cnt);
+			out.dbp += cnt;
+			out.dbcnt += cnt;
+		}
+		++out.dbcnt;
+		*out.dbp++ = '\n';
+		if (out.dbcnt >= out.dbsz)
+			dd_out(0);
+	}
+	if (in.dbcnt)
+		(void)memmove(in.db, in.dbp - in.dbcnt, in.dbcnt);
+	in.dbp = in.db + in.dbcnt;
+}
+
+void
+unblock_close(void)
+{
+	uint64_t cnt;
+	u_char *t;
+
+	if (in.dbcnt) {
+		warnx("%s: short input record", in.name);
+		for (t = in.db + in.dbcnt - 1; t >= in.db && *t == ' '; --t);
+		if (t >= in.db) {
+			cnt = t - in.db + 1;
+			(void)memmove(out.dbp, in.db, cnt);
+			out.dbp += cnt;
+			out.dbcnt += cnt;
+		}
+		++out.dbcnt;
+		*out.dbp++ = '\n';
+	}
+}
+
+#endif	/* NO_CONV */
diff --git a/toolbox/upstream-netbsd/bin/dd/dd.c b/toolbox/upstream-netbsd/bin/dd/dd.c
new file mode 100644
index 0000000..03d080c
--- /dev/null
+++ b/toolbox/upstream-netbsd/bin/dd/dd.c
@@ -0,0 +1,598 @@
+/*	$NetBSD: dd.c,v 1.49 2012/02/21 01:49:01 matt Exp $	*/
+
+/*-
+ * Copyright (c) 1991, 1993, 1994
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Keith Muller of the University of California, San Diego and Lance
+ * Visser of Convex Computer Corporation.
+ *
+ * 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) 1991, 1993, 1994\
+ The Regents of the University of California.  All rights reserved.");
+#endif /* not lint */
+
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)dd.c	8.5 (Berkeley) 4/2/94";
+#else
+__RCSID("$NetBSD: dd.c,v 1.49 2012/02/21 01:49:01 matt Exp $");
+#endif
+#endif /* not lint */
+
+#include <sys/param.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <sys/mtio.h>
+#include <sys/time.h>
+
+#include <ctype.h>
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <locale.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "dd.h"
+#include "extern.h"
+
+static void dd_close(void);
+static void dd_in(void);
+static void getfdtype(IO *);
+static void redup_clean_fd(IO *);
+static void setup(void);
+
+int main(int, char *[]);
+
+IO		in, out;		/* input/output state */
+STAT		st;			/* statistics */
+void		(*cfunc)(void);		/* conversion function */
+uint64_t	cpy_cnt;		/* # of blocks to copy */
+static off_t	pending = 0;		/* pending seek if sparse */
+u_int		ddflags;		/* conversion options */
+uint64_t	cbsz;			/* conversion block size */
+u_int		files_cnt = 1;		/* # of files to copy */
+uint64_t	progress = 0;		/* display sign of life */
+const u_char	*ctab;			/* conversion table */
+sigset_t	infoset;		/* a set blocking SIGINFO */
+const char	*msgfmt = "posix";	/* default summary() message format */
+
+/*
+ * Ops for stdin/stdout and crunch'd dd.  These are always host ops.
+ */
+static const struct ddfops ddfops_stdfd = {
+	.op_open = open,
+	.op_close = close,
+	.op_fcntl = fcntl,
+	.op_ioctl = ioctl,
+	.op_fstat = fstat,
+	.op_fsync = fsync,
+	.op_ftruncate = ftruncate,
+	.op_lseek = lseek,
+	.op_read = read,
+	.op_write = write,
+};
+extern const struct ddfops ddfops_prog;
+
+int
+main(int argc, char *argv[])
+{
+	int ch;
+
+	setprogname(argv[0]);
+	(void)setlocale(LC_ALL, "");
+
+	while ((ch = getopt(argc, argv, "")) != -1) {
+		switch (ch) {
+		default:
+			errx(EXIT_FAILURE, "usage: dd [operand ...]");
+			/* NOTREACHED */
+		}
+	}
+	argc -= (optind - 1);
+	argv += (optind - 1);
+
+	jcl(argv);
+#ifndef CRUNCHOPS
+	if (ddfops_prog.op_init && ddfops_prog.op_init() == -1)
+		err(1, "prog init");
+#endif
+	setup();
+
+	(void)signal(SIGINFO, summaryx);
+	(void)signal(SIGINT, terminate);
+	(void)sigemptyset(&infoset);
+	(void)sigaddset(&infoset, SIGINFO);
+
+	(void)atexit(summary);
+
+	while (files_cnt--)
+		dd_in();
+
+	dd_close();
+	exit(0);
+	/* NOTREACHED */
+}
+
+static void
+setup(void)
+{
+#ifdef CRUNCHOPS
+	const struct ddfops *prog_ops = &ddfops_stdfd;
+#else
+	const struct ddfops *prog_ops = &ddfops_prog;
+#endif
+
+	if (in.name == NULL) {
+		in.name = "stdin";
+		in.fd = STDIN_FILENO;
+		in.ops = &ddfops_stdfd;
+	} else {
+		in.ops = prog_ops;
+		in.fd = ddop_open(in, in.name, O_RDONLY, 0);
+		if (in.fd < 0)
+			err(EXIT_FAILURE, "%s", in.name);
+			/* NOTREACHED */
+
+		/* Ensure in.fd is outside the stdio descriptor range */
+		redup_clean_fd(&in);
+	}
+
+	getfdtype(&in);
+
+	if (files_cnt > 1 && !(in.flags & ISTAPE)) {
+		errx(EXIT_FAILURE, "files is not supported for non-tape devices");
+		/* NOTREACHED */
+	}
+
+	if (out.name == NULL) {
+		/* No way to check for read access here. */
+		out.fd = STDOUT_FILENO;
+		out.name = "stdout";
+		out.ops = &ddfops_stdfd;
+	} else {
+		out.ops = prog_ops;
+#define	OFLAGS \
+    (O_CREAT | (ddflags & (C_SEEK | C_NOTRUNC) ? 0 : O_TRUNC))
+		out.fd = ddop_open(out, out.name, O_RDWR | OFLAGS, DEFFILEMODE);
+		/*
+		 * May not have read access, so try again with write only.
+		 * Without read we may have a problem if output also does
+		 * not support seeks.
+		 */
+		if (out.fd < 0) {
+			out.fd = ddop_open(out, out.name, O_WRONLY | OFLAGS,
+			    DEFFILEMODE);
+			out.flags |= NOREAD;
+		}
+		if (out.fd < 0) {
+			err(EXIT_FAILURE, "%s", out.name);
+			/* NOTREACHED */
+		}
+
+		/* Ensure out.fd is outside the stdio descriptor range */
+		redup_clean_fd(&out);
+	}
+
+	getfdtype(&out);
+
+	/*
+	 * Allocate space for the input and output buffers.  If not doing
+	 * record oriented I/O, only need a single buffer.
+	 */
+	if (!(ddflags & (C_BLOCK|C_UNBLOCK))) {
+		size_t dbsz = out.dbsz;
+		if (!(ddflags & C_BS))
+			dbsz += in.dbsz - 1;
+		if ((in.db = malloc(dbsz)) == NULL) {
+			err(EXIT_FAILURE, NULL);
+			/* NOTREACHED */
+		}
+		out.db = in.db;
+	} else if ((in.db =
+	    malloc((u_int)(MAX(in.dbsz, cbsz) + cbsz))) == NULL ||
+	    (out.db = malloc((u_int)(out.dbsz + cbsz))) == NULL) {
+		err(EXIT_FAILURE, NULL);
+		/* NOTREACHED */
+	}
+	in.dbp = in.db;
+	out.dbp = out.db;
+
+	/* Position the input/output streams. */
+	if (in.offset)
+		pos_in();
+	if (out.offset)
+		pos_out();
+
+	/*
+	 * Truncate the output file; ignore errors because it fails on some
+	 * kinds of output files, tapes, for example.
+	 */
+	if ((ddflags & (C_OF | C_SEEK | C_NOTRUNC)) == (C_OF | C_SEEK))
+		(void)ddop_ftruncate(out, out.fd, (off_t)out.offset * out.dbsz);
+
+	/*
+	 * If converting case at the same time as another conversion, build a
+	 * table that does both at once.  If just converting case, use the
+	 * built-in tables.
+	 */
+	if (ddflags & (C_LCASE|C_UCASE)) {
+#ifdef	NO_CONV
+		/* Should not get here, but just in case... */
+		errx(EXIT_FAILURE, "case conv and -DNO_CONV");
+		/* NOTREACHED */
+#else	/* NO_CONV */
+		u_int cnt;
+
+		if (ddflags & C_ASCII || ddflags & C_EBCDIC) {
+			if (ddflags & C_LCASE) {
+				for (cnt = 0; cnt < 256; ++cnt)
+					casetab[cnt] = tolower(ctab[cnt]);
+			} else {
+				for (cnt = 0; cnt < 256; ++cnt)
+					casetab[cnt] = toupper(ctab[cnt]);
+			}
+		} else {
+			if (ddflags & C_LCASE) {
+				for (cnt = 0; cnt < 256; ++cnt)
+					casetab[cnt] = tolower(cnt);
+			} else {
+				for (cnt = 0; cnt < 256; ++cnt)
+					casetab[cnt] = toupper(cnt);
+			}
+		}
+
+		ctab = casetab;
+#endif	/* NO_CONV */
+	}
+
+	(void)gettimeofday(&st.start, NULL);	/* Statistics timestamp. */
+}
+
+static void
+getfdtype(IO *io)
+{
+	struct mtget mt;
+	struct stat sb;
+
+	if (io->ops->op_fstat(io->fd, &sb)) {
+		err(EXIT_FAILURE, "%s", io->name);
+		/* NOTREACHED */
+	}
+	if (S_ISCHR(sb.st_mode))
+		io->flags |= io->ops->op_ioctl(io->fd, MTIOCGET, &mt)
+		    ? ISCHR : ISTAPE;
+	else if (io->ops->op_lseek(io->fd, (off_t)0, SEEK_CUR) == -1
+	    && errno == ESPIPE)
+		io->flags |= ISPIPE;		/* XXX fixed in 4.4BSD */
+}
+
+/*
+ * Move the parameter file descriptor to a descriptor that is outside the
+ * stdio descriptor range, if necessary.  This is required to avoid
+ * accidentally outputting completion or error messages into the
+ * output file that were intended for the tty.
+ */
+static void
+redup_clean_fd(IO *io)
+{
+	int fd = io->fd;
+	int newfd;
+
+	if (fd != STDIN_FILENO && fd != STDOUT_FILENO &&
+	    fd != STDERR_FILENO)
+		/* File descriptor is ok, return immediately. */
+		return;
+
+	/*
+	 * 3 is the first descriptor greater than STD*_FILENO.  Any
+	 * free descriptor valued 3 or above is acceptable...
+	 */
+	newfd = io->ops->op_fcntl(fd, F_DUPFD, 3);
+	if (newfd < 0) {
+		err(EXIT_FAILURE, "dupfd IO");
+		/* NOTREACHED */
+	}
+
+	io->ops->op_close(fd);
+	io->fd = newfd;
+}
+
+static void
+dd_in(void)
+{
+	int flags;
+	int64_t n;
+
+	for (flags = ddflags;;) {
+		if (cpy_cnt && (st.in_full + st.in_part) >= cpy_cnt)
+			return;
+
+		/*
+		 * Clear the buffer first if doing "sync" on input.
+		 * If doing block operations use spaces.  This will
+		 * affect not only the C_NOERROR case, but also the
+		 * last partial input block which should be padded
+		 * with zero and not garbage.
+		 */
+		if (flags & C_SYNC) {
+			if (flags & (C_BLOCK|C_UNBLOCK))
+				(void)memset(in.dbp, ' ', in.dbsz);
+			else
+				(void)memset(in.dbp, 0, in.dbsz);
+		}
+
+		n = ddop_read(in, in.fd, in.dbp, in.dbsz);
+		if (n == 0) {
+			in.dbrcnt = 0;
+			return;
+		}
+
+		/* Read error. */
+		if (n < 0) {
+
+			/*
+			 * If noerror not specified, die.  POSIX requires that
+			 * the warning message be followed by an I/O display.
+			 */
+			if (!(flags & C_NOERROR)) {
+				err(EXIT_FAILURE, "%s", in.name);
+				/* NOTREACHED */
+			}
+			warn("%s", in.name);
+			summary();
+
+			/*
+			 * If it's not a tape drive or a pipe, seek past the
+			 * error.  If your OS doesn't do the right thing for
+			 * raw disks this section should be modified to re-read
+			 * in sector size chunks.
+			 */
+			if (!(in.flags & (ISPIPE|ISTAPE)) &&
+			    ddop_lseek(in, in.fd, (off_t)in.dbsz, SEEK_CUR))
+				warn("%s", in.name);
+
+			/* If sync not specified, omit block and continue. */
+			if (!(ddflags & C_SYNC))
+				continue;
+
+			/* Read errors count as full blocks. */
+			in.dbcnt += in.dbrcnt = in.dbsz;
+			++st.in_full;
+
+		/* Handle full input blocks. */
+		} else if ((uint64_t)n == in.dbsz) {
+			in.dbcnt += in.dbrcnt = n;
+			++st.in_full;
+
+		/* Handle partial input blocks. */
+		} else {
+			/* If sync, use the entire block. */
+			if (ddflags & C_SYNC)
+				in.dbcnt += in.dbrcnt = in.dbsz;
+			else
+				in.dbcnt += in.dbrcnt = n;
+			++st.in_part;
+		}
+
+		/*
+		 * POSIX states that if bs is set and no other conversions
+		 * than noerror, notrunc or sync are specified, the block
+		 * is output without buffering as it is read.
+		 */
+		if (ddflags & C_BS) {
+			out.dbcnt = in.dbcnt;
+			dd_out(1);
+			in.dbcnt = 0;
+			continue;
+		}
+
+		if (ddflags & C_SWAB) {
+			if ((n = in.dbrcnt) & 1) {
+				++st.swab;
+				--n;
+			}
+			swab(in.dbp, in.dbp, n);
+		}
+
+		in.dbp += in.dbrcnt;
+		(*cfunc)();
+	}
+}
+
+/*
+ * Cleanup any remaining I/O and flush output.  If necessary, output file
+ * is truncated.
+ */
+static void
+dd_close(void)
+{
+
+	if (cfunc == def)
+		def_close();
+	else if (cfunc == block)
+		block_close();
+	else if (cfunc == unblock)
+		unblock_close();
+	if (ddflags & C_OSYNC && out.dbcnt < out.dbsz) {
+		(void)memset(out.dbp, 0, out.dbsz - out.dbcnt);
+		out.dbcnt = out.dbsz;
+	}
+	/* If there are pending sparse blocks, make sure
+	 * to write out the final block un-sparse
+	 */
+	if ((out.dbcnt == 0) && pending) {
+		memset(out.db, 0, out.dbsz);
+		out.dbcnt = out.dbsz;
+		out.dbp = out.db + out.dbcnt;
+		pending -= out.dbsz;
+	}
+	if (out.dbcnt)
+		dd_out(1);
+
+	/*
+	 * Reporting nfs write error may be deferred until next
+	 * write(2) or close(2) system call.  So, we need to do an
+	 * extra check.  If an output is stdout, the file structure
+	 * may be shared with other processes and close(2) just
+	 * decreases the reference count.
+	 */
+	if (out.fd == STDOUT_FILENO && ddop_fsync(out, out.fd) == -1
+	    && errno != EINVAL) {
+		err(EXIT_FAILURE, "fsync stdout");
+		/* NOTREACHED */
+	}
+	if (ddop_close(out, out.fd) == -1) {
+		err(EXIT_FAILURE, "close");
+		/* NOTREACHED */
+	}
+}
+
+void
+dd_out(int force)
+{
+	static int warned;
+	int64_t cnt, n, nw;
+	u_char *outp;
+
+	/*
+	 * Write one or more blocks out.  The common case is writing a full
+	 * output block in a single write; increment the full block stats.
+	 * Otherwise, we're into partial block writes.  If a partial write,
+	 * and it's a character device, just warn.  If a tape device, quit.
+	 *
+	 * The partial writes represent two cases.  1: Where the input block
+	 * was less than expected so the output block was less than expected.
+	 * 2: Where the input block was the right size but we were forced to
+	 * write the block in multiple chunks.  The original versions of dd(1)
+	 * never wrote a block in more than a single write, so the latter case
+	 * never happened.
+	 *
+	 * One special case is if we're forced to do the write -- in that case
+	 * we play games with the buffer size, and it's usually a partial write.
+	 */
+	outp = out.db;
+	for (n = force ? out.dbcnt : out.dbsz;; n = out.dbsz) {
+		for (cnt = n;; cnt -= nw) {
+
+			if (!force && ddflags & C_SPARSE) {
+				int sparse, i;
+				sparse = 1;	/* Is buffer sparse? */
+				for (i = 0; i < cnt; i++)
+					if (outp[i] != 0) {
+						sparse = 0;
+						break;
+					}
+				if (sparse) {
+					pending += cnt;
+					outp += cnt;
+					nw = 0;
+					break;
+				}
+			}
+			if (pending != 0) {
+				if (ddop_lseek(out,
+				    out.fd, pending, SEEK_CUR) == -1)
+					err(EXIT_FAILURE, "%s: seek error creating sparse file",
+					    out.name);
+			}
+			nw = bwrite(&out, outp, cnt);
+			if (nw <= 0) {
+				if (nw == 0)
+					errx(EXIT_FAILURE,
+						"%s: end of device", out.name);
+					/* NOTREACHED */
+				if (errno != EINTR)
+					err(EXIT_FAILURE, "%s", out.name);
+					/* NOTREACHED */
+				nw = 0;
+			}
+			if (pending) {
+				st.bytes += pending;
+				st.sparse += pending/out.dbsz;
+				st.out_full += pending/out.dbsz;
+				pending = 0;
+			}
+			outp += nw;
+			st.bytes += nw;
+			if (nw == n) {
+				if ((uint64_t)n != out.dbsz)
+					++st.out_part;
+				else
+					++st.out_full;
+				break;
+			}
+			++st.out_part;
+			if (nw == cnt)
+				break;
+			if (out.flags & ISCHR && !warned) {
+				warned = 1;
+				warnx("%s: short write on character device", out.name);
+			}
+			if (out.flags & ISTAPE)
+				errx(EXIT_FAILURE,
+					"%s: short write on tape device", out.name);
+				/* NOTREACHED */
+
+		}
+		if ((out.dbcnt -= n) < out.dbsz)
+			break;
+	}
+
+	/* Reassemble the output block. */
+	if (out.dbcnt)
+		(void)memmove(out.db, out.dbp - out.dbcnt, out.dbcnt);
+	out.dbp = out.db + out.dbcnt;
+
+	if (progress && (st.out_full + st.out_part) % progress == 0)
+		(void)write(STDERR_FILENO, ".", 1);
+}
+
+/*
+ * A protected against SIGINFO write
+ */
+ssize_t
+bwrite(IO *io, const void *buf, size_t len)
+{
+	sigset_t oset;
+	ssize_t rv;
+	int oerrno;
+
+	(void)sigprocmask(SIG_BLOCK, &infoset, &oset);
+	rv = io->ops->op_write(io->fd, buf, len);
+	oerrno = errno;
+	(void)sigprocmask(SIG_SETMASK, &oset, NULL);
+	errno = oerrno;
+	return (rv);
+}
diff --git a/toolbox/dd.h b/toolbox/upstream-netbsd/bin/dd/dd.h
similarity index 74%
rename from toolbox/dd.h
rename to toolbox/upstream-netbsd/bin/dd/dd.h
index 89f2833..b01c7b3 100644
--- a/toolbox/dd.h
+++ b/toolbox/upstream-netbsd/bin/dd/dd.h
@@ -1,4 +1,4 @@
-/*	$NetBSD: dd.h,v 1.12 2004/01/17 20:48:57 dbj Exp $	*/
+/*	$NetBSD: dd.h,v 1.15 2011/02/04 19:42:12 pooka Exp $	*/
 
 /*-
  * Copyright (c) 1991, 1993, 1994
@@ -35,7 +35,40 @@
  *	@(#)dd.h	8.3 (Berkeley) 4/2/94
  */
 
-#include <stdint.h>
+#include <sys/stat.h>
+
+struct ddfops {
+	int (*op_init)(void);
+
+	int (*op_open)(const char *, int, ...);
+	int (*op_close)(int);
+
+	int (*op_fcntl)(int, int, ...);
+#ifdef __ANDROID__
+	int (*op_ioctl)(int, int, ...);
+#else
+	int (*op_ioctl)(int, unsigned long, ...);
+#endif
+
+	int (*op_fstat)(int, struct stat *);
+	int (*op_fsync)(int);
+	int (*op_ftruncate)(int, off_t);
+
+	off_t (*op_lseek)(int, off_t, int);
+
+	ssize_t (*op_read)(int, void *, size_t);
+	ssize_t (*op_write)(int, const void *, size_t);
+};
+
+#define ddop_open(dir, a1, a2, ...)	dir.ops->op_open(a1, a2, __VA_ARGS__)
+#define ddop_close(dir, a1)		dir.ops->op_close(a1)
+#define ddop_fcntl(dir, a1, a2, ...)	dir.ops->op_fcntl(a1, a2, __VA_ARGS__)
+#define ddop_ioctl(dir, a1, a2, ...)	dir.ops->op_ioctl(a1, a2, __VA_ARGS__)
+#define ddop_fsync(dir, a1)		dir.ops->op_fsync(a1)
+#define ddop_ftruncate(dir, a1, a2)	dir.ops->op_ftruncate(a1, a2)
+#define ddop_lseek(dir, a1, a2, a3)	dir.ops->op_lseek(a1, a2, a3)
+#define ddop_read(dir, a1, a2, a3)	dir.ops->op_read(a1, a2, a3)
+#define ddop_write(dir, a1, a2, a3)	dir.ops->op_write(a1, a2, a3)
 
 /* Input/output stream state. */
 typedef struct {
@@ -54,6 +87,7 @@
 	const char  	*name;		/* name */
 	int		fd;		/* file descriptor */
 	uint64_t	offset;		/* # of blocks to skip */
+	struct ddfops	const *ops;	/* ops to use with fd */
 } IO;
 
 typedef struct {
@@ -91,4 +125,3 @@
 #define	C_UNBLOCK	0x80000
 #define	C_OSYNC		0x100000
 #define	C_SPARSE	0x200000
-#define	C_FDATASYNC	0x400000
diff --git a/toolbox/upstream-netbsd/bin/dd/dd_hostops.c b/toolbox/upstream-netbsd/bin/dd/dd_hostops.c
new file mode 100644
index 0000000..d6e7a89
--- /dev/null
+++ b/toolbox/upstream-netbsd/bin/dd/dd_hostops.c
@@ -0,0 +1,53 @@
+/*      $NetBSD: dd_hostops.c,v 1.1 2011/02/04 19:42:12 pooka Exp $	*/
+
+/*-
+ * Copyright (c) 2010 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+#ifndef lint
+__RCSID("$NetBSD: dd_hostops.c,v 1.1 2011/02/04 19:42:12 pooka Exp $");
+#endif /* !lint */
+
+#include <sys/types.h>
+#include <sys/ioctl.h>
+
+#include <fcntl.h>
+#include <unistd.h>
+
+#include "dd.h"
+
+const struct ddfops ddfops_prog = {
+	.op_open = open,
+	.op_close = close,
+	.op_fcntl = fcntl,
+	.op_ioctl = ioctl,
+	.op_fstat = fstat,
+	.op_fsync = fsync,
+	.op_ftruncate = ftruncate,
+	.op_lseek = lseek,
+	.op_read = read,
+	.op_write = write,
+};
diff --git a/toolbox/upstream-netbsd/bin/dd/extern.h b/toolbox/upstream-netbsd/bin/dd/extern.h
new file mode 100644
index 0000000..9c59021
--- /dev/null
+++ b/toolbox/upstream-netbsd/bin/dd/extern.h
@@ -0,0 +1,82 @@
+/*	$NetBSD: extern.h,v 1.22 2011/11/07 22:24:23 jym Exp $	*/
+
+/*-
+ * Copyright (c) 1991, 1993, 1994
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Keith Muller of the University of California, San Diego and Lance
+ * Visser of Convex Computer Corporation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)extern.h	8.3 (Berkeley) 4/2/94
+ */
+
+#include <sys/cdefs.h>
+
+#ifdef NO_CONV
+__dead void block(void);
+__dead void block_close(void);
+__dead void unblock(void);
+__dead void unblock_close(void);
+#else
+void block(void);
+void block_close(void);
+void unblock(void);
+void unblock_close(void);
+#endif
+
+#ifndef NO_MSGFMT
+int dd_write_msg(const char *, int);
+#endif
+
+void dd_out(int);
+void def(void);
+void def_close(void);
+void jcl(char **);
+void pos_in(void);
+void pos_out(void);
+void summary(void);
+void summaryx(int);
+__dead void terminate(int);
+void unblock(void);
+void unblock_close(void);
+ssize_t bwrite(IO *, const void *, size_t);
+
+extern IO		in, out;
+extern STAT		st;
+extern void		(*cfunc)(void);
+extern uint64_t		cpy_cnt;
+extern uint64_t		cbsz;
+extern u_int		ddflags;
+extern u_int		files_cnt;
+extern uint64_t		progress;
+extern const u_char	*ctab;
+extern const u_char	a2e_32V[], a2e_POSIX[];
+extern const u_char	e2a_32V[], e2a_POSIX[];
+extern const u_char	a2ibm_32V[], a2ibm_POSIX[];
+extern u_char		casetab[];
+extern const char	*msgfmt;
diff --git a/toolbox/upstream-netbsd/bin/dd/misc.c b/toolbox/upstream-netbsd/bin/dd/misc.c
new file mode 100644
index 0000000..0fac98b
--- /dev/null
+++ b/toolbox/upstream-netbsd/bin/dd/misc.c
@@ -0,0 +1,342 @@
+/*	$NetBSD: misc.c,v 1.23 2011/11/07 22:24:23 jym Exp $	*/
+
+/*-
+ * Copyright (c) 1991, 1993, 1994
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Keith Muller of the University of California, San Diego and Lance
+ * Visser of Convex Computer Corporation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)misc.c	8.3 (Berkeley) 4/2/94";
+#else
+__RCSID("$NetBSD: misc.c,v 1.23 2011/11/07 22:24:23 jym Exp $");
+#endif
+#endif /* not lint */
+
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/time.h>
+
+#include <err.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <util.h>
+#include <inttypes.h>
+
+#include "dd.h"
+#include "extern.h"
+
+#define	tv2mS(tv) ((tv).tv_sec * 1000LL + ((tv).tv_usec + 500) / 1000)
+
+static void posix_summary(void);
+#ifndef NO_MSGFMT
+static void custom_summary(void);
+static void human_summary(void);
+static void quiet_summary(void);
+
+static void buffer_write(const char *, size_t, int);
+#endif /* NO_MSGFMT */
+
+void
+summary(void)
+{
+
+	if (progress)
+		(void)write(STDERR_FILENO, "\n", 1);
+
+#ifdef NO_MSGFMT
+	return posix_summary();
+#else /* NO_MSGFMT */
+	if (strncmp(msgfmt, "human", sizeof("human")) == 0)
+		return human_summary();
+
+	if (strncmp(msgfmt, "posix", sizeof("posix")) == 0)
+		return posix_summary();
+
+	if (strncmp(msgfmt, "quiet", sizeof("quiet")) == 0)
+		return quiet_summary();
+
+	return custom_summary();
+#endif /* NO_MSGFMT */
+}
+
+static void
+posix_summary(void)
+{
+	char buf[100];
+	int64_t mS;
+	struct timeval tv;
+
+	if (progress)
+		(void)write(STDERR_FILENO, "\n", 1);
+
+	(void)gettimeofday(&tv, NULL);
+	mS = tv2mS(tv) - tv2mS(st.start);
+	if (mS == 0)
+		mS = 1;
+
+	/* Use snprintf(3) so that we don't reenter stdio(3). */
+	(void)snprintf(buf, sizeof(buf),
+	    "%llu+%llu records in\n%llu+%llu records out\n",
+	    (unsigned long long)st.in_full,  (unsigned long long)st.in_part,
+	    (unsigned long long)st.out_full, (unsigned long long)st.out_part);
+	(void)write(STDERR_FILENO, buf, strlen(buf));
+	if (st.swab) {
+		(void)snprintf(buf, sizeof(buf), "%llu odd length swab %s\n",
+		    (unsigned long long)st.swab,
+		    (st.swab == 1) ? "block" : "blocks");
+		(void)write(STDERR_FILENO, buf, strlen(buf));
+	}
+	if (st.trunc) {
+		(void)snprintf(buf, sizeof(buf), "%llu truncated %s\n",
+		    (unsigned long long)st.trunc,
+		    (st.trunc == 1) ? "block" : "blocks");
+		(void)write(STDERR_FILENO, buf, strlen(buf));
+	}
+	if (st.sparse) {
+		(void)snprintf(buf, sizeof(buf), "%llu sparse output %s\n",
+		    (unsigned long long)st.sparse,
+		    (st.sparse == 1) ? "block" : "blocks");
+		(void)write(STDERR_FILENO, buf, strlen(buf));
+	}
+	(void)snprintf(buf, sizeof(buf),
+	    "%llu bytes transferred in %lu.%03d secs (%llu bytes/sec)\n",
+	    (unsigned long long) st.bytes,
+	    (long) (mS / 1000),
+	    (int) (mS % 1000),
+	    (unsigned long long) (st.bytes * 1000LL / mS));
+	(void)write(STDERR_FILENO, buf, strlen(buf));
+}
+
+/* ARGSUSED */
+void
+summaryx(int notused)
+{
+
+	summary();
+}
+
+/* ARGSUSED */
+void
+terminate(int signo)
+{
+
+	summary();
+	(void)raise_default_signal(signo);
+	_exit(127);
+}
+
+#ifndef NO_MSGFMT
+/*
+ * Buffer write(2) calls
+ */
+static void
+buffer_write(const char *str, size_t size, int flush)
+{
+	static char wbuf[128];
+	static size_t cnt = 0; /* Internal counter to allow wbuf to wrap */
+	
+	unsigned int i;
+
+	for (i = 0; i < size; i++) {
+		if (str != NULL) {
+			wbuf[cnt++] = str[i];
+		}
+		if (cnt >= sizeof(wbuf)) {
+			(void)write(STDERR_FILENO, wbuf, cnt);
+			cnt = 0;
+		}
+	}
+
+	if (flush != 0) {
+		(void)write(STDERR_FILENO, wbuf, cnt);
+		cnt = 0;
+	}
+}
+
+/*
+ * Write summary to stderr according to format 'fmt'. If 'enable' is 0, it
+ * will not attempt to write anything. Can be used to validate the
+ * correctness of the 'fmt' string.
+ */
+int
+dd_write_msg(const char *fmt, int enable)
+{
+	char hbuf[7], nbuf[32];
+	const char *ptr;
+	int64_t mS;
+	struct timeval tv;
+
+	(void)gettimeofday(&tv, NULL);
+	mS = tv2mS(tv) - tv2mS(st.start);
+	if (mS == 0)
+		mS = 1;
+
+#define ADDC(c) do { if (enable != 0) buffer_write(&c, 1, 0); } \
+	while (/*CONSTCOND*/0)
+#define ADDS(p) do { if (enable != 0) buffer_write(p, strlen(p), 0); } \
+	while (/*CONSTCOND*/0)
+
+	for (ptr = fmt; *ptr; ptr++) {
+		if (*ptr != '%') {
+			ADDC(*ptr);
+			continue;
+		}
+
+ 		switch (*++ptr) {
+		case 'b':
+			(void)snprintf(nbuf, sizeof(nbuf), "%llu",
+			    (unsigned long long)st.bytes);
+			ADDS(nbuf);
+			break;
+		case 'B':
+			if (humanize_number(hbuf, sizeof(hbuf),
+			    st.bytes, "B",
+			    HN_AUTOSCALE, HN_DECIMAL) == -1)
+				warnx("humanize_number (bytes transferred)");
+			ADDS(hbuf);
+			break;
+		case 'e':
+			(void)snprintf(nbuf, sizeof(nbuf), "%llu",
+			    (unsigned long long) (st.bytes * 1000LL / mS));
+			ADDS(nbuf);
+			break;
+		case 'E':
+			if (humanize_number(hbuf, sizeof(hbuf),
+			    st.bytes * 1000LL / mS, "B",
+			    HN_AUTOSCALE, HN_DECIMAL) == -1)
+				warnx("humanize_number (bytes per second)");
+			ADDS(hbuf); ADDS("/sec");
+			break;
+		case 'i':
+			(void)snprintf(nbuf, sizeof(nbuf), "%llu",
+			    (unsigned long long)st.in_part);
+			ADDS(nbuf);
+			break;
+		case 'I':
+			(void)snprintf(nbuf, sizeof(nbuf), "%llu",
+			    (unsigned long long)st.in_full);
+			ADDS(nbuf);
+			break;
+		case 'o':
+			(void)snprintf(nbuf, sizeof(nbuf), "%llu",
+			    (unsigned long long)st.out_part);
+			ADDS(nbuf);
+			break;
+		case 'O':
+			(void)snprintf(nbuf, sizeof(nbuf), "%llu",
+			    (unsigned long long)st.out_full);
+			ADDS(nbuf);
+			break;
+		case 's':
+			(void)snprintf(nbuf, sizeof(nbuf), "%li.%03d",
+			    (long) (mS / 1000), (int) (mS % 1000));
+			ADDS(nbuf);
+			break;
+		case 'p':
+			(void)snprintf(nbuf, sizeof(nbuf), "%llu",
+			    (unsigned long long)st.sparse);
+			ADDS(nbuf);
+			break;
+		case 't':
+			(void)snprintf(nbuf, sizeof(nbuf), "%llu",
+			    (unsigned long long)st.trunc);
+			ADDS(nbuf);
+			break;
+		case 'w':
+			(void)snprintf(nbuf, sizeof(nbuf), "%llu",
+			    (unsigned long long)st.swab);
+			ADDS(nbuf);
+			break;
+		case 'P':
+			ADDS("block");
+			if (st.sparse != 1) ADDS("s");
+			break;
+		case 'T':
+			ADDS("block");
+			if (st.trunc != 1) ADDS("s");
+			break;
+		case 'W':
+			ADDS("block");
+			if (st.swab != 1) ADDS("s");
+			break;
+		case '%':
+			ADDC(*ptr);
+			break;
+		default:
+			if (*ptr == '\0')
+				goto done;
+			errx(EXIT_FAILURE, "unknown specifier '%c' in "
+			    "msgfmt string", *ptr);
+			/* NOTREACHED */
+		}
+	}
+
+done:
+	/* flush buffer */
+	buffer_write(NULL, 0, 1);
+	return 0;
+}
+
+static void
+custom_summary(void)
+{
+
+	dd_write_msg(msgfmt, 1);
+}
+
+static void
+human_summary(void)
+{
+	(void)dd_write_msg("%I+%i records in\n%O+%o records out\n", 1);
+	if (st.swab) {
+		(void)dd_write_msg("%w odd length swab %W\n", 1);
+	}
+	if (st.trunc) {
+		(void)dd_write_msg("%t truncated %T\n", 1);
+	}
+	if (st.sparse) {
+		(void)dd_write_msg("%p sparse output %P\n", 1);
+	}
+	(void)dd_write_msg("%b bytes (%B) transferred in %s secs "
+	    "(%e bytes/sec - %E)\n", 1);
+}
+
+static void
+quiet_summary(void)
+{
+
+	/* stay quiet */
+}
+#endif /* NO_MSGFMT */
diff --git a/toolbox/upstream-netbsd/bin/dd/position.c b/toolbox/upstream-netbsd/bin/dd/position.c
new file mode 100644
index 0000000..36dd580
--- /dev/null
+++ b/toolbox/upstream-netbsd/bin/dd/position.c
@@ -0,0 +1,185 @@
+/*	$NetBSD: position.c,v 1.18 2010/11/22 21:04:28 pooka Exp $	*/
+
+/*-
+ * Copyright (c) 1991, 1993, 1994
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Keith Muller of the University of California, San Diego and Lance
+ * Visser of Convex Computer Corporation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)position.c	8.3 (Berkeley) 4/2/94";
+#else
+__RCSID("$NetBSD: position.c,v 1.18 2010/11/22 21:04:28 pooka Exp $");
+#endif
+#endif /* not lint */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <sys/mtio.h>
+#include <sys/time.h>
+
+#include <err.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "dd.h"
+#include "extern.h"
+
+/*
+ * Position input/output data streams before starting the copy.  Device type
+ * dependent.  Seekable devices use lseek, and the rest position by reading.
+ * Seeking past the end of file can cause null blocks to be written to the
+ * output.
+ */
+void
+pos_in(void)
+{
+	int bcnt, cnt, nr, warned;
+
+	/* If not a pipe or tape device, try to seek on it. */
+	if (!(in.flags & (ISPIPE|ISTAPE))) {
+		if (ddop_lseek(in, in.fd,
+		    (off_t)in.offset * (off_t)in.dbsz, SEEK_CUR) == -1) {
+			err(EXIT_FAILURE, "%s", in.name);
+			/* NOTREACHED */
+		}
+		return;
+		/* NOTREACHED */
+	}
+
+	/*
+	 * Read the data.  If a pipe, read until satisfy the number of bytes
+	 * being skipped.  No differentiation for reading complete and partial
+	 * blocks for other devices.
+	 */
+	for (bcnt = in.dbsz, cnt = in.offset, warned = 0; cnt;) {
+		if ((nr = ddop_read(in, in.fd, in.db, bcnt)) > 0) {
+			if (in.flags & ISPIPE) {
+				if (!(bcnt -= nr)) {
+					bcnt = in.dbsz;
+					--cnt;
+				}
+			} else
+				--cnt;
+			continue;
+		}
+
+		if (nr == 0) {
+			if (files_cnt > 1) {
+				--files_cnt;
+				continue;
+			}
+			errx(EXIT_FAILURE, "skip reached end of input");
+			/* NOTREACHED */
+		}
+
+		/*
+		 * Input error -- either EOF with no more files, or I/O error.
+		 * If noerror not set die.  POSIX requires that the warning
+		 * message be followed by an I/O display.
+		 */
+		if (ddflags & C_NOERROR) {
+			if (!warned) {
+
+				warn("%s", in.name);
+				warned = 1;
+				summary();
+			}
+			continue;
+		}
+		err(EXIT_FAILURE, "%s", in.name);
+		/* NOTREACHED */
+	}
+}
+
+void
+pos_out(void)
+{
+	struct mtop t_op;
+	int n;
+	uint64_t cnt;
+
+	/*
+	 * If not a tape, try seeking on the file.  Seeking on a pipe is
+	 * going to fail, but don't protect the user -- they shouldn't
+	 * have specified the seek operand.
+	 */
+	if (!(out.flags & ISTAPE)) {
+		if (ddop_lseek(out, out.fd,
+		    (off_t)out.offset * (off_t)out.dbsz, SEEK_SET) == -1)
+			err(EXIT_FAILURE, "%s", out.name);
+			/* NOTREACHED */
+		return;
+	}
+
+	/* If no read access, try using mtio. */
+	if (out.flags & NOREAD) {
+		t_op.mt_op = MTFSR;
+		t_op.mt_count = out.offset;
+
+		if (ddop_ioctl(out, out.fd, MTIOCTOP, &t_op) < 0)
+			err(EXIT_FAILURE, "%s", out.name);
+			/* NOTREACHED */
+		return;
+	}
+
+	/* Read it. */
+	for (cnt = 0; cnt < out.offset; ++cnt) {
+		if ((n = ddop_read(out, out.fd, out.db, out.dbsz)) > 0)
+			continue;
+
+		if (n < 0)
+			err(EXIT_FAILURE, "%s", out.name);
+			/* NOTREACHED */
+
+		/*
+		 * If reach EOF, fill with NUL characters; first, back up over
+		 * the EOF mark.  Note, cnt has not yet been incremented, so
+		 * the EOF read does not count as a seek'd block.
+		 */
+		t_op.mt_op = MTBSR;
+		t_op.mt_count = 1;
+		if (ddop_ioctl(out, out.fd, MTIOCTOP, &t_op) == -1)
+			err(EXIT_FAILURE, "%s", out.name);
+			/* NOTREACHED */
+
+		while (cnt++ < out.offset)
+			if ((uint64_t)(n = bwrite(&out,
+			    out.db, out.dbsz)) != out.dbsz)
+				err(EXIT_FAILURE, "%s", out.name);
+				/* NOTREACHED */
+		break;
+	}
+}
diff --git a/toolbox/upstream-netbsd/bin/kill/kill.c b/toolbox/upstream-netbsd/bin/kill/kill.c
new file mode 100644
index 0000000..0592577
--- /dev/null
+++ b/toolbox/upstream-netbsd/bin/kill/kill.c
@@ -0,0 +1,253 @@
+/* $NetBSD: kill.c,v 1.27 2011/08/29 14:51:18 joerg Exp $ */
+
+/*
+ * Copyright (c) 1988, 1993, 1994
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+#if !defined(lint) && !defined(SHELL)
+__COPYRIGHT("@(#) Copyright (c) 1988, 1993, 1994\
+ The Regents of the University of California.  All rights reserved.");
+#endif /* not lint */
+
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)kill.c	8.4 (Berkeley) 4/28/95";
+#else
+__RCSID("$NetBSD: kill.c,v 1.27 2011/08/29 14:51:18 joerg Exp $");
+#endif
+#endif /* not lint */
+
+#include <ctype.h>
+#include <err.h>
+#include <errno.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <limits.h>
+#include <inttypes.h>
+#include <string.h>
+#include <termios.h>
+#include <unistd.h>
+#include <locale.h>
+#include <sys/ioctl.h>
+
+#ifdef SHELL            /* sh (aka ash) builtin */
+int killcmd(int, char *argv[]);
+#define main killcmd
+#include "../../bin/sh/bltin/bltin.h"
+#endif /* SHELL */ 
+
+__dead static void nosig(char *);
+static void printsignals(FILE *);
+static int signame_to_signum(char *);
+__dead static void usage(void);
+
+int
+main(int argc, char *argv[])
+{
+	int errors;
+	intmax_t numsig, pid;
+	char *ep;
+
+	setprogname(argv[0]);
+	setlocale(LC_ALL, "");
+	if (argc < 2)
+		usage();
+
+	numsig = SIGTERM;
+
+	argc--, argv++;
+	if (strcmp(*argv, "-l") == 0) {
+		argc--, argv++;
+		if (argc > 1)
+			usage();
+		if (argc == 1) {
+			if (isdigit((unsigned char)**argv) == 0)
+				usage();
+			numsig = strtoimax(*argv, &ep, 10);
+			/* check for correctly parsed number */
+			if (*ep != '\0' || numsig == INTMAX_MIN || numsig == INTMAX_MAX) {
+				errx(EXIT_FAILURE, "illegal signal number: %s",
+						*argv);
+				/* NOTREACHED */
+			}
+			if (numsig >= 128)
+				numsig -= 128;
+			/* and whether it fits into signals range */
+			if (numsig <= 0 || numsig >= NSIG)
+				nosig(*argv);
+			printf("%s\n", sys_signame[(int) numsig]);
+			exit(0);
+		}
+		printsignals(stdout);
+		exit(0);
+	}
+
+	if (!strcmp(*argv, "-s")) {
+		argc--, argv++;
+		if (argc < 1) {
+			warnx("option requires an argument -- s");
+			usage();
+		}
+		if (strcmp(*argv, "0")) {
+			if ((numsig = signame_to_signum(*argv)) < 0)
+				nosig(*argv);
+		} else
+			numsig = 0;
+		argc--, argv++;
+	} else if (**argv == '-') {
+		char *sn = *argv + 1;
+		if (isalpha((unsigned char)*sn)) {
+			if ((numsig = signame_to_signum(sn)) < 0)
+				nosig(sn);
+		} else if (isdigit((unsigned char)*sn)) {
+			numsig = strtoimax(sn, &ep, 10);
+			/* check for correctly parsed number */
+			if (*ep || numsig == INTMAX_MIN || numsig == INTMAX_MAX ) {
+				errx(EXIT_FAILURE, "illegal signal number: %s",
+						sn);
+				/* NOTREACHED */
+			}
+			/* and whether it fits into signals range */
+			if (numsig < 0 || numsig >= NSIG)
+				nosig(sn);
+		} else
+			nosig(sn);
+		argc--, argv++;
+	}
+
+	if (argc == 0)
+		usage();
+
+	for (errors = 0; argc; argc--, argv++) {
+#ifdef SHELL
+		extern int getjobpgrp(const char *);
+		if (*argv[0] == '%') {
+			pid = getjobpgrp(*argv);
+			if (pid == 0) {
+				warnx("illegal job id: %s", *argv);
+				errors = 1;
+				continue;
+			}
+		} else 
+#endif
+		{
+			pid = strtoimax(*argv, &ep, 10);
+			/* make sure the pid is a number and fits into pid_t */
+			if (!**argv || *ep || pid == INTMAX_MIN ||
+				pid == INTMAX_MAX || pid != (pid_t) pid) {
+
+				warnx("illegal process id: %s", *argv);
+				errors = 1;
+				continue;
+			}
+		}
+		if (kill((pid_t) pid, (int) numsig) == -1) {
+			warn("%s", *argv);
+			errors = 1;
+		}
+#ifdef SHELL
+		/* Wakeup the process if it was suspended, so it can
+		   exit without an explicit 'fg'. */
+		if (numsig == SIGTERM || numsig == SIGHUP)
+			kill((pid_t) pid, SIGCONT);
+#endif
+	}
+
+	exit(errors);
+	/* NOTREACHED */
+}
+
+static int
+signame_to_signum(char *sig)
+{
+	int n;
+
+	if (strncasecmp(sig, "sig", 3) == 0)
+		sig += 3;
+	for (n = 1; n < NSIG; n++) {
+		if (!strcasecmp(sys_signame[n], sig))
+			return (n);
+	}
+	return (-1);
+}
+
+static void
+nosig(char *name)
+{
+
+	warnx("unknown signal %s; valid signals:", name);
+	printsignals(stderr);
+	exit(1);
+	/* NOTREACHED */
+}
+
+static void
+printsignals(FILE *fp)
+{
+	int sig;
+	int len, nl;
+	const char *name;
+	int termwidth = 80;
+
+	if (isatty(fileno(fp))) {
+		struct winsize win;
+		if (ioctl(fileno(fp), TIOCGWINSZ, &win) == 0 && win.ws_col > 0)
+			termwidth = win.ws_col;
+	}
+
+	for (len = 0, sig = 1; sig < NSIG; sig++) {
+		name = sys_signame[sig];
+		nl = 1 + strlen(name);
+
+		if (len + nl >= termwidth) {
+			fprintf(fp, "\n");
+			len = 0;
+		} else
+			if (len != 0)
+				fprintf(fp, " ");
+		len += nl;
+		fprintf(fp, "%s", name);
+	}
+	if (len != 0)
+		fprintf(fp, "\n");
+}
+
+static void
+usage(void)
+{
+
+	fprintf(stderr, "usage: %s [-s signal_name] pid ...\n"
+	    "       %s -l [exit_status]\n"
+	    "       %s -signal_name pid ...\n"
+	    "       %s -signal_number pid ...\n",
+	    getprogname(), getprogname(), getprogname(), getprogname());
+	exit(1);
+	/* NOTREACHED */
+}
diff --git a/toolbox/upstream-netbsd/bin/ln/ln.c b/toolbox/upstream-netbsd/bin/ln/ln.c
new file mode 100644
index 0000000..9127477
--- /dev/null
+++ b/toolbox/upstream-netbsd/bin/ln/ln.c
@@ -0,0 +1,230 @@
+/* $NetBSD: ln.c,v 1.35 2011/08/29 14:38:30 joerg Exp $ */
+
+/*
+ * Copyright (c) 1987, 1993, 1994
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+#ifndef lint
+__COPYRIGHT("@(#) Copyright (c) 1987, 1993, 1994\
+ The Regents of the University of California.  All rights reserved.");
+#endif /* not lint */
+
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)ln.c	8.2 (Berkeley) 3/31/94";
+#else
+__RCSID("$NetBSD: ln.c,v 1.35 2011/08/29 14:38:30 joerg Exp $");
+#endif
+#endif /* not lint */
+
+#include <sys/param.h>
+#include <sys/stat.h>
+
+#include <err.h>
+#include <errno.h>
+#include <locale.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+static int	fflag;				/* Unlink existing files. */
+static int	hflag;				/* Check new name for symlink first. */
+static int	iflag;				/* Interactive mode. */
+static int	sflag;				/* Symbolic, not hard, link. */
+static int	vflag;                          /* Verbose output */
+
+					/* System link call. */
+static int (*linkf)(const char *, const char *);
+static char   linkch;
+
+static int	linkit(const char *, const char *, int);
+__dead static void	usage(void);
+
+int
+main(int argc, char *argv[])
+{
+	struct stat sb;
+	int ch, exitval;
+	char *sourcedir;
+
+	setprogname(argv[0]);
+	(void)setlocale(LC_ALL, "");
+
+	while ((ch = getopt(argc, argv, "fhinsv")) != -1)
+		switch (ch) {
+		case 'f':
+			fflag = 1;
+			iflag = 0;
+			break;
+		case 'h':
+		case 'n':
+			hflag = 1;
+			break;
+		case 'i':
+			iflag = 1;
+			fflag = 0;
+			break;
+		case 's':
+			sflag = 1;
+			break;
+		case 'v':               
+			vflag = 1;
+			break;
+		case '?':
+		default:
+			usage();
+			/* NOTREACHED */
+		}
+
+	argv += optind;
+	argc -= optind;
+
+	if (sflag) {
+		linkf  = symlink;
+		linkch = '-';
+	} else {
+		linkf  = link;
+		linkch = '=';
+	}
+
+	switch(argc) {
+	case 0:
+		usage();
+		/* NOTREACHED */
+	case 1:				/* ln target */
+		exit(linkit(argv[0], ".", 1));
+		/* NOTREACHED */
+	case 2:				/* ln target source */
+		exit(linkit(argv[0], argv[1], 0));
+		/* NOTREACHED */
+	}
+
+					/* ln target1 target2 directory */
+	sourcedir = argv[argc - 1];
+	if (hflag && lstat(sourcedir, &sb) == 0 && S_ISLNK(sb.st_mode)) {
+		/* we were asked not to follow symlinks, but found one at
+		   the target--simulate "not a directory" error */
+		errno = ENOTDIR;
+		err(EXIT_FAILURE, "%s", sourcedir);
+		/* NOTREACHED */
+	}
+	if (stat(sourcedir, &sb)) {
+		err(EXIT_FAILURE, "%s", sourcedir);
+		/* NOTREACHED */
+	}
+	if (!S_ISDIR(sb.st_mode)) {
+		usage();
+		/* NOTREACHED */
+	}
+	for (exitval = 0; *argv != sourcedir; ++argv)
+		exitval |= linkit(*argv, sourcedir, 1);
+	exit(exitval);
+	/* NOTREACHED */
+}
+
+static int
+linkit(const char *target, const char *source, int isdir)
+{
+	struct stat sb;
+	const char *p;
+	char path[MAXPATHLEN];
+	int ch, exists, first;
+
+	if (!sflag) {
+		/* If target doesn't exist, quit now. */
+		if (stat(target, &sb)) {
+			warn("%s", target);
+			return (1);
+		}
+	}
+
+	/* If the source is a directory (and not a symlink if hflag),
+	   append the target's name. */
+	if (isdir ||
+	    (!lstat(source, &sb) && S_ISDIR(sb.st_mode)) ||
+	    (!hflag && !stat(source, &sb) && S_ISDIR(sb.st_mode))) {
+		if ((p = strrchr(target, '/')) == NULL)
+			p = target;
+		else
+			++p;
+		(void)snprintf(path, sizeof(path), "%s/%s", source, p);
+		source = path;
+	}
+
+	exists = !lstat(source, &sb);
+
+	/*
+	 * If the file exists, then unlink it forcibly if -f was specified
+	 * and interactively if -i was specified.
+	 */
+	if (fflag && exists) {
+		if (unlink(source)) {
+			warn("%s", source);
+			return (1);
+		}
+	} else if (iflag && exists) {
+		fflush(stdout);
+		(void)fprintf(stderr, "replace %s? ", source);
+
+		first = ch = getchar();
+		while (ch != '\n' && ch != EOF)
+			ch = getchar();
+		if (first != 'y' && first != 'Y') {
+			(void)fprintf(stderr, "not replaced\n");
+			return (1);
+		}
+
+		if (unlink(source)) {
+			warn("%s", source);
+			return (1);
+		}
+	}
+
+	/* Attempt the link. */
+	if ((*linkf)(target, source)) {
+		warn("%s", source);
+		return (1);
+	}
+	if (vflag)
+		(void)printf("%s %c> %s\n", source, linkch, target);
+
+	return (0);
+}
+
+static void
+usage(void)
+{
+
+	(void)fprintf(stderr,
+	    "usage:\t%s [-fhinsv] file1 file2\n\t%s [-fhinsv] file ... directory\n",
+	    getprogname(), getprogname());
+	exit(1);
+	/* NOTREACHED */
+}
diff --git a/toolbox/upstream-netbsd/bin/mv/mv.c b/toolbox/upstream-netbsd/bin/mv/mv.c
new file mode 100644
index 0000000..4be6c30
--- /dev/null
+++ b/toolbox/upstream-netbsd/bin/mv/mv.c
@@ -0,0 +1,396 @@
+/* $NetBSD: mv.c,v 1.43 2011/08/29 14:46:54 joerg Exp $ */
+
+/*
+ * Copyright (c) 1989, 1993, 1994
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Ken Smith of The State University of New York at Buffalo.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+#ifndef lint
+__COPYRIGHT("@(#) Copyright (c) 1989, 1993, 1994\
+ The Regents of the University of California.  All rights reserved.");
+#endif /* not lint */
+
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)mv.c	8.2 (Berkeley) 4/2/94";
+#else
+__RCSID("$NetBSD: mv.c,v 1.43 2011/08/29 14:46:54 joerg Exp $");
+#endif
+#endif /* not lint */
+
+#include <sys/param.h>
+#include <sys/time.h>
+#include <sys/wait.h>
+#include <sys/stat.h>
+#include <sys/extattr.h>
+
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <grp.h>
+#include <locale.h>
+#include <pwd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "pathnames.h"
+
+static int fflg, iflg, vflg;
+static int stdin_ok;
+
+static int	copy(char *, char *);
+static int	do_move(char *, char *);
+static int	fastcopy(char *, char *, struct stat *);
+__dead static void	usage(void);
+
+int
+main(int argc, char *argv[])
+{
+	int ch, len, rval;
+	char *p, *endp;
+	struct stat sb;
+	char path[MAXPATHLEN + 1];
+	size_t baselen;
+
+	setprogname(argv[0]);
+	(void)setlocale(LC_ALL, "");
+
+	while ((ch = getopt(argc, argv, "ifv")) != -1)
+		switch (ch) {
+		case 'i':
+			fflg = 0;
+			iflg = 1;
+			break;
+		case 'f':
+			iflg = 0;
+			fflg = 1;
+			break;
+		case 'v':
+			vflg = 1;
+			break;
+		default:
+			usage();
+		}
+	argc -= optind;
+	argv += optind;
+
+	if (argc < 2)
+		usage();
+
+	stdin_ok = isatty(STDIN_FILENO);
+
+	/*
+	 * If the stat on the target fails or the target isn't a directory,
+	 * try the move.  More than 2 arguments is an error in this case.
+	 */
+	if (stat(argv[argc - 1], &sb) || !S_ISDIR(sb.st_mode)) {
+		if (argc > 2)
+			usage();
+		exit(do_move(argv[0], argv[1]));
+	}
+
+	/* It's a directory, move each file into it. */
+	baselen = strlcpy(path, argv[argc - 1], sizeof(path));
+	if (baselen >= sizeof(path))
+		errx(1, "%s: destination pathname too long", argv[argc - 1]);
+	endp = &path[baselen];
+	if (!baselen || *(endp - 1) != '/') {
+		*endp++ = '/';
+		++baselen;
+	}
+	for (rval = 0; --argc; ++argv) {
+		p = *argv + strlen(*argv) - 1;
+		while (*p == '/' && p != *argv)
+			*p-- = '\0';
+		if ((p = strrchr(*argv, '/')) == NULL)
+			p = *argv;
+		else
+			++p;
+
+		if ((baselen + (len = strlen(p))) >= MAXPATHLEN) {
+			warnx("%s: destination pathname too long", *argv);
+			rval = 1;
+		} else {
+			memmove(endp, p, len + 1);
+			if (do_move(*argv, path))
+				rval = 1;
+		}
+	}
+	exit(rval);
+	/* NOTREACHED */
+}
+
+static int
+do_move(char *from, char *to)
+{
+	struct stat sb;
+	char modep[15];
+
+	/*
+	 * (1)	If the destination path exists, the -f option is not specified
+	 *	and either of the following conditions are true:
+	 *
+	 *	(a) The permissions of the destination path do not permit
+	 *	    writing and the standard input is a terminal.
+	 *	(b) The -i option is specified.
+	 *
+	 *	the mv utility shall write a prompt to standard error and
+	 *	read a line from standard input.  If the response is not
+	 *	affirmative, mv shall do nothing more with the current
+	 *	source file...
+	 */
+	if (!fflg && !access(to, F_OK)) {
+		int ask = 1;
+		int ch;
+
+		if (iflg) {
+			if (access(from, F_OK)) {
+				warn("rename %s", from);
+				return (1);
+			}
+			(void)fprintf(stderr, "overwrite %s? ", to);
+		} else if (stdin_ok && access(to, W_OK) && !stat(to, &sb)) {
+			if (access(from, F_OK)) {
+				warn("rename %s", from);
+				return (1);
+			}
+			strmode(sb.st_mode, modep);
+			(void)fprintf(stderr, "override %s%s%s/%s for %s? ",
+			    modep + 1, modep[9] == ' ' ? "" : " ",
+			    user_from_uid(sb.st_uid, 0),
+			    group_from_gid(sb.st_gid, 0), to);
+		} else
+			ask = 0;
+		if (ask) {
+			if ((ch = getchar()) != EOF && ch != '\n') {
+				int ch2;
+				while ((ch2 = getchar()) != EOF && ch2 != '\n')
+					continue;
+			}
+			if (ch != 'y' && ch != 'Y')
+				return (0);
+		}
+	}
+
+	/*
+	 * (2)	If rename() succeeds, mv shall do nothing more with the
+	 *	current source file.  If it fails for any other reason than
+	 *	EXDEV, mv shall write a diagnostic message to the standard
+	 *	error and do nothing more with the current source file.
+	 *
+	 * (3)	If the destination path exists, and it is a file of type
+	 *	directory and source_file is not a file of type directory,
+	 *	or it is a file not of type directory, and source file is
+	 *	a file of type directory, mv shall write a diagnostic
+	 *	message to standard error, and do nothing more with the
+	 *	current source file...
+	 */
+	if (!rename(from, to)) {
+		if (vflg)
+			printf("%s -> %s\n", from, to);
+		return (0);
+	}
+
+	if (errno != EXDEV) {
+		warn("rename %s to %s", from, to);
+		return (1);
+	}
+
+	/*
+	 * (4)	If the destination path exists, mv shall attempt to remove it.
+	 *	If this fails for any reason, mv shall write a diagnostic
+	 *	message to the standard error and do nothing more with the
+	 *	current source file...
+	 */
+	if (!lstat(to, &sb)) {
+		if ((S_ISDIR(sb.st_mode)) ? rmdir(to) : unlink(to)) {
+			warn("can't remove %s", to);
+			return (1);
+		}
+	}
+
+	/*
+	 * (5)	The file hierarchy rooted in source_file shall be duplicated
+	 *	as a file hierarchy rooted in the destination path...
+	 */
+	if (lstat(from, &sb)) {
+		warn("%s", from);
+		return (1);
+	}
+
+	return (S_ISREG(sb.st_mode) ?
+	    fastcopy(from, to, &sb) : copy(from, to));
+}
+
+static int
+fastcopy(char *from, char *to, struct stat *sbp)
+{
+	struct timeval tval[2];
+	static blksize_t blen;
+	static char *bp;
+	int nread, from_fd, to_fd;
+
+	if ((from_fd = open(from, O_RDONLY, 0)) < 0) {
+		warn("%s", from);
+		return (1);
+	}
+	if ((to_fd =
+	    open(to, O_CREAT | O_TRUNC | O_WRONLY, sbp->st_mode)) < 0) {
+		warn("%s", to);
+		(void)close(from_fd);
+		return (1);
+	}
+	if (!blen && !(bp = malloc(blen = sbp->st_blksize))) {
+		warn(NULL);
+		blen = 0;
+		(void)close(from_fd);
+		(void)close(to_fd);
+		return (1);
+	}
+	while ((nread = read(from_fd, bp, blen)) > 0)
+		if (write(to_fd, bp, nread) != nread) {
+			warn("%s", to);
+			goto err;
+		}
+	if (nread < 0) {
+		warn("%s", from);
+err:		if (unlink(to))
+			warn("%s: remove", to);
+		(void)close(from_fd);
+		(void)close(to_fd);
+		return (1);
+	}
+
+#ifndef __ANDROID__
+	if (fcpxattr(from_fd, to_fd) == -1)
+		warn("%s: error copying extended attributes", to);
+#endif
+
+	(void)close(from_fd);
+#ifdef BSD4_4
+	TIMESPEC_TO_TIMEVAL(&tval[0], &sbp->st_atimespec);
+	TIMESPEC_TO_TIMEVAL(&tval[1], &sbp->st_mtimespec);
+#else
+	tval[0].tv_sec = sbp->st_atime;
+	tval[1].tv_sec = sbp->st_mtime;
+	tval[0].tv_usec = 0;
+	tval[1].tv_usec = 0;
+#endif
+#ifdef __SVR4
+	if (utimes(to, tval))
+#else
+	if (futimes(to_fd, tval))
+#endif
+		warn("%s: set times", to);
+	if (fchown(to_fd, sbp->st_uid, sbp->st_gid)) {
+		if (errno != EPERM)
+			warn("%s: set owner/group", to);
+		sbp->st_mode &= ~(S_ISUID | S_ISGID);
+	}
+	if (fchmod(to_fd, sbp->st_mode))
+		warn("%s: set mode", to);
+#ifndef __ANDROID__
+	if (fchflags(to_fd, sbp->st_flags) && (errno != EOPNOTSUPP))
+		warn("%s: set flags (was: 0%07o)", to, sbp->st_flags);
+#endif
+
+	if (close(to_fd)) {
+		warn("%s", to);
+		return (1);
+	}
+
+	if (unlink(from)) {
+		warn("%s: remove", from);
+		return (1);
+	}
+
+	if (vflg)
+		printf("%s -> %s\n", from, to);
+
+	return (0);
+}
+
+static int
+copy(char *from, char *to)
+{
+	pid_t pid;
+	int status;
+
+	if ((pid = vfork()) == 0) {
+		execl(_PATH_CP, "mv", vflg ? "-PRpv" : "-PRp", "--", from, to, NULL);
+		warn("%s", _PATH_CP);
+		_exit(1);
+	}
+	if (waitpid(pid, &status, 0) == -1) {
+		warn("%s: waitpid", _PATH_CP);
+		return (1);
+	}
+	if (!WIFEXITED(status)) {
+		warnx("%s: did not terminate normally", _PATH_CP);
+		return (1);
+	}
+	if (WEXITSTATUS(status)) {
+		warnx("%s: terminated with %d (non-zero) status",
+		    _PATH_CP, WEXITSTATUS(status));
+		return (1);
+	}
+	if (!(pid = vfork())) {
+		execl(_PATH_RM, "mv", "-rf", "--", from, NULL);
+		warn("%s", _PATH_RM);
+		_exit(1);
+	}
+	if (waitpid(pid, &status, 0) == -1) {
+		warn("%s: waitpid", _PATH_RM);
+		return (1);
+	}
+	if (!WIFEXITED(status)) {
+		warnx("%s: did not terminate normally", _PATH_RM);
+		return (1);
+	}
+	if (WEXITSTATUS(status)) {
+		warnx("%s: terminated with %d (non-zero) status",
+		    _PATH_RM, WEXITSTATUS(status));
+		return (1);
+	}
+	return (0);
+}
+
+static void
+usage(void)
+{
+	(void)fprintf(stderr, "usage: %s [-fiv] source target\n"
+	    "       %s [-fiv] source ... directory\n", getprogname(),
+	    getprogname());
+	exit(1);
+	/* NOTREACHED */
+}
diff --git a/toolbox/cp/extern.h b/toolbox/upstream-netbsd/bin/mv/pathnames.h
similarity index 63%
copy from toolbox/cp/extern.h
copy to toolbox/upstream-netbsd/bin/mv/pathnames.h
index ffbadf7..7838946 100644
--- a/toolbox/cp/extern.h
+++ b/toolbox/upstream-netbsd/bin/mv/pathnames.h
@@ -1,7 +1,7 @@
-/* $NetBSD: extern.h,v 1.17 2012/01/04 15:58:37 christos Exp $ */
+/*	$NetBSD: pathnames.h,v 1.8 2004/08/19 22:26:07 christos Exp $	*/
 
-/*-
- * Copyright (c) 1991, 1993, 1994
+/*
+ * Copyright (c) 1989, 1993
  *	The Regents of the University of California.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -28,34 +28,18 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- *	@(#)extern.h	8.2 (Berkeley) 4/1/94
+ *	@(#)pathnames.h	8.1 (Berkeley) 5/31/93
  */
 
-#ifndef _EXTERN_H_
-#define _EXTERN_H_
-
-typedef struct {
-	char *p_end;			/* pointer to NULL at end of path */
-	char *target_end;		/* pointer to end of target base */
-	char p_path[MAXPATHLEN + 1];	/* pointer to the start of a path */
-} PATH_T;
-
-extern PATH_T to;
-extern uid_t myuid;
-extern int Rflag, rflag, Hflag, Lflag, Pflag, fflag, iflag, lflag, pflag, Nflag;
-extern mode_t myumask;
-extern sig_atomic_t pinfo;
-
-#include <sys/cdefs.h>
-
-__BEGIN_DECLS
-int	copy_fifo(struct stat *, int);
-int	copy_file(FTSENT *, int);
-int	copy_link(FTSENT *, int);
-int	copy_special(struct stat *, int);
-int	set_utimes(const char *, struct stat *);
-int	setfile(struct stat *, int);
-void cp_usage(void) __attribute__((__noreturn__));
-__END_DECLS
-
-#endif /* !_EXTERN_H_ */
+#ifdef __ANDROID__
+#define	_PATH_RM	"/system/bin/rm"
+#define	_PATH_CP	"/system/bin/cp"
+#else
+#ifdef RESCUEDIR
+#define	_PATH_RM	RESCUEDIR "/rm"
+#define	_PATH_CP	RESCUEDIR "/cp"
+#else
+#define	_PATH_RM	"/bin/rm"
+#define	_PATH_CP	"/bin/cp"
+#endif
+#endif
diff --git a/toolbox/upstream-netbsd/bin/rm/rm.c b/toolbox/upstream-netbsd/bin/rm/rm.c
new file mode 100644
index 0000000..f183810
--- /dev/null
+++ b/toolbox/upstream-netbsd/bin/rm/rm.c
@@ -0,0 +1,625 @@
+/* $NetBSD: rm.c,v 1.53 2013/04/26 18:43:22 christos Exp $ */
+
+/*-
+ * Copyright (c) 1990, 1993, 1994, 2003
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+#ifndef lint
+__COPYRIGHT("@(#) Copyright (c) 1990, 1993, 1994\
+ The Regents of the University of California.  All rights reserved.");
+#endif /* not lint */
+
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)rm.c	8.8 (Berkeley) 4/27/95";
+#else
+__RCSID("$NetBSD: rm.c,v 1.53 2013/04/26 18:43:22 christos Exp $");
+#endif
+#endif /* not lint */
+
+#include <sys/param.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <fts.h>
+#include <grp.h>
+#include <locale.h>
+#include <pwd.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+static int dflag, eval, fflag, iflag, Pflag, stdin_ok, vflag, Wflag;
+static int xflag;
+static sig_atomic_t pinfo;
+
+static int	check(char *, char *, struct stat *);
+static void	checkdot(char **);
+static void	progress(int);
+static void	rm_file(char **);
+static int	rm_overwrite(char *, struct stat *);
+static void	rm_tree(char **);
+__dead static void	usage(void);
+
+/*
+ * For the sake of the `-f' flag, check whether an error number indicates the
+ * failure of an operation due to an non-existent file, either per se (ENOENT)
+ * or because its filename argument was illegal (ENAMETOOLONG, ENOTDIR).
+ */
+#define NONEXISTENT(x) \
+    ((x) == ENOENT || (x) == ENAMETOOLONG || (x) == ENOTDIR)
+
+/*
+ * rm --
+ *	This rm is different from historic rm's, but is expected to match
+ *	POSIX 1003.2 behavior.  The most visible difference is that -f
+ *	has two specific effects now, ignore non-existent files and force
+ * 	file removal.
+ */
+int
+main(int argc, char *argv[])
+{
+	int ch, rflag;
+
+	setprogname(argv[0]);
+	(void)setlocale(LC_ALL, "");
+
+	Pflag = rflag = xflag = 0;
+	while ((ch = getopt(argc, argv, "dfiPRrvWx")) != -1)
+		switch (ch) {
+		case 'd':
+			dflag = 1;
+			break;
+		case 'f':
+			fflag = 1;
+			iflag = 0;
+			break;
+		case 'i':
+			fflag = 0;
+			iflag = 1;
+			break;
+		case 'P':
+			Pflag = 1;
+			break;
+		case 'R':
+		case 'r':			/* Compatibility. */
+			rflag = 1;
+			break;
+		case 'v':
+			vflag = 1;
+			break;
+		case 'x':
+			xflag = 1;
+			break;
+#ifndef __ANDROID__
+		case 'W':
+			Wflag = 1;
+			break;
+#endif
+		case '?':
+		default:
+			usage();
+		}
+	argc -= optind;
+	argv += optind;
+
+	if (argc < 1) {
+		if (fflag)
+			return 0;
+		usage();
+	}
+
+	(void)signal(SIGINFO, progress);
+
+	checkdot(argv);
+
+	if (*argv) {
+		stdin_ok = isatty(STDIN_FILENO);
+
+		if (rflag)
+			rm_tree(argv);
+		else
+			rm_file(argv);
+	}
+
+	exit(eval);
+	/* NOTREACHED */
+}
+
+static void
+rm_tree(char **argv)
+{
+	FTS *fts;
+	FTSENT *p;
+	int flags, needstat, rval;
+			
+	/*
+	 * Remove a file hierarchy.  If forcing removal (-f), or interactive
+	 * (-i) or can't ask anyway (stdin_ok), don't stat the file.
+	 */
+	needstat = !fflag && !iflag && stdin_ok;
+
+	/*
+	 * If the -i option is specified, the user can skip on the pre-order
+	 * visit.  The fts_number field flags skipped directories.
+	 */
+#define	SKIPPED	1
+
+	flags = FTS_PHYSICAL;
+	if (!needstat)
+		flags |= FTS_NOSTAT;
+#ifndef __ANDROID__
+	if (Wflag)
+		flags |= FTS_WHITEOUT;
+#endif
+	if (xflag)
+		flags |= FTS_XDEV;
+	if ((fts = fts_open(argv, flags, NULL)) == NULL)
+		err(1, "fts_open failed");
+	while ((p = fts_read(fts)) != NULL) {
+	
+		switch (p->fts_info) {
+		case FTS_DNR:
+			if (!fflag || p->fts_errno != ENOENT) {
+				warnx("%s: %s", p->fts_path,
+						strerror(p->fts_errno));
+				eval = 1;
+			}
+			continue;
+		case FTS_ERR:
+			errx(EXIT_FAILURE, "%s: %s", p->fts_path,
+					strerror(p->fts_errno));
+			/* NOTREACHED */
+		case FTS_NS:
+			/*
+			 * FTS_NS: assume that if can't stat the file, it
+			 * can't be unlinked.
+			 */
+			if (fflag && NONEXISTENT(p->fts_errno))
+				continue;
+			if (needstat) {
+				warnx("%s: %s", p->fts_path,
+						strerror(p->fts_errno));
+				eval = 1;
+				continue;
+			}
+			break;
+		case FTS_D:
+			/* Pre-order: give user chance to skip. */
+			if (!fflag && !check(p->fts_path, p->fts_accpath,
+			    p->fts_statp)) {
+				(void)fts_set(fts, p, FTS_SKIP);
+				p->fts_number = SKIPPED;
+			}
+			continue;
+		case FTS_DP:
+			/* Post-order: see if user skipped. */
+			if (p->fts_number == SKIPPED)
+				continue;
+			break;
+		default:
+			if (!fflag &&
+			    !check(p->fts_path, p->fts_accpath, p->fts_statp))
+				continue;
+		}
+
+		rval = 0;
+		/*
+		 * If we can't read or search the directory, may still be
+		 * able to remove it.  Don't print out the un{read,search}able
+		 * message unless the remove fails.
+		 */
+		switch (p->fts_info) {
+		case FTS_DP:
+		case FTS_DNR:
+			rval = rmdir(p->fts_accpath);
+			if (rval != 0 && fflag && errno == ENOENT)
+				continue;
+			break;
+
+#ifndef __ANDROID__
+		case FTS_W:
+			rval = undelete(p->fts_accpath);
+			if (rval != 0 && fflag && errno == ENOENT)
+				continue;
+			break;
+#endif
+
+		default:
+			if (Pflag) {
+				if (rm_overwrite(p->fts_accpath, NULL))
+					continue;
+			}
+			rval = unlink(p->fts_accpath);
+			if (rval != 0 && fflag && NONEXISTENT(errno))
+				continue;
+			break;
+		}
+		if (rval != 0) {
+			warn("%s", p->fts_path);
+			eval = 1;
+		} else if (vflag || pinfo) {
+			pinfo = 0;
+			(void)printf("%s\n", p->fts_path);
+		}
+	}
+	if (errno)
+		err(1, "fts_read");
+	fts_close(fts);
+}
+
+static void
+rm_file(char **argv)
+{
+	struct stat sb;
+	int rval;
+	char *f;
+
+	/*
+	 * Remove a file.  POSIX 1003.2 states that, by default, attempting
+	 * to remove a directory is an error, so must always stat the file.
+	 */
+	while ((f = *argv++) != NULL) {
+		/* Assume if can't stat the file, can't unlink it. */
+		if (lstat(f, &sb)) {
+#ifndef __ANDROID__
+			if (Wflag) {
+				sb.st_mode = S_IFWHT|S_IWUSR|S_IRUSR;
+			} else {
+#endif
+				if (!fflag || !NONEXISTENT(errno)) {
+					warn("%s", f);
+					eval = 1;
+				}
+				continue;
+#ifndef __ANDROID__
+			}
+		} else if (Wflag) {
+			warnx("%s: %s", f, strerror(EEXIST));
+			eval = 1;
+			continue;
+#endif
+		}
+
+		if (S_ISDIR(sb.st_mode) && !dflag) {
+			warnx("%s: is a directory", f);
+			eval = 1;
+			continue;
+		}
+		if (!fflag && !S_ISWHT(sb.st_mode) && !check(f, f, &sb))
+			continue;
+#ifndef __ANDROID__
+		if (S_ISWHT(sb.st_mode))
+			rval = undelete(f);
+		else if (S_ISDIR(sb.st_mode))
+#else
+		if (S_ISDIR(sb.st_mode))
+#endif
+			rval = rmdir(f);
+		else {
+			if (Pflag) {
+				if (rm_overwrite(f, &sb))
+					continue;
+			}
+			rval = unlink(f);
+		}
+		if (rval && (!fflag || !NONEXISTENT(errno))) {
+			warn("%s", f);
+			eval = 1;
+		}
+		if (vflag && rval == 0)
+			(void)printf("%s\n", f);
+	}
+}
+
+/*
+ * rm_overwrite --
+ *	Overwrite the file 3 times with varying bit patterns.
+ *
+ * This is an expensive way to keep people from recovering files from your
+ * non-snapshotted FFS filesystems using fsdb(8).  Really.  No more.  Only
+ * regular files are deleted, directories (and therefore names) will remain.
+ * Also, this assumes a fixed-block file system (like FFS, or a V7 or a
+ * System V file system).  In a logging file system, you'll have to have
+ * kernel support.
+ *
+ * A note on standards:  U.S. DoD 5220.22-M "National Industrial Security
+ * Program Operating Manual" ("NISPOM") is often cited as a reference
+ * for clearing and sanitizing magnetic media.  In fact, a matrix of
+ * "clearing" and "sanitization" methods for various media was given in
+ * Chapter 8 of the original 1995 version of NISPOM.  However, that
+ * matrix was *removed from the document* when Chapter 8 was rewritten
+ * in Change 2 to the document in 2001.  Recently, the Defense Security
+ * Service has made a revised clearing and sanitization matrix available
+ * in Microsoft Word format on the DSS web site.  The standardization
+ * status of this matrix is unclear.  Furthermore, one must be very
+ * careful when referring to this matrix: it is intended for the "clearing"
+ * prior to reuse or "sanitization" prior to disposal of *entire media*,
+ * not individual files and the only non-physically-destructive method of
+ * "sanitization" that is permitted for magnetic disks of any kind is
+ * specifically noted to be prohibited for media that have contained
+ * Top Secret data.
+ *
+ * It is impossible to actually conform to the exact procedure given in
+ * the matrix if one is overwriting a file, not an entire disk, because
+ * the procedure requires examination and comparison of the disk's defect
+ * lists.  Any program that claims to securely erase *files* while 
+ * conforming to the standard, then, is not correct.  We do as much of
+ * what the standard requires as can actually be done when erasing a
+ * file, rather than an entire disk; but that does not make us conformant.
+ *
+ * Furthermore, the presence of track caches, disk and controller write
+ * caches, and so forth make it extremely difficult to ensure that data
+ * have actually been written to the disk, particularly when one tries
+ * to repeatedly overwrite the same sectors in quick succession.  We call
+ * fsync(), but controllers with nonvolatile cache, as well as IDE disks
+ * that just plain lie about the stable storage of data, will defeat this.
+ *
+ * Finally, widely respected research suggests that the given procedure
+ * is nowhere near sufficient to prevent the recovery of data using special
+ * forensic equipment and techniques that are well-known.  This is 
+ * presumably one reason that the matrix requires physical media destruction,
+ * rather than any technique of the sort attempted here, for secret data.
+ *
+ * Caveat Emptor.
+ *
+ * rm_overwrite will return 0 on success.
+ */
+
+static int
+rm_overwrite(char *file, struct stat *sbp)
+{
+	struct stat sb, sb2;
+	int fd, randint;
+	char randchar;
+
+	fd = -1;
+	if (sbp == NULL) {
+		if (lstat(file, &sb))
+			goto err;
+		sbp = &sb;
+	}
+	if (!S_ISREG(sbp->st_mode))
+		return 0;
+
+	/* flags to try to defeat hidden caching by forcing seeks */
+	if ((fd = open(file, O_RDWR|O_SYNC|O_RSYNC|O_NOFOLLOW, 0)) == -1)
+		goto err;
+
+	if (fstat(fd, &sb2)) {
+		goto err;
+	}
+
+	if (sb2.st_dev != sbp->st_dev || sb2.st_ino != sbp->st_ino ||
+	    !S_ISREG(sb2.st_mode)) {
+		errno = EPERM;
+		goto err;
+	}
+
+#define RAND_BYTES	1
+#define THIS_BYTE	0
+
+#define	WRITE_PASS(mode, byte) do {					\
+	off_t len;							\
+	size_t wlen, i;							\
+	char buf[8 * 1024];						\
+									\
+	if (fsync(fd) || lseek(fd, (off_t)0, SEEK_SET))			\
+		goto err;						\
+									\
+	if (mode == THIS_BYTE)						\
+		memset(buf, byte, sizeof(buf));				\
+	for (len = sbp->st_size; len > 0; len -= wlen) {		\
+		if (mode == RAND_BYTES) {				\
+			for (i = 0; i < sizeof(buf); 			\
+			    i+= sizeof(u_int32_t))			\
+				*(int *)(buf + i) = arc4random();	\
+		}							\
+		wlen = len < (off_t)sizeof(buf) ? (size_t)len : sizeof(buf); \
+		if ((size_t)write(fd, buf, wlen) != wlen)		\
+			goto err;					\
+	}								\
+	sync();		/* another poke at hidden caches */		\
+} while (/* CONSTCOND */ 0)
+
+#define READ_PASS(byte) do {						\
+	off_t len;							\
+	size_t rlen;							\
+	char pattern[8 * 1024];						\
+	char buf[8 * 1024];						\
+									\
+	if (fsync(fd) || lseek(fd, (off_t)0, SEEK_SET))			\
+		goto err;						\
+									\
+	memset(pattern, byte, sizeof(pattern));				\
+	for(len = sbp->st_size; len > 0; len -= rlen) {			\
+		rlen = len < (off_t)sizeof(buf) ? (size_t)len : sizeof(buf); \
+		if((size_t)read(fd, buf, rlen) != rlen)			\
+			goto err;					\
+		if(memcmp(buf, pattern, rlen))				\
+			goto err;					\
+	}								\
+	sync();		/* another poke at hidden caches */		\
+} while (/* CONSTCOND */ 0)
+
+	/*
+	 * DSS sanitization matrix "clear" for magnetic disks: 
+	 * option 'c' "Overwrite all addressable locations with a single 
+	 * character."
+	 */
+	randint = arc4random();
+	randchar = *(char *)&randint;
+	WRITE_PASS(THIS_BYTE, randchar);
+
+	/*
+	 * DSS sanitization matrix "sanitize" for magnetic disks: 
+	 * option 'd', sub 2 "Overwrite all addressable locations with a
+	 * character, then its complement.  Verify "complement" character
+	 * was written successfully to all addressable locations, then
+	 * overwrite all addressable locations with random characters; or
+	 * verify third overwrite of random characters."  The rest of the
+	 * text in d-sub-2 specifies requirements for overwriting spared
+	 * sectors; we cannot conform to it when erasing only a file, thus
+	 * we do not conform to the standard.
+	 */
+
+	/* 1. "a character" */
+	WRITE_PASS(THIS_BYTE, 0xff);
+
+	/* 2. "its complement" */
+	WRITE_PASS(THIS_BYTE, 0x00);
+
+	/* 3. "Verify 'complement' character" */
+	READ_PASS(0x00);
+
+	/* 4. "overwrite all addressable locations with random characters" */
+
+	WRITE_PASS(RAND_BYTES, 0x00);
+
+	/*
+	 * As the file might be huge, and we note that this revision of
+	 * the matrix says "random characters", not "a random character"
+	 * as the original did, we do not verify the random-character
+	 * write; the "or" in the standard allows this.
+	 */
+
+	if (close(fd) == -1) {
+		fd = -1;
+		goto err;
+	}
+
+	return 0;
+
+err:	eval = 1;
+	warn("%s", file);
+	if (fd != -1)
+		close(fd);
+	return 1;
+}
+
+static int
+check(char *path, char *name, struct stat *sp)
+{
+	int ch, first;
+	char modep[15];
+
+	/* Check -i first. */
+	if (iflag)
+		(void)fprintf(stderr, "remove '%s'? ", path);
+	else {
+		/*
+		 * If it's not a symbolic link and it's unwritable and we're
+		 * talking to a terminal, ask.  Symbolic links are excluded
+		 * because their permissions are meaningless.  Check stdin_ok
+		 * first because we may not have stat'ed the file.
+		 */
+		if (!stdin_ok || S_ISLNK(sp->st_mode) ||
+		    !(access(name, W_OK) && (errno != ETXTBSY)))
+			return (1);
+		strmode(sp->st_mode, modep);
+		if (Pflag) {
+			warnx(
+			    "%s: -P was specified but file could not"
+			    " be overwritten", path);
+			return 0;
+		}
+		(void)fprintf(stderr, "override %s%s%s:%s for '%s'? ",
+		    modep + 1, modep[9] == ' ' ? "" : " ",
+		    user_from_uid(sp->st_uid, 0),
+		    group_from_gid(sp->st_gid, 0), path);
+	}
+	(void)fflush(stderr);
+
+	first = ch = getchar();
+	while (ch != '\n' && ch != EOF)
+		ch = getchar();
+	return (first == 'y' || first == 'Y');
+}
+
+/*
+ * POSIX.2 requires that if "." or ".." are specified as the basename
+ * portion of an operand, a diagnostic message be written to standard
+ * error and nothing more be done with such operands.
+ *
+ * Since POSIX.2 defines basename as the final portion of a path after
+ * trailing slashes have been removed, we'll remove them here.
+ */
+#define ISDOT(a) ((a)[0] == '.' && (!(a)[1] || ((a)[1] == '.' && !(a)[2])))
+static void
+checkdot(char **argv)
+{
+	char *p, **save, **t;
+	int complained;
+
+	complained = 0;
+	for (t = argv; *t;) {
+		/* strip trailing slashes */
+		p = strrchr(*t, '\0');
+		while (--p > *t && *p == '/')
+			*p = '\0';
+
+		/* extract basename */
+		if ((p = strrchr(*t, '/')) != NULL)
+			++p;
+		else
+			p = *t;
+
+		if (ISDOT(p)) {
+			if (!complained++)
+				warnx("\".\" and \"..\" may not be removed");
+			eval = 1;
+			for (save = t; (t[0] = t[1]) != NULL; ++t)
+				continue;
+			t = save;
+		} else
+			++t;
+	}
+}
+
+static void
+usage(void)
+{
+
+	(void)fprintf(stderr, "usage: %s [-f|-i] [-dPRrvWx] file ...\n",
+	    getprogname());
+	exit(1);
+	/* NOTREACHED */
+}
+
+static void
+progress(int sig __unused)
+{
+	
+	pinfo++;
+}
diff --git a/toolbox/upstream-netbsd/bin/rmdir/rmdir.c b/toolbox/upstream-netbsd/bin/rmdir/rmdir.c
new file mode 100644
index 0000000..03261ce
--- /dev/null
+++ b/toolbox/upstream-netbsd/bin/rmdir/rmdir.c
@@ -0,0 +1,121 @@
+/* $NetBSD: rmdir.c,v 1.26 2011/08/29 14:49:38 joerg Exp $ */
+
+/*-
+ * Copyright (c) 1992, 1993, 1994
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+#ifndef lint
+__COPYRIGHT("@(#) Copyright (c) 1992, 1993, 1994\
+ The Regents of the University of California.  All rights reserved.");
+#endif /* not lint */
+
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)rmdir.c	8.3 (Berkeley) 4/2/94";
+#else
+__RCSID("$NetBSD: rmdir.c,v 1.26 2011/08/29 14:49:38 joerg Exp $");
+#endif
+#endif /* not lint */
+
+#include <sys/param.h>
+
+#include <err.h>
+#include <locale.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+static int	rm_path(char *);
+__dead static void	usage(void);
+
+int
+main(int argc, char *argv[])
+{
+	int ch, errors, pflag;
+
+	setprogname(argv[0]);
+	(void)setlocale(LC_ALL, "");
+
+	pflag = 0;
+	while ((ch = getopt(argc, argv, "p")) != -1)
+		switch(ch) {
+		case 'p':
+			pflag = 1;
+			break;
+		case '?':
+		default:
+			usage();
+		}
+	argc -= optind;
+	argv += optind;
+
+	if (argc == 0)
+		usage();
+
+	for (errors = 0; *argv; argv++) {
+		/* We rely on the kernel to ignore trailing '/' characters. */
+		if (rmdir(*argv) < 0) {
+			warn("%s", *argv);
+			errors = 1;
+		} else if (pflag)
+			errors |= rm_path(*argv);
+	}
+
+	exit(errors);
+	/* NOTREACHED */
+}
+
+static int
+rm_path(char *path)
+{
+	char *p;
+
+	while ((p = strrchr(path, '/')) != NULL) {
+		*p = 0;
+		if (p[1] == 0)
+			/* Ignore trailing '/' on deleted name */
+			continue;
+
+		if (rmdir(path) < 0) {
+			warn("%s", path);
+			return (1);
+		}
+	}
+
+	return (0);
+}
+
+static void
+usage(void)
+{
+	(void)fprintf(stderr, "usage: %s [-p] directory ...\n", getprogname());
+	exit(1);
+	/* NOTREACHED */
+}
diff --git a/toolbox/upstream-netbsd/bin/sleep/sleep.c b/toolbox/upstream-netbsd/bin/sleep/sleep.c
new file mode 100644
index 0000000..4349af4
--- /dev/null
+++ b/toolbox/upstream-netbsd/bin/sleep/sleep.c
@@ -0,0 +1,159 @@
+/* $NetBSD: sleep.c,v 1.24 2011/08/29 14:51:19 joerg Exp $ */
+
+/*
+ * Copyright (c) 1988, 1993, 1994
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+#ifndef lint
+__COPYRIGHT("@(#) Copyright (c) 1988, 1993, 1994\
+ The Regents of the University of California.  All rights reserved.");
+#endif /* not lint */
+
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)sleep.c	8.3 (Berkeley) 4/2/94";
+#else
+__RCSID("$NetBSD: sleep.c,v 1.24 2011/08/29 14:51:19 joerg Exp $");
+#endif
+#endif /* not lint */
+
+#include <ctype.h>
+#include <err.h>
+#include <locale.h>
+#include <math.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <unistd.h>
+
+__dead static void alarmhandle(int);
+__dead static void usage(void);
+
+static volatile sig_atomic_t report_requested;
+static void
+report_request(int signo __unused)
+{
+
+	report_requested = 1;
+}
+
+int
+main(int argc, char *argv[])
+{
+	char *arg, *temp;
+	double fval, ival, val;
+	struct timespec ntime;
+	time_t original;
+	int ch, fracflag, rv;
+
+	setprogname(argv[0]);
+	(void)setlocale(LC_ALL, "");
+
+	(void)signal(SIGALRM, alarmhandle);
+
+	while ((ch = getopt(argc, argv, "")) != -1)
+		switch(ch) {
+		default:
+			usage();
+		}
+	argc -= optind;
+	argv += optind;
+
+	if (argc != 1)
+		usage();
+
+	/*
+	 * Okay, why not just use atof for everything? Why bother
+	 * checking if there is a fraction in use? Because the old
+	 * sleep handled the full range of integers, that's why, and a
+	 * double can't handle a large long. This is fairly useless
+	 * given how large a number a double can hold on most
+	 * machines, but now we won't ever have trouble. If you want
+	 * 1000000000.9 seconds of sleep, well, that's your
+	 * problem. Why use an isdigit() check instead of checking for
+	 * a period? Because doing it this way means locales will be
+	 * handled transparently by the atof code.
+	 */
+	fracflag = 0;
+	arg = *argv;
+	for (temp = arg; *temp != '\0'; temp++)
+		if (!isdigit((unsigned char)*temp))
+			fracflag++;
+
+	if (fracflag) {
+		val = atof(arg);
+		if (val <= 0)
+			usage();
+		ival = floor(val);
+		fval = (1000000000 * (val-ival));
+		ntime.tv_sec = ival;
+		ntime.tv_nsec = fval;
+	}
+	else {
+		ntime.tv_sec = atol(arg);
+		if (ntime.tv_sec <= 0)
+			return EXIT_SUCCESS;
+		ntime.tv_nsec = 0;
+	}
+
+	original = ntime.tv_sec;
+	signal(SIGINFO, report_request);
+	while ((rv = nanosleep(&ntime, &ntime)) != 0) {
+		if (report_requested) {
+		/* Reporting does not bother with nanoseconds. */
+			warnx("about %d second(s) left out of the original %d",
+			(int)ntime.tv_sec, (int)original);
+			report_requested = 0;
+		} else
+			break;
+	}
+
+	if (rv == -1)
+		err(EXIT_FAILURE, "nanosleep failed");
+
+	return EXIT_SUCCESS;
+	/* NOTREACHED */
+}
+
+static void
+usage(void)
+{
+	(void)fprintf(stderr, "usage: %s seconds\n", getprogname());
+	exit(EXIT_FAILURE);
+	/* NOTREACHED */
+}
+
+/* ARGSUSED */
+static void
+alarmhandle(int i)
+{
+	_exit(EXIT_SUCCESS);
+	/* NOTREACHED */
+}
diff --git a/toolbox/cp/extern.h b/toolbox/upstream-netbsd/bin/sync/sync.c
similarity index 64%
copy from toolbox/cp/extern.h
copy to toolbox/upstream-netbsd/bin/sync/sync.c
index ffbadf7..2b9c367 100644
--- a/toolbox/cp/extern.h
+++ b/toolbox/upstream-netbsd/bin/sync/sync.c
@@ -1,7 +1,7 @@
-/* $NetBSD: extern.h,v 1.17 2012/01/04 15:58:37 christos Exp $ */
+/* $NetBSD: sync.c,v 1.13 2008/07/20 00:52:40 lukem Exp $ */
 
-/*-
- * Copyright (c) 1991, 1993, 1994
+/*
+ * Copyright (c) 1987, 1993
  *	The Regents of the University of California.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -27,35 +27,33 @@
  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
- *
- *	@(#)extern.h	8.2 (Berkeley) 4/1/94
  */
 
-#ifndef _EXTERN_H_
-#define _EXTERN_H_
-
-typedef struct {
-	char *p_end;			/* pointer to NULL at end of path */
-	char *target_end;		/* pointer to end of target base */
-	char p_path[MAXPATHLEN + 1];	/* pointer to the start of a path */
-} PATH_T;
-
-extern PATH_T to;
-extern uid_t myuid;
-extern int Rflag, rflag, Hflag, Lflag, Pflag, fflag, iflag, lflag, pflag, Nflag;
-extern mode_t myumask;
-extern sig_atomic_t pinfo;
-
 #include <sys/cdefs.h>
+#ifndef lint
+__COPYRIGHT("@(#) Copyright (c) 1987, 1993\
+ The Regents of the University of California.  All rights reserved.");
+#endif /* not lint */
 
-__BEGIN_DECLS
-int	copy_fifo(struct stat *, int);
-int	copy_file(FTSENT *, int);
-int	copy_link(FTSENT *, int);
-int	copy_special(struct stat *, int);
-int	set_utimes(const char *, struct stat *);
-int	setfile(struct stat *, int);
-void cp_usage(void) __attribute__((__noreturn__));
-__END_DECLS
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)sync.c	8.1 (Berkeley) 5/31/93";
+#else
+__RCSID("$NetBSD: sync.c,v 1.13 2008/07/20 00:52:40 lukem Exp $");
+#endif
+#endif /* not lint */
 
-#endif /* !_EXTERN_H_ */
+#include <stdlib.h>
+#include <unistd.h>
+
+int main(int, char *[]);
+
+/* ARGSUSED */
+int
+main(int argc, char *argv[])
+{
+	setprogname(argv[0]);
+	sync();
+	exit(0);
+	/* NOTREACHED */
+}
diff --git a/toolbox/upstream-netbsd/include/namespace.h b/toolbox/upstream-netbsd/include/namespace.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/toolbox/upstream-netbsd/include/namespace.h
diff --git a/toolbox/upstream-netbsd/include/sys/extattr.h b/toolbox/upstream-netbsd/include/sys/extattr.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/toolbox/upstream-netbsd/include/sys/extattr.h
diff --git a/toolbox/upstream-netbsd/include/sys/mtio.h b/toolbox/upstream-netbsd/include/sys/mtio.h
new file mode 100644
index 0000000..8fb5655
--- /dev/null
+++ b/toolbox/upstream-netbsd/include/sys/mtio.h
@@ -0,0 +1 @@
+#include <linux/mtio.h>
diff --git a/toolbox/upstream-netbsd/lib/libc/gen/getbsize.c b/toolbox/upstream-netbsd/lib/libc/gen/getbsize.c
new file mode 100644
index 0000000..a9ce2c1
--- /dev/null
+++ b/toolbox/upstream-netbsd/lib/libc/gen/getbsize.c
@@ -0,0 +1,118 @@
+/*	$NetBSD: getbsize.c,v 1.17 2012/06/25 22:32:43 abs Exp $	*/
+
+/*-
+ * Copyright (c) 1991, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char sccsid[] = "@(#)getbsize.c	8.1 (Berkeley) 6/4/93";
+#else
+__RCSID("$NetBSD: getbsize.c,v 1.17 2012/06/25 22:32:43 abs Exp $");
+#endif
+#endif /* not lint */
+
+#include "namespace.h"
+
+#include <assert.h>
+#include <err.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef __weak_alias
+__weak_alias(getbsize,_getbsize)
+#endif
+
+char *
+getbsize(int *headerlenp, long *blocksizep)
+{
+	static char header[20];
+	long n, max, mul, blocksize;
+	char *ep, *p;
+	const char *form;
+
+#define	KB	(1024L)
+#define	MB	(1024L * 1024L)
+#define	GB	(1024L * 1024L * 1024L)
+#define	MAXB	GB		/* No tera, peta, nor exa. */
+	form = "";
+	if ((p = getenv("BLOCKSIZE")) != NULL && *p != '\0') {
+		if ((n = strtol(p, &ep, 10)) < 0)
+			goto underflow;
+		if (n == 0)
+			n = 1;
+		if (*ep && ep[1])
+			goto fmterr;
+		switch (*ep) {
+		case 'G': case 'g':
+			form = "G";
+			max = MAXB / GB;
+			mul = GB;
+			break;
+		case 'K': case 'k':
+			form = "K";
+			max = MAXB / KB;
+			mul = KB;
+			break;
+		case 'M': case 'm':
+			form = "M";
+			max = MAXB / MB;
+			mul = MB;
+			break;
+		case '\0':
+			max = MAXB;
+			mul = 1;
+			break;
+		default:
+fmterr:			warnx("%s: unknown blocksize", p);
+			n = 512;
+			mul = 1;
+			max = 0;
+			break;
+		}
+		if (n > max) {
+			warnx("maximum blocksize is %ldG", MAXB / GB);
+			n = max;
+		}
+		if ((blocksize = n * mul) < 512) {
+underflow:		warnx("%s: minimum blocksize is 512", p);
+			form = "";
+			blocksize = n = 512;
+		}
+	} else
+		blocksize = n = 512;
+
+	if (headerlenp)
+		*headerlenp =
+		    snprintf(header, sizeof(header), "%ld%s-blocks", n, form);
+	if (blocksizep)
+		*blocksizep = blocksize;
+	return (header);
+}
diff --git a/toolbox/upstream-netbsd/lib/libc/gen/humanize_number.c b/toolbox/upstream-netbsd/lib/libc/gen/humanize_number.c
new file mode 100644
index 0000000..533560f
--- /dev/null
+++ b/toolbox/upstream-netbsd/lib/libc/gen/humanize_number.c
@@ -0,0 +1,161 @@
+/*	$NetBSD: humanize_number.c,v 1.16 2012/03/17 20:01:14 christos Exp $	*/
+
+/*
+ * Copyright (c) 1997, 1998, 1999, 2002 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
+ * NASA Ames Research Center, by Luke Mewburn and by Tomas Svensson.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+__RCSID("$NetBSD: humanize_number.c,v 1.16 2012/03/17 20:01:14 christos Exp $");
+#endif /* LIBC_SCCS and not lint */
+
+#include "namespace.h"
+#include <assert.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <locale.h>
+
+int
+humanize_number(char *buf, size_t len, int64_t bytes,
+    const char *suffix, int scale, int flags)
+{
+	const char *prefixes, *sep;
+	int	b, r, s1, s2, sign;
+	int64_t	divisor, max, post = 1;
+	size_t	i, baselen, maxscale;
+
+	_DIAGASSERT(buf != NULL);
+	_DIAGASSERT(suffix != NULL);
+	_DIAGASSERT(scale >= 0);
+
+	if (flags & HN_DIVISOR_1000) {
+		/* SI for decimal multiplies */
+		divisor = 1000;
+		if (flags & HN_B)
+			prefixes = "B\0k\0M\0G\0T\0P\0E";
+		else
+			prefixes = "\0\0k\0M\0G\0T\0P\0E";
+	} else {
+		/*
+		 * binary multiplies
+		 * XXX IEC 60027-2 recommends Ki, Mi, Gi...
+		 */
+		divisor = 1024;
+		if (flags & HN_B)
+			prefixes = "B\0K\0M\0G\0T\0P\0E";
+		else
+			prefixes = "\0\0K\0M\0G\0T\0P\0E";
+	}
+
+#define	SCALE2PREFIX(scale)	(&prefixes[(scale) << 1])
+	maxscale = 7;
+
+	if ((size_t)scale >= maxscale &&
+	    (scale & (HN_AUTOSCALE | HN_GETSCALE)) == 0)
+		return (-1);
+
+	if (buf == NULL || suffix == NULL)
+		return (-1);
+
+	if (len > 0)
+		buf[0] = '\0';
+	if (bytes < 0) {
+		sign = -1;
+		baselen = 3;		/* sign, digit, prefix */
+		if (-bytes < INT64_MAX / 100)
+			bytes *= -100;
+		else {
+			bytes = -bytes;
+			post = 100;
+			baselen += 2;
+		}
+	} else {
+		sign = 1;
+		baselen = 2;		/* digit, prefix */
+		if (bytes < INT64_MAX / 100)
+			bytes *= 100;
+		else {
+			post = 100;
+			baselen += 2;
+		}
+	}
+	if (flags & HN_NOSPACE)
+		sep = "";
+	else {
+		sep = " ";
+		baselen++;
+	}
+	baselen += strlen(suffix);
+
+	/* Check if enough room for `x y' + suffix + `\0' */
+	if (len < baselen + 1)
+		return (-1);
+
+	if (scale & (HN_AUTOSCALE | HN_GETSCALE)) {
+		/* See if there is additional columns can be used. */
+		for (max = 100, i = len - baselen; i-- > 0;)
+			max *= 10;
+
+		/*
+		 * Divide the number until it fits the given column.
+		 * If there will be an overflow by the rounding below,
+		 * divide once more.
+		 */
+		for (i = 0; bytes >= max - 50 && i < maxscale; i++)
+			bytes /= divisor;
+
+		if (scale & HN_GETSCALE) {
+			_DIAGASSERT(__type_fit(int, i));
+			return (int)i;
+		}
+	} else
+		for (i = 0; i < (size_t)scale && i < maxscale; i++)
+			bytes /= divisor;
+	bytes *= post;
+
+	/* If a value <= 9.9 after rounding and ... */
+	if (bytes < 995 && i > 0 && flags & HN_DECIMAL) {
+		/* baselen + \0 + .N */
+		if (len < baselen + 1 + 2)
+			return (-1);
+		b = ((int)bytes + 5) / 10;
+		s1 = b / 10;
+		s2 = b % 10;
+		r = snprintf(buf, len, "%d%s%d%s%s%s",
+		    sign * s1, localeconv()->decimal_point, s2,
+		    sep, SCALE2PREFIX(i), suffix);
+	} else
+		r = snprintf(buf, len, "%" PRId64 "%s%s%s",
+		    sign * ((bytes + 50) / 100),
+		    sep, SCALE2PREFIX(i), suffix);
+
+	return (r);
+}
diff --git a/toolbox/upstream-netbsd/lib/libc/stdlib/strsuftoll.c b/toolbox/upstream-netbsd/lib/libc/stdlib/strsuftoll.c
new file mode 100644
index 0000000..80fc52f
--- /dev/null
+++ b/toolbox/upstream-netbsd/lib/libc/stdlib/strsuftoll.c
@@ -0,0 +1,249 @@
+/*	$NetBSD: strsuftoll.c,v 1.9 2011/10/22 22:08:47 christos Exp $	*/
+/*-
+ * Copyright (c) 2001-2002,2004 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Luke Mewburn.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+/*-
+ * Copyright (c) 1991, 1993, 1994
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Keith Muller of the University of California, San Diego and Lance
+ * Visser of Convex Computer Corporation.
+ *
+ * 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(LIBC_SCCS) && !defined(lint)
+__RCSID("$NetBSD: strsuftoll.c,v 1.9 2011/10/22 22:08:47 christos Exp $");
+#endif /* LIBC_SCCS and not lint */
+
+#ifdef _LIBC
+#include "namespace.h"
+#endif
+
+#if !HAVE_STRSUFTOLL
+
+#include <sys/types.h>
+#include <sys/time.h>
+
+#include <assert.h>
+#include <ctype.h>
+#include <err.h>
+#include <errno.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef _LIBC
+# ifdef __weak_alias
+__weak_alias(strsuftoll, _strsuftoll)
+__weak_alias(strsuftollx, _strsuftollx)
+# endif
+#endif /* LIBC */
+
+/*
+ * Convert an expression of the following forms to a (u)int64_t.
+ * 	1) A positive decimal number.
+ *	2) A positive decimal number followed by a b (mult by 512).
+ *	3) A positive decimal number followed by a k (mult by 1024).
+ *	4) A positive decimal number followed by a m (mult by 1048576).
+ *	5) A positive decimal number followed by a g (mult by 1073741824).
+ *	6) A positive decimal number followed by a t (mult by 1099511627776).
+ *	7) A positive decimal number followed by a w (mult by sizeof int)
+ *	8) Two or more positive decimal numbers (with/without k,b or w).
+ *	   separated by x (also * for backwards compatibility), specifying
+ *	   the product of the indicated values.
+ * Returns the result upon successful conversion, or exits with an
+ * appropriate error.
+ * 
+ */
+/* LONGLONG */
+long long
+strsuftoll(const char *desc, const char *val,
+    long long min, long long max)
+{
+	long long result;
+	char	errbuf[100];
+
+	result = strsuftollx(desc, val, min, max, errbuf, sizeof(errbuf));
+	if (*errbuf != '\0')
+		errx(EXIT_FAILURE, "%s", errbuf);
+	return result;
+}
+
+/*
+ * As strsuftoll(), but returns the error message into the provided buffer
+ * rather than exiting with it.
+ */
+/* LONGLONG */
+static long long
+__strsuftollx(const char *desc, const char *val,
+    long long min, long long max, char *ebuf, size_t ebuflen, size_t depth)
+{
+	long long num, t;
+	char	*expr;
+
+	_DIAGASSERT(desc != NULL);
+	_DIAGASSERT(val != NULL);
+	_DIAGASSERT(ebuf != NULL);
+
+	if (depth > 16) {
+		snprintf(ebuf, ebuflen, "%s: Recursion limit exceeded", desc);
+		return 0;
+	}
+
+	while (isspace((unsigned char)*val))	/* Skip leading space */
+		val++;
+
+	errno = 0;
+	num = strtoll(val, &expr, 10);
+	if (errno == ERANGE)
+		goto erange;			/* Overflow */
+
+	if (expr == val)			/* No digits */
+		goto badnum;
+
+	switch (*expr) {
+	case 'b':
+		t = num;
+		num *= 512;			/* 1 block */
+		if (t > num)
+			goto erange;
+		++expr;
+		break;
+	case 'k':
+		t = num;
+		num *= 1024;			/* 1 kibibyte */
+		if (t > num)
+			goto erange;
+		++expr;
+		break;
+	case 'm':
+		t = num;
+		num *= 1048576;			/* 1 mebibyte */
+		if (t > num)
+			goto erange;
+		++expr;
+		break;
+	case 'g':
+		t = num;
+		num *= 1073741824;		/* 1 gibibyte */
+		if (t > num)
+			goto erange;
+		++expr;
+		break;
+	case 't':
+		t = num;
+		num *= 1099511627776LL;		/* 1 tebibyte */
+		if (t > num)
+			goto erange;
+		++expr;
+		break;
+	case 'w':
+		t = num;
+		num *= sizeof(int);		/* 1 word */
+		if (t > num)
+			goto erange;
+		++expr;
+		break;
+	}
+
+	switch (*expr) {
+	case '\0':
+		break;
+	case '*':				/* Backward compatible */
+	case 'x':
+		t = num;
+		num *= __strsuftollx(desc, expr + 1, min, max, ebuf, ebuflen,
+			depth + 1);
+		if (*ebuf != '\0')
+			return 0;
+		if (t > num) {
+ erange:	 	
+			errno = ERANGE;
+			snprintf(ebuf, ebuflen, "%s: %s", desc, strerror(errno));
+			return 0;
+		}
+		break;
+	default:
+ badnum:
+		snprintf(ebuf, ebuflen, "%s `%s': illegal number", desc, val);
+		return 0;
+	}
+	if (num < min) {
+		/* LONGLONG */
+		snprintf(ebuf, ebuflen, "%s %lld is less than %lld.",
+		    desc, (long long)num, (long long)min);
+		return 0;
+	}
+	if (num > max) {
+		/* LONGLONG */
+		snprintf(ebuf, ebuflen, "%s %lld is greater than %lld.",
+		    desc, (long long)num, (long long)max);
+		return 0;
+	}
+	*ebuf = '\0';
+	return num;
+}
+
+long long
+strsuftollx(const char *desc, const char *val,
+    long long min, long long max, char *ebuf, size_t ebuflen)
+{
+	return __strsuftollx(desc, val, min, max, ebuf, ebuflen, 0);
+}
+#endif /* !HAVE_STRSUFTOLL */
diff --git a/toolbox/cp/extern.h b/toolbox/upstream-netbsd/lib/libc/string/swab.c
similarity index 61%
copy from toolbox/cp/extern.h
copy to toolbox/upstream-netbsd/lib/libc/string/swab.c
index ffbadf7..392b186 100644
--- a/toolbox/cp/extern.h
+++ b/toolbox/upstream-netbsd/lib/libc/string/swab.c
@@ -1,9 +1,12 @@
-/* $NetBSD: extern.h,v 1.17 2012/01/04 15:58:37 christos Exp $ */
+/*	$NetBSD: swab.c,v 1.18 2011/01/04 17:14:07 martin Exp $	*/
 
-/*-
- * Copyright (c) 1991, 1993, 1994
+/*
+ * Copyright (c) 1988, 1993
  *	The Regents of the University of California.  All rights reserved.
  *
+ * This code is derived from software contributed to Berkeley by
+ * Jeffrey Mogul.
+ *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
@@ -27,35 +30,51 @@
  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
- *
- *	@(#)extern.h	8.2 (Berkeley) 4/1/94
  */
 
-#ifndef _EXTERN_H_
-#define _EXTERN_H_
-
-typedef struct {
-	char *p_end;			/* pointer to NULL at end of path */
-	char *target_end;		/* pointer to end of target base */
-	char p_path[MAXPATHLEN + 1];	/* pointer to the start of a path */
-} PATH_T;
-
-extern PATH_T to;
-extern uid_t myuid;
-extern int Rflag, rflag, Hflag, Lflag, Pflag, fflag, iflag, lflag, pflag, Nflag;
-extern mode_t myumask;
-extern sig_atomic_t pinfo;
-
 #include <sys/cdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char sccsid[] = "@(#)swab.c	8.1 (Berkeley) 6/4/93";
+#else
+__RCSID("$NetBSD: swab.c,v 1.18 2011/01/04 17:14:07 martin Exp $");
+#endif
+#endif /* LIBC_SCCS and not lint */
 
-__BEGIN_DECLS
-int	copy_fifo(struct stat *, int);
-int	copy_file(FTSENT *, int);
-int	copy_link(FTSENT *, int);
-int	copy_special(struct stat *, int);
-int	set_utimes(const char *, struct stat *);
-int	setfile(struct stat *, int);
-void cp_usage(void) __attribute__((__noreturn__));
-__END_DECLS
+#include <assert.h>
+#include <unistd.h>
 
-#endif /* !_EXTERN_H_ */
+void
+swab(const void * __restrict from, void * __restrict to, ssize_t len)
+{
+	char temp;
+	const char *fp;
+	char *tp;
+
+	if (len <= 1)
+		return;
+
+	_DIAGASSERT(from != NULL);
+	_DIAGASSERT(to != NULL);
+
+	len /= 2;
+	fp = (const char *)from;
+	tp = (char *)to;
+#define	STEP	temp = *fp++,*tp++ = *fp++,*tp++ = temp
+
+	if (__predict_false(len == 1)) {
+		STEP;
+		return;
+	}
+
+	/* round to multiple of 8 */
+	while ((--len % 8) != 0)
+		STEP;
+	len /= 8;
+	if (len == 0)
+		return;
+	while (len-- != 0) {
+		STEP; STEP; STEP; STEP;
+		STEP; STEP; STEP; STEP;
+	}
+}
diff --git a/toolbox/upstream-netbsd/lib/libutil/raise_default_signal.c b/toolbox/upstream-netbsd/lib/libutil/raise_default_signal.c
new file mode 100644
index 0000000..50cffd4
--- /dev/null
+++ b/toolbox/upstream-netbsd/lib/libutil/raise_default_signal.c
@@ -0,0 +1,117 @@
+/*	$NetBSD: raise_default_signal.c,v 1.3 2008/04/28 20:23:03 martin Exp $	 */
+
+/*-
+ * Copyright (c) 2007 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Luke Mewburn.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#if HAVE_NBTOOL_CONFIG_H
+#include "nbtool_config.h"
+#endif
+
+#include <sys/cdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+__RCSID("$NetBSD: raise_default_signal.c,v 1.3 2008/04/28 20:23:03 martin Exp $");
+#endif
+
+#include <errno.h>
+#include <signal.h>
+#include <stdio.h>
+#include <string.h>
+#include <util.h>
+
+#if ! HAVE_RAISE_DEFAULT_SIGNAL
+/*
+ * raise_default_signal sig
+ *	Raise the default signal handler for sig, by
+ *	- block all signals
+ *	- set the signal handler to SIG_DFL
+ *	- raise the signal
+ *	- unblock the signal to deliver it
+ *
+ *	The original signal mask and signal handler is restored on exit
+ *	(whether successful or not).
+ *
+ *	Returns 0 on success, or -1 on failure with errno set to
+ *	on of the values for sigemptyset(), sigaddset(), sigprocmask(),
+ *	sigaction(), or raise().
+ */
+int
+raise_default_signal(int sig)
+{
+	struct sigaction origact, act;
+	sigset_t origmask, fullmask, mask;
+	int retval, oerrno;
+
+	retval = -1;
+
+		/* Setup data structures */
+		/* XXX memset(3) isn't async-safe according to signal(7) */
+	(void)memset(&act, 0, sizeof(act));
+	act.sa_handler = SIG_DFL;
+	act.sa_flags = 0;
+	if ((sigemptyset(&act.sa_mask) == -1) ||
+	    (sigfillset(&fullmask) == -1) ||
+	    (sigemptyset(&mask) == -1) ||
+	    (sigaddset(&mask, sig) == -1))
+		goto restore_none;
+
+		/* Block all signals */
+	if (sigprocmask(SIG_BLOCK, &fullmask, &origmask) == -1)
+		goto restore_none;
+		/* (use 'goto restore_mask' to restore state) */
+
+		/* Enable the SIG_DFL handler */
+	if (sigaction(sig, &act, &origact) == -1)
+		goto restore_mask;
+		/* (use 'goto restore_act' to restore state) */
+
+		/* Raise the signal, and unblock the signal to deliver it */
+	if ((raise(sig) == -1) ||
+	    (sigprocmask(SIG_UNBLOCK, &mask, NULL) == -1))
+		goto restore_act;
+
+		/* Flag successful raise() */
+	retval = 0;
+
+		/* Restore the original handler */
+ restore_act:
+	oerrno = errno;
+	(void)sigaction(sig, &origact, NULL);
+	errno = oerrno;
+
+		/* Restore the original mask */
+ restore_mask:
+	oerrno = errno;
+	(void)sigprocmask(SIG_SETMASK, &origmask, NULL);
+	errno = oerrno;
+
+ restore_none:
+	return retval;
+}
+
+#endif	/* ! HAVE_RAISE_DEFAULT_SIGNAL */
diff --git a/toolbox/chown.c b/toolbox/upstream-netbsd/sbin/chown/chown.c
similarity index 99%
rename from toolbox/chown.c
rename to toolbox/upstream-netbsd/sbin/chown/chown.c
index 6ac2233..ee46eee 100644
--- a/toolbox/chown.c
+++ b/toolbox/upstream-netbsd/sbin/chown/chown.c
@@ -78,7 +78,7 @@
 };
 
 int
-chown_main(int argc, char **argv)
+main(int argc, char **argv)
 {
 	FTS *ftsp;
 	FTSENT *p;
diff --git a/toolbox/du.c b/toolbox/upstream-netbsd/usr.bin/du/du.c
similarity index 80%
rename from toolbox/du.c
rename to toolbox/upstream-netbsd/usr.bin/du/du.c
index c8beba5..086ac4a 100644
--- a/toolbox/du.c
+++ b/toolbox/upstream-netbsd/usr.bin/du/du.c
@@ -1,4 +1,4 @@
-/*	$NetBSD: du.c,v 1.33 2008/07/30 22:03:40 dsl Exp $	*/
+/*	$NetBSD: du.c,v 1.36 2012/03/11 11:23:20 shattered Exp $	*/
 
 /*
  * Copyright (c) 1989, 1993, 1994
@@ -42,10 +42,11 @@
 #if 0
 static char sccsid[] = "@(#)du.c	8.5 (Berkeley) 5/4/95";
 #else
-__RCSID("$NetBSD: du.c,v 1.33 2008/07/30 22:03:40 dsl Exp $");
+__RCSID("$NetBSD: du.c,v 1.36 2012/03/11 11:23:20 shattered Exp $");
 #endif
 #endif /* not lint */
 
+#include <sys/param.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 
@@ -53,6 +54,7 @@
 #include <err.h>
 #include <errno.h>
 #include <fts.h>
+#include <inttypes.h>
 #include <util.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -60,30 +62,32 @@
 #include <unistd.h>
 #include <limits.h>
 
-int	linkchk(dev_t, ino_t);
-void	prstat(const char *, int64_t);
-static void	usage(void);
+/* Count inodes or file size */
+#define	COUNT	(iflag ? 1 : p->fts_statp->st_blocks)
 
-long blocksize;
+static int	linkchk(dev_t, ino_t);
+static void	prstat(const char *, int64_t);
+__dead static void	usage(void);
 
-#define howmany(x, y)   (((x)+((y)-1))/(y))
+static int hflag, iflag;
+static long blocksize;
 
 int
-du_main(int argc, char *argv[])
+main(int argc, char *argv[])
 {
 	FTS *fts;
 	FTSENT *p;
 	int64_t totalblocks;
 	int ftsoptions, listfiles;
 	int depth;
-	int Hflag, Lflag, aflag, ch, cflag, dflag, gkmflag, rval, sflag;
+	int Hflag, Lflag, aflag, ch, cflag, dflag, gkmflag, nflag, rval, sflag;
 	const char *noargv[2];
 
-	Hflag = Lflag = aflag = cflag = dflag = gkmflag = sflag = 0;
+	Hflag = Lflag = aflag = cflag = dflag = gkmflag = nflag = sflag = 0;
 	totalblocks = 0;
 	ftsoptions = FTS_PHYSICAL;
 	depth = INT_MAX;
-	while ((ch = getopt(argc, argv, "HLPacd:ghkmnrsx")) != -1)
+	while ((ch = getopt(argc, argv, "HLPacd:ghikmnrsx")) != -1)
 		switch (ch) {
 		case 'H':
 			Hflag = 1;
@@ -115,6 +119,12 @@
 			blocksize = 1024 * 1024 * 1024;
 			gkmflag = 1;
 			break;
+		case 'h':
+			hflag = 1;
+			break;
+		case 'i':
+			iflag = 1;
+			break;
 		case 'k':
 			blocksize = 1024;
 			gkmflag = 1;
@@ -123,6 +133,9 @@
 			blocksize = 1024 * 1024;
 			gkmflag = 1;
 			break; 
+		case 'n':
+			nflag = 1;
+			break;
 		case 'r':
 			break;
 		case 's':
@@ -175,21 +188,36 @@
 	}
 
 	if (!gkmflag)
-		blocksize = 512;
+		(void)getbsize(NULL, &blocksize);
 	blocksize /= 512;
 
 	if ((fts = fts_open(argv, ftsoptions, NULL)) == NULL)
 		err(1, "fts_open `%s'", *argv);
 
 	for (rval = 0; (p = fts_read(fts)) != NULL;) {
+#ifndef __ANDROID__
+		if (nflag) {
+			switch (p->fts_info) {
+			case FTS_NS:
+			case FTS_SLNONE:
+				/* nothing */
+				break;
+			default:
+				if (p->fts_statp->st_flags & UF_NODUMP) {
+					fts_set(fts, p, FTS_SKIP);
+					continue;
+				}
+			}
+		}
+#endif
 		switch (p->fts_info) {
 		case FTS_D:			/* Ignore. */
 			break;
 		case FTS_DP:
 			p->fts_parent->fts_number += 
-			    p->fts_number += p->fts_statp->st_blocks;
+			    p->fts_number += COUNT;
 			if (cflag)
-				totalblocks += p->fts_statp->st_blocks;
+				totalblocks += COUNT;
 			/*
 			 * If listing each directory, or not listing files
 			 * or directories and this is post-order of the
@@ -216,10 +244,10 @@
 			 * the root of a traversal, display the total.
 			 */
 			if (listfiles || !p->fts_level)
-				prstat(p->fts_path, p->fts_statp->st_blocks);
-			p->fts_parent->fts_number += p->fts_statp->st_blocks;
+				prstat(p->fts_path, COUNT);
+			p->fts_parent->fts_number += COUNT;
 			if (cflag)
-				totalblocks += p->fts_statp->st_blocks;
+				totalblocks += COUNT;
 		}
 	}
 	if (errno)
@@ -229,15 +257,29 @@
 	exit(rval);
 }
 
-void
+static void
 prstat(const char *fname, int64_t blocks)
 {
-	(void)printf("%lld\t%s\n",
-	    (long long)howmany(blocks, (int64_t)blocksize),
-	    fname);
+	if (iflag) {
+		(void)printf("%" PRId64 "\t%s\n", blocks, fname);
+		return;
+	}
+
+	if (hflag) {
+		char buf[5];
+		int64_t sz = blocks * 512;
+
+		humanize_number(buf, sizeof(buf), sz, "", HN_AUTOSCALE,
+		    HN_B | HN_NOSPACE | HN_DECIMAL);
+
+		(void)printf("%s\t%s\n", buf, fname);
+	} else
+		(void)printf("%" PRId64 "\t%s\n",
+		    howmany(blocks, (int64_t)blocksize),
+		    fname);
 }
 
-int
+static int
 linkchk(dev_t dev, ino_t ino)
 {
 	static struct entry {
@@ -317,6 +359,6 @@
 {
 
 	(void)fprintf(stderr,
-		"usage: du [-H | -L | -P] [-a | -d depth | -s] [-cgkmrx] [file ...]\n");
+		"usage: du [-H | -L | -P] [-a | -d depth | -s] [-cghikmnrx] [file ...]\n");
 	exit(1);
 }
diff --git a/toolbox/grep/fastgrep.c b/toolbox/upstream-netbsd/usr.bin/grep/fastgrep.c
similarity index 100%
rename from toolbox/grep/fastgrep.c
rename to toolbox/upstream-netbsd/usr.bin/grep/fastgrep.c
diff --git a/toolbox/grep/file.c b/toolbox/upstream-netbsd/usr.bin/grep/file.c
similarity index 97%
rename from toolbox/grep/file.c
rename to toolbox/upstream-netbsd/usr.bin/grep/file.c
index d28dff5..da03d71 100644
--- a/toolbox/grep/file.c
+++ b/toolbox/upstream-netbsd/usr.bin/grep/file.c
@@ -41,7 +41,7 @@
 #include <sys/types.h>
 #include <sys/stat.h>
 
-#ifndef ANDROID
+#ifndef __ANDROID__
 #include <bzlib.h>
 #endif
 #include <err.h>
@@ -53,7 +53,7 @@
 #include <unistd.h>
 #include <wchar.h>
 #include <wctype.h>
-#ifndef ANDROID
+#ifndef __ANDROID__
 #include <zlib.h>
 #endif
 
@@ -62,7 +62,7 @@
 #define	MAXBUFSIZ	(32 * 1024)
 #define	LNBUFBUMP	80
 
-#ifndef ANDROID
+#ifndef __ANDROID__
 static gzFile gzbufdesc;
 static BZFILE* bzbufdesc;
 #endif
@@ -78,14 +78,12 @@
 grep_refill(struct file *f)
 {
 	ssize_t nr;
-#ifndef ANDROID
 	int bzerr;
-#endif
 
 	bufpos = buffer;
 	bufrem = 0;
 
-#ifndef ANDROID
+#ifndef __ANDROID__
 	if (filebehave == FILE_GZIP)
 		nr = gzread(gzbufdesc, buffer, MAXBUFSIZ);
 	else if (filebehave == FILE_BZIP && bzbufdesc != NULL) {
@@ -204,7 +202,7 @@
 grep_file_init(struct file *f)
 {
 
-#ifndef ANDROID
+#ifndef __ANDROID__
 	if (filebehave == FILE_GZIP &&
 	    (gzbufdesc = gzdopen(f->fd, "r")) == NULL)
 		goto error;
diff --git a/toolbox/grep/grep.c b/toolbox/upstream-netbsd/usr.bin/grep/grep.c
similarity index 97%
rename from toolbox/grep/grep.c
rename to toolbox/upstream-netbsd/usr.bin/grep/grep.c
index 7b2c487..1ea6ed3 100644
--- a/toolbox/grep/grep.c
+++ b/toolbox/upstream-netbsd/usr.bin/grep/grep.c
@@ -1,4 +1,4 @@
-/*	$NetBSD: grep.c,v 1.11 2012/05/06 22:27:00 joerg Exp $	*/
+/*	$NetBSD: grep.c,v 1.12 2014/07/11 16:30:45 christos Exp $	*/
 /* 	$FreeBSD: head/usr.bin/grep/grep.c 211519 2010-08-19 22:55:17Z delphij $	*/
 /*	$OpenBSD: grep.c,v 1.42 2010/07/02 22:18:03 tedu Exp $	*/
 
@@ -34,7 +34,7 @@
 #endif
 
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: grep.c,v 1.11 2012/05/06 22:27:00 joerg Exp $");
+__RCSID("$NetBSD: grep.c,v 1.12 2014/07/11 16:30:45 christos Exp $");
 
 #include <sys/stat.h>
 #include <sys/types.h>
@@ -159,7 +159,6 @@
 {
 	fprintf(stderr, getstr(4), __progname);
 	fprintf(stderr, "%s", getstr(5));
-	fprintf(stderr, "%s", getstr(5));
 	fprintf(stderr, "%s", getstr(6));
 	fprintf(stderr, "%s", getstr(7));
 	exit(2);
@@ -312,7 +311,7 @@
 }
 
 int
-grep_main(int argc, char *argv[])
+main(int argc, char *argv[])
 {
 	char **aargv, **eargv, *eopts;
 	char *ep;
@@ -403,7 +402,7 @@
 				Aflag = 0;
 			else if (Aflag > LLONG_MAX / 10) {
 				errno = ERANGE;
-				err(2, "%llu", Aflag);
+				err(2, NULL);
 			}
 			Aflag = Bflag = (Aflag * 10) + (c - '0');
 			break;
@@ -420,10 +419,10 @@
 			l = strtoull(optarg, &ep, 10);
 			if (((errno == ERANGE) && (l == ULLONG_MAX)) ||
 			    ((errno == EINVAL) && (l == 0)))
-				err(2, "strtoull");
+				err(2, NULL);
 			else if (ep[0] != '\0') {
 				errno = EINVAL;
-				err(2, "empty");
+				err(2, NULL);
 			}
 			if (c == 'A')
 				Aflag = l;
@@ -509,10 +508,10 @@
 			mcount = strtoull(optarg, &ep, 10);
 			if (((errno == ERANGE) && (mcount == ULLONG_MAX)) ||
 			    ((errno == EINVAL) && (mcount == 0)))
-				err(2, "strtoull");
+				err(2, NULL);
 			else if (ep[0] != '\0') {
 				errno = EINVAL;
-				err(2, "empty");
+				err(2, NULL);
 			}
 			break;
 		case 'n':
diff --git a/toolbox/grep/grep.h b/toolbox/upstream-netbsd/usr.bin/grep/grep.h
similarity index 97%
rename from toolbox/grep/grep.h
rename to toolbox/upstream-netbsd/usr.bin/grep/grep.h
index 6454f93..fa2a3e3 100644
--- a/toolbox/grep/grep.h
+++ b/toolbox/upstream-netbsd/usr.bin/grep/grep.h
@@ -29,18 +29,14 @@
  * SUCH DAMAGE.
  */
 
-#ifdef ANDROID
-#define WITHOUT_NLS
-#endif
-
-#ifndef ANDROID
+#ifndef __ANDROID__
 #include <bzlib.h>
 #endif
 #include <limits.h>
 #include <regex.h>
 #include <stdbool.h>
 #include <stdio.h>
-#ifndef ANDROID
+#ifndef __ANDROID__
 #include <zlib.h>
 #endif
 
diff --git a/toolbox/grep/queue.c b/toolbox/upstream-netbsd/usr.bin/grep/queue.c
similarity index 100%
rename from toolbox/grep/queue.c
rename to toolbox/upstream-netbsd/usr.bin/grep/queue.c
diff --git a/toolbox/grep/util.c b/toolbox/upstream-netbsd/usr.bin/grep/util.c
similarity index 96%
rename from toolbox/grep/util.c
rename to toolbox/upstream-netbsd/usr.bin/grep/util.c
index 5712fee..ecd948d 100644
--- a/toolbox/grep/util.c
+++ b/toolbox/upstream-netbsd/usr.bin/grep/util.c
@@ -1,4 +1,4 @@
-/*	$NetBSD: util.c,v 1.16 2012/05/06 22:32:05 joerg Exp $	*/
+/*	$NetBSD: util.c,v 1.17 2013/01/21 03:24:43 msaitoh Exp $	*/
 /*	$FreeBSD: head/usr.bin/grep/util.c 211496 2010-08-19 09:28:59Z des $	*/
 /*	$OpenBSD: util.c,v 1.39 2010/07/02 22:18:03 tedu Exp $	*/
 
@@ -34,7 +34,7 @@
 #endif
 
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: util.c,v 1.16 2012/05/06 22:32:05 joerg Exp $");
+__RCSID("$NetBSD: util.c,v 1.17 2013/01/21 03:24:43 msaitoh Exp $");
 
 #include <sys/stat.h>
 #include <sys/types.h>
@@ -74,9 +74,10 @@
 	for (i = 0; i < fpatterns; ++i) {
 		if (fnmatch(fpattern[i].pat, fname, 0) == 0 ||
 		    fnmatch(fpattern[i].pat, fname_base, 0) == 0) {
-			if (fpattern[i].mode == EXCL_PAT)
+			if (fpattern[i].mode == EXCL_PAT) {
+				free(fname_copy);
 				return (false);
-			else
+			} else
 				ret = true;
 		}
 	}
@@ -128,7 +129,7 @@
 		break;
 	default:
 		fts_flags = FTS_LOGICAL;
-
+			
 	}
 
 	fts_flags |= FTS_NOSTAT | FTS_NOCHDIR;
@@ -273,7 +274,7 @@
 	return (c);
 }
 
-#define iswword(x)	(iswalnum((wint_t)(x)) || (x) == L'_')
+#define iswword(x)	(iswalnum((x)) || (x) == L'_')
 
 /*
  * Processes a line comparing it with the specified patterns.  Each pattern
@@ -474,13 +475,13 @@
 			if (!oflag)
 				fwrite(line->dat + a, matches[i].rm_so - a, 1,
 				    stdout);
-			if (color)
+			if (color) 
 				fprintf(stdout, "\33[%sm\33[K", color);
 
-				fwrite(line->dat + matches[i].rm_so,
+				fwrite(line->dat + matches[i].rm_so, 
 				    matches[i].rm_eo - matches[i].rm_so, 1,
 				    stdout);
-			if (color)
+			if (color) 
 				fprintf(stdout, "\33[m\33[K");
 			a = matches[i].rm_eo;
 			if (oflag)
diff --git a/toolbox/upstream-netbsd/usr.bin/printenv/printenv.c b/toolbox/upstream-netbsd/usr.bin/printenv/printenv.c
new file mode 100644
index 0000000..e15384f
--- /dev/null
+++ b/toolbox/upstream-netbsd/usr.bin/printenv/printenv.c
@@ -0,0 +1,102 @@
+/*	$NetBSD: printenv.c,v 1.12 2011/09/06 18:26:55 joerg Exp $	*/
+
+/*
+ * Copyright (c) 1987, 1993
+ *    The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+#ifndef lint
+__COPYRIGHT("@(#) Copyright (c) 1987, 1993\
+ The Regents of the University of California.  All rights reserved.");
+#endif /* not lint */
+
+#ifndef lint
+/*static char sccsid[] = "from: @(#)printenv.c	8.2 (Berkeley) 5/4/95";*/
+__RCSID("$NetBSD: printenv.c,v 1.12 2011/09/06 18:26:55 joerg Exp $");
+#endif /* not lint */
+
+#include <sys/types.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <err.h>
+
+__dead static void usage(void);
+
+/*
+ * printenv
+ *
+ * Bill Joy, UCB
+ * February, 1979
+ */
+int
+main(int argc, char *argv[])
+{
+	extern char **environ;
+	char *cp, **ep;
+	size_t len;
+	int ch;
+
+	while ((ch = getopt(argc, argv, "")) != -1)
+		switch(ch) {
+		case '?':
+		default:
+			usage();
+		}
+	argc -= optind;
+	argv += optind;
+
+	if (argc == 0) {
+		for (ep = environ; *ep; ep++)
+			(void)printf("%s\n", *ep);
+		exit(0);
+	}
+	if (argc != 1)
+		usage();
+	if (strchr(*argv, '=') != NULL)
+		errx(1, "Invalid environment variable %s", *argv);
+	len = strlen(*argv);
+	for (ep = environ; *ep; ep++)
+		if (!memcmp(*ep, *argv, len)) {
+			cp = *ep + len;
+			if (!*cp || *cp == '=') {
+				(void)printf("%s\n", *cp ? cp + 1 : cp);
+				exit(0);
+			}
+		}
+	exit(1);
+}
+
+static void
+usage(void)
+{
+	(void)fprintf(stderr, "Usage: printenv [name]\n");
+	exit(1);
+}