diff options
Diffstat (limited to 'updater/install.c')
-rw-r--r-- | updater/install.c | 115 |
1 files changed, 105 insertions, 10 deletions
diff --git a/updater/install.c b/updater/install.c index 01a5dd2..19c22fb 100644 --- a/updater/install.c +++ b/updater/install.c @@ -33,6 +33,7 @@ #include <sys/xattr.h> #include <linux/xattr.h> #include <inttypes.h> +#include <blkid/blkid.h> #include "bootloader.h" #include "applypatch/applypatch.h" @@ -47,11 +48,8 @@ #include "updater.h" #include "install.h" #include "tune2fs.h" - -#ifdef USE_EXT4 #include "make_ext4fs.h" #include "wipe.h" -#endif void uiPrint(State* state, char* buffer) { char* line = strtok(buffer, "\n"); @@ -61,6 +59,11 @@ void uiPrint(State* state, char* buffer) { line = strtok(NULL, "\n"); } fprintf(ui->cmd_pipe, "ui_print\n"); + + // The recovery will only print the contents to screen for pipe command + // ui_print. We need to dump the contents to stderr (which has been + // redirected to the log file) directly. + fprintf(stderr, "%s", buffer); } __attribute__((__format__(printf, 2, 3))) __nonnull((2)) @@ -165,6 +168,16 @@ Value* MountFn(const char* name, State* state, int argc, Expr* argv[]) { } result = mount_point; } else { + char *detected_fs_type = blkid_get_tag_value(NULL, "TYPE", location); + if (detected_fs_type) { + uiPrintf(state, "detected filesystem %s for %s\n", + detected_fs_type, location); + fs_type = detected_fs_type; + } else { + uiPrintf(state, "could not detect filesystem for %s, assuming %s\n", + location, fs_type); + } + if (mount(location, mount_point, fs_type, MS_NOATIME | MS_NODEV | MS_NODIRATIME, has_mount_options ? mount_options : "") < 0) { @@ -332,7 +345,6 @@ Value* FormatFn(const char* name, State* state, int argc, Expr* argv[]) { goto done; } result = location; -#ifdef USE_EXT4 } else if (strcmp(fs_type, "ext4") == 0) { int status = make_ext4fs(location, atoll(fs_size), mount_point, sehandle); if (status != 0) { @@ -360,7 +372,6 @@ Value* FormatFn(const char* name, State* state, int argc, Expr* argv[]) { goto done; } result = location; -#endif } else { printf("%s: unsupported fs_type \"%s\" partition_type \"%s\"", name, fs_type, partition_type); @@ -931,6 +942,74 @@ Value* GetPropFn(const char* name, State* state, int argc, Expr* argv[]) { return StringValue(strdup(value)); } +//Check to confirm if this is the same hardware as the one the package was +//generated on or not. 32 vs 64 bit variants are upgrade compatible but have +//names such as msmWXYZ msmWXYZ_32 vs msmWXYZ_64.Input to this +//function is the BuildProp value that gets stored in the update package +//at the time it it created. +Value* ConfirmDevVariant(const char* name, State* state, int argc, Expr* argv[]) +{ + //ro.product.device that was on the build that the update package was made + //from + char* package_dev_variant; + //ro.product.device on the current hardware + char current_dev_variant[PROPERTY_VALUE_MAX]; + int comparison_len; + int package_dev_variant_len; + int current_dev_variant_len; + if (argc != 1) { + return ErrorAbort(state, "%s() expects 1 arg, got %d", name, argc); + } + package_dev_variant = Evaluate(state, argv[0]); + if (!package_dev_variant) goto error; + property_get("ro.product.device", current_dev_variant, "n/a"); + if (!strncmp(current_dev_variant,"n/a",3)) { + ErrorAbort(state, "Failed to get valid ro.product.device"); + goto error; + } + package_dev_variant_len = strlen(package_dev_variant); + current_dev_variant_len = strlen(current_dev_variant); + //Ensure device variant lengths are atleast 3 characters long + if ((package_dev_variant_len < 3) || (current_dev_variant_len < 3)) { + ErrorAbort(state, "Device Variant length is less than 3 characters"); + goto error; + } + //Length of the largest string - 3(for _32/64) + comparison_len = + (package_dev_variant_len >= current_dev_variant_len ? + package_dev_variant_len : + current_dev_variant_len) - 3; + //Complete match + if (!strncmp(current_dev_variant, package_dev_variant, + strlen(current_dev_variant))) + goto success; + //Match except for the last 3 char's of either string which are _32 or _64 + if (!strncmp(current_dev_variant, package_dev_variant, comparison_len)) { + if (package_dev_variant_len >= current_dev_variant_len) { + if (!strncmp(&package_dev_variant[package_dev_variant_len-3], + "_32", 3) || + !strncmp(&package_dev_variant[package_dev_variant_len-3], + "_64", 3)) + goto success; + } else { + if (!strncmp(¤t_dev_variant[current_dev_variant_len-3], + "_32", 3) || + !strncmp(¤t_dev_variant[current_dev_variant_len-3], + "_64", 3)) + goto success; + } + ErrorAbort(state, "Invalid target for update package"); + goto error; + } +success: + free(package_dev_variant); + return StringValue(strdup("OK")); +error: + if (package_dev_variant) { + free(package_dev_variant); + } + return StringValue(strdup("ERROR")); +} // file_getprop(file, key) // @@ -974,7 +1053,7 @@ Value* FileGetPropFn(const char* name, State* state, int argc, Expr* argv[]) { goto done; } - if (fread(buffer, 1, st.st_size, f) != st.st_size) { + if (fread(buffer, 1, st.st_size, f) != (size_t)st.st_size) { ErrorAbort(state, "%s: failed to read %lld bytes from %s", name, (long long)st.st_size+1, filename); fclose(f); @@ -1416,10 +1495,11 @@ Value* ReadFileFn(const char* name, State* state, int argc, Expr* argv[]) { // current package (because nothing has cleared the copy of the // arguments stored in the BCB). // -// The argument is the partition name passed to the android reboot -// property. It can be "recovery" to boot from the recovery -// partition, or "" (empty string) to boot from the regular boot -// partition. +// The first argument is the block device for the misc partition +// ("/misc" in the fstab). The second argument is the argument +// passed to the android reboot property. It can be "recovery" to +// boot from the recovery partition, or "" (empty string) to boot +// from the regular boot partition. Value* RebootNowFn(const char* name, State* state, int argc, Expr* argv[]) { if (argc != 2) { return ErrorAbort(state, "%s() expects 2 args, got %d", name, argc); @@ -1435,6 +1515,9 @@ Value* RebootNowFn(const char* name, State* state, int argc, Expr* argv[]) { memset(buffer, 0, sizeof(((struct bootloader_message*)0)->command)); FILE* f = fopen(filename, "r+b"); fseek(f, offsetof(struct bootloader_message, command), SEEK_SET); +#ifdef BOARD_RECOVERY_BLDRMSG_OFFSET + fseek(f, BOARD_RECOVERY_BLDRMSG_OFFSET, SEEK_CUR); +#endif fwrite(buffer, sizeof(((struct bootloader_message*)0)->command), 1, f); fclose(f); free(filename); @@ -1447,6 +1530,11 @@ Value* RebootNowFn(const char* name, State* state, int argc, Expr* argv[]) { property_set(ANDROID_RB_PROPERTY, buffer); sleep(5); + // Attempt to reboot using older methods in case the recovery + // that we are updating does not support init reboots + android_reboot(ANDROID_RB_RESTART, 0, 0); + + sleep(5); free(property); ErrorAbort(state, "%s() failed to reboot", name); return NULL; @@ -1477,6 +1565,9 @@ Value* SetStageFn(const char* name, State* state, int argc, Expr* argv[]) { // package installation. FILE* f = fopen(filename, "r+b"); fseek(f, offsetof(struct bootloader_message, stage), SEEK_SET); +#ifdef BOARD_RECOVERY_BLDRMSG_OFFSET + fseek(f, BOARD_RECOVERY_BLDRMSG_OFFSET, SEEK_CUR); +#endif int to_write = strlen(stagestr)+1; int max_size = sizeof(((struct bootloader_message*)0)->stage); if (to_write > max_size) { @@ -1503,6 +1594,9 @@ Value* GetStageFn(const char* name, State* state, int argc, Expr* argv[]) { char buffer[sizeof(((struct bootloader_message*)0)->stage)]; FILE* f = fopen(filename, "rb"); fseek(f, offsetof(struct bootloader_message, stage), SEEK_SET); +#ifdef BOARD_RECOVERY_BLDRMSG_OFFSET + fseek(f, BOARD_RECOVERY_BLDRMSG_OFFSET, SEEK_CUR); +#endif fread(buffer, sizeof(buffer), 1, f); fclose(f); buffer[sizeof(buffer)-1] = '\0'; @@ -1622,4 +1716,5 @@ void RegisterInstallFunctions() { RegisterFunction("enable_reboot", EnableRebootFn); RegisterFunction("tune2fs", Tune2FsFn); + RegisterFunction("get_device_compatible", ConfirmDevVariant); } |