aboutsummaryrefslogtreecommitdiffstats
path: root/updater/install.c
diff options
context:
space:
mode:
Diffstat (limited to 'updater/install.c')
-rw-r--r--updater/install.c115
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(&current_dev_variant[current_dev_variant_len-3],
+ "_32", 3) ||
+ !strncmp(&current_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);
}