Merge "Fix build when TARGET_USERIMAGES_USE_EXT4 is not defined"
diff --git a/Android.mk b/Android.mk
index 4eb18aa..e360c6b 100644
--- a/Android.mk
+++ b/Android.mk
@@ -64,6 +64,7 @@
     libmtdutils \
     libmincrypt \
     libminadbd \
+    libadb \
     libfusesideload \
     libminui \
     libpng \
@@ -94,7 +95,6 @@
 endif
 
 LOCAL_C_INCLUDES += system/extras/ext4_utils
-LOCAL_C_INCLUDES += external/openssl/include
 
 include $(BUILD_EXECUTABLE)
 
diff --git a/adb_install.cpp b/adb_install.cpp
index be3b9a0..e328960 100644
--- a/adb_install.cpp
+++ b/adb_install.cpp
@@ -61,9 +61,7 @@
 
 static void
 maybe_restart_adbd() {
-    char value[PROPERTY_VALUE_MAX+1];
-    int len = property_get("ro.debuggable", value, NULL);
-    if (len == 1 && value[0] == '1') {
+    if (is_ro_debuggable()) {
         ui->Print("Restarting adbd...\n");
         set_usb_driver(true);
         property_set("ctl.start", "adbd");
diff --git a/applypatch/bspatch.c b/applypatch/bspatch.c
index b34ec2a..b57760e 100644
--- a/applypatch/bspatch.c
+++ b/applypatch/bspatch.c
@@ -23,6 +23,7 @@
 #include <stdio.h>
 #include <sys/stat.h>
 #include <errno.h>
+#include <malloc.h>
 #include <unistd.h>
 #include <string.h>
 
diff --git a/applypatch/imgpatch.c b/applypatch/imgpatch.c
index 33c4487..09b0a73 100644
--- a/applypatch/imgpatch.c
+++ b/applypatch/imgpatch.c
@@ -21,6 +21,7 @@
 #include <sys/cdefs.h>
 #include <sys/stat.h>
 #include <errno.h>
+#include <malloc.h>
 #include <unistd.h>
 #include <string.h>
 
diff --git a/asn1_decoder.cpp b/asn1_decoder.cpp
index 7280f74..e7aef78 100644
--- a/asn1_decoder.cpp
+++ b/asn1_decoder.cpp
@@ -14,6 +14,7 @@
  * limitations under the License.
  */
 
+#include <malloc.h>
 #include <stdint.h>
 #include <string.h>
 
diff --git a/common.h b/common.h
index 768f499..4f1c099 100644
--- a/common.h
+++ b/common.h
@@ -17,6 +17,7 @@
 #ifndef RECOVERY_COMMON_H
 #define RECOVERY_COMMON_H
 
+#include <stdbool.h>
 #include <stdio.h>
 #include <stdarg.h>
 
@@ -46,6 +47,8 @@
 
 void ui_print(const char* format, ...);
 
+bool is_ro_debuggable();
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/edify/Android.mk b/edify/Android.mk
index 61ed6fa..03c04e4 100644
--- a/edify/Android.mk
+++ b/edify/Android.mk
@@ -7,9 +7,10 @@
 	parser.y \
 	expr.c
 
-# "-x c" forces the lex/yacc files to be compiled as c;
-# the build system otherwise forces them to be c++.
-edify_cflags := -x c
+# "-x c" forces the lex/yacc files to be compiled as c the build system
+# otherwise forces them to be c++. Need to also add an explicit -std because the
+# build system will soon default C++ to -std=c++11.
+edify_cflags := -x c -std=gnu89
 
 #
 # Build the host-side command line tool
diff --git a/edify/main.c b/edify/main.c
index b3fad53..b1baa0b 100644
--- a/edify/main.c
+++ b/edify/main.c
@@ -25,13 +25,12 @@
 
 int expect(const char* expr_str, const char* expected, int* errors) {
     Expr* e;
-    int error;
     char* result;
 
     printf(".");
 
     int error_count = parse_string(expr_str, &e, &error_count);
-    if (error > 0 || error_count > 0) {
+    if (error_count > 0) {
         printf("error parsing \"%s\" (%d errors)\n",
                expr_str, error_count);
         ++*errors;
diff --git a/fuse_sdcard_provider.c b/fuse_sdcard_provider.c
index 19fb52d..ca8c914 100644
--- a/fuse_sdcard_provider.c
+++ b/fuse_sdcard_provider.c
@@ -16,6 +16,7 @@
 
 #include <stdlib.h>
 #include <stdio.h>
+#include <string.h>
 #include <errno.h>
 #include <pthread.h>
 #include <sys/mount.h>
diff --git a/install.cpp b/install.cpp
index 9db5640..31606bb 100644
--- a/install.cpp
+++ b/install.cpp
@@ -18,6 +18,7 @@
 #include <errno.h>
 #include <fcntl.h>
 #include <limits.h>
+#include <string.h>
 #include <sys/stat.h>
 #include <sys/wait.h>
 #include <unistd.h>
diff --git a/minadbd/Android.mk b/minadbd/Android.mk
index 04956d8..c077157 100644
--- a/minadbd/Android.mk
+++ b/minadbd/Android.mk
@@ -12,7 +12,6 @@
 
 LOCAL_SRC_FILES := \
 	adb.c \
-	fdevent.c \
 	fuse_adb_provider.c \
 	transport.c \
 	transport_usb.c \
@@ -27,6 +26,4 @@
 
 LOCAL_MODULE := libminadbd
 
-LOCAL_STATIC_LIBRARIES := libfusesideload libcutils libc
-
 include $(BUILD_STATIC_LIBRARY)
diff --git a/minadbd/adb.c b/minadbd/adb.c
index 127d072..0ac16e4 100644
--- a/minadbd/adb.c
+++ b/minadbd/adb.c
@@ -379,7 +379,7 @@
 int adb_main()
 {
     atexit(adb_cleanup);
-#if defined(HAVE_FORKEXEC)
+#if !defined(_WIN32)
     // No SIGCHLD. Let the service subproc handle its children.
     signal(SIGPIPE, SIG_IGN);
 #endif
diff --git a/minadbd/fdevent.c b/minadbd/fdevent.c
deleted file mode 100644
index 5c374a7..0000000
--- a/minadbd/fdevent.c
+++ /dev/null
@@ -1,695 +0,0 @@
-/* http://frotznet.googlecode.com/svn/trunk/utils/fdevent.c
-**
-** Copyright 2006, Brian Swetland <swetland@frotz.net>
-**
-** 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 <sys/ioctl.h>
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#include <errno.h>
-
-#include <fcntl.h>
-
-#include <stdarg.h>
-#include <stddef.h>
-
-#include "fdevent.h"
-#include "transport.h"
-#include "sysdeps.h"
-
-
-/* !!! Do not enable DEBUG for the adb that will run as the server:
-** both stdout and stderr are used to communicate between the client
-** and server. Any extra output will cause failures.
-*/
-#define DEBUG 0   /* non-0 will break adb server */
-
-// This socket is used when a subproc shell service exists.
-// It wakes up the fdevent_loop() and cause the correct handling
-// of the shell's pseudo-tty master. I.e. force close it.
-int SHELL_EXIT_NOTIFY_FD = -1;
-
-static void fatal(const char *fn, const char *fmt, ...)
-{
-    va_list ap;
-    va_start(ap, fmt);
-    fprintf(stderr, "%s:", fn);
-    vfprintf(stderr, fmt, ap);
-    va_end(ap);
-    abort();
-}
-
-#define FATAL(x...) fatal(__FUNCTION__, x)
-
-#if DEBUG
-#define D(...) \
-    do { \
-        adb_mutex_lock(&D_lock);               \
-        int save_errno = errno;                \
-        fprintf(stderr, "%s::%s():", __FILE__, __FUNCTION__);  \
-        errno = save_errno;                    \
-        fprintf(stderr, __VA_ARGS__);          \
-        adb_mutex_unlock(&D_lock);             \
-        errno = save_errno;                    \
-    } while(0)
-static void dump_fde(fdevent *fde, const char *info)
-{
-    adb_mutex_lock(&D_lock);
-    fprintf(stderr,"FDE #%03d %c%c%c %s\n", fde->fd,
-            fde->state & FDE_READ ? 'R' : ' ',
-            fde->state & FDE_WRITE ? 'W' : ' ',
-            fde->state & FDE_ERROR ? 'E' : ' ',
-            info);
-    adb_mutex_unlock(&D_lock);
-}
-#else
-#define D(...) ((void)0)
-#define dump_fde(fde, info) do { } while(0)
-#endif
-
-#define FDE_EVENTMASK  0x00ff
-#define FDE_STATEMASK  0xff00
-
-#define FDE_ACTIVE     0x0100
-#define FDE_PENDING    0x0200
-#define FDE_CREATED    0x0400
-
-static void fdevent_plist_enqueue(fdevent *node);
-static void fdevent_plist_remove(fdevent *node);
-static fdevent *fdevent_plist_dequeue(void);
-static void fdevent_subproc_event_func(int fd, unsigned events, void *userdata);
-
-static fdevent list_pending = {
-    .next = &list_pending,
-    .prev = &list_pending,
-};
-
-static fdevent **fd_table = 0;
-static int fd_table_max = 0;
-
-#ifdef CRAPTASTIC
-//HAVE_EPOLL
-
-#include <sys/epoll.h>
-
-static int epoll_fd = -1;
-
-static void fdevent_init()
-{
-        /* XXX: what's a good size for the passed in hint? */
-    epoll_fd = epoll_create(256);
-
-    if(epoll_fd < 0) {
-        perror("epoll_create() failed");
-        exit(1);
-    }
-
-        /* mark for close-on-exec */
-    fcntl(epoll_fd, F_SETFD, FD_CLOEXEC);
-}
-
-static void fdevent_connect(fdevent *fde)
-{
-    struct epoll_event ev;
-
-    memset(&ev, 0, sizeof(ev));
-    ev.events = 0;
-    ev.data.ptr = fde;
-
-#if 0
-    if(epoll_ctl(epoll_fd, EPOLL_CTL_ADD, fde->fd, &ev)) {
-        perror("epoll_ctl() failed\n");
-        exit(1);
-    }
-#endif
-}
-
-static void fdevent_disconnect(fdevent *fde)
-{
-    struct epoll_event ev;
-
-    memset(&ev, 0, sizeof(ev));
-    ev.events = 0;
-    ev.data.ptr = fde;
-
-        /* technically we only need to delete if we
-        ** were actively monitoring events, but let's
-        ** be aggressive and do it anyway, just in case
-        ** something's out of sync
-        */
-    epoll_ctl(epoll_fd, EPOLL_CTL_DEL, fde->fd, &ev);
-}
-
-static void fdevent_update(fdevent *fde, unsigned events)
-{
-    struct epoll_event ev;
-    int active;
-
-    active = (fde->state & FDE_EVENTMASK) != 0;
-
-    memset(&ev, 0, sizeof(ev));
-    ev.events = 0;
-    ev.data.ptr = fde;
-
-    if(events & FDE_READ) ev.events |= EPOLLIN;
-    if(events & FDE_WRITE) ev.events |= EPOLLOUT;
-    if(events & FDE_ERROR) ev.events |= (EPOLLERR | EPOLLHUP);
-
-    fde->state = (fde->state & FDE_STATEMASK) | events;
-
-    if(active) {
-            /* we're already active. if we're changing to *no*
-            ** events being monitored, we need to delete, otherwise
-            ** we need to just modify
-            */
-        if(ev.events) {
-            if(epoll_ctl(epoll_fd, EPOLL_CTL_MOD, fde->fd, &ev)) {
-                perror("epoll_ctl() failed\n");
-                exit(1);
-            }
-        } else {
-            if(epoll_ctl(epoll_fd, EPOLL_CTL_DEL, fde->fd, &ev)) {
-                perror("epoll_ctl() failed\n");
-                exit(1);
-            }
-        }
-    } else {
-            /* we're not active.  if we're watching events, we need
-            ** to add, otherwise we can just do nothing
-            */
-        if(ev.events) {
-            if(epoll_ctl(epoll_fd, EPOLL_CTL_ADD, fde->fd, &ev)) {
-                perror("epoll_ctl() failed\n");
-                exit(1);
-            }
-        }
-    }
-}
-
-static void fdevent_process()
-{
-    struct epoll_event events[256];
-    fdevent *fde;
-    int i, n;
-
-    n = epoll_wait(epoll_fd, events, 256, -1);
-
-    if(n < 0) {
-        if(errno == EINTR) return;
-        perror("epoll_wait");
-        exit(1);
-    }
-
-    for(i = 0; i < n; i++) {
-        struct epoll_event *ev = events + i;
-        fde = ev->data.ptr;
-
-        if(ev->events & EPOLLIN) {
-            fde->events |= FDE_READ;
-        }
-        if(ev->events & EPOLLOUT) {
-            fde->events |= FDE_WRITE;
-        }
-        if(ev->events & (EPOLLERR | EPOLLHUP)) {
-            fde->events |= FDE_ERROR;
-        }
-        if(fde->events) {
-            if(fde->state & FDE_PENDING) continue;
-            fde->state |= FDE_PENDING;
-            fdevent_plist_enqueue(fde);
-        }
-    }
-}
-
-#else /* USE_SELECT */
-
-#ifdef HAVE_WINSOCK
-#include <winsock2.h>
-#else
-#include <sys/select.h>
-#endif
-
-static fd_set read_fds;
-static fd_set write_fds;
-static fd_set error_fds;
-
-static int select_n = 0;
-
-static void fdevent_init(void)
-{
-    FD_ZERO(&read_fds);
-    FD_ZERO(&write_fds);
-    FD_ZERO(&error_fds);
-}
-
-static void fdevent_connect(fdevent *fde)
-{
-    if(fde->fd >= select_n) {
-        select_n = fde->fd + 1;
-    }
-}
-
-static void fdevent_disconnect(fdevent *fde)
-{
-    int i, n;
-
-    FD_CLR(fde->fd, &read_fds);
-    FD_CLR(fde->fd, &write_fds);
-    FD_CLR(fde->fd, &error_fds);
-
-    for(n = 0, i = 0; i < select_n; i++) {
-        if(fd_table[i] != 0) n = i;
-    }
-    select_n = n + 1;
-}
-
-static void fdevent_update(fdevent *fde, unsigned events)
-{
-    if(events & FDE_READ) {
-        FD_SET(fde->fd, &read_fds);
-    } else {
-        FD_CLR(fde->fd, &read_fds);
-    }
-    if(events & FDE_WRITE) {
-        FD_SET(fde->fd, &write_fds);
-    } else {
-        FD_CLR(fde->fd, &write_fds);
-    }
-    if(events & FDE_ERROR) {
-        FD_SET(fde->fd, &error_fds);
-    } else {
-        FD_CLR(fde->fd, &error_fds);
-    }
-
-    fde->state = (fde->state & FDE_STATEMASK) | events;
-}
-
-/* Looks at fd_table[] for bad FDs and sets bit in fds.
-** Returns the number of bad FDs.
-*/
-static int fdevent_fd_check(fd_set *fds)
-{
-    int i, n = 0;
-    fdevent *fde;
-
-    for(i = 0; i < select_n; i++) {
-        fde = fd_table[i];
-        if(fde == 0) continue;
-        if(fcntl(i, F_GETFL, NULL) < 0) {
-            FD_SET(i, fds);
-            n++;
-            // fde->state |= FDE_DONT_CLOSE;
-
-        }
-    }
-    return n;
-}
-
-#if !DEBUG
-static inline void dump_all_fds(const char *extra_msg) {}
-#else
-static void dump_all_fds(const char *extra_msg)
-{
-int i;
-    fdevent *fde;
-    // per fd: 4 digits (but really: log10(FD_SETSIZE)), 1 staus, 1 blank
-    char msg_buff[FD_SETSIZE*6 + 1], *pb=msg_buff;
-    size_t max_chars = FD_SETSIZE * 6 + 1;
-    int printed_out;
-#define SAFE_SPRINTF(...)                                                    \
-    do {                                                                     \
-        printed_out = snprintf(pb, max_chars, __VA_ARGS__);                  \
-        if (printed_out <= 0) {                                              \
-            D("... snprintf failed.\n");                                     \
-            return;                                                          \
-        }                                                                    \
-        if (max_chars < (unsigned int)printed_out) {                         \
-            D("... snprintf out of space.\n");                               \
-            return;                                                          \
-        }                                                                    \
-        pb += printed_out;                                                   \
-        max_chars -= printed_out;                                            \
-    } while(0)
-
-    for(i = 0; i < select_n; i++) {
-        fde = fd_table[i];
-        SAFE_SPRINTF("%d", i);
-        if(fde == 0) {
-            SAFE_SPRINTF("? ");
-            continue;
-        }
-        if(fcntl(i, F_GETFL, NULL) < 0) {
-            SAFE_SPRINTF("b");
-        }
-        SAFE_SPRINTF(" ");
-    }
-    D("%s fd_table[]->fd = {%s}\n", extra_msg, msg_buff);
-}
-#endif
-
-static void fdevent_process()
-{
-    int i, n;
-    fdevent *fde;
-    unsigned events;
-    fd_set rfd, wfd, efd;
-
-    memcpy(&rfd, &read_fds, sizeof(fd_set));
-    memcpy(&wfd, &write_fds, sizeof(fd_set));
-    memcpy(&efd, &error_fds, sizeof(fd_set));
-
-    dump_all_fds("pre select()");
-
-    n = select(select_n, &rfd, &wfd, &efd, NULL);
-    int saved_errno = errno;
-    D("select() returned n=%d, errno=%d\n", n, n<0?saved_errno:0);
-
-    dump_all_fds("post select()");
-
-    if(n < 0) {
-        switch(saved_errno) {
-        case EINTR: return;
-        case EBADF:
-            // Can't trust the FD sets after an error.
-            FD_ZERO(&wfd);
-            FD_ZERO(&efd);
-            FD_ZERO(&rfd);
-            break;
-        default:
-            D("Unexpected select() error=%d\n", saved_errno);
-            return;
-        }
-    }
-    if(n <= 0) {
-        // We fake a read, as the rest of the code assumes
-        // that errors will be detected at that point.
-        n = fdevent_fd_check(&rfd);
-    }
-
-    for(i = 0; (i < select_n) && (n > 0); i++) {
-        events = 0;
-        if(FD_ISSET(i, &rfd)) { events |= FDE_READ; n--; }
-        if(FD_ISSET(i, &wfd)) { events |= FDE_WRITE; n--; }
-        if(FD_ISSET(i, &efd)) { events |= FDE_ERROR; n--; }
-
-        if(events) {
-            fde = fd_table[i];
-            if(fde == 0)
-              FATAL("missing fde for fd %d\n", i);
-
-            fde->events |= events;
-
-            D("got events fde->fd=%d events=%04x, state=%04x\n",
-                fde->fd, fde->events, fde->state);
-            if(fde->state & FDE_PENDING) continue;
-            fde->state |= FDE_PENDING;
-            fdevent_plist_enqueue(fde);
-        }
-    }
-}
-
-#endif
-
-static void fdevent_register(fdevent *fde)
-{
-    if(fde->fd < 0) {
-        FATAL("bogus negative fd (%d)\n", fde->fd);
-    }
-
-    if(fde->fd >= fd_table_max) {
-        int oldmax = fd_table_max;
-        if(fde->fd > 32000) {
-            FATAL("bogus huuuuge fd (%d)\n", fde->fd);
-        }
-        if(fd_table_max == 0) {
-            fdevent_init();
-            fd_table_max = 256;
-        }
-        while(fd_table_max <= fde->fd) {
-            fd_table_max *= 2;
-        }
-        fd_table = realloc(fd_table, sizeof(fdevent*) * fd_table_max);
-        if(fd_table == 0) {
-            FATAL("could not expand fd_table to %d entries\n", fd_table_max);
-        }
-        memset(fd_table + oldmax, 0, sizeof(int) * (fd_table_max - oldmax));
-    }
-
-    fd_table[fde->fd] = fde;
-}
-
-static void fdevent_unregister(fdevent *fde)
-{
-    if((fde->fd < 0) || (fde->fd >= fd_table_max)) {
-        FATAL("fd out of range (%d)\n", fde->fd);
-    }
-
-    if(fd_table[fde->fd] != fde) {
-        FATAL("fd_table out of sync [%d]\n", fde->fd);
-    }
-
-    fd_table[fde->fd] = 0;
-
-    if(!(fde->state & FDE_DONT_CLOSE)) {
-        dump_fde(fde, "close");
-        adb_close(fde->fd);
-    }
-}
-
-static void fdevent_plist_enqueue(fdevent *node)
-{
-    fdevent *list = &list_pending;
-
-    node->next = list;
-    node->prev = list->prev;
-    node->prev->next = node;
-    list->prev = node;
-}
-
-static void fdevent_plist_remove(fdevent *node)
-{
-    node->prev->next = node->next;
-    node->next->prev = node->prev;
-    node->next = 0;
-    node->prev = 0;
-}
-
-static fdevent *fdevent_plist_dequeue(void)
-{
-    fdevent *list = &list_pending;
-    fdevent *node = list->next;
-
-    if(node == list) return 0;
-
-    list->next = node->next;
-    list->next->prev = list;
-    node->next = 0;
-    node->prev = 0;
-
-    return node;
-}
-
-static void fdevent_call_fdfunc(fdevent* fde)
-{
-    unsigned events = fde->events;
-    fde->events = 0;
-    if(!(fde->state & FDE_PENDING)) return;
-    fde->state &= (~FDE_PENDING);
-    dump_fde(fde, "callback");
-    fde->func(fde->fd, events, fde->arg);
-}
-
-static void fdevent_subproc_event_func(int fd, unsigned ev, void *userdata)
-{
-
-    D("subproc handling on fd=%d ev=%04x\n", fd, ev);
-
-    // Hook oneself back into the fde's suitable for select() on read.
-    if((fd < 0) || (fd >= fd_table_max)) {
-        FATAL("fd %d out of range for fd_table \n", fd);
-    }
-    fdevent *fde = fd_table[fd];
-    fdevent_add(fde, FDE_READ);
-
-    if(ev & FDE_READ){
-      int subproc_fd;
-
-      if(readx(fd, &subproc_fd, sizeof(subproc_fd))) {
-          FATAL("Failed to read the subproc's fd from fd=%d\n", fd);
-      }
-      if((subproc_fd < 0) || (subproc_fd >= fd_table_max)) {
-          D("subproc_fd %d out of range 0, fd_table_max=%d\n",
-            subproc_fd, fd_table_max);
-          return;
-      }
-      fdevent *subproc_fde = fd_table[subproc_fd];
-      if(!subproc_fde) {
-          D("subproc_fd %d cleared from fd_table\n", subproc_fd);
-          return;
-      }
-      if(subproc_fde->fd != subproc_fd) {
-          // Already reallocated?
-          D("subproc_fd %d != fd_table[].fd %d\n", subproc_fd, subproc_fde->fd);
-          return;
-      }
-
-      subproc_fde->force_eof = 1;
-
-      int rcount = 0;
-      ioctl(subproc_fd, FIONREAD, &rcount);
-      D("subproc with fd=%d  has rcount=%d err=%d\n",
-        subproc_fd, rcount, errno);
-
-      if(rcount) {
-        // If there is data left, it will show up in the select().
-        // This works because there is no other thread reading that
-        // data when in this fd_func().
-        return;
-      }
-
-      D("subproc_fde.state=%04x\n", subproc_fde->state);
-      subproc_fde->events |= FDE_READ;
-      if(subproc_fde->state & FDE_PENDING) {
-        return;
-      }
-      subproc_fde->state |= FDE_PENDING;
-      fdevent_call_fdfunc(subproc_fde);
-    }
-}
-
-fdevent *fdevent_create(int fd, fd_func func, void *arg)
-{
-    fdevent *fde = (fdevent*) malloc(sizeof(fdevent));
-    if(fde == 0) return 0;
-    fdevent_install(fde, fd, func, arg);
-    fde->state |= FDE_CREATED;
-    return fde;
-}
-
-void fdevent_destroy(fdevent *fde)
-{
-    if(fde == 0) return;
-    if(!(fde->state & FDE_CREATED)) {
-        FATAL("fde %p not created by fdevent_create()\n", fde);
-    }
-    fdevent_remove(fde);
-}
-
-void fdevent_install(fdevent *fde, int fd, fd_func func, void *arg)
-{
-    memset(fde, 0, sizeof(fdevent));
-    fde->state = FDE_ACTIVE;
-    fde->fd = fd;
-    fde->force_eof = 0;
-    fde->func = func;
-    fde->arg = arg;
-
-#ifndef HAVE_WINSOCK
-    fcntl(fd, F_SETFL, O_NONBLOCK);
-#endif
-    fdevent_register(fde);
-    dump_fde(fde, "connect");
-    fdevent_connect(fde);
-    fde->state |= FDE_ACTIVE;
-}
-
-void fdevent_remove(fdevent *fde)
-{
-    if(fde->state & FDE_PENDING) {
-        fdevent_plist_remove(fde);
-    }
-
-    if(fde->state & FDE_ACTIVE) {
-        fdevent_disconnect(fde);
-        dump_fde(fde, "disconnect");
-        fdevent_unregister(fde);
-    }
-
-    fde->state = 0;
-    fde->events = 0;
-}
-
-
-void fdevent_set(fdevent *fde, unsigned events)
-{
-    events &= FDE_EVENTMASK;
-
-    if((fde->state & FDE_EVENTMASK) == events) return;
-
-    if(fde->state & FDE_ACTIVE) {
-        fdevent_update(fde, events);
-        dump_fde(fde, "update");
-    }
-
-    fde->state = (fde->state & FDE_STATEMASK) | events;
-
-    if(fde->state & FDE_PENDING) {
-            /* if we're pending, make sure
-            ** we don't signal an event that
-            ** is no longer wanted.
-            */
-        fde->events &= (~events);
-        if(fde->events == 0) {
-            fdevent_plist_remove(fde);
-            fde->state &= (~FDE_PENDING);
-        }
-    }
-}
-
-void fdevent_add(fdevent *fde, unsigned events)
-{
-    fdevent_set(
-        fde, (fde->state & FDE_EVENTMASK) | (events & FDE_EVENTMASK));
-}
-
-void fdevent_del(fdevent *fde, unsigned events)
-{
-    fdevent_set(
-        fde, (fde->state & FDE_EVENTMASK) & (~(events & FDE_EVENTMASK)));
-}
-
-void fdevent_subproc_setup()
-{
-    int s[2];
-
-    if(adb_socketpair(s)) {
-        FATAL("cannot create shell-exit socket-pair\n");
-    }
-    SHELL_EXIT_NOTIFY_FD = s[0];
-    fdevent *fde;
-    fde = fdevent_create(s[1], fdevent_subproc_event_func, NULL);
-    if(!fde)
-      FATAL("cannot create fdevent for shell-exit handler\n");
-    fdevent_add(fde, FDE_READ);
-}
-
-void fdevent_loop()
-{
-    fdevent *fde;
-    fdevent_subproc_setup();
-
-    for(;;) {
-        D("--- ---- waiting for events\n");
-
-        fdevent_process();
-
-        while((fde = fdevent_plist_dequeue())) {
-            fdevent_call_fdfunc(fde);
-        }
-    }
-}
diff --git a/minadbd/fuse_adb_provider.c b/minadbd/fuse_adb_provider.c
index f80533a..e926285 100644
--- a/minadbd/fuse_adb_provider.c
+++ b/minadbd/fuse_adb_provider.c
@@ -16,6 +16,7 @@
 
 #include <stdlib.h>
 #include <stdio.h>
+#include <string.h>
 #include <errno.h>
 
 #include "adb.h"
diff --git a/minadbd/usb_linux_client.c b/minadbd/usb_linux_client.c
index 29bab15..b3a38dc 100644
--- a/minadbd/usb_linux_client.c
+++ b/minadbd/usb_linux_client.c
@@ -52,7 +52,31 @@
     int bulk_in;  /* "in" from the host's perspective => sink for adbd */
 };
 
-static const struct {
+struct func_desc {
+    struct usb_interface_descriptor intf;
+    struct usb_endpoint_descriptor_no_audio source;
+    struct usb_endpoint_descriptor_no_audio sink;
+} __attribute__((packed));
+
+struct desc_v1 {
+    struct usb_functionfs_descs_head_v1 {
+        __le32 magic;
+        __le32 length;
+        __le32 fs_count;
+        __le32 hs_count;
+    } __attribute__((packed)) header;
+    struct func_desc fs_descs, hs_descs;
+} __attribute__((packed));
+
+struct desc_v2 {
+    struct usb_functionfs_descs_head_v2 header;
+    // The rest of the structure depends on the flags in the header.
+    __le32 fs_count;
+    __le32 hs_count;
+    struct func_desc fs_descs, hs_descs;
+} __attribute__((packed));
+
+/*static const struct {
     struct usb_functionfs_descs_head header;
     struct {
         struct usb_interface_descriptor intf;
@@ -66,57 +90,60 @@
         .fs_count = 3,
         .hs_count = 3,
     },
-    .fs_descs = {
-        .intf = {
-            .bLength = sizeof(descriptors.fs_descs.intf),
-            .bDescriptorType = USB_DT_INTERFACE,
-            .bInterfaceNumber = 0,
-            .bNumEndpoints = 2,
-            .bInterfaceClass = ADB_CLASS,
-            .bInterfaceSubClass = ADB_SUBCLASS,
-            .bInterfaceProtocol = ADB_PROTOCOL,
-            .iInterface = 1, /* first string from the provided table */
-        },
-        .source = {
-            .bLength = sizeof(descriptors.fs_descs.source),
-            .bDescriptorType = USB_DT_ENDPOINT,
-            .bEndpointAddress = 1 | USB_DIR_OUT,
-            .bmAttributes = USB_ENDPOINT_XFER_BULK,
-            .wMaxPacketSize = MAX_PACKET_SIZE_FS,
-        },
-        .sink = {
-            .bLength = sizeof(descriptors.fs_descs.sink),
-            .bDescriptorType = USB_DT_ENDPOINT,
-            .bEndpointAddress = 2 | USB_DIR_IN,
-            .bmAttributes = USB_ENDPOINT_XFER_BULK,
-            .wMaxPacketSize = MAX_PACKET_SIZE_FS,
-        },
+
+*/
+
+struct func_desc fs_descriptors = {
+    .intf = {
+        .bLength = sizeof(fs_descriptors.intf),
+        .bDescriptorType = USB_DT_INTERFACE,
+        .bInterfaceNumber = 0,
+        .bNumEndpoints = 2,
+        .bInterfaceClass = ADB_CLASS,
+        .bInterfaceSubClass = ADB_SUBCLASS,
+        .bInterfaceProtocol = ADB_PROTOCOL,
+        .iInterface = 1, /* first string from the provided table */
     },
-    .hs_descs = {
-        .intf = {
-            .bLength = sizeof(descriptors.hs_descs.intf),
-            .bDescriptorType = USB_DT_INTERFACE,
-            .bInterfaceNumber = 0,
-            .bNumEndpoints = 2,
-            .bInterfaceClass = ADB_CLASS,
-            .bInterfaceSubClass = ADB_SUBCLASS,
-            .bInterfaceProtocol = ADB_PROTOCOL,
-            .iInterface = 1, /* first string from the provided table */
-        },
-        .source = {
-            .bLength = sizeof(descriptors.hs_descs.source),
-            .bDescriptorType = USB_DT_ENDPOINT,
-            .bEndpointAddress = 1 | USB_DIR_OUT,
-            .bmAttributes = USB_ENDPOINT_XFER_BULK,
-            .wMaxPacketSize = MAX_PACKET_SIZE_HS,
-        },
-        .sink = {
-            .bLength = sizeof(descriptors.hs_descs.sink),
-            .bDescriptorType = USB_DT_ENDPOINT,
-            .bEndpointAddress = 2 | USB_DIR_IN,
-            .bmAttributes = USB_ENDPOINT_XFER_BULK,
-            .wMaxPacketSize = MAX_PACKET_SIZE_HS,
-        },
+    .source = {
+        .bLength = sizeof(fs_descriptors.source),
+        .bDescriptorType = USB_DT_ENDPOINT,
+        .bEndpointAddress = 1 | USB_DIR_OUT,
+        .bmAttributes = USB_ENDPOINT_XFER_BULK,
+        .wMaxPacketSize = MAX_PACKET_SIZE_FS,
+    },
+    .sink = {
+        .bLength = sizeof(fs_descriptors.sink),
+        .bDescriptorType = USB_DT_ENDPOINT,
+        .bEndpointAddress = 2 | USB_DIR_IN,
+        .bmAttributes = USB_ENDPOINT_XFER_BULK,
+        .wMaxPacketSize = MAX_PACKET_SIZE_FS,
+    },
+};
+
+struct func_desc hs_descriptors = {
+    .intf = {
+        .bLength = sizeof(hs_descriptors.intf),
+        .bDescriptorType = USB_DT_INTERFACE,
+        .bInterfaceNumber = 0,
+        .bNumEndpoints = 2,
+        .bInterfaceClass = ADB_CLASS,
+        .bInterfaceSubClass = ADB_SUBCLASS,
+        .bInterfaceProtocol = ADB_PROTOCOL,
+        .iInterface = 1, /* first string from the provided table */
+    },
+    .source = {
+        .bLength = sizeof(hs_descriptors.source),
+        .bDescriptorType = USB_DT_ENDPOINT,
+        .bEndpointAddress = 1 | USB_DIR_OUT,
+        .bmAttributes = USB_ENDPOINT_XFER_BULK,
+        .wMaxPacketSize = MAX_PACKET_SIZE_HS,
+    },
+    .sink = {
+        .bLength = sizeof(hs_descriptors.sink),
+        .bDescriptorType = USB_DT_ENDPOINT,
+        .bEndpointAddress = 2 | USB_DIR_IN,
+        .bmAttributes = USB_ENDPOINT_XFER_BULK,
+        .wMaxPacketSize = MAX_PACKET_SIZE_HS,
     },
 };
 
@@ -267,6 +294,17 @@
 static void init_functionfs(struct usb_handle *h)
 {
     ssize_t ret;
+    struct desc_v1 v1_descriptor;
+    struct desc_v2 v2_descriptor;
+
+    v2_descriptor.header.magic = cpu_to_le32(FUNCTIONFS_DESCRIPTORS_MAGIC_V2);
+    v2_descriptor.header.length = cpu_to_le32(sizeof(v2_descriptor));
+    v2_descriptor.header.flags = FUNCTIONFS_HAS_FS_DESC | FUNCTIONFS_HAS_HS_DESC;
+    v2_descriptor.fs_count = 3;
+    v2_descriptor.hs_count = 3;
+    v2_descriptor.fs_descs = fs_descriptors;
+    v2_descriptor.hs_descs = hs_descriptors;
+
 
     D("OPENING %s\n", USB_FFS_ADB_EP0);
     h->control = adb_open(USB_FFS_ADB_EP0, O_RDWR);
@@ -275,10 +313,20 @@
         goto err;
     }
 
-    ret = adb_write(h->control, &descriptors, sizeof(descriptors));
+    ret = adb_write(h->control, &v2_descriptor, sizeof(v2_descriptor));
     if (ret < 0) {
-        D("[ %s: write descriptors failed: errno=%d ]\n", USB_FFS_ADB_EP0, errno);
-        goto err;
+            v1_descriptor.header.magic = cpu_to_le32(FUNCTIONFS_DESCRIPTORS_MAGIC);
+            v1_descriptor.header.length = cpu_to_le32(sizeof(v1_descriptor));
+            v1_descriptor.header.fs_count = 3;
+            v1_descriptor.header.hs_count = 3;
+            v1_descriptor.fs_descs = fs_descriptors;
+            v1_descriptor.hs_descs = hs_descriptors;
+            D("[ %s: Switching to V1_descriptor format errno=%d ]\n", USB_FFS_ADB_EP0, errno);
+            ret = adb_write(h->control, &v1_descriptor, sizeof(v1_descriptor));
+            if (ret < 0) {
+                D("[ %s: write descriptors failed: errno=%d ]\n", USB_FFS_ADB_EP0, errno);
+                goto err;
+            }
     }
 
     ret = adb_write(h->control, &strings, sizeof(strings));
diff --git a/minui/Android.mk b/minui/Android.mk
index df4aac1..aee2a34 100644
--- a/minui/Android.mk
+++ b/minui/Android.mk
@@ -30,3 +30,10 @@
 endif
 
 include $(BUILD_STATIC_LIBRARY)
+
+# Used by OEMs for factory test images.
+include $(CLEAR_VARS)
+LOCAL_MODULE := libminui
+LOCAL_WHOLE_STATIC_LIBRARIES += libminui
+LOCAL_SHARED_LIBRARIES := libpng
+include $(BUILD_SHARED_LIBRARY)
diff --git a/minui/events.c b/minui/events.c
index df7dad4..9e4255d 100644
--- a/minui/events.c
+++ b/minui/events.c
@@ -16,6 +16,8 @@
 
 #include <stdio.h>
 #include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
 #include <fcntl.h>
 #include <dirent.h>
 #include <sys/epoll.h>
@@ -78,8 +80,8 @@
             }
 
             /* TODO: add ability to specify event masks. For now, just assume
-             * that only EV_KEY and EV_REL event types are ever needed. */
-            if (!test_bit(EV_KEY, ev_bits) && !test_bit(EV_REL, ev_bits)) {
+             * that only EV_KEY, EV_REL & EV_SW event types are ever needed. */
+            if (!test_bit(EV_KEY, ev_bits) && !test_bit(EV_REL, ev_bits) && !test_bit(EV_SW, ev_bits)) {
                 close(fd);
                 continue;
             }
diff --git a/minui/graphics.c b/minui/graphics.c
index 6049d85..ec39433 100644
--- a/minui/graphics.c
+++ b/minui/graphics.c
@@ -16,6 +16,7 @@
 
 #include <stdbool.h>
 #include <stdlib.h>
+#include <string.h>
 #include <unistd.h>
 
 #include <fcntl.h>
diff --git a/minui/graphics_adf.c b/minui/graphics_adf.c
index ac6d64e..289c3be 100644
--- a/minui/graphics_adf.c
+++ b/minui/graphics_adf.c
@@ -19,6 +19,7 @@
 #include <stdbool.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <string.h>
 #include <unistd.h>
 
 #include <sys/cdefs.h>
diff --git a/minui/graphics_fbdev.c b/minui/graphics_fbdev.c
index c0c1bcb..a087899 100644
--- a/minui/graphics_fbdev.c
+++ b/minui/graphics_fbdev.c
@@ -16,6 +16,7 @@
 
 #include <stdbool.h>
 #include <stdlib.h>
+#include <string.h>
 #include <unistd.h>
 
 #include <fcntl.h>
diff --git a/minui/resources.c b/minui/resources.c
index 2bae4de..f645c4b 100644
--- a/minui/resources.c
+++ b/minui/resources.c
@@ -15,6 +15,7 @@
  */
 
 #include <stdlib.h>
+#include <string.h>
 #include <unistd.h>
 
 #include <fcntl.h>
diff --git a/minzip/DirUtil.c b/minzip/DirUtil.c
index fe2c880..97cb2e0 100644
--- a/minzip/DirUtil.c
+++ b/minzip/DirUtil.c
@@ -85,7 +85,7 @@
             c--;
         }
         if (c == cpath) {
-//xxx test this path
+            //xxx test this path
             /* No directory component.  Act like the path was empty.
              */
             errno = ENOENT;
@@ -206,7 +206,7 @@
     /* recurse over components */
     errno = 0;
     while ((de = readdir(dir)) != NULL) {
-//TODO: don't blow the stack
+        //TODO: don't blow the stack
         char dn[PATH_MAX];
         if (!strcmp(de->d_name, "..") || !strcmp(de->d_name, ".")) {
             continue;
diff --git a/minzip/Hash.c b/minzip/Hash.c
index 8c6ca9b..8f8ed68 100644
--- a/minzip/Hash.c
+++ b/minzip/Hash.c
@@ -140,7 +140,6 @@
     int i;
 
     assert(countTombStones(pHashTable) == pHashTable->numDeadEntries);
-    //LOGI("before: dead=%d\n", pHashTable->numDeadEntries);
 
     pNewEntries = (HashEntry*) calloc(newSize, sizeof(HashTable));
     if (pNewEntries == NULL)
@@ -196,7 +195,6 @@
             (*cmpFunc)(pEntry->data, item) == 0)
         {
             /* match */
-            //LOGD("+++ match on entry %d\n", pEntry - pHashTable->pEntries);
             break;
         }
 
@@ -206,8 +204,6 @@
                 break;      /* edge case - single-entry table */
             pEntry = pHashTable->pEntries;
         }
-
-        //LOGI("+++ look probing %d...\n", pEntry - pHashTable->pEntries);
     }
 
     if (pEntry->data == NULL) {
@@ -228,10 +224,6 @@
                     abort();
                 }
                 /* note "pEntry" is now invalid */
-            } else {
-                //LOGW("okay %d/%d/%d\n",
-                //    pHashTable->numEntries, pHashTable->tableSize,
-                //    (pHashTable->tableSize * LOAD_NUMER) / LOAD_DENOM);
             }
 
             /* full table is bad -- search for nonexistent never halts */
@@ -264,7 +256,6 @@
     pEnd = &pHashTable->pEntries[pHashTable->tableSize];
     while (pEntry->data != NULL) {
         if (pEntry->data == item) {
-            //LOGI("+++ stepping on entry %d\n", pEntry - pHashTable->pEntries);
             pEntry->data = HASH_TOMBSTONE;
             pHashTable->numEntries--;
             pHashTable->numDeadEntries++;
@@ -277,8 +268,6 @@
                 break;      /* edge case - single-entry table */
             pEntry = pHashTable->pEntries;
         }
-
-        //LOGI("+++ del probing %d...\n", pEntry - pHashTable->pEntries);
     }
 
     return false;
diff --git a/minzip/Zip.c b/minzip/Zip.c
index 5070104..aec35e3 100644
--- a/minzip/Zip.c
+++ b/minzip/Zip.c
@@ -327,10 +327,6 @@
 #else
         pEntry = &pArchive->pEntries[i];
 #endif
-
-        //LOGI("%d: localHdr=%d fnl=%d el=%d cl=%d\n",
-        //    i, localHdrOffset, fileNameLen, extraLen, commentLen);
-
         pEntry->fileNameLen = fileNameLen;
         pEntry->fileName = fileName;
 
@@ -923,8 +919,8 @@
 
     /* Walk through the entries and extract anything whose path begins
      * with zpath.
-//TODO: since the entries are sorted, binary search for the first match
-//      and stop after the first non-match.
+    //TODO: since the entries are sorted, binary search for the first match
+    //      and stop after the first non-match.
      */
     unsigned int i;
     bool seenMatch = false;
@@ -933,10 +929,10 @@
     for (i = 0; i < pArchive->numEntries; i++) {
         ZipEntry *pEntry = pArchive->pEntries + i;
         if (pEntry->fileNameLen < zipDirLen) {
-//TODO: look out for a single empty directory entry that matches zpath, but
-//      missing the trailing slash.  Most zip files seem to include
-//      the trailing slash, but I think it's legal to leave it off.
-//      e.g., zpath "a/b/", entry "a/b", with no children of the entry.
+       //TODO: look out for a single empty directory entry that matches zpath, but
+       //      missing the trailing slash.  Most zip files seem to include
+       //      the trailing slash, but I think it's legal to leave it off.
+       //      e.g., zpath "a/b/", entry "a/b", with no children of the entry.
             /* No chance of matching.
              */
 #if SORT_ENTRIES
diff --git a/mtdutils/mounts.c b/mtdutils/mounts.c
index c90fc8a..6a9b03d 100644
--- a/mtdutils/mounts.c
+++ b/mtdutils/mounts.c
@@ -14,6 +14,7 @@
  * limitations under the License.
  */
 
+#include <mntent.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -59,10 +60,8 @@
 int
 scan_mounted_volumes()
 {
-    char buf[2048];
-    const char *bufp;
-    int fd;
-    ssize_t nbytes;
+    FILE* fp;
+    struct mntent* mentry;
 
     if (g_mounts_state.volumes == NULL) {
         const int numv = 32;
@@ -84,80 +83,20 @@
     }
     g_mounts_state.volume_count = 0;
 
-    /* Open and read the file contents.
-     */
-    fd = open(PROC_MOUNTS_FILENAME, O_RDONLY);
-    if (fd < 0) {
-        goto bail;
+    /* Open and read mount table entries. */
+    fp = setmntent(PROC_MOUNTS_FILENAME, "r");
+    if (fp == NULL) {
+        return -1;
     }
-    nbytes = read(fd, buf, sizeof(buf) - 1);
-    close(fd);
-    if (nbytes < 0) {
-        goto bail;
+    while ((mentry = getmntent(fp)) != NULL) {
+        MountedVolume* v = &g_mounts_state.volumes[g_mounts_state.volume_count++];
+        v->device = strdup(mentry->mnt_fsname);
+        v->mount_point = strdup(mentry->mnt_dir);
+        v->filesystem = strdup(mentry->mnt_type);
+        v->flags = strdup(mentry->mnt_opts);
     }
-    buf[nbytes] = '\0';
-
-    /* Parse the contents of the file, which looks like:
-     *
-     *     # cat /proc/mounts
-     *     rootfs / rootfs rw 0 0
-     *     /dev/pts /dev/pts devpts rw 0 0
-     *     /proc /proc proc rw 0 0
-     *     /sys /sys sysfs rw 0 0
-     *     /dev/block/mtdblock4 /system yaffs2 rw,nodev,noatime,nodiratime 0 0
-     *     /dev/block/mtdblock5 /data yaffs2 rw,nodev,noatime,nodiratime 0 0
-     *     /dev/block/mmcblk0p1 /sdcard vfat rw,sync,dirsync,fmask=0000,dmask=0000,codepage=cp437,iocharset=iso8859-1,utf8 0 0
-     *
-     * The zeroes at the end are dummy placeholder fields to make the
-     * output match Linux's /etc/mtab, but don't represent anything here.
-     */
-    bufp = buf;
-    while (nbytes > 0) {
-        char device[64];
-        char mount_point[64];
-        char filesystem[64];
-        char flags[128];
-        int matches;
-
-        /* %as is a gnu extension that malloc()s a string for each field.
-         */
-        matches = sscanf(bufp, "%63s %63s %63s %127s",
-                device, mount_point, filesystem, flags);
-
-        if (matches == 4) {
-            device[sizeof(device)-1] = '\0';
-            mount_point[sizeof(mount_point)-1] = '\0';
-            filesystem[sizeof(filesystem)-1] = '\0';
-            flags[sizeof(flags)-1] = '\0';
-
-            MountedVolume *v =
-                    &g_mounts_state.volumes[g_mounts_state.volume_count++];
-            v->device = strdup(device);
-            v->mount_point = strdup(mount_point);
-            v->filesystem = strdup(filesystem);
-            v->flags = strdup(flags);
-        } else {
-printf("matches was %d on <<%.40s>>\n", matches, bufp);
-        }
-
-        /* Eat the line.
-         */
-        while (nbytes > 0 && *bufp != '\n') {
-            bufp++;
-            nbytes--;
-        }
-        if (nbytes > 0) {
-            bufp++;
-            nbytes--;
-        }
-    }
-
+    endmntent(fp);
     return 0;
-
-bail:
-//TODO: free the strings we've allocated.
-    g_mounts_state.volume_count = 0;
-    return -1;
 }
 
 const MountedVolume *
diff --git a/recovery.cpp b/recovery.cpp
index 7f17b16..d8756d7 100644
--- a/recovery.cpp
+++ b/recovery.cpp
@@ -161,6 +161,11 @@
     return fp;
 }
 
+bool is_ro_debuggable() {
+    char value[PROPERTY_VALUE_MAX+1];
+    return (property_get("ro.debuggable", value, NULL) == 1 && value[0] == '1');
+}
+
 // close a file, log an error if the error indicator is set
 static void
 check_and_fclose(FILE *fp, const char *name) {
@@ -954,9 +959,7 @@
             // If this is an eng or userdebug build, then automatically
             // turn the text display on if the script fails so the error
             // message is visible.
-            char buffer[PROPERTY_VALUE_MAX+1];
-            property_get("ro.build.fingerprint", buffer, "");
-            if (strstr(buffer, ":userdebug/") || strstr(buffer, ":eng/")) {
+            if (is_ro_debuggable()) {
                 ui->ShowText(true);
             }
         }
diff --git a/tools/ota/check-lost+found.c b/tools/ota/check-lost+found.c
index da02f46..cbf7926 100644
--- a/tools/ota/check-lost+found.c
+++ b/tools/ota/check-lost+found.c
@@ -26,6 +26,7 @@
 #include <sys/stat.h>
 #include <sys/types.h>
 #include <time.h>
+#include <unistd.h>
 
 #include "private/android_filesystem_config.h"
 
diff --git a/uncrypt/uncrypt.c b/uncrypt/uncrypt.c
index 189fa57..b90bd6b 100644
--- a/uncrypt/uncrypt.c
+++ b/uncrypt/uncrypt.c
@@ -39,8 +39,10 @@
 // Recovery can take this block map file and retrieve the underlying
 // file data to use as an update package.
 
+#include <errno.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <string.h>
 #include <stdarg.h>
 #include <sys/types.h>
 #include <sys/stat.h>
diff --git a/updater/Android.mk b/updater/Android.mk
index a3a900a..c73cdc0 100644
--- a/updater/Android.mk
+++ b/updater/Android.mk
@@ -69,7 +69,7 @@
 	$(hide) $(foreach lib,$(libs),echo "  Register_$(lib)();" >> $@;)
 	$(hide) echo "}" >> $@
 
-$(call intermediates-dir-for,EXECUTABLES,updater)/updater.o : $(inc)
+$(call intermediates-dir-for,EXECUTABLES,updater,,,$(TARGET_PREFER_32_BIT))/updater.o : $(inc)
 LOCAL_C_INCLUDES += $(dir $(inc))
 
 inc :=
diff --git a/updater/MODULE_LICENSE_GPL b/updater/MODULE_LICENSE_GPL
deleted file mode 100644
index e69de29..0000000
--- a/updater/MODULE_LICENSE_GPL
+++ /dev/null
diff --git a/updater/NOTICE b/updater/NOTICE
deleted file mode 100644
index e77696a..0000000
--- a/updater/NOTICE
+++ /dev/null
@@ -1,339 +0,0 @@
-		    GNU GENERAL PUBLIC LICENSE
-		       Version 2, June 1991
-
- Copyright (C) 1989, 1991 Free Software Foundation, Inc.
-                          675 Mass Ave, Cambridge, MA 02139, USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
-			    Preamble
-
-  The licenses for most software are designed to take away your
-freedom to share and change it.  By contrast, the GNU General Public
-License is intended to guarantee your freedom to share and change free
-software--to make sure the software is free for all its users.  This
-General Public License applies to most of the Free Software
-Foundation's software and to any other program whose authors commit to
-using it.  (Some other Free Software Foundation software is covered by
-the GNU Library General Public License instead.)  You can apply it to
-your programs, too.
-
-  When we speak of free software, we are referring to freedom, not
-price.  Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-this service if you wish), that you receive source code or can get it
-if you want it, that you can change the software or use pieces of it
-in new free programs; and that you know you can do these things.
-
-  To protect your rights, we need to make restrictions that forbid
-anyone to deny you these rights or to ask you to surrender the rights.
-These restrictions translate to certain responsibilities for you if you
-distribute copies of the software, or if you modify it.
-
-  For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must give the recipients all the rights that
-you have.  You must make sure that they, too, receive or can get the
-source code.  And you must show them these terms so they know their
-rights.
-
-  We protect your rights with two steps: (1) copyright the software, and
-(2) offer you this license which gives you legal permission to copy,
-distribute and/or modify the software.
-
-  Also, for each author's protection and ours, we want to make certain
-that everyone understands that there is no warranty for this free
-software.  If the software is modified by someone else and passed on, we
-want its recipients to know that what they have is not the original, so
-that any problems introduced by others will not reflect on the original
-authors' reputations.
-
-  Finally, any free program is threatened constantly by software
-patents.  We wish to avoid the danger that redistributors of a free
-program will individually obtain patent licenses, in effect making the
-program proprietary.  To prevent this, we have made it clear that any
-patent must be licensed for everyone's free use or not licensed at all.
-
-  The precise terms and conditions for copying, distribution and
-modification follow.
-
-		    GNU GENERAL PUBLIC LICENSE
-   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
-  0. This License applies to any program or other work which contains
-a notice placed by the copyright holder saying it may be distributed
-under the terms of this General Public License.  The "Program", below,
-refers to any such program or work, and a "work based on the Program"
-means either the Program or any derivative work under copyright law:
-that is to say, a work containing the Program or a portion of it,
-either verbatim or with modifications and/or translated into another
-language.  (Hereinafter, translation is included without limitation in
-the term "modification".)  Each licensee is addressed as "you".
-
-Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope.  The act of
-running the Program is not restricted, and the output from the Program
-is covered only if its contents constitute a work based on the
-Program (independent of having been made by running the Program).
-Whether that is true depends on what the Program does.
-
-  1. You may copy and distribute verbatim copies of the Program's
-source code as you receive it, in any medium, provided that you
-conspicuously and appropriately publish on each copy an appropriate
-copyright notice and disclaimer of warranty; keep intact all the
-notices that refer to this License and to the absence of any warranty;
-and give any other recipients of the Program a copy of this License
-along with the Program.
-
-You may charge a fee for the physical act of transferring a copy, and
-you may at your option offer warranty protection in exchange for a fee.
-
-  2. You may modify your copy or copies of the Program or any portion
-of it, thus forming a work based on the Program, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
-    a) You must cause the modified files to carry prominent notices
-    stating that you changed the files and the date of any change.
-
-    b) You must cause any work that you distribute or publish, that in
-    whole or in part contains or is derived from the Program or any
-    part thereof, to be licensed as a whole at no charge to all third
-    parties under the terms of this License.
-
-    c) If the modified program normally reads commands interactively
-    when run, you must cause it, when started running for such
-    interactive use in the most ordinary way, to print or display an
-    announcement including an appropriate copyright notice and a
-    notice that there is no warranty (or else, saying that you provide
-    a warranty) and that users may redistribute the program under
-    these conditions, and telling the user how to view a copy of this
-    License.  (Exception: if the Program itself is interactive but
-    does not normally print such an announcement, your work based on
-    the Program is not required to print an announcement.)
-
-These requirements apply to the modified work as a whole.  If
-identifiable sections of that work are not derived from the Program,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works.  But when you
-distribute the same sections as part of a whole which is a work based
-on the Program, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Program.
-
-In addition, mere aggregation of another work not based on the Program
-with the Program (or with a work based on the Program) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
-  3. You may copy and distribute the Program (or a work based on it,
-under Section 2) in object code or executable form under the terms of
-Sections 1 and 2 above provided that you also do one of the following:
-
-    a) Accompany it with the complete corresponding machine-readable
-    source code, which must be distributed under the terms of Sections
-    1 and 2 above on a medium customarily used for software interchange; or,
-
-    b) Accompany it with a written offer, valid for at least three
-    years, to give any third party, for a charge no more than your
-    cost of physically performing source distribution, a complete
-    machine-readable copy of the corresponding source code, to be
-    distributed under the terms of Sections 1 and 2 above on a medium
-    customarily used for software interchange; or,
-
-    c) Accompany it with the information you received as to the offer
-    to distribute corresponding source code.  (This alternative is
-    allowed only for noncommercial distribution and only if you
-    received the program in object code or executable form with such
-    an offer, in accord with Subsection b above.)
-
-The source code for a work means the preferred form of the work for
-making modifications to it.  For an executable work, complete source
-code means all the source code for all modules it contains, plus any
-associated interface definition files, plus the scripts used to
-control compilation and installation of the executable.  However, as a
-special exception, the source code distributed need not include
-anything that is normally distributed (in either source or binary
-form) with the major components (compiler, kernel, and so on) of the
-operating system on which the executable runs, unless that component
-itself accompanies the executable.
-
-If distribution of executable or object code is made by offering
-access to copy from a designated place, then offering equivalent
-access to copy the source code from the same place counts as
-distribution of the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
-  4. You may not copy, modify, sublicense, or distribute the Program
-except as expressly provided under this License.  Any attempt
-otherwise to copy, modify, sublicense or distribute the Program is
-void, and will automatically terminate your rights under this License.
-However, parties who have received copies, or rights, from you under
-this License will not have their licenses terminated so long as such
-parties remain in full compliance.
-
-  5. You are not required to accept this License, since you have not
-signed it.  However, nothing else grants you permission to modify or
-distribute the Program or its derivative works.  These actions are
-prohibited by law if you do not accept this License.  Therefore, by
-modifying or distributing the Program (or any work based on the
-Program), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Program or works based on it.
-
-  6. Each time you redistribute the Program (or any work based on the
-Program), the recipient automatically receives a license from the
-original licensor to copy, distribute or modify the Program subject to
-these terms and conditions.  You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties to
-this License.
-
-  7. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License.  If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Program at all.  For example, if a patent
-license would not permit royalty-free redistribution of the Program by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Program.
-
-If any portion of this section is held invalid or unenforceable under
-any particular circumstance, the balance of the section is intended to
-apply and the section as a whole is intended to apply in other
-circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system, which is
-implemented by public license practices.  Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
-  8. If the distribution and/or use of the Program is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Program under this License
-may add an explicit geographical distribution limitation excluding
-those countries, so that distribution is permitted only in or among
-countries not thus excluded.  In such case, this License incorporates
-the limitation as if written in the body of this License.
-
-  9. The Free Software Foundation may publish revised and/or new versions
-of the General Public License from time to time.  Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
-Each version is given a distinguishing version number.  If the Program
-specifies a version number of this License which applies to it and "any
-later version", you have the option of following the terms and conditions
-either of that version or of any later version published by the Free
-Software Foundation.  If the Program does not specify a version number of
-this License, you may choose any version ever published by the Free Software
-Foundation.
-
-  10. If you wish to incorporate parts of the Program into other free
-programs whose distribution conditions are different, write to the author
-to ask for permission.  For software which is copyrighted by the Free
-Software Foundation, write to the Free Software Foundation; we sometimes
-make exceptions for this.  Our decision will be guided by the two goals
-of preserving the free status of all derivatives of our free software and
-of promoting the sharing and reuse of software generally.
-
-			    NO WARRANTY
-
-  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
-FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
-OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
-PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
-OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
-TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
-PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
-REPAIR OR CORRECTION.
-
-  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
-REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
-INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
-OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
-TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
-YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
-PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGES.
-
-		     END OF TERMS AND CONDITIONS
-
-	    How to Apply These Terms to Your New Programs
-
-  If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
-  To do so, attach the following notices to the program.  It is safest
-to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
-    <one line to give the program's name and a brief idea of what it does.>
-    Copyright (C) 19yy  <name of author>
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-Also add information on how to contact you by electronic and paper mail.
-
-If the program is interactive, make it output a short notice like this
-when it starts in an interactive mode:
-
-    Gnomovision version 69, Copyright (C) 19yy name of author
-    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
-    This is free software, and you are welcome to redistribute it
-    under certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the appropriate
-parts of the General Public License.  Of course, the commands you use may
-be called something other than `show w' and `show c'; they could even be
-mouse-clicks or menu items--whatever suits your program.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the program, if
-necessary.  Here is a sample; alter the names:
-
-  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
-  `Gnomovision' (which makes passes at compilers) written by James Hacker.
-
-  <signature of Ty Coon>, 1 April 1989
-  Ty Coon, President of Vice
-
-This General Public License does not permit incorporating your program into
-proprietary programs.  If your program is a subroutine library, you may
-consider it more useful to permit linking proprietary applications with the
-library.  If this is what you want to do, use the GNU Library General
-Public License instead of this License.
diff --git a/updater/updater.c b/updater/updater.c
index 465e123..661f695 100644
--- a/updater/updater.c
+++ b/updater/updater.c
@@ -17,6 +17,7 @@
 #include <stdio.h>
 #include <unistd.h>
 #include <stdlib.h>
+#include <string.h>
 
 #include "edify/expr.h"
 #include "updater.h"
diff --git a/verifier.cpp b/verifier.cpp
index eeff95a..61e5adf 100644
--- a/verifier.cpp
+++ b/verifier.cpp
@@ -26,9 +26,10 @@
 #include "mincrypt/sha.h"
 #include "mincrypt/sha256.h"
 
-#include <string.h>
-#include <stdio.h>
 #include <errno.h>
+#include <malloc.h>
+#include <stdio.h>
+#include <string.h>
 
 extern RecoveryUI* ui;
 
diff --git a/verifier_test.cpp b/verifier_test.cpp
index 10a5dda..93a071e 100644
--- a/verifier_test.cpp
+++ b/verifier_test.cpp
@@ -14,12 +14,14 @@
  * limitations under the License.
  */
 
+#include <errno.h>
+#include <fcntl.h>
+#include <stdarg.h>
 #include <stdio.h>
 #include <stdlib.h>
-#include <stdarg.h>
+#include <string.h>
 #include <sys/types.h>
 #include <sys/stat.h>
-#include <fcntl.h>
 
 #include "common.h"
 #include "verifier.h"