applypatch: add support for BML partitions

This actually uses the EMMC partition access code. In order for this
to work, the BML partition name is changed back to the block
device name (e.g. "boot" -> "/dev/block/bml9"), and the
BML_UNLOCK_ALL ioctl is called before writing.

Change-Id: I012f1eca0b486b7465ca38b5db1f513ee8a246ea
diff --git a/applypatch/Android.mk b/applypatch/Android.mk
index a146dfa..98981a6 100644
--- a/applypatch/Android.mk
+++ b/applypatch/Android.mk
@@ -15,6 +15,14 @@
 LOCAL_PATH := $(call my-dir)
 include $(CLEAR_VARS)
 
+BOARD_RECOVERY_DEFINES := BOARD_BML_BOOT BOARD_BML_RECOVERY
+
+$(foreach board_define,$(BOARD_RECOVERY_DEFINES), \
+  $(if $($(board_define)), \
+    $(eval LOCAL_CFLAGS += -D$(board_define)=\"$($(board_define))\") \
+  ) \
+  )
+
 LOCAL_SRC_FILES := applypatch.c bspatch.c freecache.c imgpatch.c utils.c
 LOCAL_MODULE := libapplypatch
 LOCAL_MODULE_TAGS := eng
diff --git a/applypatch/applypatch.c b/applypatch/applypatch.c
index 6b8da2a..b5ff12c 100644
--- a/applypatch/applypatch.c
+++ b/applypatch/applypatch.c
@@ -27,6 +27,7 @@
 
 #include "mincrypt/sha.h"
 #include "applypatch.h"
+#include "bmlutils/bmlutils.h"
 #include "mtdutils/mtdutils.h"
 #include "edify/expr.h"
 
@@ -57,7 +58,8 @@
     // A special 'filename' beginning with "MTD:" or "EMMC:" means to
     // load the contents of a partition.
     if (strncmp(filename, "MTD:", 4) == 0 ||
-        strncmp(filename, "EMMC:", 5) == 0) {
+        strncmp(filename, "EMMC:", 5) == 0 ||
+        strncmp(filename, "BML:", 4) == 0) {
         return LoadPartitionContents(filename, file);
     }
 
@@ -147,6 +149,8 @@
         type = MTD;
     } else if (strcmp(magic, "EMMC") == 0) {
         type = EMMC;
+    } else if (strcmp(magic, "BML") == 0) {
+        type = EMMC;
     } else {
         printf("LoadPartitionContents called with bad filename (%s)\n",
                filename);
@@ -154,6 +158,14 @@
     }
     const char* partition = strtok(NULL, ":");
 
+    if (strcmp(magic, "BML") == 0) {
+        if (strcmp(partition, "boot") == 0) {
+            partition = BOARD_BML_BOOT;
+        } else if (strcmp(partition, "recovery") == 0) {
+            partition = BOARD_BML_RECOVERY;
+        }
+    }
+
     int i;
     int colons = 0;
     for (i = 0; filename[i] != '\0'; ++i) {
@@ -368,12 +380,31 @@
         type = MTD;
     } else if (strcmp(magic, "EMMC") == 0) {
         type = EMMC;
+    } else if (strcmp(magic, "BML") == 0) {
+        type = EMMC;
     } else {
         printf("WriteToPartition called with bad target (%s)\n", target);
         return -1;
     }
     const char* partition = strtok(NULL, ":");
 
+    if (strcmp(magic, "BML") == 0) {
+        if (strcmp(partition, "boot") == 0) {
+            partition = BOARD_BML_BOOT;
+        } else if (strcmp(partition, "recovery") == 0) {
+            partition = BOARD_BML_RECOVERY;
+        }
+
+        int bmlpartition = open(partition, O_RDWR | O_LARGEFILE);
+        if (bmlpartition < 0)
+            return -1;
+        if (ioctl(bmlpartition, BML_UNLOCK_ALL, 0)) {
+            printf("failed to unlock BML partition: (%s)\n", partition);
+            return -1;
+        }
+        close(bmlpartition);
+    }
+
     if (partition == NULL) {
         printf("bad partition target name \"%s\"\n", target);
         return -1;
@@ -845,7 +876,8 @@
         // file?
 
         if (strncmp(target_filename, "MTD:", 4) == 0 ||
-            strncmp(target_filename, "EMMC:", 5) == 0) {
+            strncmp(target_filename, "EMMC:", 5) == 0 ||
+            strncmp(target_filename, "BML:", 4) == 0) {
             // If the target is a partition, we're actually going to
             // write the output to /tmp and then copy it to the
             // partition.  statfs() always returns 0 blocks free for
@@ -887,7 +919,8 @@
                 // location.
 
                 if (strncmp(source_filename, "MTD:", 4) == 0 ||
-                    strncmp(source_filename, "EMMC:", 5) == 0) {
+                    strncmp(source_filename, "EMMC:", 5) == 0 ||
+                    strncmp(source_filename, "BML:", 4) == 0) {
                     // It's impossible to free space on the target filesystem by
                     // deleting the source if the source is a partition.  If
                     // we're ever in a state where we need to do this, fail.
@@ -932,7 +965,8 @@
         output = -1;
         outname = NULL;
         if (strncmp(target_filename, "MTD:", 4) == 0 ||
-            strncmp(target_filename, "EMMC:", 5) == 0) {
+            strncmp(target_filename, "EMMC:", 5) == 0 ||
+            strncmp(target_filename, "BML:", 4) == 0) {
             // We store the decoded output in memory.
             msi.buffer = malloc(target_size);
             if (msi.buffer == NULL) {
diff --git a/bmlutils/bmlutils.c b/bmlutils/bmlutils.c
index 54b67f5..d59475e 100644
--- a/bmlutils/bmlutils.c
+++ b/bmlutils/bmlutils.c
@@ -20,15 +20,7 @@
 #include <signal.h>
 #include <sys/wait.h>
 
-#define BML_UNLOCK_ALL				0x8A29		///< unlock all partition RO -> RW
-
-#ifndef BOARD_BML_BOOT
-#define BOARD_BML_BOOT              "/dev/block/bml7"
-#endif
-
-#ifndef BOARD_BML_RECOVERY
-#define BOARD_BML_RECOVERY          "/dev/block/bml8"
-#endif
+#include <bmlutils.h>
 
 #undef _PATH_BSHELL
 #define _PATH_BSHELL "/sbin/sh"
diff --git a/bmlutils/bmlutils.h b/bmlutils/bmlutils.h
index e6ffeee..1e85f08 100644
--- a/bmlutils/bmlutils.h
+++ b/bmlutils/bmlutils.h
@@ -3,4 +3,14 @@
 
 int format_rfs_device (const char *device, const char *path);
 
+#define BML_UNLOCK_ALL				0x8A29		///< unlock all partition RO -> RW
+
+#ifndef BOARD_BML_BOOT
+#define BOARD_BML_BOOT              "/dev/block/bml7"
+#endif
+
+#ifndef BOARD_BML_RECOVERY
+#define BOARD_BML_RECOVERY          "/dev/block/bml8"
+#endif
+
 #endif // BMLUTILS_H_