Merge "Start losing code to libadb."
diff --git a/Android.mk b/Android.mk
index b55bb4e..5847ad9 100644
--- a/Android.mk
+++ b/Android.mk
@@ -93,7 +93,6 @@
 endif
 
 LOCAL_C_INCLUDES += system/extras/ext4_utils
-LOCAL_C_INCLUDES += external/openssl/include
 
 include $(BUILD_EXECUTABLE)
 
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/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/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/uncrypt/uncrypt.c b/uncrypt/uncrypt.c
index 189fa57..e619237 100644
--- a/uncrypt/uncrypt.c
+++ b/uncrypt/uncrypt.c
@@ -39,6 +39,7 @@
 // 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 <stdarg.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/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"