diff options
author | Koushik Dutta <koushd@gmail.com> | 2010-12-18 17:42:31 -0800 |
---|---|---|
committer | Koushik Dutta <koushd@gmail.com> | 2010-12-18 17:42:31 -0800 |
commit | df1e4067821353af7a006ef4d70b7001ad3bd924 (patch) | |
tree | 874fd5be1d93fb75610bf1d14925799934127977 /install.c | |
parent | 5d6309e77f6055a9aec062dd991d071054726ebb (diff) | |
parent | 0b7bbf29d5864fc2939ab9b954c0e1d18a24bffd (diff) | |
download | bootable_recovery-df1e4067821353af7a006ef4d70b7001ad3bd924.zip bootable_recovery-df1e4067821353af7a006ef4d70b7001ad3bd924.tar.gz bootable_recovery-df1e4067821353af7a006ef4d70b7001ad3bd924.tar.bz2 |
Merge from ClockworkMod recovery
Change-Id: Id5b312147173ced559a62d97029acede6c2f8766
Diffstat (limited to 'install.c')
-rw-r--r-- | install.c | 125 |
1 files changed, 104 insertions, 21 deletions
@@ -28,14 +28,74 @@ #include "minui/minui.h" #include "minzip/SysUtil.h" #include "minzip/Zip.h" -#include "mtdutils/mounts.h" +#include "mounts.h" #include "mtdutils/mtdutils.h" #include "roots.h" #include "verifier.h" +#include "firmware.h" + +#include "extendedcommands.h" + + #define ASSUMED_UPDATE_BINARY_NAME "META-INF/com/google/android/update-binary" #define PUBLIC_KEYS_FILE "/res/keys" +// 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, 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, data_size, filename); + + char* data = malloc(data_size); + if (data == NULL) { + LOGI("Can't allocate %d bytes for firmware data\n", data_size); + 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); + } + + free(filename); + + return INSTALL_SUCCESS; +} + // If the package contains an update binary, extract it and run it. static int try_update_binary(const char *path, ZipArchive *zip) { @@ -43,7 +103,7 @@ try_update_binary(const char *path, ZipArchive *zip) { mzFindZipEntry(zip, ASSUMED_UPDATE_BINARY_NAME); if (binary_entry == NULL) { mzCloseZipArchive(zip); - return INSTALL_CORRUPT; + return INSTALL_UPDATE_BINARY_MISSING; } char* binary = "/tmp/update_binary"; @@ -117,6 +177,9 @@ try_update_binary(const char *path, ZipArchive *zip) { } close(pipefd[1]); + char* firmware_type = NULL; + char* firmware_filename = NULL; + char buffer[1024]; FILE* from_child = fdopen(pipefd[0], "r"); while (fgets(buffer, sizeof(buffer), from_child) != NULL) { @@ -136,6 +199,18 @@ try_update_binary(const char *path, ZipArchive *zip) { char* fraction_s = strtok(NULL, " \n"); float fraction = strtof(fraction_s, NULL); ui_set_progress(fraction); + } else if (strcmp(command, "firmware") == 0) { + char* type = strtok(NULL, " \n"); + char* filename = strtok(NULL, " \n"); + + if (type != NULL && filename != NULL) { + if (firmware_type != NULL) { + LOGE("ignoring attempt to do multiple firmware updates"); + } else { + firmware_type = strdup(type); + firmware_filename = strdup(filename); + } + } } else if (strcmp(command, "ui_print") == 0) { char* str = strtok(NULL, "\n"); if (str) { @@ -156,6 +231,11 @@ try_update_binary(const char *path, ZipArchive *zip) { return INSTALL_ERROR; } + if (firmware_type != NULL) { + return handle_firmware_update(firmware_type, firmware_filename, zip); + } else { + return INSTALL_SUCCESS; + } return INSTALL_SUCCESS; } @@ -248,27 +328,30 @@ install_package(const char *path) ui_print("Opening update package...\n"); - int numKeys; - RSAPublicKey* loadedKeys = load_keys(PUBLIC_KEYS_FILE, &numKeys); - if (loadedKeys == NULL) { - LOGE("Failed to load keys\n"); - return INSTALL_CORRUPT; - } - LOGI("%d key(s) loaded from %s\n", numKeys, PUBLIC_KEYS_FILE); + int err; + + if (signature_check_enabled) { + int numKeys; + RSAPublicKey* loadedKeys = load_keys(PUBLIC_KEYS_FILE, &numKeys); + if (loadedKeys == NULL) { + LOGE("Failed to load keys\n"); + return INSTALL_CORRUPT; + } + LOGI("%d key(s) loaded from %s\n", numKeys, PUBLIC_KEYS_FILE); - // Give verification half the progress bar... - ui_print("Verifying update package...\n"); - ui_show_progress( - VERIFICATION_PROGRESS_FRACTION, - VERIFICATION_PROGRESS_TIME); + // Give verification half the progress bar... + ui_print("Verifying update package...\n"); + ui_show_progress( + VERIFICATION_PROGRESS_FRACTION, + VERIFICATION_PROGRESS_TIME); - int err; - err = verify_file(path, loadedKeys, numKeys); - free(loadedKeys); - LOGI("verify_file returned %d\n", err); - if (err != VERIFY_SUCCESS) { - LOGE("signature verification failed\n"); - return INSTALL_CORRUPT; + err = verify_file(path, loadedKeys, numKeys); + free(loadedKeys); + LOGI("verify_file returned %d\n", err); + if (err != VERIFY_SUCCESS) { + LOGE("signature verification failed\n"); + return INSTALL_CORRUPT; + } } /* Try to open the package. |