diff options
-rw-r--r-- | common.h | 3 | ||||
-rw-r--r-- | install.c | 26 | ||||
-rw-r--r-- | recovery.c | 2 | ||||
-rw-r--r-- | updater/install.c | 67 |
4 files changed, 68 insertions, 30 deletions
@@ -126,4 +126,7 @@ typedef struct { } UIParameters; +// fopen a file, mounting volumes and making parent dirs as necessary. +FILE* fopen_path(const char *path, const char *mode); + #endif // RECOVERY_COMMON_H @@ -36,6 +36,8 @@ #define ASSUMED_UPDATE_BINARY_NAME "META-INF/com/google/android/update-binary" #define PUBLIC_KEYS_FILE "/res/keys" +static const char *LAST_INSTALL_FILE = "/cache/recovery/last_install"; + // If the package contains an update binary, extract it and run it. static int try_update_binary(const char *path, ZipArchive *zip) { @@ -233,8 +235,8 @@ exit: return NULL; } -int -install_package(const char *path) +static int +really_install_package(const char *path) { ui_set_background(BACKGROUND_ICON_INSTALLING); ui_print("Finding update package...\n"); @@ -285,3 +287,23 @@ install_package(const char *path) ui_print("Installing update...\n"); return try_update_binary(path, &zip); } + +int +install_package(const char* path) +{ + FILE* install_log = fopen_path(LAST_INSTALL_FILE, "w"); + if (install_log) { + fputs(path, install_log); + fputc('\n', install_log); + } else { + LOGE("failed to open last_install: %s\n", strerror(errno)); + } + int result = really_install_package(path); + if (install_log) { + fputc(result == INSTALL_SUCCESS ? '1' : '0', install_log); + fputc('\n', install_log); + fclose(install_log); + chmod(LAST_INSTALL_FILE, 0644); + } + return result; +} diff --git a/recovery.c b/recovery.c index fd7ce42f1..3a412d5c5 100644 --- a/recovery.c +++ b/recovery.c @@ -120,7 +120,7 @@ static const int MAX_ARG_LENGTH = 4096; static const int MAX_ARGS = 100; // open a given path, mounting partitions as necessary -static FILE* +FILE* fopen_path(const char *path, const char *mode) { if (ensure_path_mounted(path) != 0) { LOGE("Can't mount %s\n", path); diff --git a/updater/install.c b/updater/install.c index 6a7996467..0396bae6c 100644 --- a/updater/install.c +++ b/updater/install.c @@ -782,21 +782,26 @@ static bool write_raw_image_cb(const unsigned char* data, return false; } -// write_raw_image(file, partition) +// write_raw_image(filename_or_blob, partition) Value* WriteRawImageFn(const char* name, State* state, int argc, Expr* argv[]) { char* result = NULL; - char* partition; - char* filename; - if (ReadArgs(state, argv, 2, &filename, &partition) < 0) { + Value* partition_value; + Value* contents; + if (ReadValueArgs(state, argv, 2, &contents, &partition_value) < 0) { return NULL; } + if (partition_value->type != VAL_STRING) { + ErrorAbort(state, "partition argument to %s must be string", name); + goto done; + } + char* partition = partition_value->data; if (strlen(partition) == 0) { ErrorAbort(state, "partition argument to %s can't be empty", name); goto done; } - if (strlen(filename) == 0) { + if (contents->type == VAL_STRING && strlen((char*) contents->data) == 0) { ErrorAbort(state, "file argument to %s can't be empty", name); goto done; } @@ -819,27 +824,35 @@ Value* WriteRawImageFn(const char* name, State* state, int argc, Expr* argv[]) { bool success; - FILE* f = fopen(filename, "rb"); - if (f == NULL) { - fprintf(stderr, "%s: can't open %s: %s\n", - name, filename, strerror(errno)); - result = strdup(""); - goto done; - } + if (contents->type == VAL_STRING) { + // we're given a filename as the contents + char* filename = contents->data; + FILE* f = fopen(filename, "rb"); + if (f == NULL) { + fprintf(stderr, "%s: can't open %s: %s\n", + name, filename, strerror(errno)); + result = strdup(""); + goto done; + } - success = true; - char* buffer = malloc(BUFSIZ); - int read; - while (success && (read = fread(buffer, 1, BUFSIZ, f)) > 0) { - int wrote = mtd_write_data(ctx, buffer, read); - success = success && (wrote == read); - if (!success) { - fprintf(stderr, "mtd_write_data to %s failed: %s\n", - partition, strerror(errno)); + success = true; + char* buffer = malloc(BUFSIZ); + int read; + while (success && (read = fread(buffer, 1, BUFSIZ, f)) > 0) { + int wrote = mtd_write_data(ctx, buffer, read); + success = success && (wrote == read); } + free(buffer); + fclose(f); + } else { + // we're given a blob as the contents + ssize_t wrote = mtd_write_data(ctx, contents->data, contents->size); + success = (wrote == contents->size); + } + if (!success) { + fprintf(stderr, "mtd_write_data to %s failed: %s\n", + partition, strerror(errno)); } - free(buffer); - fclose(f); if (mtd_erase_blocks(ctx, -1) == -1) { fprintf(stderr, "%s: error erasing blocks of %s\n", name, partition); @@ -848,14 +861,14 @@ Value* WriteRawImageFn(const char* name, State* state, int argc, Expr* argv[]) { fprintf(stderr, "%s: error closing write of %s\n", name, partition); } - printf("%s %s partition from %s\n", - success ? "wrote" : "failed to write", partition, filename); + printf("%s %s partition\n", + success ? "wrote" : "failed to write", partition); result = success ? partition : strdup(""); done: - if (result != partition) free(partition); - free(filename); + if (result != partition) FreeValue(partition_value); + FreeValue(contents); return StringValue(result); } |