let the "firmware" command take the file straight from the package

To do a firmware-install-on-reboot, the update binary tells recovery
what file to install before rebooting.  Let this file be specified as
"PACKAGE:<foo>" to indicate taking the file out of the OTA package,
avoiding an extra copy to /tmp.  Bump the API version number to
reflect this change.
diff --git a/install.c b/install.c
index c2e1385..cbb3580 100644
--- a/install.c
+++ b/install.c
@@ -117,34 +117,54 @@
 // The update binary ask us to install a firmware file on reboot.  Set
 // that up.  Takes ownership of type and filename.
 static int
-handle_firmware_update(char* type, char* filename) {
-    struct stat st_data;
-    if (stat(filename, &st_data) < 0) {
-        LOGE("Error stat'ing %s: %s\n", filename, strerror(errno));
-        return INSTALL_ERROR;
+handle_firmware_update(char* type, char* filename, ZipArchive* zip) {
+    unsigned int data_size;
+    const ZipEntry* entry = NULL;
+
+    if (strncmp(filename, "PACKAGE:", 8) == 0) {
+        entry = mzFindZipEntry(zip, filename+8);
+        if (entry == NULL) {
+            LOGE("Failed to find \"%s\" in package", filename+8);
+            return INSTALL_ERROR;
+        }
+        data_size = entry->uncompLen;
+    } else {
+        struct stat st_data;
+        if (stat(filename, &st_data) < 0) {
+            LOGE("Error stat'ing %s: %s\n", filename, strerror(errno));
+            return INSTALL_ERROR;
+        }
+        data_size = st_data.st_size;
     }
 
     LOGI("type is %s; size is %d; file is %s\n",
-         type, (int)st_data.st_size, filename);
+         type, data_size, filename);
 
-    char* data = malloc(st_data.st_size);
+    char* data = malloc(data_size);
     if (data == NULL) {
-        LOGE("Can't allocate %d bytes for firmware data\n", st_data.st_size);
+        LOGI("Can't allocate %d bytes for firmware data\n", data_size);
         return INSTALL_ERROR;
     }
 
-    FILE* f = fopen(filename, "rb");
-    if (f == NULL) {
-        LOGE("Failed to open %s: %s\n", filename, strerror(errno));
-        return INSTALL_ERROR;
+    if (entry) {
+        if (mzReadZipEntry(zip, entry, data, data_size) == false) {
+            LOGE("Failed to read \"%s\" from package", filename+8);
+            return INSTALL_ERROR;
+        }
+    } else {
+        FILE* f = fopen(filename, "rb");
+        if (f == NULL) {
+            LOGE("Failed to open %s: %s\n", filename, strerror(errno));
+            return INSTALL_ERROR;
+        }
+        if (fread(data, 1, data_size, f) != data_size) {
+            LOGE("Failed to read firmware data: %s\n", strerror(errno));
+            return INSTALL_ERROR;
+        }
+        fclose(f);
     }
-    if (fread(data, 1, st_data.st_size, f) != st_data.st_size) {
-        LOGE("Failed to read firmware data: %s\n", strerror(errno));
-        return INSTALL_ERROR;
-    }
-    fclose(f);
 
-    if (remember_firmware_update(type, data, st_data.st_size)) {
+    if (remember_firmware_update(type, data, data_size)) {
         LOGE("Can't store %s image\n", type);
         free(data);
         return INSTALL_ERROR;
@@ -184,7 +204,7 @@
     // When executing the update binary contained in the package, the
     // arguments passed are:
     //
-    //   - the version number for this interface (currently 1)
+    //   - the version number for this interface
     //
     //   - an fd to which the program can write in order to update the
     //     progress bar.  The program can write single-line commands:
@@ -194,7 +214,9 @@
     //
     //        firmware <"hboot"|"radio"> <filename>
     //            arrange to install the contents of <filename> in the
-    //            given partition on reboot.
+    //            given partition on reboot.  (API v2: <filename> may
+    //            start with "PACKAGE:" to indicate taking a file from
+    //            the OTA package.)
     //
     //        ui_print <string>
     //            display <string> on the screen.
@@ -204,7 +226,7 @@
 
     char** args = malloc(sizeof(char*) * 5);
     args[0] = binary;
-    args[1] = "1";
+    args[1] = EXPAND(RECOVERY_API_VERSION);   // defined in Android.mk
     args[2] = malloc(10);
     sprintf(args[2], "%d", pipefd[1]);
     args[3] = (char*)path;
@@ -272,7 +294,7 @@
     }
 
     if (firmware_type != NULL) {
-        return handle_firmware_update(firmware_type, firmware_filename);
+        return handle_firmware_update(firmware_type, firmware_filename, zip);
     } else {
         return INSTALL_SUCCESS;
     }