Merge remote-tracking branch 'goog/ics-aah-exp'
diff --git a/Android.mk b/Android.mk
index 7e48e7f..036da9e 100644
--- a/Android.mk
+++ b/Android.mk
@@ -40,8 +40,8 @@
 else
   LOCAL_STATIC_LIBRARIES += $(TARGET_RECOVERY_UI_LIB)
 endif
-LOCAL_STATIC_LIBRARIES += libext4_utils libz
-LOCAL_STATIC_LIBRARIES += libminzip libunz libmtdutils libmincrypt libminadbd
+LOCAL_STATIC_LIBRARIES += libext4_utils
+LOCAL_STATIC_LIBRARIES += libminzip libz libmtdutils libmincrypt libminadbd
 LOCAL_STATIC_LIBRARIES += libminui libpixelflinger_static libpng libcutils
 LOCAL_STATIC_LIBRARIES += libstdc++ libc
 
diff --git a/applypatch/applypatch.c b/applypatch/applypatch.c
index 1060913..00004e9 100644
--- a/applypatch/applypatch.c
+++ b/applypatch/applypatch.c
@@ -30,10 +30,16 @@
 #include "mtdutils/mtdutils.h"
 #include "edify/expr.h"
 
-int SaveFileContents(const char* filename, FileContents file);
 static int LoadPartitionContents(const char* filename, FileContents* file);
-int ParseSha1(const char* str, uint8_t* digest);
 static ssize_t FileSink(unsigned char* data, ssize_t len, void* token);
+static int GenerateTarget(FileContents* source_file,
+                          const Value* source_patch_value,
+                          FileContents* copy_file,
+                          const Value* copy_patch_value,
+                          const char* source_filename,
+                          const char* target_filename,
+                          const uint8_t target_sha1[SHA_DIGEST_SIZE],
+                          size_t target_size);
 
 static int mtd_partitions_scanned = 0;
 
@@ -113,11 +119,6 @@
     }
 }
 
-void FreeFileContents(FileContents* file) {
-    if (file) free(file->data);
-    free(file);
-}
-
 // Load the contents of an MTD or EMMC partition into the provided
 // FileContents.  filename should be a string of the form
 // "MTD:<partition_name>:<size_1>:<sha1_1>:<size_2>:<sha1_2>:..."  (or
@@ -322,7 +323,7 @@
 
 // Save the contents of the given FileContents object under the given
 // filename.  Return 0 on success.
-int SaveFileContents(const char* filename, FileContents file) {
+int SaveFileContents(const char* filename, const FileContents* file) {
     int fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC);
     if (fd < 0) {
         printf("failed to open \"%s\" for write: %s\n",
@@ -330,10 +331,10 @@
         return -1;
     }
 
-    ssize_t bytes_written = FileSink(file.data, file.size, &fd);
-    if (bytes_written != file.size) {
+    ssize_t bytes_written = FileSink(file->data, file->size, &fd);
+    if (bytes_written != file->size) {
         printf("short write of \"%s\" (%ld bytes of %ld) (%s)\n",
-               filename, (long)bytes_written, (long)file.size,
+               filename, (long)bytes_written, (long)file->size,
                strerror(errno));
         close(fd);
         return -1;
@@ -341,11 +342,11 @@
     fsync(fd);
     close(fd);
 
-    if (chmod(filename, file.st.st_mode) != 0) {
+    if (chmod(filename, file->st.st_mode) != 0) {
         printf("chmod of \"%s\" failed: %s\n", filename, strerror(errno));
         return -1;
     }
-    if (chown(filename, file.st.st_uid, file.st.st_gid) != 0) {
+    if (chown(filename, file->st.st_uid, file->st.st_gid) != 0) {
         printf("chown of \"%s\" failed: %s\n", filename, strerror(errno));
         return -1;
     }
@@ -471,7 +472,7 @@
 // Search an array of sha1 strings for one matching the given sha1.
 // Return the index of the match on success, or -1 if no match is
 // found.
-int FindMatchingPatch(uint8_t* sha1, char** const patch_sha1_str,
+int FindMatchingPatch(uint8_t* sha1, const char** patch_sha1_str,
                       int num_patches) {
     int i;
     uint8_t patch_sha1[SHA_DIGEST_SIZE];
@@ -503,6 +504,7 @@
                "sha1 sums; checking cache\n", filename);
 
         free(file.data);
+        file.data = NULL;
 
         // If the source file is missing or corrupted, it might be because
         // we were killed in the middle of patching it.  A copy of it
@@ -631,9 +633,10 @@
 
     FileContents copy_file;
     FileContents source_file;
+    copy_file.data = NULL;
+    source_file.data = NULL;
     const Value* source_patch_value = NULL;
     const Value* copy_patch_value = NULL;
-    int made_copy = 0;
 
     // We try to load the target file into the source_file object.
     if (LoadFileContents(target_filename, &source_file,
@@ -643,6 +646,7 @@
             // has the desired hash, nothing for us to do.
             printf("\"%s\" is already target; no patch needed\n",
                    target_filename);
+            free(source_file.data);
             return 0;
         }
     }
@@ -653,6 +657,7 @@
         // Need to load the source file:  either we failed to load the
         // target file, or we did but it's different from the source file.
         free(source_file.data);
+        source_file.data = NULL;
         LoadFileContents(source_filename, &source_file,
                          RETOUCH_DO_MASK);
     }
@@ -667,6 +672,7 @@
 
     if (source_patch_value == NULL) {
         free(source_file.data);
+        source_file.data = NULL;
         printf("source file is bad; trying copy\n");
 
         if (LoadFileContents(CACHE_TEMP_SOURCE, &copy_file,
@@ -685,16 +691,36 @@
         if (copy_patch_value == NULL) {
             // fail.
             printf("copy file doesn't match source SHA-1s either\n");
+            free(copy_file.data);
             return 1;
         }
     }
 
+    int result = GenerateTarget(&source_file, source_patch_value,
+                                &copy_file, copy_patch_value,
+                                source_filename, target_filename,
+                                target_sha1, target_size);
+    free(source_file.data);
+    free(copy_file.data);
+
+    return result;
+}
+
+static int GenerateTarget(FileContents* source_file,
+                          const Value* source_patch_value,
+                          FileContents* copy_file,
+                          const Value* copy_patch_value,
+                          const char* source_filename,
+                          const char* target_filename,
+                          const uint8_t target_sha1[SHA_DIGEST_SIZE],
+                          size_t target_size) {
     int retry = 1;
     SHA_CTX ctx;
     int output;
     MemorySinkInfo msi;
     FileContents* source_to_use;
     char* outname;
+    int made_copy = 0;
 
     // assume that target_filename (eg "/system/app/Foo.apk") is located
     // on the same filesystem as its top-level directory ("/system").
@@ -723,7 +749,7 @@
 
             // We still write the original source to cache, in case
             // the partition write is interrupted.
-            if (MakeFreeSpaceOnCache(source_file.size) < 0) {
+            if (MakeFreeSpaceOnCache(source_file->size) < 0) {
                 printf("not enough free space on /cache\n");
                 return 1;
             }
@@ -763,7 +789,7 @@
                     return 1;
                 }
 
-                if (MakeFreeSpaceOnCache(source_file.size) < 0) {
+                if (MakeFreeSpaceOnCache(source_file->size) < 0) {
                     printf("not enough free space on /cache\n");
                     return 1;
                 }
@@ -782,10 +808,10 @@
 
         const Value* patch;
         if (source_patch_value != NULL) {
-            source_to_use = &source_file;
+            source_to_use = source_file;
             patch = source_patch_value;
         } else {
-            source_to_use = &copy_file;
+            source_to_use = copy_file;
             patch = copy_patch_value;
         }
 
diff --git a/applypatch/applypatch.h b/applypatch/applypatch.h
index a78c89b..fb58843 100644
--- a/applypatch/applypatch.h
+++ b/applypatch/applypatch.h
@@ -62,9 +62,9 @@
 
 int LoadFileContents(const char* filename, FileContents* file,
                      int retouch_flag);
-int SaveFileContents(const char* filename, FileContents file);
+int SaveFileContents(const char* filename, const FileContents* file);
 void FreeFileContents(FileContents* file);
-int FindMatchingPatch(uint8_t* sha1, char** const patch_sha1_str,
+int FindMatchingPatch(uint8_t* sha1, const char** patch_sha1_str,
                       int num_patches);
 
 // bsdiff.c
diff --git a/etc/init.rc b/etc/init.rc
index a301779..89a161e 100644
--- a/etc/init.rc
+++ b/etc/init.rc
@@ -15,13 +15,16 @@
     mkdir /cache
     mount /tmp /tmp tmpfs
 
+    chown root shell /tmp
+    chmod 0775 /tmp
+
     write /sys/class/android_usb/android0/enable 0
     write /sys/class/android_usb/android0/idVendor 18D1
     write /sys/class/android_usb/android0/idProduct D001
     write /sys/class/android_usb/android0/functions adb
-    write /sys/class/android_usb/android0/iManufacturer $ro.product.manufacturer
-    write /sys/class/android_usb/android0/iProduct $ro.product.model
-    write /sys/class/android_usb/android0/iSerial $ro.serialno
+    write /sys/class/android_usb/android0/iManufacturer ${ro.product.manufacturer}
+    write /sys/class/android_usb/android0/iProduct ${ro.product.model}
+    write /sys/class/android_usb/android0/iSerial ${ro.serialno}
 
 
 on boot
diff --git a/minadbd/README.txt b/minadbd/README.txt
index 0c190d0..c9df484 100644
--- a/minadbd/README.txt
+++ b/minadbd/README.txt
@@ -4,16 +4,19 @@
 adb.c
   - much support for host mode and non-linux OS's stripped out; this
     version only runs as adbd on the device.
-  - does not setuid/setgid itself (always stays root)
+  - always setuid/setgid's itself to the shell user
   - only uses USB transport
   - references to JDWP removed
   - main() removed
+  - all ADB_HOST and win32 code removed
+  - removed listeners, logging code, background server (for host)
 
 adb.h
   - minor changes to match adb.c changes
 
 sockets.c
   - references to JDWP removed
+  - ADB_HOST code removed
 
 services.c
   - all services except echo_service (which is commented out) removed
@@ -25,3 +28,12 @@
 Android.mk
   - only builds in adbd mode; builds as static library instead of a
     standalone executable.
+
+sysdeps.h
+  - changes adb_creat() to use O_NOFOLLOW
+
+transport.c
+  - removed ADB_HOST code
+
+transport_usb.c
+  - removed ADB_HOST code
diff --git a/minadbd/adb.c b/minadbd/adb.c
index d1e97b3..0e8fd2a 100644
--- a/minadbd/adb.c
+++ b/minadbd/adb.c
@@ -28,13 +28,9 @@
 #include "sysdeps.h"
 #include "adb.h"
 
-#if !ADB_HOST
 #include <private/android_filesystem_config.h>
 #include <linux/capability.h>
 #include <linux/prctl.h>
-#else
-#include "usb_vendors.h"
-#endif
 
 #if ADB_TRACE
 ADB_MUTEX_DEFINE( D_lock );
@@ -228,29 +224,6 @@
             HOST ? "host" : adb_device_banner);
     cp->msg.data_length = strlen((char*) cp->data) + 1;
     send_packet(cp, t);
-#if ADB_HOST
-        /* XXX why sleep here? */
-    // allow the device some time to respond to the connect message
-    adb_sleep_ms(1000);
-#endif
-}
-
-static char *connection_state_name(atransport *t)
-{
-    if (t == NULL) {
-        return "unknown";
-    }
-
-    switch(t->connection_state) {
-    case CS_BOOTLOADER:
-        return "bootloader";
-    case CS_DEVICE:
-        return "device";
-    case CS_OFFLINE:
-        return "offline";
-    default:
-        return "unknown";
-    }
 }
 
 void parse_banner(char *banner, atransport *t)
@@ -400,448 +373,11 @@
     put_apacket(p);
 }
 
-alistener listener_list = {
-    .next = &listener_list,
-    .prev = &listener_list,
-};
-
-static void ss_listener_event_func(int _fd, unsigned ev, void *_l)
-{
-    asocket *s;
-
-    if(ev & FDE_READ) {
-        struct sockaddr addr;
-        socklen_t alen;
-        int fd;
-
-        alen = sizeof(addr);
-        fd = adb_socket_accept(_fd, &addr, &alen);
-        if(fd < 0) return;
-
-        adb_socket_setbufsize(fd, CHUNK_SIZE);
-
-        s = create_local_socket(fd);
-        if(s) {
-            connect_to_smartsocket(s);
-            return;
-        }
-
-        adb_close(fd);
-    }
-}
-
-static void listener_event_func(int _fd, unsigned ev, void *_l)
-{
-    alistener *l = _l;
-    asocket *s;
-
-    if(ev & FDE_READ) {
-        struct sockaddr addr;
-        socklen_t alen;
-        int fd;
-
-        alen = sizeof(addr);
-        fd = adb_socket_accept(_fd, &addr, &alen);
-        if(fd < 0) return;
-
-        s = create_local_socket(fd);
-        if(s) {
-            s->transport = l->transport;
-            connect_to_remote(s, l->connect_to);
-            return;
-        }
-
-        adb_close(fd);
-    }
-}
-
-static void  free_listener(alistener*  l)
-{
-    if (l->next) {
-        l->next->prev = l->prev;
-        l->prev->next = l->next;
-        l->next = l->prev = l;
-    }
-
-    // closes the corresponding fd
-    fdevent_remove(&l->fde);
-
-    if (l->local_name)
-        free((char*)l->local_name);
-
-    if (l->connect_to)
-        free((char*)l->connect_to);
-
-    if (l->transport) {
-        remove_transport_disconnect(l->transport, &l->disconnect);
-    }
-    free(l);
-}
-
-static void listener_disconnect(void*  _l, atransport*  t)
-{
-    alistener*  l = _l;
-
-    free_listener(l);
-}
-
-int local_name_to_fd(const char *name)
-{
-    int port;
-
-    if(!strncmp("tcp:", name, 4)){
-        int  ret;
-        port = atoi(name + 4);
-        ret = socket_loopback_server(port, SOCK_STREAM);
-        return ret;
-    }
-#ifndef HAVE_WIN32_IPC  /* no Unix-domain sockets on Win32 */
-    // It's non-sensical to support the "reserved" space on the adb host side
-    if(!strncmp(name, "local:", 6)) {
-        return socket_local_server(name + 6,
-                ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM);
-    } else if(!strncmp(name, "localabstract:", 14)) {
-        return socket_local_server(name + 14,
-                ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM);
-    } else if(!strncmp(name, "localfilesystem:", 16)) {
-        return socket_local_server(name + 16,
-                ANDROID_SOCKET_NAMESPACE_FILESYSTEM, SOCK_STREAM);
-    }
-
-#endif
-    printf("unknown local portname '%s'\n", name);
-    return -1;
-}
-
-static int remove_listener(const char *local_name, const char *connect_to, atransport* transport)
-{
-    alistener *l;
-
-    for (l = listener_list.next; l != &listener_list; l = l->next) {
-        if (!strcmp(local_name, l->local_name) &&
-            !strcmp(connect_to, l->connect_to) &&
-            l->transport && l->transport == transport) {
-
-            listener_disconnect(l, transport);
-            return 0;
-        }
-    }
-
-    return -1;
-}
-
-static int install_listener(const char *local_name, const char *connect_to, atransport* transport)
-{
-    alistener *l;
-
-    //printf("install_listener('%s','%s')\n", local_name, connect_to);
-
-    for(l = listener_list.next; l != &listener_list; l = l->next){
-        if(strcmp(local_name, l->local_name) == 0) {
-            char *cto;
-
-                /* can't repurpose a smartsocket */
-            if(l->connect_to[0] == '*') {
-                return -1;
-            }
-
-            cto = strdup(connect_to);
-            if(cto == 0) {
-                return -1;
-            }
-
-            //printf("rebinding '%s' to '%s'\n", local_name, connect_to);
-            free((void*) l->connect_to);
-            l->connect_to = cto;
-            if (l->transport != transport) {
-                remove_transport_disconnect(l->transport, &l->disconnect);
-                l->transport = transport;
-                add_transport_disconnect(l->transport, &l->disconnect);
-            }
-            return 0;
-        }
-    }
-
-    if((l = calloc(1, sizeof(alistener))) == 0) goto nomem;
-    if((l->local_name = strdup(local_name)) == 0) goto nomem;
-    if((l->connect_to = strdup(connect_to)) == 0) goto nomem;
-
-
-    l->fd = local_name_to_fd(local_name);
-    if(l->fd < 0) {
-        free((void*) l->local_name);
-        free((void*) l->connect_to);
-        free(l);
-        printf("cannot bind '%s'\n", local_name);
-        return -2;
-    }
-
-    close_on_exec(l->fd);
-    if(!strcmp(l->connect_to, "*smartsocket*")) {
-        fdevent_install(&l->fde, l->fd, ss_listener_event_func, l);
-    } else {
-        fdevent_install(&l->fde, l->fd, listener_event_func, l);
-    }
-    fdevent_set(&l->fde, FDE_READ);
-
-    l->next = &listener_list;
-    l->prev = listener_list.prev;
-    l->next->prev = l;
-    l->prev->next = l;
-    l->transport = transport;
-
-    if (transport) {
-        l->disconnect.opaque = l;
-        l->disconnect.func   = listener_disconnect;
-        add_transport_disconnect(transport, &l->disconnect);
-    }
-    return 0;
-
-nomem:
-    fatal("cannot allocate listener");
-    return 0;
-}
-
-#ifdef HAVE_WIN32_PROC
-static BOOL WINAPI ctrlc_handler(DWORD type)
-{
-    exit(STATUS_CONTROL_C_EXIT);
-    return TRUE;
-}
-#endif
-
 static void adb_cleanup(void)
 {
     usb_cleanup();
 }
 
-void start_logging(void)
-{
-#ifdef HAVE_WIN32_PROC
-    char    temp[ MAX_PATH ];
-    FILE*   fnul;
-    FILE*   flog;
-
-    GetTempPath( sizeof(temp) - 8, temp );
-    strcat( temp, "adb.log" );
-
-    /* Win32 specific redirections */
-    fnul = fopen( "NUL", "rt" );
-    if (fnul != NULL)
-        stdin[0] = fnul[0];
-
-    flog = fopen( temp, "at" );
-    if (flog == NULL)
-        flog = fnul;
-
-    setvbuf( flog, NULL, _IONBF, 0 );
-
-    stdout[0] = flog[0];
-    stderr[0] = flog[0];
-    fprintf(stderr,"--- adb starting (pid %d) ---\n", getpid());
-#else
-    int fd;
-
-    fd = unix_open("/dev/null", O_RDONLY);
-    dup2(fd, 0);
-    adb_close(fd);
-
-    fd = unix_open("/tmp/adb.log", O_WRONLY | O_CREAT | O_APPEND, 0640);
-    if(fd < 0) {
-        fd = unix_open("/dev/null", O_WRONLY);
-    }
-    dup2(fd, 1);
-    dup2(fd, 2);
-    adb_close(fd);
-    fprintf(stderr,"--- adb starting (pid %d) ---\n", getpid());
-#endif
-}
-
-#if !ADB_HOST
-void start_device_log(void)
-{
-    int fd;
-    char    path[PATH_MAX];
-    struct tm now;
-    time_t t;
-    char value[PROPERTY_VALUE_MAX];
-
-    // read the trace mask from persistent property persist.adb.trace_mask
-    // give up if the property is not set or cannot be parsed
-    property_get("persist.adb.trace_mask", value, "");
-    if (sscanf(value, "%x", &adb_trace_mask) != 1)
-        return;
-
-    adb_mkdir("/data/adb", 0775);
-    tzset();
-    time(&t);
-    localtime_r(&t, &now);
-    strftime(path, sizeof(path),
-                "/data/adb/adb-%Y-%m-%d-%H-%M-%S.txt",
-                &now);
-    fd = unix_open(path, O_WRONLY | O_CREAT | O_TRUNC, 0640);
-    if (fd < 0)
-        return;
-
-    // redirect stdout and stderr to the log file
-    dup2(fd, 1);
-    dup2(fd, 2);
-    fprintf(stderr,"--- adb starting (pid %d) ---\n", getpid());
-    adb_close(fd);
-
-    fd = unix_open("/dev/null", O_RDONLY);
-    dup2(fd, 0);
-    adb_close(fd);
-}
-#endif
-
-#if ADB_HOST
-int launch_server(int server_port)
-{
-#ifdef HAVE_WIN32_PROC
-    /* we need to start the server in the background                    */
-    /* we create a PIPE that will be used to wait for the server's "OK" */
-    /* message since the pipe handles must be inheritable, we use a     */
-    /* security attribute                                               */
-    HANDLE                pipe_read, pipe_write;
-    SECURITY_ATTRIBUTES   sa;
-    STARTUPINFO           startup;
-    PROCESS_INFORMATION   pinfo;
-    char                  program_path[ MAX_PATH ];
-    int                   ret;
-
-    sa.nLength = sizeof(sa);
-    sa.lpSecurityDescriptor = NULL;
-    sa.bInheritHandle = TRUE;
-
-    /* create pipe, and ensure its read handle isn't inheritable */
-    ret = CreatePipe( &pipe_read, &pipe_write, &sa, 0 );
-    if (!ret) {
-        fprintf(stderr, "CreatePipe() failure, error %ld\n", GetLastError() );
-        return -1;
-    }
-
-    SetHandleInformation( pipe_read, HANDLE_FLAG_INHERIT, 0 );
-
-    ZeroMemory( &startup, sizeof(startup) );
-    startup.cb = sizeof(startup);
-    startup.hStdInput  = GetStdHandle( STD_INPUT_HANDLE );
-    startup.hStdOutput = pipe_write;
-    startup.hStdError  = GetStdHandle( STD_ERROR_HANDLE );
-    startup.dwFlags    = STARTF_USESTDHANDLES;
-
-    ZeroMemory( &pinfo, sizeof(pinfo) );
-
-    /* get path of current program */
-    GetModuleFileName( NULL, program_path, sizeof(program_path) );
-
-    ret = CreateProcess(
-            program_path,                              /* program path  */
-            "adb fork-server server",
-                                    /* the fork-server argument will set the
-                                       debug = 2 in the child           */
-            NULL,                   /* process handle is not inheritable */
-            NULL,                    /* thread handle is not inheritable */
-            TRUE,                          /* yes, inherit some handles */
-            DETACHED_PROCESS, /* the new process doesn't have a console */
-            NULL,                     /* use parent's environment block */
-            NULL,                    /* use parent's starting directory */
-            &startup,                 /* startup info, i.e. std handles */
-            &pinfo );
-
-    CloseHandle( pipe_write );
-
-    if (!ret) {
-        fprintf(stderr, "CreateProcess failure, error %ld\n", GetLastError() );
-        CloseHandle( pipe_read );
-        return -1;
-    }
-
-    CloseHandle( pinfo.hProcess );
-    CloseHandle( pinfo.hThread );
-
-    /* wait for the "OK\n" message */
-    {
-        char  temp[3];
-        DWORD  count;
-
-        ret = ReadFile( pipe_read, temp, 3, &count, NULL );
-        CloseHandle( pipe_read );
-        if ( !ret ) {
-            fprintf(stderr, "could not read ok from ADB Server, error = %ld\n", GetLastError() );
-            return -1;
-        }
-        if (count != 3 || temp[0] != 'O' || temp[1] != 'K' || temp[2] != '\n') {
-            fprintf(stderr, "ADB server didn't ACK\n" );
-            return -1;
-        }
-    }
-#elif defined(HAVE_FORKEXEC)
-    char    path[PATH_MAX];
-    int     fd[2];
-
-    // set up a pipe so the child can tell us when it is ready.
-    // fd[0] will be parent's end, and fd[1] will get mapped to stderr in the child.
-    if (pipe(fd)) {
-        fprintf(stderr, "pipe failed in launch_server, errno: %d\n", errno);
-        return -1;
-    }
-    get_my_path(path, PATH_MAX);
-    pid_t pid = fork();
-    if(pid < 0) return -1;
-
-    if (pid == 0) {
-        // child side of the fork
-
-        // redirect stderr to the pipe
-        // we use stderr instead of stdout due to stdout's buffering behavior.
-        adb_close(fd[0]);
-        dup2(fd[1], STDERR_FILENO);
-        adb_close(fd[1]);
-
-        // child process
-        int result = execl(path, "adb", "fork-server", "server", NULL);
-        // this should not return
-        fprintf(stderr, "OOPS! execl returned %d, errno: %d\n", result, errno);
-    } else  {
-        // parent side of the fork
-
-        char  temp[3];
-
-        temp[0] = 'A'; temp[1] = 'B'; temp[2] = 'C';
-        // wait for the "OK\n" message
-        adb_close(fd[1]);
-        int ret = adb_read(fd[0], temp, 3);
-        int saved_errno = errno;
-        adb_close(fd[0]);
-        if (ret < 0) {
-            fprintf(stderr, "could not read ok from ADB Server, errno = %d\n", saved_errno);
-            return -1;
-        }
-        if (ret != 3 || temp[0] != 'O' || temp[1] != 'K' || temp[2] != '\n') {
-            fprintf(stderr, "ADB server didn't ACK\n" );
-            return -1;
-        }
-
-        setsid();
-    }
-#else
-#error "cannot implement background server start on this platform"
-#endif
-    return 0;
-}
-#endif
-
-/* Constructs a local name of form tcp:port.
- * target_str points to the target string, it's content will be overwritten.
- * target_size is the capacity of the target string.
- * server_port is the port number to use for the local name.
- */
-void build_local_name(char* target_str, size_t target_size, int server_port)
-{
-  snprintf(target_str, target_size, "tcp:%d", server_port);
-}
-
 int adb_main()
 {
     atexit(adb_cleanup);
@@ -858,6 +394,16 @@
         usb_init();
     }
 
+    if (setgid(AID_SHELL) != 0) {
+        fprintf(stderr, "failed to setgid to shell\n");
+        exit(1);
+    }
+    if (setuid(AID_SHELL) != 0) {
+        fprintf(stderr, "failed to setuid to shell\n");
+        exit(1);
+    }
+    fprintf(stderr, "userid is %d\n", getuid());
+
     D("Event loop starting\n");
 
     fdevent_loop();
@@ -866,286 +412,3 @@
 
     return 0;
 }
-
-#if ADB_HOST
-void connect_device(char* host, char* buffer, int buffer_size)
-{
-    int port, fd;
-    char* portstr = strchr(host, ':');
-    char hostbuf[100];
-    char serial[100];
-
-    strncpy(hostbuf, host, sizeof(hostbuf) - 1);
-    if (portstr) {
-        if (portstr - host >= sizeof(hostbuf)) {
-            snprintf(buffer, buffer_size, "bad host name %s", host);
-            return;
-        }
-        // zero terminate the host at the point we found the colon
-        hostbuf[portstr - host] = 0;
-        if (sscanf(portstr + 1, "%d", &port) == 0) {
-            snprintf(buffer, buffer_size, "bad port number %s", portstr);
-            return;
-        }
-    } else {
-        port = DEFAULT_ADB_LOCAL_TRANSPORT_PORT;
-    }
-
-    snprintf(serial, sizeof(serial), "%s:%d", hostbuf, port);
-    if (find_transport(serial)) {
-        snprintf(buffer, buffer_size, "already connected to %s", serial);
-        return;
-    }
-
-    fd = socket_network_client(hostbuf, port, SOCK_STREAM);
-    if (fd < 0) {
-        snprintf(buffer, buffer_size, "unable to connect to %s:%d", host, port);
-        return;
-    }
-
-    D("client: connected on remote on fd %d\n", fd);
-    close_on_exec(fd);
-    disable_tcp_nagle(fd);
-    register_socket_transport(fd, serial, port, 0);
-    snprintf(buffer, buffer_size, "connected to %s", serial);
-}
-
-void connect_emulator(char* port_spec, char* buffer, int buffer_size)
-{
-    char* port_separator = strchr(port_spec, ',');
-    if (!port_separator) {
-        snprintf(buffer, buffer_size,
-                "unable to parse '%s' as <console port>,<adb port>",
-                port_spec);
-        return;
-    }
-
-    // Zero-terminate console port and make port_separator point to 2nd port.
-    *port_separator++ = 0;
-    int console_port = strtol(port_spec, NULL, 0);
-    int adb_port = strtol(port_separator, NULL, 0);
-    if (!(console_port > 0 && adb_port > 0)) {
-        *(port_separator - 1) = ',';
-        snprintf(buffer, buffer_size,
-                "Invalid port numbers: Expected positive numbers, got '%s'",
-                port_spec);
-        return;
-    }
-
-    /* Check if the emulator is already known.
-     * Note: There's a small but harmless race condition here: An emulator not
-     * present just yet could be registered by another invocation right
-     * after doing this check here. However, local_connect protects
-     * against double-registration too. From here, a better error message
-     * can be produced. In the case of the race condition, the very specific
-     * error message won't be shown, but the data doesn't get corrupted. */
-    atransport* known_emulator = find_emulator_transport_by_adb_port(adb_port);
-    if (known_emulator != NULL) {
-        snprintf(buffer, buffer_size,
-                "Emulator on port %d already registered.", adb_port);
-        return;
-    }
-
-    /* Check if more emulators can be registered. Similar unproblematic
-     * race condition as above. */
-    int candidate_slot = get_available_local_transport_index();
-    if (candidate_slot < 0) {
-        snprintf(buffer, buffer_size, "Cannot accept more emulators.");
-        return;
-    }
-
-    /* Preconditions met, try to connect to the emulator. */
-    if (!local_connect_arbitrary_ports(console_port, adb_port)) {
-        snprintf(buffer, buffer_size,
-                "Connected to emulator on ports %d,%d", console_port, adb_port);
-    } else {
-        snprintf(buffer, buffer_size,
-                "Could not connect to emulator on ports %d,%d",
-                console_port, adb_port);
-    }
-}
-#endif
-
-int handle_host_request(char *service, transport_type ttype, char* serial, int reply_fd, asocket *s)
-{
-    atransport *transport = NULL;
-    char buf[4096];
-
-    if(!strcmp(service, "kill")) {
-        fprintf(stderr,"adb server killed by remote request\n");
-        fflush(stdout);
-        adb_write(reply_fd, "OKAY", 4);
-        usb_cleanup();
-        exit(0);
-    }
-
-#if ADB_HOST
-    // "transport:" is used for switching transport with a specified serial number
-    // "transport-usb:" is used for switching transport to the only USB transport
-    // "transport-local:" is used for switching transport to the only local transport
-    // "transport-any:" is used for switching transport to the only transport
-    if (!strncmp(service, "transport", strlen("transport"))) {
-        char* error_string = "unknown failure";
-        transport_type type = kTransportAny;
-
-        if (!strncmp(service, "transport-usb", strlen("transport-usb"))) {
-            type = kTransportUsb;
-        } else if (!strncmp(service, "transport-local", strlen("transport-local"))) {
-            type = kTransportLocal;
-        } else if (!strncmp(service, "transport-any", strlen("transport-any"))) {
-            type = kTransportAny;
-        } else if (!strncmp(service, "transport:", strlen("transport:"))) {
-            service += strlen("transport:");
-            serial = service;
-        }
-
-        transport = acquire_one_transport(CS_ANY, type, serial, &error_string);
-
-        if (transport) {
-            s->transport = transport;
-            adb_write(reply_fd, "OKAY", 4);
-        } else {
-            sendfailmsg(reply_fd, error_string);
-        }
-        return 1;
-    }
-
-    // return a list of all connected devices
-    if (!strcmp(service, "devices")) {
-        char buffer[4096];
-        memset(buf, 0, sizeof(buf));
-        memset(buffer, 0, sizeof(buffer));
-        D("Getting device list \n");
-        list_transports(buffer, sizeof(buffer));
-        snprintf(buf, sizeof(buf), "OKAY%04x%s",(unsigned)strlen(buffer),buffer);
-        D("Wrote device list \n");
-        writex(reply_fd, buf, strlen(buf));
-        return 0;
-    }
-
-    // add a new TCP transport, device or emulator
-    if (!strncmp(service, "connect:", 8)) {
-        char buffer[4096];
-        char* host = service + 8;
-        if (!strncmp(host, "emu:", 4)) {
-            connect_emulator(host + 4, buffer, sizeof(buffer));
-        } else {
-            connect_device(host, buffer, sizeof(buffer));
-        }
-        // Send response for emulator and device
-        snprintf(buf, sizeof(buf), "OKAY%04x%s",(unsigned)strlen(buffer), buffer);
-        writex(reply_fd, buf, strlen(buf));
-        return 0;
-    }
-
-    // remove TCP transport
-    if (!strncmp(service, "disconnect:", 11)) {
-        char buffer[4096];
-        memset(buffer, 0, sizeof(buffer));
-        char* serial = service + 11;
-        if (serial[0] == 0) {
-            // disconnect from all TCP devices
-            unregister_all_tcp_transports();
-        } else {
-            char hostbuf[100];
-            // assume port 5555 if no port is specified
-            if (!strchr(serial, ':')) {
-                snprintf(hostbuf, sizeof(hostbuf) - 1, "%s:5555", serial);
-                serial = hostbuf;
-            }
-            atransport *t = find_transport(serial);
-
-            if (t) {
-                unregister_transport(t);
-            } else {
-                snprintf(buffer, sizeof(buffer), "No such device %s", serial);
-            }
-        }
-
-        snprintf(buf, sizeof(buf), "OKAY%04x%s",(unsigned)strlen(buffer), buffer);
-        writex(reply_fd, buf, strlen(buf));
-        return 0;
-    }
-
-    // returns our value for ADB_SERVER_VERSION
-    if (!strcmp(service, "version")) {
-        char version[12];
-        snprintf(version, sizeof version, "%04x", ADB_SERVER_VERSION);
-        snprintf(buf, sizeof buf, "OKAY%04x%s", (unsigned)strlen(version), version);
-        writex(reply_fd, buf, strlen(buf));
-        return 0;
-    }
-
-    if(!strncmp(service,"get-serialno",strlen("get-serialno"))) {
-        char *out = "unknown";
-         transport = acquire_one_transport(CS_ANY, ttype, serial, NULL);
-       if (transport && transport->serial) {
-            out = transport->serial;
-        }
-        snprintf(buf, sizeof buf, "OKAY%04x%s",(unsigned)strlen(out),out);
-        writex(reply_fd, buf, strlen(buf));
-        return 0;
-    }
-    // indicates a new emulator instance has started
-    if (!strncmp(service,"emulator:",9)) {
-        int  port = atoi(service+9);
-        local_connect(port);
-        /* we don't even need to send a reply */
-        return 0;
-    }
-#endif // ADB_HOST
-
-    if(!strncmp(service,"forward:",8) || !strncmp(service,"killforward:",12)) {
-        char *local, *remote, *err;
-        int r;
-        atransport *transport;
-
-        int createForward = strncmp(service,"kill",4);
-
-        local = service + (createForward ? 8 : 12);
-        remote = strchr(local,';');
-        if(remote == 0) {
-            sendfailmsg(reply_fd, "malformed forward spec");
-            return 0;
-        }
-
-        *remote++ = 0;
-        if((local[0] == 0) || (remote[0] == 0) || (remote[0] == '*')){
-            sendfailmsg(reply_fd, "malformed forward spec");
-            return 0;
-        }
-
-        transport = acquire_one_transport(CS_ANY, ttype, serial, &err);
-        if (!transport) {
-            sendfailmsg(reply_fd, err);
-            return 0;
-        }
-
-        if (createForward) {
-            r = install_listener(local, remote, transport);
-        } else {
-            r = remove_listener(local, remote, transport);
-        }
-        if(r == 0) {
-                /* 1st OKAY is connect, 2nd OKAY is status */
-            writex(reply_fd, "OKAYOKAY", 8);
-            return 0;
-        }
-
-        if (createForward) {
-            sendfailmsg(reply_fd, (r == -1) ? "cannot rebind smartsocket" : "cannot bind socket");
-        } else {
-            sendfailmsg(reply_fd, "cannot remove listener");
-        }
-        return 0;
-    }
-
-    if(!strncmp(service,"get-state",strlen("get-state"))) {
-        transport = acquire_one_transport(CS_ANY, ttype, serial, NULL);
-        char *state = connection_state_name(transport);
-        snprintf(buf, sizeof buf, "OKAY%04x%s",(unsigned)strlen(state),state);
-        writex(reply_fd, buf, strlen(buf));
-        return 0;
-    }
-    return -1;
-}
diff --git a/minadbd/adb.h b/minadbd/adb.h
index a989edd..98fa597 100644
--- a/minadbd/adb.h
+++ b/minadbd/adb.h
@@ -41,7 +41,6 @@
 typedef struct amessage amessage;
 typedef struct apacket apacket;
 typedef struct asocket asocket;
-typedef struct alistener alistener;
 typedef struct aservice aservice;
 typedef struct atransport atransport;
 typedef struct adisconnect  adisconnect;
@@ -134,7 +133,7 @@
 /* the adisconnect structure is used to record a callback that
 ** will be called whenever a transport is disconnected (e.g. by the user)
 ** this should be used to cleanup objects that depend on the
-** transport (e.g. remote sockets, listeners, etc...)
+** transport (e.g. remote sockets, etc...)
 */
 struct  adisconnect
 {
@@ -194,30 +193,6 @@
 };
 
 
-/* A listener is an entity which binds to a local port
-** and, upon receiving a connection on that port, creates
-** an asocket to connect the new local connection to a
-** specific remote service.
-**
-** TODO: some listeners read from the new connection to
-** determine what exact service to connect to on the far
-** side.
-*/
-struct alistener
-{
-    alistener *next;
-    alistener *prev;
-
-    fdevent fde;
-    int fd;
-
-    const char *local_name;
-    const char *connect_to;
-    atransport *transport;
-    adisconnect  disconnect;
-};
-
-
 void print_packet(const char *label, apacket *p);
 
 asocket *find_local_socket(unsigned id);
diff --git a/minadbd/services.c b/minadbd/services.c
index 8fc8b3c..aef37f7 100644
--- a/minadbd/services.c
+++ b/minadbd/services.c
@@ -53,6 +53,7 @@
 
     fd = adb_creat(ADB_SIDELOAD_FILENAME, 0644);
     if(fd < 0) {
+        fprintf(stderr, "failed to create %s\n", ADB_SIDELOAD_FILENAME);
         adb_close(s);
         return;
     }
diff --git a/minadbd/sockets.c b/minadbd/sockets.c
index 9f4cecb..2dd6461 100644
--- a/minadbd/sockets.c
+++ b/minadbd/sockets.c
@@ -413,22 +413,6 @@
     return s;
 }
 
-#if ADB_HOST
-static asocket *create_host_service_socket(const char *name, const char* serial)
-{
-    asocket *s;
-
-    s = host_service_to_socket(name, serial);
-
-    if (s != NULL) {
-        D("LS(%d) bound to '%s'\n", s->id, name);
-        return s;
-    }
-
-    return s;
-}
-#endif /* ADB_HOST */
-
 /* a Remote socket is used to send/receive data to/from a given transport object
 ** it needs to be closed when the transport is forcibly destroyed by the user
 */
@@ -612,11 +596,6 @@
 static int smart_socket_enqueue(asocket *s, apacket *p)
 {
     unsigned len;
-#if ADB_HOST
-    char *service = NULL;
-    char* serial = NULL;
-    transport_type ttype = kTransportAny;
-#endif
 
     D("SS(%d): enqueue %d\n", s->id, p->len);
 
@@ -658,84 +637,6 @@
 
     D("SS(%d): '%s'\n", s->id, (char*) (p->data + 4));
 
-#if ADB_HOST
-    service = (char *)p->data + 4;
-    if(!strncmp(service, "host-serial:", strlen("host-serial:"))) {
-        char* serial_end;
-        service += strlen("host-serial:");
-
-        // serial number should follow "host:" and could be a host:port string.
-        serial_end = skip_host_serial(service);
-        if (serial_end) {
-            *serial_end = 0; // terminate string
-            serial = service;
-            service = serial_end + 1;
-        }
-    } else if (!strncmp(service, "host-usb:", strlen("host-usb:"))) {
-        ttype = kTransportUsb;
-        service += strlen("host-usb:");
-    } else if (!strncmp(service, "host-local:", strlen("host-local:"))) {
-        ttype = kTransportLocal;
-        service += strlen("host-local:");
-    } else if (!strncmp(service, "host:", strlen("host:"))) {
-        ttype = kTransportAny;
-        service += strlen("host:");
-    } else {
-        service = NULL;
-    }
-
-    if (service) {
-        asocket *s2;
-
-            /* some requests are handled immediately -- in that
-            ** case the handle_host_request() routine has sent
-            ** the OKAY or FAIL message and all we have to do
-            ** is clean up.
-            */
-        if(handle_host_request(service, ttype, serial, s->peer->fd, s) == 0) {
-                /* XXX fail message? */
-            D( "SS(%d): handled host service '%s'\n", s->id, service );
-            goto fail;
-        }
-        if (!strncmp(service, "transport", strlen("transport"))) {
-            D( "SS(%d): okay transport\n", s->id );
-            p->len = 0;
-            return 0;
-        }
-
-            /* try to find a local service with this name.
-            ** if no such service exists, we'll fail out
-            ** and tear down here.
-            */
-        s2 = create_host_service_socket(service, serial);
-        if(s2 == 0) {
-            D( "SS(%d): couldn't create host service '%s'\n", s->id, service );
-            sendfailmsg(s->peer->fd, "unknown host service");
-            goto fail;
-        }
-
-            /* we've connected to a local host service,
-            ** so we make our peer back into a regular
-            ** local socket and bind it to the new local
-            ** service socket, acknowledge the successful
-            ** connection, and close this smart socket now
-            ** that its work is done.
-            */
-        adb_write(s->peer->fd, "OKAY", 4);
-
-        s->peer->ready = local_socket_ready;
-        s->peer->close = local_socket_close;
-        s->peer->peer = s2;
-        s2->peer = s->peer;
-        s->peer = 0;
-        D( "SS(%d): okay\n", s->id );
-        s->close(s);
-
-            /* initial state is "ready" */
-        s2->ready(s2);
-        return 0;
-    }
-#else /* !ADB_HOST */
     if (s->transport == NULL) {
         char* error_string = "unknown failure";
         s->transport = acquire_one_transport (CS_ANY,
@@ -746,7 +647,6 @@
             goto fail;
         }
     }
-#endif
 
     if(!(s->transport) || (s->transport->connection_state == CS_OFFLINE)) {
            /* if there's no remote we fail the connection
diff --git a/minadbd/sysdeps.h b/minadbd/sysdeps.h
index b518076..800ddb7 100644
--- a/minadbd/sysdeps.h
+++ b/minadbd/sysdeps.h
@@ -324,6 +324,18 @@
     return open( pathname, options, mode );
 }
 
+static __inline__  int  adb_creat(const char*  path, int  mode)
+{
+    int  fd = open(path, O_CREAT|O_WRONLY|O_TRUNC|O_NOFOLLOW, mode);
+
+    if ( fd < 0 )
+        return -1;
+
+    close_on_exec(fd);
+    return fd;
+}
+#undef   creat
+#define  creat  ___xxx_creat
 
 static __inline__ int  adb_open( const char*  pathname, int  options )
 {
@@ -380,19 +392,6 @@
 #undef  unlink
 #define unlink  ___xxx_unlink
 
-static __inline__  int  adb_creat(const char*  path, int  mode)
-{
-    int  fd = creat(path, mode);
-
-    if ( fd < 0 )
-        return -1;
-
-    close_on_exec(fd);
-    return fd;
-}
-#undef   creat
-#define  creat  ___xxx_creat
-
 static __inline__ int  adb_socket_accept(int  serverfd, struct sockaddr*  addr, socklen_t  *addrlen)
 {
     int fd;
diff --git a/minadbd/transport.c b/minadbd/transport.c
index 2f7bd27..ff20049 100644
--- a/minadbd/transport.c
+++ b/minadbd/transport.c
@@ -363,154 +363,10 @@
 static int transport_registration_recv = -1;
 static fdevent transport_registration_fde;
 
-
-#if ADB_HOST
-static int list_transports_msg(char*  buffer, size_t  bufferlen)
-{
-    char  head[5];
-    int   len;
-
-    len = list_transports(buffer+4, bufferlen-4);
-    snprintf(head, sizeof(head), "%04x", len);
-    memcpy(buffer, head, 4);
-    len += 4;
-    return len;
-}
-
-/* this adds support required by the 'track-devices' service.
- * this is used to send the content of "list_transport" to any
- * number of client connections that want it through a single
- * live TCP connection
- */
-typedef struct device_tracker  device_tracker;
-struct device_tracker {
-    asocket          socket;
-    int              update_needed;
-    device_tracker*  next;
-};
-
-/* linked list of all device trackers */
-static device_tracker*   device_tracker_list;
-
-static void
-device_tracker_remove( device_tracker*  tracker )
-{
-    device_tracker**  pnode = &device_tracker_list;
-    device_tracker*   node  = *pnode;
-
-    adb_mutex_lock( &transport_lock );
-    while (node) {
-        if (node == tracker) {
-            *pnode = node->next;
-            break;
-        }
-        pnode = &node->next;
-        node  = *pnode;
-    }
-    adb_mutex_unlock( &transport_lock );
-}
-
-static void
-device_tracker_close( asocket*  socket )
-{
-    device_tracker*  tracker = (device_tracker*) socket;
-    asocket*         peer    = socket->peer;
-
-    D( "device tracker %p removed\n", tracker);
-    if (peer) {
-        peer->peer = NULL;
-        peer->close(peer);
-    }
-    device_tracker_remove(tracker);
-    free(tracker);
-}
-
-static int
-device_tracker_enqueue( asocket*  socket, apacket*  p )
-{
-    /* you can't read from a device tracker, close immediately */
-    put_apacket(p);
-    device_tracker_close(socket);
-    return -1;
-}
-
-static int
-device_tracker_send( device_tracker*  tracker,
-                     const char*      buffer,
-                     int              len )
-{
-    apacket*  p = get_apacket();
-    asocket*  peer = tracker->socket.peer;
-
-    memcpy(p->data, buffer, len);
-    p->len = len;
-    return peer->enqueue( peer, p );
-}
-
-
-static void
-device_tracker_ready( asocket*  socket )
-{
-    device_tracker*  tracker = (device_tracker*) socket;
-
-    /* we want to send the device list when the tracker connects
-    * for the first time, even if no update occured */
-    if (tracker->update_needed > 0) {
-        char  buffer[1024];
-        int   len;
-
-        tracker->update_needed = 0;
-
-        len = list_transports_msg(buffer, sizeof(buffer));
-        device_tracker_send(tracker, buffer, len);
-    }
-}
-
-
-asocket*
-create_device_tracker(void)
-{
-    device_tracker*  tracker = calloc(1,sizeof(*tracker));
-
-    if(tracker == 0) fatal("cannot allocate device tracker");
-
-    D( "device tracker %p created\n", tracker);
-
-    tracker->socket.enqueue = device_tracker_enqueue;
-    tracker->socket.ready   = device_tracker_ready;
-    tracker->socket.close   = device_tracker_close;
-    tracker->update_needed  = 1;
-
-    tracker->next       = device_tracker_list;
-    device_tracker_list = tracker;
-
-    return &tracker->socket;
-}
-
-
-/* call this function each time the transport list has changed */
-void  update_transports(void)
-{
-    char             buffer[1024];
-    int              len;
-    device_tracker*  tracker;
-
-    len = list_transports_msg(buffer, sizeof(buffer));
-
-    tracker = device_tracker_list;
-    while (tracker != NULL) {
-        device_tracker*  next = tracker->next;
-        /* note: this may destroy the tracker if the connection is closed */
-        device_tracker_send(tracker, buffer, len);
-        tracker = next;
-    }
-}
-#else
 void  update_transports(void)
 {
     // nothing to do on the device side
 }
-#endif // ADB_HOST
 
 typedef struct tmsg tmsg;
 struct tmsg
@@ -822,64 +678,6 @@
     return result;
 }
 
-#if ADB_HOST
-static const char *statename(atransport *t)
-{
-    switch(t->connection_state){
-    case CS_OFFLINE: return "offline";
-    case CS_BOOTLOADER: return "bootloader";
-    case CS_DEVICE: return "device";
-    case CS_HOST: return "host";
-    case CS_RECOVERY: return "recovery";
-    case CS_SIDELOAD: return "sideload";
-    case CS_NOPERM: return "no permissions";
-    default: return "unknown";
-    }
-}
-
-int list_transports(char *buf, size_t  bufsize)
-{
-    char*       p   = buf;
-    char*       end = buf + bufsize;
-    int         len;
-    atransport *t;
-
-        /* XXX OVERRUN PROBLEMS XXX */
-    adb_mutex_lock(&transport_lock);
-    for(t = transport_list.next; t != &transport_list; t = t->next) {
-        const char* serial = t->serial;
-        if (!serial || !serial[0])
-            serial = "????????????";
-        len = snprintf(p, end - p, "%s\t%s\n", serial, statename(t));
-
-        if (p + len >= end) {
-            /* discard last line if buffer is too short */
-            break;
-        }
-        p += len;
-    }
-    p[0] = 0;
-    adb_mutex_unlock(&transport_lock);
-    return p - buf;
-}
-
-
-/* hack for osx */
-void close_usb_devices()
-{
-    atransport *t;
-
-    adb_mutex_lock(&transport_lock);
-    for(t = transport_list.next; t != &transport_list; t = t->next) {
-        if ( !t->kicked ) {
-            t->kicked = 1;
-            t->kick(t);
-        }
-    }
-    adb_mutex_unlock(&transport_lock);
-}
-#endif // ADB_HOST
-
 void register_socket_transport(int s, const char *serial, int port, int local)
 {
     atransport *t = calloc(1, sizeof(atransport));
@@ -901,61 +699,6 @@
     register_transport(t);
 }
 
-#if ADB_HOST
-atransport *find_transport(const char *serial)
-{
-    atransport *t;
-
-    adb_mutex_lock(&transport_lock);
-    for(t = transport_list.next; t != &transport_list; t = t->next) {
-        if (t->serial && !strcmp(serial, t->serial)) {
-            break;
-        }
-     }
-    adb_mutex_unlock(&transport_lock);
-
-    if (t != &transport_list)
-        return t;
-    else
-        return 0;
-}
-
-void unregister_transport(atransport *t)
-{
-    adb_mutex_lock(&transport_lock);
-    t->next->prev = t->prev;
-    t->prev->next = t->next;
-    adb_mutex_unlock(&transport_lock);
-
-    kick_transport(t);
-    transport_unref(t);
-}
-
-// unregisters all non-emulator TCP transports
-void unregister_all_tcp_transports()
-{
-    atransport *t, *next;
-    adb_mutex_lock(&transport_lock);
-    for (t = transport_list.next; t != &transport_list; t = next) {
-        next = t->next;
-        if (t->type == kTransportLocal && t->adb_port == 0) {
-            t->next->prev = t->prev;
-            t->prev->next = next;
-            // we cannot call kick_transport when holding transport_lock
-            if (!t->kicked)
-            {
-                t->kicked = 1;
-                t->kick(t);
-            }
-            transport_unref_locked(t);
-        }
-     }
-
-    adb_mutex_unlock(&transport_lock);
-}
-
-#endif
-
 void register_usb_transport(usb_handle *usb, const char *serial, unsigned writeable)
 {
     atransport *t = calloc(1, sizeof(atransport));
diff --git a/minadbd/transport_usb.c b/minadbd/transport_usb.c
index ee6b637..91cbf61 100644
--- a/minadbd/transport_usb.c
+++ b/minadbd/transport_usb.c
@@ -23,10 +23,6 @@
 #define  TRACE_TAG  TRACE_TRANSPORT
 #include "adb.h"
 
-#if ADB_HOST
-#include "usb_vendors.h"
-#endif
-
 #ifdef HAVE_BIG_ENDIAN
 #define H4(x)	(((x) & 0xFF000000) >> 24) | (((x) & 0x00FF0000) >> 8) | (((x) & 0x0000FF00) << 8) | (((x) & 0x000000FF) << 24)
 static inline void fix_endians(apacket *p)
@@ -121,28 +117,5 @@
     t->type = kTransportUsb;
     t->usb = h;
 
-#if ADB_HOST
-    HOST = 1;
-#else
     HOST = 0;
-#endif
 }
-
-#if ADB_HOST
-int is_adb_interface(int vid, int pid, int usb_class, int usb_subclass, int usb_protocol)
-{
-    unsigned i;
-    for (i = 0; i < vendorIdCount; i++) {
-        if (vid == vendorIds[i]) {
-            if (usb_class == ADB_CLASS && usb_subclass == ADB_SUBCLASS &&
-                    usb_protocol == ADB_PROTOCOL) {
-                return 1;
-            }
-
-            return 0;
-        }
-    }
-
-    return 0;
-}
-#endif
diff --git a/minelf/Retouch.c b/minelf/Retouch.c
index 33809cd..d75eec1 100644
--- a/minelf/Retouch.c
+++ b/minelf/Retouch.c
@@ -194,213 +194,3 @@
     if (retouch_offset != NULL) *retouch_offset = offset_candidate;
     return RETOUCH_DATA_MATCHED;
 }
-
-// On success, _override is set to the offset that was actually applied.
-// This implies that once we randomize to an offset we stick with it.
-// This in turn is necessary in order to guarantee recovery after crash.
-bool retouch_one_library(const char *binary_name,
-                         const char *binary_sha1,
-                         int32_t retouch_offset,
-                         int32_t *retouch_offset_override) {
-    bool success = true;
-    int result;
-
-    FileContents file;
-    file.data = NULL;
-
-    char binary_name_atomic[strlen(binary_name)+10];
-    strcpy(binary_name_atomic, binary_name);
-    strcat(binary_name_atomic, ".atomic");
-
-    // We need a path that exists for calling statfs() later.
-    //
-    // Assume that binary_name (eg "/system/app/Foo.apk") is located
-    // on the same filesystem as its top-level directory ("/system").
-    char target_fs[strlen(binary_name)+1];
-    char* slash = strchr(binary_name+1, '/');
-    if (slash != NULL) {
-        int count = slash - binary_name;
-        strncpy(target_fs, binary_name, count);
-        target_fs[count] = '\0';
-    } else {
-        strcpy(target_fs, binary_name);
-    }
-
-    result = LoadFileContents(binary_name, &file, RETOUCH_DONT_MASK);
-
-    if (result == 0) {
-        // Figure out the *apparent* offset to which this file has been
-        // retouched. If it looks good, we will skip processing (we might
-        // have crashed and during this recovery pass we don't want to
-        // overwrite a valuable saved file in /cache---which would happen
-        // if we blindly retouch everything again). NOTE: This implies
-        // that we might have to override the supplied retouch offset. We
-        // can do the override only once though: everything should match
-        // afterward.
-
-        int32_t inferred_offset;
-        int retouch_probe_result = retouch_mask_data(file.data,
-                                                     file.size,
-                                                     NULL,
-                                                     &inferred_offset);
-
-        if (retouch_probe_result == RETOUCH_DATA_MATCHED) {
-            if ((retouch_offset == inferred_offset) ||
-                ((retouch_offset != 0 && inferred_offset != 0) &&
-                 (retouch_offset_override != NULL))) {
-                // This file is OK already and we are allowed to override.
-                // Let's just return the offset override value. It is critical
-                // to skip regardless of override: a broken file might need
-                // recovery down the list and we should not mess up the saved
-                // copy by doing unnecessary retouching.
-                //
-                // NOTE: If retouching was already started with a different
-                // value, we will not be allowed to override. This happens
-                // if on the retouch list there is a patched binary (which is
-                // masked in apply_patch()) before there is a non-patched
-                // binary.
-                if (retouch_offset_override != NULL)
-                    *retouch_offset_override = inferred_offset;
-                success = true;
-                goto out;
-            } else {
-                // Retouch to zero (mask the retouching), to make sure that
-                // the SHA-1 check will pass below.
-                int32_t zero = 0;
-                retouch_mask_data(file.data, file.size, &zero, NULL);
-                SHA(file.data, file.size, file.sha1);
-            }
-        }
-
-        if (retouch_probe_result == RETOUCH_DATA_NOTAPPLICABLE) {
-            // In the case of not retouchable, fake it. We do not want
-            // to do the normal processing and overwrite the backup file:
-            // we might be recovering!
-            //
-            // We return a zero override, which tells the caller that we
-            // simply skipped the file.
-            if (retouch_offset_override != NULL)
-                *retouch_offset_override = 0;
-            success = true;
-            goto out;
-        }
-
-        // If we get here, either there was a mismatch in the offset, or
-        // the file has not been processed yet. Continue with normal
-        // processing.
-    }
-
-    if (result != 0 || FindMatchingPatch(file.sha1, &binary_sha1, 1) < 0) {
-        free(file.data);
-        printf("Attempting to recover source from '%s' ...\n",
-               CACHE_TEMP_SOURCE);
-        result = LoadFileContents(CACHE_TEMP_SOURCE, &file, RETOUCH_DO_MASK);
-        if (result != 0 || FindMatchingPatch(file.sha1, &binary_sha1, 1) < 0) {
-            printf(" failed.\n");
-            success = false;
-            goto out;
-        }
-        printf(" succeeded.\n");
-    }
-
-    // Retouch in-memory before worrying about backing up the original.
-    //
-    // Recovery steps will be oblivious to the actual retouch offset used,
-    // so might as well write out the already-retouched copy. Then, in the
-    // usual case, we will just swap the file locally, with no more writes
-    // needed. In the no-free-space case, we will then write the same to the
-    // original location.
-
-    result = retouch_mask_data(file.data, file.size, &retouch_offset, NULL);
-    if (result != RETOUCH_DATA_MATCHED) {
-        success = false;
-        goto out;
-    }
-    if (retouch_offset_override != NULL)
-        *retouch_offset_override = retouch_offset;
-
-    // How much free space do we need?
-    bool enough_space = false;
-    size_t free_space = FreeSpaceForFile(target_fs);
-    // 50% margin when estimating the space needed.
-    enough_space = (free_space > (file.size * 3 / 2));
-
-    // The experts say we have to allow for a retry of the
-    // whole process to avoid filesystem weirdness.
-    int retry = 1;
-    bool made_copy = false;
-    do {
-        // First figure out where to store a copy of the original.
-        // Ideally leave the original itself intact until the
-        // atomic swap. If no room on the same partition, fall back
-        // to the cache partition and remove the original.
-
-        if (!enough_space) {
-            printf("Target is %ldB; free space is %ldB: not enough.\n",
-                   (long)file.size, (long)free_space);
-
-            retry = 0;
-            if (MakeFreeSpaceOnCache(file.size) < 0) {
-                printf("Not enough free space on '/cache'.\n");
-                success = false;
-                goto out;
-            }
-            if (SaveFileContents(CACHE_TEMP_SOURCE, file) < 0) {
-                printf("Failed to back up source file.\n");
-                success = false;
-                goto out;
-            }
-            made_copy = true;
-            unlink(binary_name);
-
-            size_t free_space = FreeSpaceForFile(target_fs);
-            printf("(now %ld bytes free for target)\n", (long)free_space);
-        }
-
-        result = SaveFileContents(binary_name_atomic, file);
-        if (result != 0) {
-            // Maybe the filesystem was optimistic: retry.
-            enough_space = false;
-            unlink(binary_name_atomic);
-            printf("Saving the retouched contents failed; retrying.\n");
-            continue;
-        }
-
-        // Succeeded; no need to retry.
-        break;
-    } while (retry-- > 0);
-
-    // Give the .atomic file the same owner, group, and mode of the
-    // original source file.
-    if (chmod(binary_name_atomic, file.st.st_mode) != 0) {
-        printf("chmod of \"%s\" failed: %s\n",
-               binary_name_atomic, strerror(errno));
-        success = false;
-        goto out;
-    }
-    if (chown(binary_name_atomic, file.st.st_uid, file.st.st_gid) != 0) {
-        printf("chown of \"%s\" failed: %s\n",
-               binary_name_atomic,
-               strerror(errno));
-        success = false;
-        goto out;
-    }
-
-    // Finally, rename the .atomic file to replace the target file.
-    if (rename(binary_name_atomic, binary_name) != 0) {
-        printf("rename of .atomic to \"%s\" failed: %s\n",
-               binary_name, strerror(errno));
-        success = false;
-        goto out;
-    }
-
-    // If this run created a copy, and we're here, we can delete it.
-    if (made_copy) unlink(CACHE_TEMP_SOURCE);
-
-  out:
-    // clean up
-    free(file.data);
-    unlink(binary_name_atomic);
-
-    return success;
-}
diff --git a/minelf/Retouch.h b/minelf/Retouch.h
index 048d78e..13bacd5 100644
--- a/minelf/Retouch.h
+++ b/minelf/Retouch.h
@@ -25,12 +25,6 @@
   uint32_t blob_size; /* in bytes, located right before this struct */
 } retouch_info_t __attribute__((packed));
 
-// Retouch a file. Use CACHED_SOURCE_TEMP to store a copy.
-bool retouch_one_library(const char *binary_name,
-                         const char *binary_sha1,
-                         int32_t retouch_offset,
-                         int32_t *retouch_offset_override);
-
 #define RETOUCH_DONT_MASK           0
 #define RETOUCH_DO_MASK             1
 
diff --git a/mtdutils/flash_image.c b/mtdutils/flash_image.c
index c776876..a39d600 100644
--- a/mtdutils/flash_image.c
+++ b/mtdutils/flash_image.c
@@ -42,7 +42,7 @@
     }
 
     fprintf(stderr, "%s\n", buf);
-    LOGE("%s\n", buf);
+    ALOGE("%s\n", buf);
     exit(1);
 }
 
@@ -74,23 +74,23 @@
 
     MtdReadContext *in = mtd_read_partition(partition);
     if (in == NULL) {
-        LOGW("error opening %s: %s\n", argv[1], strerror(errno));
+        ALOGW("error opening %s: %s\n", argv[1], strerror(errno));
         // just assume it needs re-writing
     } else {
         char check[HEADER_SIZE];
         int checklen = mtd_read_data(in, check, sizeof(check));
         if (checklen <= 0) {
-            LOGW("error reading %s: %s\n", argv[1], strerror(errno));
+            ALOGW("error reading %s: %s\n", argv[1], strerror(errno));
             // just assume it needs re-writing
         } else if (checklen == headerlen && !memcmp(header, check, headerlen)) {
-            LOGI("header is the same, not flashing %s\n", argv[1]);
+            ALOGI("header is the same, not flashing %s\n", argv[1]);
             return 0;
         }
         mtd_read_close(in);
     }
 
     // Skip the header (we'll come back to it), write everything else
-    LOGI("flashing %s from %s\n", argv[1], argv[2]);
+    ALOGI("flashing %s from %s\n", argv[1], argv[2]);
 
     MtdWriteContext *out = mtd_write_partition(partition);
     if (out == NULL) die("error writing %s", argv[1]);
diff --git a/recovery.cpp b/recovery.cpp
index 3f95372..726442b 100644
--- a/recovery.cpp
+++ b/recovery.cpp
@@ -682,6 +682,10 @@
                 break;
 
             case Device::APPLY_EXT:
+                // Some packages expect /cache to be mounted (eg,
+                // standard incremental packages expect to use /cache
+                // as scratch space).
+                ensure_path_mounted(CACHE_ROOT);
                 status = update_directory(SDCARD_ROOT, SDCARD_ROOT, &wipe_cache, device);
                 if (status == INSTALL_SUCCESS && wipe_cache) {
                     ui->Print("\n-- Wiping cache (at package request)...\n");
diff --git a/updater/install.c b/updater/install.c
index f68bd03..c087d4e 100644
--- a/updater/install.c
+++ b/updater/install.c
@@ -33,7 +33,6 @@
 #include "edify/expr.h"
 #include "mincrypt/sha.h"
 #include "minzip/DirUtil.h"
-#include "minelf/Retouch.h"
 #include "mtdutils/mounts.h"
 #include "mtdutils/mtdutils.h"
 #include "updater.h"
@@ -435,121 +434,6 @@
 }
 
 
-// retouch_binaries(lib1, lib2, ...)
-Value* RetouchBinariesFn(const char* name, State* state,
-                         int argc, Expr* argv[]) {
-    UpdaterInfo* ui = (UpdaterInfo*)(state->cookie);
-
-    char **retouch_entries  = ReadVarArgs(state, argc, argv);
-    if (retouch_entries == NULL) {
-        return StringValue(strdup("t"));
-    }
-
-    // some randomness from the clock
-    int32_t override_base;
-    bool override_set = false;
-    int32_t random_base = time(NULL) % 1024;
-    // some more randomness from /dev/random
-    FILE *f_random = fopen("/dev/random", "rb");
-    uint16_t random_bits = 0;
-    if (f_random != NULL) {
-        fread(&random_bits, 2, 1, f_random);
-        random_bits = random_bits % 1024;
-        fclose(f_random);
-    }
-    random_base = (random_base + random_bits) % 1024;
-    fprintf(ui->cmd_pipe, "ui_print Random offset: 0x%x\n", random_base);
-    fprintf(ui->cmd_pipe, "ui_print\n");
-
-    // make sure we never randomize to zero; this let's us look at a file
-    // and know for sure whether it has been processed; important in the
-    // crash recovery process
-    if (random_base == 0) random_base = 1;
-    // make sure our randomization is page-aligned
-    random_base *= -0x1000;
-    override_base = random_base;
-
-    int i = 0;
-    bool success = true;
-    while (i < (argc - 1)) {
-        success = success && retouch_one_library(retouch_entries[i],
-                                                 retouch_entries[i+1],
-                                                 random_base,
-                                                 override_set ?
-                                                   NULL :
-                                                   &override_base);
-        if (!success)
-            ErrorAbort(state, "Failed to retouch '%s'.", retouch_entries[i]);
-
-        free(retouch_entries[i]);
-        free(retouch_entries[i+1]);
-        i += 2;
-
-        if (success && override_base != 0) {
-            random_base = override_base;
-            override_set = true;
-        }
-    }
-    if (i < argc) {
-        free(retouch_entries[i]);
-        success = false;
-    }
-    free(retouch_entries);
-
-    if (!success) {
-      Value* v = malloc(sizeof(Value));
-      v->type = VAL_STRING;
-      v->data = NULL;
-      v->size = -1;
-      return v;
-    }
-    return StringValue(strdup("t"));
-}
-
-
-// undo_retouch_binaries(lib1, lib2, ...)
-Value* UndoRetouchBinariesFn(const char* name, State* state,
-                             int argc, Expr* argv[]) {
-    UpdaterInfo* ui = (UpdaterInfo*)(state->cookie);
-
-    char **retouch_entries  = ReadVarArgs(state, argc, argv);
-    if (retouch_entries == NULL) {
-        return StringValue(strdup("t"));
-    }
-
-    int i = 0;
-    bool success = true;
-    int32_t override_base;
-    while (i < (argc-1)) {
-        success = success && retouch_one_library(retouch_entries[i],
-                                                 retouch_entries[i+1],
-                                                 0 /* undo => offset==0 */,
-                                                 NULL);
-        if (!success)
-            ErrorAbort(state, "Failed to unretouch '%s'.",
-                       retouch_entries[i]);
-
-        free(retouch_entries[i]);
-        free(retouch_entries[i+1]);
-        i += 2;
-    }
-    if (i < argc) {
-        free(retouch_entries[i]);
-        success = false;
-    }
-    free(retouch_entries);
-
-    if (!success) {
-      Value* v = malloc(sizeof(Value));
-      v->type = VAL_STRING;
-      v->data = NULL;
-      v->size = -1;
-      return v;
-    }
-    return StringValue(strdup("t"));
-}
-
-
 // symlink target src1 src2 ...
 //    unlinks any previously existing src1, src2, etc before creating symlinks.
 Value* SymlinkFn(const char* name, State* state, int argc, Expr* argv[]) {
@@ -1190,8 +1074,6 @@
     RegisterFunction("delete_recursive", DeleteFn);
     RegisterFunction("package_extract_dir", PackageExtractDirFn);
     RegisterFunction("package_extract_file", PackageExtractFileFn);
-    RegisterFunction("retouch_binaries", RetouchBinariesFn);
-    RegisterFunction("undo_retouch_binaries", UndoRetouchBinariesFn);
     RegisterFunction("symlink", SymlinkFn);
     RegisterFunction("set_perm", SetPermFn);
     RegisterFunction("set_perm_recursive", SetPermFn);