summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--common.h3
-rw-r--r--install.c26
-rw-r--r--recovery.c2
-rw-r--r--updater/install.c67
4 files changed, 68 insertions, 30 deletions
diff --git a/common.h b/common.h
index cba4c861d..ef2fe9f62 100644
--- a/common.h
+++ b/common.h
@@ -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
diff --git a/install.c b/install.c
index 5bb3a78fa..707cda438 100644
--- a/install.c
+++ b/install.c
@@ -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);
}