int install_package(const char *root_path) { ui_set_background(BACKGROUND_ICON_INSTALLING); ui_print("Finding update package...\n"); ui_show_indeterminate_progress(); LOGI("Update location: %s\n", root_path); if (ensure_root_path_mounted(root_path) != 0) { LOGE("Can't mount %s\n", root_path); return INSTALL_CORRUPT; } char path[PATH_MAX] = ""; if (translate_root_path(root_path, path, sizeof(path)) == NULL) { LOGE("Bad path %s\n", root_path); return INSTALL_CORRUPT; } ui_print("Opening update package...\n"); LOGI("Update file path: %s\n", path); 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); 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; } /* Try to open the package. */ ZipArchive zip; err = mzOpenZipArchive(path, &zip); if (err != 0) { LOGE("Can't open %s\n(%s)\n", path, err != -1 ? strerror(err) : "bad"); return INSTALL_CORRUPT; } /* Verify and install the contents of the package. */ int status = handle_update_package(path, &zip); mzCloseZipArchive(&zip); return status; }
static int erase_root(const char *root) { ui_set_background(BACKGROUND_ICON_INSTALLING); ui_show_indeterminate_progress(); ui_print("Formatting %s...\n", root); return format_root_device(root); }
int nandroid_restore(const char* backup_path, int restore_boot, int restore_system, int restore_data, int restore_cache, int restore_sdext) { ui_set_background(BACKGROUND_ICON_INSTALLING); ui_show_indeterminate_progress(); yaffs_files_total = 0; if (ensure_root_path_mounted("SDCARD:") != 0) return print_and_error("Can't mount /sdcard\n"); char tmp[PATH_MAX]; //ui_print("Checking MD5 sums...\n"); //sprintf(tmp, "cd %s && md5sum -c nandroid.md5", backup_path); //if (0 != __system(tmp)) // return print_and_error("MD5 mismatch!\n"); int ret; #ifndef BOARD_RECOVERY_IGNORE_BOOTABLES if (restore_boot) { ui_print("Erasing boot before restore...\n"); if (0 != (ret = format_root_device("BOOT:"))) return print_and_error("Error while formatting BOOT:!\n"); sprintf(tmp, "%s/boot.img", backup_path); ui_print("Restoring boot image...\n"); if (0 != (ret = restore_raw_partition("boot", tmp))) { ui_print("Error while flashing boot image!"); return ret; } } #endif if (restore_system && 0 != (ret = nandroid_restore_partition(backup_path, "SYSTEM:"))) return ret; if (restore_data && 0 != (ret = nandroid_restore_partition(backup_path, "DATA:"))) return ret; #ifdef BOARD_HAS_DATADATA if (restore_data && 0 != (ret = nandroid_restore_partition(backup_path, "DATADATA:"))) return ret; #endif if (restore_data && 0 != (ret = nandroid_restore_partition_extended(backup_path, "SDCARD:/.android_secure", 0))) return ret; if (restore_cache && 0 != (ret = nandroid_restore_partition_extended(backup_path, "CACHE:", 0))) return ret; if (restore_sdext && 0 != (ret = nandroid_restore_partition(backup_path, "SDEXT:"))) return ret; sync(); ui_set_background(BACKGROUND_ICON_NONE); ui_reset_progress(); ui_print("\nRestore complete!\n"); return 0; }
static int really_install_package(const char *path) { ui_set_background(BACKGROUND_ICON_INSTALLING); ui_print("正在查找升级包...\n"); ui_show_indeterminate_progress(); LOGI("Update location: %s\n", path); if (ensure_path_mounted(path) != 0) { LOGE("Can't mount %s\n", path); return INSTALL_CORRUPT; } ui_print("正在打开升级包...\n"); 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("正在校验升级包...\n"); ui_show_progress( VERIFICATION_PROGRESS_FRACTION, VERIFICATION_PROGRESS_TIME); err = verify_file(path, loadedKeys, numKeys); free(loadedKeys); LOGI("verify_file returned %d\n", err); if (err != VERIFY_SUCCESS) { LOGE("signature verification failed\n"); ui_show_text(1); if (!confirm_selection("Install Untrusted Package?", "确认 - 安装不严格的zip卡刷包")) return INSTALL_CORRUPT; } } /* Try to open the package. */ ZipArchive zip; err = mzOpenZipArchive(path, &zip); if (err != 0) { LOGE("Can't open %s\n(%s)\n", path, err != -1 ? strerror(err) : "bad"); return INSTALL_CORRUPT; } /* Verify and install the contents of the package. */ ui_print("正在安装更新...\n"); return try_update_binary(path, &zip); }
int install_package(const char *path) { ui_set_background(BACKGROUND_ICON_INSTALLING); ui_print("Finding update package...\n"); ui_show_indeterminate_progress(); LOGI("Update location: %s\n", path); if (ensure_path_mounted(path) != 0) { LOGE("Can't mount %s\n", path); return INSTALL_CORRUPT; } ui_print("Opening update package...\n"); //TODO: put this back at some point /* 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); */ 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; } */ /* Try to open the package. */ ZipArchive zip; err = mzOpenZipArchive(path, &zip); if (err != 0) { LOGE("Can't open %s\n(%s)\n", path, err != -1 ? strerror(err) : "bad"); return INSTALL_CORRUPT; } /* Verify and install the contents of the package. */ ui_print("Installing update...\n"); return try_update_binary(path, &zip); }
int install_package(const char *path) { ui_set_background(BACKGROUND_ICON_INSTALLING); ui_print("Finding update package...\n"); ui_show_indeterminate_progress(); LOGI("Update location: %s\n", path); /* if (strcmp(root_path, ":") == 0) { if (ensure_root_path_mounted(root_path) != 0) { LOGE("Can't mount %s\n", root_path); return INSTALL_CORRUPT; } if (translate_root_path(root_path, path, sizeof(path)) == NULL) { LOGE("Bad path %s\n", root_path); return INSTALL_CORRUPT; } } else { path = strndup(path, root_path); } */ ui_print("Opening update package...\n"); LOGI("Update file path: %s\n", path); /* 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); */ /* Try to open the package. */ ZipArchive zip; int err = mzOpenZipArchive(path, &zip); if (err != 0) { LOGE("Can't open %s\n(%s)\n", path, err != -1 ? strerror(err) : "bad"); return INSTALL_CORRUPT; } /* Verify and install the contents of the package. */ // int status = handle_update_package(path, &zip, loadedKeys, numKeys); int status = handle_update_package(path, &zip); mzCloseZipArchive(&zip); // free(loadedKeys); return status; }
int erase_volume(const char *volume) { ui_set_background(BACKGROUND_ICON_INSTALLING); ui_show_indeterminate_progress(); ui_print("%s %s...\n", edifyformatting, volume); if (strcmp(volume, "/cache") == 0) { // Any part of the log we'd copied to cache is now gone. // Reset the pointer so we copy from the beginning of the temp // log. tmplog_offset = 0; } // Finally run format_volume from within roots return format_volume(volume); }
static int erase_volume(const char *volume) { ui_set_background(BACKGROUND_ICON_INSTALLING); ui_show_indeterminate_progress(); ui_print("正在格式化 %s \n", volume); if (strcmp(volume, "/cache") == 0) { // Any part of the log we'd copied to cache is now gone. // Reset the pointer so we copy from the beginning of the temp // log. tmplog_offset = 0; } return format_volume(volume); }
void device_toggle_truedualboot(void) { char confirm[PATH_MAX]; int enable = dualboot_is_tdb_enabled(); #ifndef PHILZ_TOUCH_RECOVERY ui_setMenuTextColor(MENU_TEXT_COLOR_RED); #endif sprintf(confirm, "Yes - %s TrueDualBoot", enable?"DISABLE":"ENABLE"); if (confirm_selection("This will WIPE DATA. Confirm?", confirm)) { // unmount /data if(ensure_path_unmounted("/data")!=0) { LOGE("Error unmounting /data!\n"); return; } // format /data ui_set_background(BACKGROUND_ICON_INSTALLING); ui_show_indeterminate_progress(); ui_print("Formatting /data...\n"); set_force_raw_format_enabled(1); if(format_volume("/data")!=0) { ui_print("Error formatting /data!\n"); ui_reset_progress(); return; } ui_reset_progress(); set_force_raw_format_enabled(0); ui_print("Done.\n"); // toggle dualboot_set_tdb_enabled(!enable); } #ifndef PHILZ_TOUCH_RECOVERY ui_setMenuTextColor(MENU_TEXT_COLOR); #endif return; }
int nandroid_restore_sd(const char* backup_path, int restore_sdext) { ui_set_background(BACKGROUND_ICON_INSTALLING); ui_show_indeterminate_progress(); yaffs_files_total = 0; if (ensure_path_mounted(backup_path) != 0) return print_and_error("Can't mount backup path\n"); char tmp[PATH_MAX]; int ret; if (restore_sdext && 0 != (ret = nandroid_restore_partition(backup_path, "/sd-ext"))) return ret; sync(); ui_set_background(BACKGROUND_ICON_NONE); ui_reset_progress(); ui_print("\nRestore complete!\n"); return 0; }
int nandroid_restore_androidSecure(const char* backup_path, int restore_androidSecure) { ui_set_background(BACKGROUND_ICON_INSTALLING); ui_show_indeterminate_progress(); yaffs_files_total = 0; if (ensure_root_path_mounted("SDCARD:") != 0) return print_and_error("Can't mount /sdcard\n"); char tmp[PATH_MAX]; int ret; if (restore_androidSecure && 0 != (ret = nandroid_restore_partition_extended(backup_path, "SDCARD:/.android_secure", 0))) return ret; sync(); ui_set_background(BACKGROUND_ICON_NONE); ui_reset_progress(); ui_print("\nRestore complete!\n"); return 0; }
int tarbackup_restore(const char* backup_path, int restore_system, int restore_data, int restore_cache, int restore_sdext) { ui_set_background(BACKGROUND_ICON_INSTALLING); ui_show_indeterminate_progress(); if (ensure_root_path_mounted("SDCARD:") != 0) return print_and_error("Can't mount /sdcard\n"); char tmp[PATH_MAX]; /* ui_print("Checking MD5 sums...\n"); sprintf(tmp, "cd %s && md5sum -c nandroid.md5", backup_path); if (0 != __system(tmp)) return print_and_error("MD5 mismatch!\n"); */ int ret=0; if (restore_system && 0 != (ret = tarbackup_restore_partition_extended(backup_path, "SYSTEM:", 1))) return ret; if (restore_data && 0 != (ret = tarbackup_restore_partition_extended(backup_path, "DATA:", 1))) return ret; if (restore_data && 0 != (ret = tarbackup_restore_partition_extended(backup_path, "DATADATA:", 1))) return ret; /* if (restore_data && 0 != (ret = tarbackup_restore_partition_extended(backup_path, "SDCARD:/.android_secure", 0))) return ret; */ if (restore_cache && 0 != (ret = tarbackup_restore_partition_extended(backup_path, "CACHE:", 0))) return ret; sync(); ui_set_background(BACKGROUND_ICON_EBCLOCKWORK); ui_reset_progress(); ui_print("\nRestore complete!\n"); detect_root_fs(); return 0; }
int nandroid_restore(const char* backup_path, int restore_boot, int restore_system, int restore_data, int restore_cache, int restore_sdext, int restore_wimax) { ui_set_background(BACKGROUND_ICON_INSTALLING); ui_show_indeterminate_progress(); if (ensure_path_mounted(backup_path) != 0) return print_and_error("Can't mount backup path\n"); char tmp[PATH_MAX]; #ifdef PHILZ_TOUCH_RECOVERY if (enable_md5sum) #endif { ui_print("Checking MD5 sums...\n"); sprintf(tmp, "cd %s && md5sum -c nandroid.md5", backup_path); if (0 != __system(tmp)) return print_and_error("MD5 mismatch!\n"); } int ret; if (restore_boot && NULL != volume_for_path("/boot") && 0 != (ret = nandroid_restore_partition(backup_path, "/boot"))) return ret; if (backup_recovery && 0 != (ret = nandroid_restore_partition(backup_path, "/recovery"))) return ret; struct stat s; Volume *vol = volume_for_path("/wimax"); if (restore_wimax && vol != NULL && 0 == stat(vol->device, &s)) { char serialno[PROPERTY_VALUE_MAX]; serialno[0] = 0; property_get("ro.serialno", serialno, ""); sprintf(tmp, "%s/wimax.%s.img", backup_path, serialno); struct stat st; if (0 != stat(tmp, &st)) { ui_print("WARNING: WiMAX partition exists, but nandroid\n"); ui_print(" backup does not contain WiMAX image.\n"); ui_print(" You should create a new backup to\n"); ui_print(" protect your WiMAX keys.\n"); } else { ui_print("Erasing WiMAX before restore...\n"); if (0 != (ret = format_volume("/wimax"))) return print_and_error("Error while formatting wimax!\n"); ui_print("Restoring WiMAX image...\n"); if (0 != (ret = restore_raw_partition(vol->fs_type, vol->device, tmp))) return ret; } } // restore of raw efs image files (efs_time-stamp.img) is done elsewhere // as it needs to pass in a filename (instead of a folder) as backup_path // this could be done here since efs is processed alone, but must be done before md5 checksum! if (backup_efs == RESTORE_EFS_TAR && 0 != (ret = nandroid_restore_partition(backup_path, "/efs"))) return ret; if (backup_modem == RAW_IMG_FILE && 0 != (ret = nandroid_restore_partition(backup_path, "/modem"))) return ret; else if (backup_modem == RAW_BIN_FILE) { sprintf(tmp, "%s/modem.bin", backup_path); custom_restore_raw_handler(tmp, "/modem"); } if (restore_system && 0 != (ret = nandroid_restore_partition(backup_path, "/system"))) return ret; if (is_custom_backup && backup_preload) { if (0 != (ret = nandroid_restore_partition(backup_path, "/preload"))) { ui_print("Failed to restore /preload!\n"); return ret; } } else if (!is_custom_backup #ifdef PHILZ_TOUCH_RECOVERY && nandroid_add_preload #endif ) { if (restore_system && 0 != (ret = nandroid_restore_partition(backup_path, "/preload"))) { ui_print("Failed to restore preload! Try to disable it.\n"); ui_print("Skipping /preload...\n"); //return ret; } } if (restore_data && 0 != (ret = nandroid_restore_partition(backup_path, "/data"))) return ret; if (has_datadata()) { if (restore_data && 0 != (ret = nandroid_restore_partition(backup_path, "/datadata"))) return ret; } if (restore_data && 0 != (ret = nandroid_restore_partition_extended(backup_path, "/sdcard/.android_secure", 0))) return ret; if (restore_cache && 0 != (ret = nandroid_restore_partition_extended(backup_path, "/cache", 0))) return ret; if (restore_sdext && 0 != (ret = nandroid_restore_partition(backup_path, "/sd-ext"))) return ret; sync(); ui_set_background(BACKGROUND_ICON_NONE); ui_reset_progress(); ui_print("\nRestore complete!\n"); return 0; }
int nandroid_restore(const char* backup_path, int restore_boot, int restore_system, int restore_data, int restore_cache, int restore_sdext, int restore_wimax) { ui_set_background(BACKGROUND_ICON_INSTALLING); ui_show_indeterminate_progress(); nandroid_files_total = 0; if (ensure_path_mounted(backup_path) != 0) return print_and_error("挂载分区失败\n"); char tmp[PATH_MAX]; ui_print("检查MD5 校验值...\n"); sprintf(tmp, "cd %s && md5sum -c nandroid.md5", backup_path); if (0 != __system(tmp)) return print_and_error("MD5不合法\n"); int ret; if (restore_boot) { if (NULL != volume_for_path("/boot") && 0 != (ret = nandroid_restore_partition(backup_path, "/boot"))) return ret; if (NULL != volume_for_path("/uboot") && 0 != (ret = nandroid_restore_partition(backup_path, "/uboot"))) return ret; if (NULL != volume_for_path("/recovery") && 0 != (ret = nandroid_restore_partition(backup_path, "/recovery"))) return ret; } struct stat s; Volume *vol = volume_for_path("/wimax"); if (restore_wimax && vol != NULL && 0 == stat(vol->device, &s)) { char serialno[PROPERTY_VALUE_MAX]; serialno[0] = 0; property_get("ro.serialno", serialno, ""); sprintf(tmp, "%s/wimax.%s.img", backup_path, serialno); struct stat st; if (0 != stat(tmp, &st)) { ui_print("警告: WiMAX分区存在,但是\n"); ui_print(" 不存在可恢复的WiMAX 镜像.\n"); ui_print(" 亦需要重新做一个备份 \n"); ui_print(" 来保护你的WiMAX keys.\n"); } else { ui_print("恢复之前先清除WiMAX...\n"); if (0 != (ret = format_volume("/wimax"))) return print_and_error("抹掉wimax失败!\n"); ui_print("恢复WiMAX 镜像...\n"); if (0 != (ret = restore_raw_partition(vol->fs_type, vol->device, tmp))) return ret; } } if (restore_system && 0 != (ret = nandroid_restore_partition(backup_path, "/system"))) return ret; if (restore_data && 0 != (ret = nandroid_restore_partition(backup_path, "/data"))) return ret; if (has_datadata()) { if (restore_data && 0 != (ret = nandroid_restore_partition(backup_path, "/datadata"))) return ret; } if (restore_data && 0 != (ret = nandroid_restore_partition_extended(backup_path, "/sdcard/.android_secure", 0))) return ret; if (restore_cache && 0 != (ret = nandroid_restore_partition_extended(backup_path, "/cache", 0))) return ret; if (restore_sdext && 0 != (ret = nandroid_restore_partition(backup_path, "/sd-ext"))) return ret; sync(); ui_set_background(BACKGROUND_ICON_NONE); ui_reset_progress(); ui_print("\n恢复完成!\n"); return 0; }
// custom raw restore handler // used to restore efs in raw mode or modem.bin files // for now, only called directly from outside functions (not from nandroid_restore()) // user selects an image file to restore, so backup_file_image path is already mounted int dd_raw_restore_handler(const char* backup_file_image, const char* root) { ui_print("\n>> Restoring %s...\n", root); Volume *vol = volume_for_path(root); if (vol == NULL || vol->fs_type == NULL) { ui_print("volume not found! Skipping raw restore of %s...\n", root); return 0; } ui_set_background(BACKGROUND_ICON_INSTALLING); ui_show_indeterminate_progress(); // make sure we have a valid image file name int i = 0; char errmsg[PATH_MAX]; char tmp[PATH_MAX]; char filename[PATH_MAX]; const char *raw_image_format[] = { ".img", ".bin", NULL }; sprintf(filename, "%s", BaseName(backup_file_image)); while (raw_image_format[i] != NULL) { if (strlen(filename) > strlen(raw_image_format[i]) && strcmp(filename + strlen(filename) - strlen(raw_image_format[i]), raw_image_format[i]) == 0 && strncmp(filename, vol->mount_point + 1, strlen(vol->mount_point)-1) == 0) { break; } i++; } if (raw_image_format[i] == NULL) { sprintf(errmsg, "invalid image file! Failed to restore %s to %s\n", filename, root); return print_and_error(errmsg, NANDROID_ERROR_GENERAL); } //make sure file exists if (!file_found(backup_file_image)) { sprintf(errmsg, "%s not found. Skipping restore of %s\n", backup_file_image, root); return print_and_error(errmsg, NANDROID_ERROR_GENERAL); } //restore raw image int ret = 0; char* device_mmcblk; ui_print("Restoring %s to %s\n", filename, vol->mount_point); if (strstr(vol->blk_device, "/dev/block/mmcblk") != NULL || strstr(vol->blk_device, "/dev/block/mtdblock") != NULL) { sprintf(tmp, "raw-backup.sh -r '%s' %s %s", backup_file_image, vol->blk_device, vol->mount_point); } else if (vol->blk_device2 != NULL && (strstr(vol->blk_device2, "/dev/block/mmcblk") != NULL || strstr(vol->blk_device2, "/dev/block/mtdblock") != NULL)) { sprintf(tmp, "raw-backup.sh -r '%s' %s %s", backup_file_image, vol->blk_device2, vol->mount_point); } else if ((device_mmcblk = readlink_device_blk(root)) != NULL) { sprintf(tmp, "raw-backup.sh -r '%s' %s %s", backup_file_image, device_mmcblk, vol->mount_point); free(device_mmcblk); } else { sprintf(errmsg, "raw restore: no device found (%s)\n", root); return print_and_error(errmsg, NANDROID_ERROR_GENERAL); } ret = __system(tmp); if (0 != ret) { sprintf(errmsg, "failed raw restore of %s to %s\n", filename, root); print_and_error(errmsg, ret); } else { finish_nandroid_job(); } sprintf(tmp, "%s/log.txt", DirName(backup_file_image)); ui_print_custom_logtail(tmp, 3); return ret; }
int nandroid_restore(const char* backup_path, int restore_boot, int restore_system, int restore_data, int restore_cache, int restore_sdext, int restore_wimax) { ui_set_background(BACKGROUND_ICON_INSTALLING); ui_show_indeterminate_progress(); yaffs_files_total = 0; if (ensure_path_mounted("/sdcard") != 0) return print_and_error("Can't mount /sdcard\n"); char tmp[PATH_MAX]; ui_print("Checking MD5 sums...\n"); sprintf(tmp, "cd %s && md5sum -c nandroid.md5", backup_path); if (0 != __system(tmp)) return print_and_error("MD5 mismatch!\n"); int ret; if (restore_boot && NULL != volume_for_path("/boot") && 0 != (ret = nandroid_restore_partition(backup_path, "/boot"))) return ret; struct stat s; Volume *vol = volume_for_path("/wimax"); if (restore_wimax && vol != NULL && 0 == stat(vol->device, &s)) { char serialno[PROPERTY_VALUE_MAX]; serialno[0] = 0; property_get("ro.serialno", serialno, ""); sprintf(tmp, "%s/wimax.%s.img", backup_path, serialno); struct stat st; if (0 != stat(tmp, &st)) { ui_print("WARNING: WiMAX partition exists, but nandroid\n"); ui_print(" backup does not contain WiMAX image.\n"); ui_print(" You should create a new backup to\n"); ui_print(" protect your WiMAX keys.\n"); } else { ui_print("Erasing WiMAX before restore...\n"); if (0 != (ret = format_volume("/wimax"))) return print_and_error("Error while formatting wimax!\n"); ui_print("Restoring WiMAX image...\n"); if (0 != (ret = restore_raw_partition(vol->fs_type, vol->device, tmp))) return ret; } } if (restore_system && 0 != (ret = nandroid_restore_partition(backup_path, "/system"))) return ret; if (restore_data && 0 != (ret = nandroid_restore_partition(backup_path, "/data"))) return ret; if (has_datadata()) { if (restore_data && 0 != (ret = nandroid_restore_partition(backup_path, "/datadata"))) return ret; } if (restore_data && 0 != (ret = nandroid_restore_partition_extended(backup_path, "/sdcard/.android_secure", 0))) return ret; if (restore_cache && 0 != (ret = nandroid_restore_partition_extended(backup_path, "/cache", 0))) return ret; #ifdef RECOVERY_HAVE_SD_EXT if (restore_sdext && 0 != (ret = nandroid_restore_partition(backup_path, "/sd-ext"))) return ret; #endif sync(); ui_set_background(BACKGROUND_ICON_NONE); ui_reset_progress(); ui_print("\nRestore complete!\n"); return 0; }
// If the package contains an update binary, extract it and run it. static int try_update_binary(const char *path, ZipArchive *zip) { int custom_binary = 0; const ZipEntry* or_script_entry = mzFindZipEntry(zip, ASSUMED_OR_UPDATE_SCRIPT_NAME); if (or_script_entry != NULL) { ui_print("Using shell script...\n"); return handle_or_update(path, zip); } const ZipEntry* binary_entry = mzFindZipEntry(zip, ASSUMED_UPDATE_BINARY_NAME); if (binary_entry == NULL) ui_print("Using default updater...\n"); else custom_binary = 1; char* binary = "/tmp/update_binary"; unlink(binary); if (custom_binary) { int fd = creat(binary, 0755); if (fd < 0) { LOGE("Can't make %s\n", binary); return 1; } bool ok = mzExtractZipEntryToFile(zip, binary_entry, fd); close(fd); if (!ok) { LOGE("Can't copy %s\n", ASSUMED_UPDATE_BINARY_NAME); return 1; } } else binary = DEFAULT_UPDATE_BINARY_NAME; ui_show_indeterminate_progress(); int pipefd[2]; pipe(pipefd); // When executing the update binary contained in the package, the // arguments passed are: // // - the version number for this interface // // - an fd to which the program can write in order to update the // progress bar. The program can write single-line commands: // // progress <frac> <secs> // fill up the next <frac> part of of the progress bar // over <secs> seconds. If <secs> is zero, use // set_progress commands to manually control the // progress of this segment of the bar // // set_progress <frac> // <frac> should be between 0.0 and 1.0; sets the // progress bar within the segment defined by the most // recent progress command. // // firmware <"hboot"|"radio"> <filename> // arrange to install the contents of <filename> in the // given partition on reboot. (API v2: <filename> may // start with "PACKAGE:" to indicate taking a file from // the OTA package.) // // ui_print <string> // display <string> on the screen. // // stasis // quit the gui // - the name of the package zip file. // char** args = malloc(sizeof(char*) * 5); args[0] = binary; args[1] = EXPAND(RECOVERY_API_VERSION); // defined in Android.mk args[2] = malloc(10); sprintf(args[2], "%d", pipefd[1]); args[3] = (char*)path; args[4] = NULL; pid_t pid = fork(); if (pid == 0) { close(pipefd[0]); execv(binary, args); fprintf(stderr, "E:Can't run %s (%s)\n", binary, strerror(errno)); _exit(-1); } close(pipefd[1]); char* firmware_type = NULL; char* firmware_filename = NULL; char buffer[1024]; FILE* from_child = fdopen(pipefd[0], "r"); ui_set_progress(0.0); while (fgets(buffer, sizeof(buffer), from_child) != NULL) { char* command = strtok(buffer, " \n"); if (command == NULL) continue; else if (strcmp(command, "progress") == 0) { char* fraction_s = strtok(NULL, " \n"); char* seconds_s = strtok(NULL, " \n"); float fraction = strtof(fraction_s, NULL); int seconds = strtol(seconds_s, NULL, 10); ui_show_progress(fraction, seconds); } else if (strcmp(command, "set_progress") == 0) { 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) ui_print(str); else ui_print("\n"); } else LOGE("unknown command [%s]\n", command); } fclose(from_child); int status; waitpid(pid, &status, 0); if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) { LOGE("Error in %s\n(Status %d)\n", path, WEXITSTATUS(status)); return INSTALL_ERROR; } if (firmware_type != NULL) return handle_firmware_update(firmware_type, firmware_filename, zip); else return INSTALL_SUCCESS; }
int convert_mtd_device(const char *root, const char* fs_list) { static char* headers[] = { "Converting Menu", "", NULL, NULL }; static char* confirm_convert = "Confirm convert?"; static char* confirm = "Yes - Convert"; const char* root_fs = get_type_internal_fs(root); headers[2] = root; typedef char* string; string tfs[NUM_FILESYSTEMS] = { "rfs", "ext4" }; static string options[NUM_FILESYSTEMS*2 + 1 + 1]; int sel_fs[NUM_FILESYSTEMS*2 + 1 + 1]; int i,j=0; // with backup for (i=0; i<NUM_FILESYSTEMS; i++) { if (fs_list[i] == '*') { if (strcmp(tfs[i], root_fs)) { sel_fs[j] = i; options[j] = (string)malloc(32); sprintf(options[j++], "to %s with backup", tfs[i]); } } else break; } options[j++] = ""; // without backup for (i=0; i<NUM_FILESYSTEMS; i++) { if (fs_list[i] == '*') { if (strcmp(tfs[i], root_fs)) { sel_fs[j] = i; options[j] = (string)malloc(32); sprintf(options[j++], "to %s through format", tfs[i]); } } else break; } options[j] = NULL; int chosen_item = get_menu_selection(headers, options, 0); if (chosen_item == GO_BACK) return 1; if (chosen_item < i) { // with backup if (!confirm_selection(confirm_convert, confirm)) return 1; ui_set_background(BACKGROUND_ICON_INSTALLING); ui_show_indeterminate_progress(); // mount $root if (0 != ensure_root_path_mounted(root)) { ui_print("Can't mount %s for backup\n", root); return -1; } // check size of $root struct statfs stat_root; if (0 != statfs(get_mount_point_for_root(root), &stat_root)) { ui_print("Can't get size of %s\n", root); return -1; } // mount SDCARD if (0 != ensure_root_path_mounted("SDCARD:")) { ui_print("Can't mount sdcard for backup\n", root); return -1; } // check size SD struct statfs stat_sd; if (0 != statfs(get_mount_point_for_root("SDCARD:"), &stat_sd)) { ui_print("Can't get size of sdcard\n"); return -1; } uint64_t root_fsize = (uint64_t)(stat_root.f_blocks-stat_root.f_bfree)*(uint64_t)stat_root.f_bsize; uint64_t sd_free_size = (uint64_t)stat_sd.f_bfree*(uint64_t)stat_sd.f_bsize; ui_print("SD free: %lluMB / need: %lluMB\n", sd_free_size/(1024*1024), root_fsize/(1024*1024)); if (root_fsize > sd_free_size) { ui_print("Can't backup need: %lluMB on SD\n", root_fsize/(1024*1024)); return -1; } // create folder for backup [/sdcard/ebrecovery/tmp] [mkdir -p /sdcard/ebrecovery/tmp] if (0 != __system("mkdir -p /sdcard/ebrecovery/tmp")) { ui_print("Can't create tmp folder for backup\n"); return -1; } ui_show_progress(0.3, root_fsize*30/(140*1024*1024)); // backup ui_print("Backuping %s...\n", root); char br_exec[256]; sprintf(br_exec, "tar -c --exclude=*RFS_LOG.LO* -f /sdcard/ebrecovery/tmp/ctmp.tar %s", get_mount_point_for_root(root)+1); if (0 != __system(br_exec)) { ui_print("Can't create backup file\n"); return -1; } // check size of backup file > sizeof($root)? // set new FS ui_print("Change fs type %s -> %s\n", get_type_internal_fs(root), tfs[sel_fs[chosen_item]]); if (0 != set_type_internal_fs(root, tfs[sel_fs[chosen_item]])) { ui_print("Error change type of file system to %s for %s\n", tfs[sel_fs[chosen_item]], root); return -1; } // format $root ui_show_progress(0.05, 10); ui_print("Formatting %s...\n", root); if (0 != format_root_device(root)) { ui_print("Error format %s\n", root); return -1; } // mount $root if (0 != ensure_root_path_mounted(root)) { ui_print("Can't mount %s for backup\n", root); return -1; } // restore $root ui_show_progress(0.65, root_fsize*500/(140*1024*1024)); ui_print("Restoring %s...\n", root); if (0 != __system("tar -x -f /sdcard/ebrecovery/tmp/ctmp.tar")) { ui_print("Can't restore backup file\n"); return -1; } // check size of $root ? // delete temp backup files (delete tmp folder) ui_show_indeterminate_progress(); if (0 != __system("rm /sdcard/ebrecovery/tmp/ctmp.tar")) { ui_print("Can't remove backup file\n"); return -1; } return 0; } else { // without if (!confirm_selection(confirm_convert, confirm)) return 1; // change file system to new ui_print("Change fs type %s -> %s\n", get_type_internal_fs(root), tfs[sel_fs[chosen_item]]); if (0 != set_type_internal_fs(root, tfs[sel_fs[chosen_item]])) { ui_print("Error change type of file system to %s for %s\n", tfs[sel_fs[chosen_item]], root); return -1; } // format ui_set_background(BACKGROUND_ICON_INSTALLING); ui_show_indeterminate_progress(); ui_print("Formatting %s...\n", root); return format_root_device(root); } return -1; }
int twrp_restore(const char* backup_path) { Backup_Size = 0; // by default, do not calculate size // progress bar will be of indeterminate progress // setting nandroid_files_total = 0 will force this in nandroid_callback() ui_set_background(BACKGROUND_ICON_INSTALLING); nandroid_files_total = 0; nandroid_start_msec = timenow_msec(); #ifdef PHILZ_TOUCH_RECOVERY // support dim screen timeout during nandroid operation last_key_ev = timenow_msec(); #endif if (ensure_path_mounted(backup_path) != 0) return print_and_error("Can't mount backup path\n", NANDROID_ERROR_GENERAL); char tmp[PATH_MAX]; if (enable_md5sum.value) { if (0 != check_twrp_md5sum(backup_path)) return print_and_error("MD5 mismatch!\n", NANDROID_ERROR_GENERAL); } ui_show_indeterminate_progress(); // call after verify_nandroid_md5sum() as it will reset the progress int ret; if (backup_boot && volume_for_path(BOOT_PARTITION_MOUNT_POINT) != NULL && 0 != (ret = nandroid_restore_partition(backup_path, BOOT_PARTITION_MOUNT_POINT))) return print_and_error(NULL, ret); if (backup_recovery && volume_for_path("/recovery") != NULL && 0 != (ret = nandroid_restore_partition(backup_path, "/recovery"))) return print_and_error(NULL, ret); #ifdef BOARD_USE_MTK_LAYOUT if ((backup_boot || backup_recovery) && volume_for_path("/uboot") != NULL && 0 != (ret = nandroid_restore_partition(backup_path, "/uboot"))) return print_and_error(NULL, ret); #endif Volume *vol = volume_for_path("/efs"); if (backup_efs == RESTORE_EFS_TAR && vol != NULL) { if (0 != (ret = nandroid_restore_partition(backup_path, "/efs"))) return print_and_error(NULL, ret); } vol = volume_for_path("/misc"); if (backup_misc && vol != NULL) { if (0 != (ret = nandroid_restore_partition(backup_path, "/misc"))) return print_and_error(NULL, ret); } vol = volume_for_path("/modem"); if (backup_modem == RAW_IMG_FILE && vol != NULL) { if (0 != (ret = nandroid_restore_partition(backup_path, "/modem"))) return print_and_error(NULL, ret); } vol = volume_for_path("/radio"); if (backup_radio == RAW_IMG_FILE && vol != NULL) { if (0 != (ret = nandroid_restore_partition(backup_path, "/radio"))) return print_and_error(NULL, ret); } if (backup_system && 0 != (ret = nandroid_restore_partition(backup_path, "/system"))) return print_and_error(NULL, ret); vol = volume_for_path("/preload"); if (backup_preload && vol != NULL) { if (0 != (ret = nandroid_restore_partition(backup_path, "/preload"))) return print_and_error(NULL, ret); } if (backup_data && 0 != (ret = nandroid_restore_partition(backup_path, "/data"))) return print_and_error(NULL, ret); if (has_datadata()) { if (backup_data && 0 != (ret = nandroid_restore_partition(backup_path, "/datadata"))) return print_and_error(NULL, ret); } // handle .android_secure on external and internal storage set_android_secure_path(tmp); if (backup_data && android_secure_ext) { if (0 != (ret = nandroid_restore_partition_extended(backup_path, tmp, 0))) return print_and_error(NULL, ret); } if (backup_cache && 0 != (ret = nandroid_restore_partition_extended(backup_path, "/cache", 0))) return print_and_error(NULL, ret); if (backup_sdext && 0 != (ret = nandroid_restore_partition(backup_path, "/sd-ext"))) return print_and_error(NULL, ret); // handle extra partitions int i; int extra_partitions_num = get_extra_partitions_state(); for (i = 0; i < extra_partitions_num; ++i) { if (extra_partition[i].backup_state && 0 != (ret = nandroid_restore_partition(backup_path, extra_partition[i].mount_point))) return print_and_error(NULL, ret); } finish_nandroid_job(); show_restore_stats(); if (reboot_after_nandroid) reboot_main_system(ANDROID_RB_RESTART, 0, 0); return 0; }
int main(int argc, char **argv) { if (argc == 2 && strcmp(argv[1], "adbd") == 0) { adb_main(); return 0; } // Recovery needs to install world-readable files, so clear umask // set by init umask(0); char* command = argv[0]; char* stripped = strrchr(argv[0], '/'); if (stripped) command = stripped + 1; if (strcmp(command, "recovery") != 0) { struct recovery_cmd cmd = get_command(command); if (cmd.name) return cmd.main_func(argc, argv); #ifdef BOARD_RECOVERY_HANDLES_MOUNT if (!strcmp(command, "mount") && argc == 2) { load_volume_table(); return ensure_path_mounted(argv[1]); } #endif if (!strcmp(command, "setup_adbd")) { load_volume_table(); setup_adbd(); return 0; } if (!strcmp(command, "start")) { property_set("ctl.start", argv[1]); return 0; } if (!strcmp(command, "stop")) { property_set("ctl.stop", argv[1]); return 0; } /* Make sure stdout is not fully buffered, we don't want to * have issues when calling busybox commands */ setlinebuf(stdout); return busybox_driver(argc, argv); } __system("/sbin/postrecoveryboot.sh"); int is_user_initiated_recovery = 0; time_t start = time(NULL); // If these fail, there's not really anywhere to complain... freopen(TEMPORARY_LOG_FILE, "a", stdout); setbuf(stdout, NULL); freopen(TEMPORARY_LOG_FILE, "a", stderr); setbuf(stderr, NULL); printf("Starting recovery on %s\n", ctime(&start)); device_ui_init(&ui_parameters); ui_init(); ui_print(EXPAND(RECOVERY_VERSION)"\n"); #ifdef BOARD_RECOVERY_SWIPE #ifndef BOARD_TOUCH_RECOVERY //display directions for swipe controls ui_print("Swipe up/down to change selections.\n"); ui_print("Swipe to the right for enter.\n"); ui_print("Swipe to the left for back.\n"); #endif #endif load_volume_table(); process_volumes(); vold_client_start(&v_callbacks, 0); vold_set_automount(1); setup_legacy_storage_paths(); LOGI("Processing arguments.\n"); ensure_path_mounted(LAST_LOG_FILE); rotate_last_logs(10); get_args(&argc, &argv); int previous_runs = 0; const char *send_intent = NULL; const char *update_package = NULL; const char *update_ubuntu_package = NULL; const char *user_data_update_package = NULL; int wipe_data = 0, wipe_cache = 0; int sideload = 0; int headless = 0; try_autodeploy(AUTODEPLOY_PACKAGE_FILE); try_autodeploy(AUTODEPLOY_PACKAGE_FILE_MULTI); LOGI("Checking arguments.\n"); int arg; while ((arg = getopt_long(argc, argv, "", OPTIONS, NULL)) != -1) { switch (arg) { case 'p': previous_runs = atoi(optarg); break; case 's': send_intent = optarg; break; case 'u': update_package = optarg; break; case 'd': user_data_update_package = optarg; break; case 'w': #ifndef BOARD_RECOVERY_ALWAYS_WIPES wipe_data = wipe_cache = 1; #endif break; case 'h': ui_set_background(BACKGROUND_ICON_CID); ui_show_text(0); headless = 1; break; case 'c': wipe_cache = 1; break; case 't': ui_show_text(1); break; case 'l': sideload = 1; break; case 'v': update_ubuntu_package = UBUNTU_UPDATE_SCRIPT; break; case '?': LOGE("Invalid command argument\n"); continue; } } struct selinux_opt seopts[] = { { SELABEL_OPT_PATH, "/file_contexts" } }; sehandle = selabel_open(SELABEL_CTX_FILE, seopts, 1); if (!sehandle) { fprintf(stderr, "Warning: No file_contexts\n"); ui_print("Warning: No file_contexts\n"); } LOGI("device_recovery_start()\n"); device_recovery_start(); printf("Command:"); for (arg = 0; arg < argc; arg++) { printf(" \"%s\"", argv[arg]); } printf("\n"); if (update_package) { // For backwards compatibility on the cache partition only, if // we're given an old 'root' path "CACHE:foo", change it to // "/cache/foo". if (strncmp(update_package, "CACHE:", 6) == 0) { int len = strlen(update_package) + 10; char* modified_path = malloc(len); strlcpy(modified_path, "/cache/", len); strlcat(modified_path, update_package+6, len); printf("(replacing path \"%s\" with \"%s\")\n", update_package, modified_path); update_package = modified_path; } } printf("\n"); property_list(print_property, NULL); printf("\n"); int status = INSTALL_SUCCESS; if (update_package != NULL) { status = install_package(update_package); if (status != INSTALL_SUCCESS) { copy_logs(); ui_print("Installation aborted.\n"); } } else if (update_ubuntu_package != NULL) { LOGI("Performing Ubuntu update"); ui_set_background(BACKGROUND_ICON_INSTALLING); ui_show_indeterminate_progress(); ui_print("Installing Ubuntu update.\n"); char tmp[PATH_MAX]; sprintf(tmp, "%s %s", UBUNTU_UPDATE_SCRIPT, UBUNTU_COMMAND_FILE ); __system(tmp); LOGI("Ubuntu update complete"); ui_print("Ubuntu update complete.\n"); } else if (wipe_data) { if (device_wipe_data()) status = INSTALL_ERROR; ignore_data_media_workaround(1); if (erase_volume("/data")) status = INSTALL_ERROR; ignore_data_media_workaround(0); if (has_datadata() && erase_volume("/datadata")) status = INSTALL_ERROR; if (wipe_cache && erase_volume("/cache")) status = INSTALL_ERROR; if (status != INSTALL_SUCCESS) { copy_logs(); ui_print("Data wipe failed.\n"); } } else if (wipe_cache) { if (wipe_cache && erase_volume("/cache")) status = INSTALL_ERROR; if (status != INSTALL_SUCCESS) { copy_logs(); ui_print("Cache wipe failed.\n"); } } else { LOGI("Checking for extendedcommand...\n"); status = INSTALL_ERROR; // No command specified // we are starting up in user initiated recovery here // let's set up some default options signature_check_enabled = 0; script_assert_enabled = 0; is_user_initiated_recovery = 1; if (!headless) { ui_set_show_text(1); ui_set_background(BACKGROUND_ICON_UBUNTU); } if (extendedcommand_file_exists()) { LOGI("Running extendedcommand...\n"); int ret; if (0 == (ret = run_and_remove_extendedcommand())) { status = INSTALL_SUCCESS; ui_set_show_text(0); } else { handle_failure(ret); } } else { LOGI("Skipping execution of extendedcommand, file not found...\n"); } } if (sideload) { signature_check_enabled = 0; if (!headless) ui_set_show_text(1); if (0 == apply_from_adb()) { status = INSTALL_SUCCESS; ui_set_show_text(0); } } if (headless) { headless_wait(); } if (user_data_update_package != NULL) { status = install_package(user_data_update_package); if (status != INSTALL_SUCCESS) ui_print("Installation aborted.\n"); } if (status != INSTALL_SUCCESS && !is_user_initiated_recovery) { ui_set_show_text(1); ui_set_background(BACKGROUND_ICON_ERROR); } else if (status != INSTALL_SUCCESS || ui_text_visible()) { prompt_and_wait(); } // We reach here when in main menu we choose reboot main system or for some wipe commands on start // If there is a radio image pending, reboot now to install it. maybe_install_firmware_update(send_intent); // Otherwise, get ready to boot the main system... finish_recovery(send_intent); ui_print("Rebooting...\n"); reboot_main_system(ANDROID_RB_RESTART, 0, 0); return EXIT_SUCCESS; }
int runve(char* filename, char** argv, char** envp, int secs) { int opipe[2]; int ipipe[2]; pipe(opipe); pipe(ipipe); pid_t pid = fork(); int status = 0; if (pid == 0) { dup2(opipe[1],1); dup2(ipipe[0],0); close(opipe[0]); close(ipipe[1]); execve(filename,argv,envp); char* error_msg = calloc(strlen(filename)+20,sizeof(char)); sprintf(error_msg,"Could not execute %s\n",filename); ui_print(error_msg); free(error_msg); return(9999); } close(opipe[1]); close(ipipe[0]); FILE* from = fdopen(opipe[0],"r"); FILE* to = fdopen(ipipe[1],"w"); char* cur_line = calloc(100,sizeof(char)); char* tok; int total_lines; int cur_lines; int num_items; int num_headers; int num_chks; float cur_progress; char** items = NULL; char** headers = NULL; char** chks = NULL; int i = 0; // iterator for menu items int j = 0; // iterator for menu headers int k = 0; // iterator for check menu items int l = 0; // iterator for outputting flags from check menu int flags = INT_MAX; int choice; while (fgets(cur_line,100,from)!=NULL) { printf(cur_line); tok=strtok(cur_line," \n"); if(tok==NULL) {continue;} if(strcmp(tok,"*")==0) { tok=strtok(NULL," \n"); if(tok==NULL) {continue;} if(strcmp(tok,"ptotal")==0) { ui_set_progress(0.0); ui_show_progress(1.0,0); total_lines=atoi(strtok(NULL," ")); } else if (strcmp(tok,"print")==0) { ui_print(strtok(NULL,"")); } else if (strcmp(tok,"items")==0) { num_items=atoi(strtok(NULL," \n")); if(items!=NULL) free(items); items=calloc((num_items+1),sizeof(char*)); items[num_items]=NULL; i=0; } else if (strcmp(tok,"item")==0) { if (i < num_items) { tok=strtok(NULL,"\n"); items[i]=calloc((strlen(tok)+1),sizeof(char)); strcpy(items[i],tok); i++; } } else if (strcmp(tok,"headers")==0) { num_headers=atoi(strtok(NULL," \n")); if(headers!=NULL) free(headers); headers=calloc((num_headers+1),sizeof(char*)); headers[num_headers]=NULL; j=0; } else if (strcmp(tok,"header")==0) { if (j < num_headers) { tok=strtok(NULL,"\n"); if (tok) { headers[j]=calloc((strlen(tok)+1),sizeof(char)); strcpy(headers[j],tok); } else { headers[j]=""; } j++; } } else if (strcmp(tok,"show_menu")==0) { choice=get_menu_selection(headers,items,0,0); fprintf(to, "%d\n", choice); fflush(to); } else if (strcmp(tok,"pcur")==0) { cur_lines=atoi(strtok(NULL,"\n")); if (cur_lines%10==0 || total_lines-cur_lines<10) { cur_progress=(float)cur_lines/((float)total_lines); ui_set_progress(cur_progress); } if (cur_lines==total_lines) ui_reset_progress(); } else if (strcmp(tok,"check_items")==0) { num_chks=atoi(strtok(NULL," \n")); if(chks!=NULL) free(chks); chks=calloc((num_chks+1),sizeof(char*)); chks[num_chks]=NULL; k = 0; } else if (strcmp(tok,"check_item")==0) { if (k < num_chks) { tok=strtok(NULL,"\n"); chks[k]=calloc(strlen(tok)+1,sizeof(char)); strcpy(chks[k],tok); k++; } } else if (strcmp(tok,"show_check_menu")==0) { show_check_menu(headers,chks,&flags); for(l=0;l<num_chks;l++) { fprintf(to, "%d\n", !!(flags&(1<<l))); } fflush(to); } else if (strcmp(tok,"show_indeterminate_progress")==0) { ui_show_indeterminate_progress(); } else {ui_print("unrecognized command "); ui_print(tok); ui_print("\n");} } } while (waitpid(pid, &status, WNOHANG) == 0) { sleep(1); } ui_print("\n"); free(cur_line); return status; }
// remove static to be able to call it from ors menu int erase_volume(const char *volume) { bool is_cache = (strcmp(volume, CACHE_ROOT) == 0); int icon = ui_get_background_icon(); ui_set_background(BACKGROUND_ICON_INSTALLING); ui_show_indeterminate_progress(); saved_log_file* head = NULL; if (is_cache) { // If we're reformatting /cache, we load any // "/cache/recovery/last*" files into memory, so we can restore // them after the reformat. ensure_path_mounted(volume); DIR* d; struct dirent* de; d = opendir(CACHE_LOG_DIR); if (d) { char path[PATH_MAX]; strcpy(path, CACHE_LOG_DIR); strcat(path, "/"); int path_len = strlen(path); while ((de = readdir(d)) != NULL) { if (strncmp(de->d_name, "last", 4) == 0) { saved_log_file* p = (saved_log_file*) malloc(sizeof(saved_log_file)); strcpy(path+path_len, de->d_name); p->name = strdup(path); if (stat(path, &(p->st)) == 0) { // truncate files to 512kb if (p->st.st_size > (1 << 19)) { p->st.st_size = 1 << 19; } p->data = (unsigned char*) malloc(p->st.st_size); FILE* f = fopen(path, "rb"); fread(p->data, 1, p->st.st_size, f); fclose(f); p->next = head; head = p; } else { free(p); } } } closedir(d); } else { if (errno != ENOENT) { printf("opendir failed: %s\n", strerror(errno)); } } } ui_print("Formatting %s...\n", volume); ensure_path_unmounted(volume); int result = format_volume(volume); if (is_cache) { while (head) { FILE* f = fopen_path(head->name, "wb"); if (f) { fwrite(head->data, 1, head->st.st_size, f); fclose(f); chmod(head->name, head->st.st_mode); chown(head->name, head->st.st_uid, head->st.st_gid); } free(head->name); free(head->data); saved_log_file* temp = head->next; free(head); head = temp; } // Any part of the log we'd copied to cache is now gone. // Reset the pointer so we copy from the beginning of the temp // log. tmplog_offset = 0; copy_logs(); } ui_set_background(icon); ui_reset_progress(); return result; }
int install_package(const char *root_path) { recovery_status = 0; int status = INSTALL_SUCCESS; ui_set_background(BACKGROUND_ICON_INSTALLING); ui_print("Finding update package...\n"); ui_show_indeterminate_progress(); if (ensure_root_path_mounted(root_path) != 0) { ui_print("Can't mount %s\n", root_path); status = INSTALL_CORRUPT; goto exit; } char path[PATH_MAX] = ""; if (translate_root_path(root_path, path, sizeof(path)) == NULL) { ui_print("Bad path %s\n", root_path); status = INSTALL_CORRUPT; goto exit; } printf("package name = '%s'\t path_len= %d\n",path,strlen(path)); ui_print("Opening update package...\n"); #if 0 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); 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; } #endif /* Try to open the package. */ int err; ZipArchive zip; err = mzOpenZipArchive(path, &zip); if (err != 0) { ui_print("Can't open %s\n(%s)\n", path, err != -1 ? strerror(err) : "bad"); status = INSTALL_CORRUPT; goto exit; } /* * Verify hw version */ /* if (check_hw_version(&zip)) { ui_print("HW version doesn't match!!!"); status = INSTALL_CORRUPT; mzCloseZipArchive(&zip); goto exit; } */ /* Verify and install the contents of the package. */ ui_print("start update package file\n"); status = handle_update_package(path, &zip); ui_print("install_success!!!\n"); mzCloseZipArchive(&zip); exit: ensure_root_path_unmounted(root_path); if (status != INSTALL_SUCCESS) recovery_status = 1; else recovery_status = 0; return status; }