int tarbackup_backup(const char* backup_path, int backup_system, int backup_data, int backup_cache, int backup_android_secure) { ui_set_background(BACKGROUND_ICON_INSTALLING); if (ensure_root_path_mounted("SDCARD:") != 0) return print_and_error("Can't mount /sdcard\n"); int ret=0; struct statfs s; if (0 != (ret = statfs("/sdcard", &s))) return print_and_error("Unable to stat /sdcard\n"); uint64_t bavail = s.f_bavail; uint64_t bsize = s.f_bsize; uint64_t sdcard_free = bavail * bsize; uint64_t sdcard_free_mb = sdcard_free / (uint64_t)(1024 * 1024); ui_print("SD Card space free: %lluMB\n", sdcard_free_mb); if (sdcard_free_mb < 220) ui_print("There may not be enough free space to complete backup... continuing...\n"); char tmp[PATH_MAX]; sprintf(tmp, "mkdir -p %s", backup_path); __system(tmp); if (backup_system && 0 != (ret = tarbackup_backup_partition_extended(backup_path, "SYSTEM:", 1))) return ret; if (backup_data && 0 != (ret = tarbackup_backup_partition_extended(backup_path, "DATA:", 1))) return ret; if (backup_data && 0 != (ret = tarbackup_backup_partition_extended(backup_path, "DATADATA:", 1))) return ret; /* struct stat st; if (0 != stat("/sdcard/.android_secure", &st)) { ui_print("No /sdcard/.android_secure found. Skipping backup of applications on external storage.\n"); } else { if (0 != (ret = nandroid_backup_partition_extended(backup_path, "SDCARD:/.android_secure", 0))) return ret; } */ if (backup_cache && 0 != (ret = tarbackup_backup_partition_extended(backup_path, "CACHE:", 0))) return ret; /* ui_print("Generating md5 sum...\n"); sprintf(tmp, "nandroid-md5.sh %s", backup_path); if (0 != (ret = __system(tmp))) { ui_print("Error while generating md5 sum!\n"); return ret; } */ sync(); ui_set_background(BACKGROUND_ICON_EBCLOCKWORK); ui_reset_progress(); ui_print("\nBackup complete!\n"); return 0; }
/* Image backup functions */ int nandroid_backup_partition_extended(const char* backup_path, char* root, int umount_when_finished) { int ret = 0; char mount_point[PATH_MAX]; translate_root_path(root, mount_point, PATH_MAX); char* name = basename(mount_point); struct stat file_info; mkyaffs2image_callback callback = NULL; if (0 != stat("/sdcard/ebrecovery/.hidenandroidprogress", &file_info)) { callback = yaffs_callback; } ui_print("Backing up %s...\n", name); if (0 != (ret = ensure_root_path_mounted(root) != 0)) { ui_print("Can't mount %s!\n", mount_point); return ret; } compute_directory_stats(mount_point); char tmp[PATH_MAX]; sprintf(tmp, "%s/%s.img", backup_path, name); ret = mkyaffs2image(mount_point, tmp, 0, callback); if (umount_when_finished) { ensure_root_path_unmounted(root); } if (0 != ret) { ui_print("Error while making a yaffs2 image of %s!\n", mount_point); return ret; } return 0; }
void show_nandroid_advanced_backup_menu() { if (ensure_root_path_mounted("SDCARD:") != 0) { LOGE ("Can't mount /sdcard\n"); return; } static char* headers[] = { "Nandroid Advanced Backup", "", NULL }; static char* list[] = { "Backup boot", "Backup system", "Backup data", "Backup cache", "Backup sd-ext", NULL }; char backup_path[PATH_MAX]; time_t t = time(NULL); struct tm *tmp = localtime(&t); if (tmp == NULL) { struct timeval tp; gettimeofday(&tp, NULL); sprintf(backup_path, "/sdcard/clockworkmod/backup/%d", tp.tv_sec); } else { strftime(backup_path, sizeof(backup_path), "/sdcard/clockworkmod/backup/%F.%H.%M.%S", tmp); } static char* confirm_restore = "Confirm backup?"; int chosen_item = get_menu_selection(headers, list, 0); switch (chosen_item) { case 0: if (confirm_selection(confirm_restore, "Yes - Backup boot")) nandroid_backup_boot(backup_path); break; case 1: if (confirm_selection(confirm_restore, "Yes - Backup system")) nandroid_backup_system(backup_path); break; case 2: if (confirm_selection(confirm_restore, "Yes - Backup data")) nandroid_backup_data(backup_path); break; case 3: if (confirm_selection(confirm_restore, "Yes - Backup cache")) nandroid_backup_cache(backup_path); break; case 4: if (confirm_selection(confirm_restore, "Yes - Backup sd-ext")) nandroid_backup_sd(backup_path);; break; } }
int nandroid_backup_cache(const char* backup_path) { ui_set_background(BACKGROUND_ICON_INSTALLING); if (ensure_root_path_mounted("SDCARD:") != 0) return print_and_error("Can't mount /sdcard\n"); int ret; struct statfs s; if (0 != (ret = statfs("/sdcard", &s))) return print_and_error("Unable to stat /sdcard\n"); uint64_t bavail = s.f_bavail; uint64_t bsize = s.f_bsize; uint64_t sdcard_free = bavail * bsize; uint64_t sdcard_free_mb = sdcard_free / (uint64_t)(1024 * 1024); ui_print("SD Card space free: %lluMB\n", sdcard_free_mb); if (sdcard_free_mb < 150) ui_print("There may not be enough free space to complete backup... continuing...\n"); char tmp[PATH_MAX]; sprintf(tmp, "mkdir -p %s", backup_path); __system(tmp); if (0 != (ret = nandroid_backup_partition_extended(backup_path, "CACHE:", 0))) return ret; sync(); ui_set_background(BACKGROUND_ICON_NONE); ui_reset_progress(); ui_print("\nBackup complete!\n"); return 0; }
int format_non_mtd_device(const char* root) { // if this is SDEXT:, don't worry about it. if (0 == strcmp(root, "SDEXT:")) { struct stat st; if (0 != stat(SDEXT_DEVICE, &st)) { ui_print("No app2sd partition found. Skipping format of /sd-ext.\n"); return 0; } } char path[PATH_MAX]; translate_root_path(root, path, PATH_MAX); if (0 != ensure_root_path_mounted(root)) { ui_print("Error mounting %s!\n", path); ui_print("Skipping format...\n"); return 0; } static char tmp[PATH_MAX]; sprintf(tmp, "rm -rf %s/*", path); __system(tmp); sprintf(tmp, "rm -rf %s/.*", path); __system(tmp); ensure_root_path_unmounted(root); return 0; }
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; }
void root_menu(int confirm) { if (confirm) { static char** title_headers = NULL; if (title_headers == NULL) { char* headers[] = { "ROOT installed ROM?", " ", "Rooting without the superuser app installed", "does nothing. Please install the superuser app", "from the market! (by ChainsDD)", " ", NULL }; title_headers = prepend_title(headers); } char* items[] = { " No", " OK, give me root!", NULL }; int chosen_item = get_menu_selection(title_headers, items, 1, 0); if (chosen_item != 1) { return; } } char* argv[] = { "/sbin/actroot", NULL }; char* envp[] = { NULL }; ensure_root_path_mounted("SYSTEM:"); remove("/system/recovery-from-boot.p"); int status = runve("/sbin/actroot",argv,envp,1); ensure_root_path_unmounted("SYSTEM:"); return; }
/* symlink <link-target> <link-path> * * Create a symlink, like "ln -s". The link path must not exist already. * Note that <link-path> is in root:path format, but <link-target> is * for the target filesystem (and may be relative). */ static int cmd_symlink(const char *name, void *cookie, int argc, const char *argv[]) { UNUSED(cookie); CHECK_WORDS(); if (argc != 2) { LOGE("Command %s requires exactly two arguments\n", name); return 1; } char path[PATH_MAX]; if (translate_root_path(argv[1], path, sizeof(path)) == NULL) { LOGE("Command %s: bad path \"%s\"\n", name, argv[1]); return 1; } if (ensure_root_path_mounted(argv[1])) { LOGE("Can't mount %s\n", argv[1]); return 1; } if (symlink(argv[0], path)) { LOGE("Can't symlink %s\n", path); return 1; } return 0; }
void wipe_battery_stats() { ui_print("Wiping battery stats...\n"); ensure_root_path_mounted("DATA:"); remove("/data/system/batterystats.bin"); ensure_root_path_unmounted("DATA:"); ui_print("Done.\n"); }
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; }
void disable_OTA() { ui_print("\nDisabling OTA updates in ROM..."); ensure_root_path_mounted("SYSTEM:"); remove("/system/etc/security/otacerts.zip"); remove("/cache/signed-*.*"); ui_print("\nOTA-updates disabled.\n"); ensure_root_path_unmounted("SYSTEM:"); return; }
void handle_failure(int ret) { if (ret == 0) return; if (0 != ensure_root_path_mounted("SDCARD:")) return; mkdir("/sdcard/clockworkmod", S_IRWXU); __system("cp /tmp/recovery.log /sdcard/clockworkmod/recovery.log"); ui_print("/tmp/recovery.log was copied to /sdcard/clockworkmod/recovery.log. Please open ROM Manager to report the issue.\n"); }
void handle_failure(int ret) { if (ret == 0) return; if (0 != ensure_root_path_mounted("SDCARD:")) return; mkdir("/sdcard/ebrecovery", S_IRWXU); __system("cp /tmp/recovery.log /sdcard/ebrecovery/recovery.log"); ui_print("/tmp/recovery.log was copied to /sdcard/ebrecovery/recovery.log.\n"); }
int nandroid_backup_sd(const char* backup_path) { ui_set_background(BACKGROUND_ICON_INSTALLING); if (ensure_root_path_mounted("SDCARD:") != 0) return print_and_error("Can't mount /sdcard\n"); int ret; struct statfs s; if (0 != (ret = statfs("/sdcard", &s))) return print_and_error("Unable to stat /sdcard\n"); uint64_t bavail = s.f_bavail; uint64_t bsize = s.f_bsize; uint64_t sdcard_free = bavail * bsize; uint64_t sdcard_free_mb = sdcard_free / (uint64_t)(1024 * 1024); ui_print("SD Card space free: %lluMB\n", sdcard_free_mb); if (sdcard_free_mb < 150) ui_print("There may not be enough free space to complete backup... continuing...\n"); char tmp[PATH_MAX]; sprintf(tmp, "mkdir -p %s", backup_path); __system(tmp); struct stat st; if (0 != stat(BOARD_SDEXT_DEVICE, &st)) { ui_print("No sd-ext found. Skipping backup of sd-ext.\n"); } else { if (0 != ensure_root_path_mounted("SDEXT:")) ui_print("Could not mount sd-ext. sd-ext backup may not be supported on this device. Skipping backup of sd-ext.\n"); else if (0 != (ret = nandroid_backup_partition(backup_path, "SDEXT:"))) return ret; } sync(); ui_set_background(BACKGROUND_ICON_NONE); ui_reset_progress(); ui_print("\nBackup complete!\n"); return 0; }
/* delete <file1> [<fileN> ...] * delete_recursive <file-or-dir1> [<file-or-dirN> ...] * * Like "rm -f", will try to delete every named file/dir, even if * earlier ones fail. Recursive deletes that fail halfway through * give up early. */ static int cmd_delete(const char *name, void *cookie, int argc, const char *argv[], PermissionRequestList *permissions) { UNUSED(cookie); CHECK_WORDS(); int nerr = 0; bool recurse; if (argc < 1) { LOGE("Command %s requires at least one argument\n", name); return 1; } recurse = (strcmp(name, "delete_recursive") == 0); ui_print("Deleting files...\n"); //xxx permissions int i; for (i = 0; i < argc; i++) { const char *root_path = argv[i]; char pathbuf[PATH_MAX]; const char *path; /* This guarantees that all paths use "SYSTEM:"-style roots; * plain paths won't make it through translate_root_path(). */ path = translate_root_path(root_path, pathbuf, sizeof(pathbuf)); if (path != NULL) { int ret = ensure_root_path_mounted(root_path); if (ret < 0) { LOGW("Can't mount volume to delete \"%s\"\n", root_path); nerr++; continue; } if (recurse) { ret = dirUnlinkHierarchy(path); } else { ret = unlink(path); } if (ret != 0 && errno != ENOENT) { LOGW("Can't delete %s\n(%s)\n", path, strerror(errno)); nerr++; } } else { nerr++; } } //TODO: add a way to fail if a delete didn't work return 0; }
int nandroid_restore_partition_extended(const char* backup_path, const char* root, int umount_when_finished) { int ret; char mount_point[PATH_MAX]; translate_root_path(root, mount_point, PATH_MAX); char* name = basename(mount_point); char tmp[PATH_MAX]; sprintf(tmp, "%s/%s.img", backup_path, name); struct stat file_info; if (0 != (ret = statfs(tmp, &file_info))) { ui_print("%s.img not found. Skipping restore of %s.\n", name, mount_point); return 0; } ensure_directory(mount_point); unyaffs_callback callback = NULL; if (0 != stat("/sdcard/ebrecovery/.hidenandroidprogress", &file_info)) { callback = yaffs_callback; } ui_print("Restoring %s...\n", name); /* if (0 != (ret = ensure_root_path_unmounted(root))) { ui_print("Can't unmount %s!\n", mount_point); return ret; } */ if (0 != (ret = format_root_device(root))) { ui_print("Error while formatting %s!\n", root); return ret; } if (0 != (ret = ensure_root_path_mounted(root))) { ui_print("Can't mount %s!\n", mount_point); return ret; } if (0 != (ret = unyaffs(tmp, mount_point, callback))) { ui_print("Error while restoring %s!\n", mount_point); return ret; } if (umount_when_finished) { ensure_root_path_unmounted(root); } return 0; }
// clear the recovery command and prepare to boot a (hopefully working) system, // copy our log file to cache as well (for the system to read), and // record any intent we were asked to communicate back to the system. // this function is idempotent: call it as many times as you like. static void finish_recovery(const char *send_intent) { // By this point, we're ready to return to the main system... if (send_intent != NULL) { FILE *fp = fopen_root_path(INTENT_FILE, "w"); if (fp == NULL) { LOGE("Can't open %s\n", INTENT_FILE); } else { fputs(send_intent, fp); check_and_fclose(fp, INTENT_FILE); } } // Copy logs to cache so the system can find out what happened. FILE *log = fopen_root_path(LOG_FILE, "a"); if (log == NULL) { LOGE("Can't open %s\n", LOG_FILE); } else { FILE *tmplog = fopen(TEMPORARY_LOG_FILE, "r"); if (tmplog == NULL) { LOGE("Can't open %s\n", TEMPORARY_LOG_FILE); } else { static long tmplog_offset = 0; fseek(tmplog, tmplog_offset, SEEK_SET); // Since last write char buf[4096]; while (fgets(buf, sizeof(buf), tmplog)) fputs(buf, log); tmplog_offset = ftell(tmplog); check_and_fclose(tmplog, TEMPORARY_LOG_FILE); } check_and_fclose(log, LOG_FILE); } #ifndef BOARD_HAS_NO_MISC_PARTITION // Reset to mormal system boot so recovery won't cycle indefinitely. struct bootloader_message boot; memset(&boot, 0, sizeof(boot)); set_bootloader_message(&boot); #endif // Remove the command file, so recovery won't repeat indefinitely. char path[PATH_MAX] = ""; if (ensure_root_path_mounted(COMMAND_FILE) != 0 || translate_root_path(COMMAND_FILE, path, sizeof(path)) == NULL || (unlink(path) && errno != ENOENT)) { LOGW("Can't unlink %s\n", COMMAND_FILE); } sync(); // For good measure. }
/* set_perm <uid> <gid> <mode> <path> [... <pathN>] * set_perm_recursive <uid> <gid> <dir-mode> <file-mode> <path> [... <pathN>] * * Like "chmod", "chown" and "chgrp" all in one, set ownership and permissions * of single files or entire directory trees. Any error causes failure. * User, group, and modes must all be integer values (hex or octal OK). */ static int cmd_set_perm(const char *name, void *cookie, int argc, const char *argv[], PermissionRequestList *permissions) { UNUSED(cookie); CHECK_WORDS(); bool recurse = !strcmp(name, "set_perm_recursive"); int min_args = 4 + (recurse ? 1 : 0); if (argc < min_args) { LOGE("Command %s requires at least %d args\n", name, min_args); return 1; } // All the arguments except the path(s) are numeric. int i, n[min_args - 1]; for (i = 0; i < min_args - 1; ++i) { char *end; n[i] = strtoul(argv[i], &end, 0); if (end[0] != '\0' || argv[i][0] == '\0') { LOGE("Command %s: invalid argument \"%s\"\n", name, argv[i]); return 1; } } for (i = min_args - 1; i < min_args; ++i) { char path[PATH_MAX]; if (translate_root_path(argv[i], path, sizeof(path)) == NULL) { LOGE("Command %s: bad path \"%s\"\n", name, argv[i]); return 1; } if (ensure_root_path_mounted(argv[i])) { LOGE("Can't mount %s\n", argv[i]); return 1; } if (recurse ? dirSetHierarchyPermissions(path, n[0], n[1], n[2], n[3]) : (chown(path, n[0], n[1]) || chmod(path, n[2]))) { LOGE("Can't chown/mod %s\n(%s)\n", path, strerror(errno)); return 1; } } return 0; }
/* file_contains(<filename>, <substring>) * Returns "true" if the file exists and contains the specified substring. */ static int fn_file_contains(const char *name, void *cookie, int argc, const char *argv[], char **result, size_t *resultLen, PermissionRequestList *permissions) { UNUSED(cookie); CHECK_FN(); NO_PERMS(permissions); if (argc != 2) { LOGE("Command %s requires exactly two arguments\n", name); return 1; } char pathbuf[PATH_MAX]; const char *root_path = argv[0]; const char *path = translate_root_path(root_path, pathbuf, sizeof(pathbuf)); if (path == NULL) { LOGE("Command %s: bad path \"%s\"\n", name, root_path); return 1; } if (ensure_root_path_mounted(root_path)) { LOGE("Can't mount %s\n", root_path); return 1; } const char *needle = argv[1]; char *haystack = (char*) load_file(path, NULL); if (haystack == NULL) { LOGI("%s: Can't read \"%s\" (%s)\n", name, path, strerror(errno)); *result = ""; /* File not found is not an error. */ } else if (strstr(haystack, needle) == NULL) { LOGI("%s: Can't find \"%s\" in \"%s\"\n", name, needle, path); *result = strdup(""); free(haystack); } else { *result = strdup("true"); free(haystack); } if (resultLen != NULL) { *resultLen = strlen(*result); } return 0; }
int tarbackup_restore_partition_extended(const char* backup_path, const char* root, int umount_when_finished) { int ret; char mount_point[PATH_MAX]; translate_root_path(root, mount_point, PATH_MAX); char* name = basename(mount_point); char tmp[PATH_MAX]; sprintf(tmp, "%s/%s.tar", backup_path, name); struct stat file_info; if (0 != (ret = statfs(tmp, &file_info))) { ui_print("%s.tar not found. Skipping restore of %s.\n", name, mount_point); return 0; } ensure_directory(mount_point); ui_print("Restoring %s...\n", name); if (0 != (ret = ensure_root_path_unmounted(root))) { ui_print("Can't unmount %s!\n", mount_point); return ret; } if (0 != (ret = format_root_device(root))) { ui_print("Error while formatting %s!\n", root); return ret; } if (0 != (ret = ensure_root_path_mounted(root))) { ui_print("Can't mount %s!\n", mount_point); return ret; } sprintf(tmp, "tar -x -f %s/%s.tar", backup_path, name); if (0 != __system(tmp)) { ui_print("Error while restoring %s!\n", mount_point); return ret; } if (umount_when_finished) { ensure_root_path_unmounted(root); } return 0; }
void show_nandroid_restore_menu() { if (ensure_root_path_mounted("SDCARD:") != 0) { LOGE ("Can't mount /sdcard\n"); return; } static char* headers[] = { "Choose an image to restore", "", NULL }; char* file = choose_file_menu("/sdcard/ebrecovery/backup/", NULL, headers); if (file == NULL) return; if (confirm_selection("Confirm restore?", "Yes - Restore")) nandroid_restore(file, 1, 1, 1, 1, 1); }
// there should be some checks whether the action actually succeded int ensure_lagfix_mount_points(const RootInfo *info) { int bindopts; bindopts = get_bind_options(); if (strcmp(info->name,"DATA:")==0) { mount_block("DATA","/dev/block/mmcblk0p2","/dev/block/loop1","/data","/res/odata"); if (bindopts>0) { ensure_root_path_mounted("DATADATA:"); __system("mkdir -p /dbdata/.data/data"); __system("mkdir -p /data/data"); __system("mount -o bind /dbdata/.data/data /data/data"); } } else if (strcmp(info->name,"DATADATA:")==0) { mount_block("DBDATA","/dev/block/stl10","/dev/block/loop2","/dbdata","/res/odbdata"); } else if (strcmp(info->name,"CACHE:")==0) { mount_block("CACHE","/dev/block/stl11","/dev/block/loop3","/cache","/res/ocache"); } else { return 1; } return 0; }
int install_img(char* filename, char* partition) { ui_print("\n-- Flash image from...\n"); ui_print(filename); ui_print("\n"); ensure_root_path_mounted("SDCARD:"); char* argv[] = { "/sbin/flash_image", partition, filename, NULL }; char* envp[] = { NULL }; int status = runve("/sbin/flash_image",argv,envp,1); ui_print("\nFlash from sdcard complete."); ui_print("\nThanks for using RZrecovery.\n"); return 0; }
// open a file given in root:path format, mounting partitions as necessary FILE* fopen_root_path(const char *root_path, const char *mode) { if (ensure_root_path_mounted(root_path) != 0) { LOGE("Can't mount %s\n", root_path); return NULL; } char path[PATH_MAX] = ""; if (translate_root_path(root_path, path, sizeof(path)) == NULL) { LOGE("Bad path %s\n", root_path); return NULL; } // When writing, try to create the containing directory, if necessary. // Use generous permissions, the system (init.rc) will reset them. if (strchr("wa", mode[0])) dirCreateHierarchy(path, 0777, NULL, 1); FILE *fp = fopen(path, mode); // if (fp == NULL) LOGE("Can't open %s\n", path); return fp; }
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 run_and_remove_extendedcommand() { char tmp[PATH_MAX]; sprintf(tmp, "cp %s /tmp/%s", EXTENDEDCOMMAND_SCRIPT, basename(EXTENDEDCOMMAND_SCRIPT)); __system(tmp); remove(EXTENDEDCOMMAND_SCRIPT); int i = 0; for (i = 20; i > 0; i--) { ui_print("Waiting for SD Card to mount (%ds)\n", i); if (ensure_root_path_mounted("SDCARD:") == 0) { ui_print("SD Card mounted...\n"); break; } sleep(1); } remove("/sdcard/ebrecovery/.recoverycheckpoint"); if (i == 0) { ui_print("Timed out waiting for SD card... continuing anyways."); } sprintf(tmp, "/tmp/%s", basename(EXTENDEDCOMMAND_SCRIPT)); return run_script(tmp); }
int install_package(const char *root_path) { ui_set_background(BACKGROUND_ICON_INSTALLING); ui_print("Finding update package...\n"); 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); /* Try to open the package. */ int err; 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; }
int nandroid_backup_boot(const char* backup_path) { ui_set_background(BACKGROUND_ICON_INSTALLING); if (ensure_root_path_mounted("SDCARD:") != 0) return print_and_error("Can't mount /sdcard\n"); int ret; struct statfs s; if (0 != (ret = statfs("/sdcard", &s))) return print_and_error("Unable to stat /sdcard\n"); uint64_t bavail = s.f_bavail; uint64_t bsize = s.f_bsize; uint64_t sdcard_free = bavail * bsize; uint64_t sdcard_free_mb = sdcard_free / (uint64_t)(1024 * 1024); ui_print("SD Card space free: %lluMB\n", sdcard_free_mb); if (sdcard_free_mb < 150) ui_print("There may not be enough free space to complete backup... continuing...\n"); char tmp[PATH_MAX]; sprintf(tmp, "mkdir -p %s", backup_path); __system(tmp); #ifndef BOARD_RECOVERY_IGNORE_BOOTABLES ui_print("Backing up boot...\n"); sprintf(tmp, "%s/%s", backup_path, "boot.img"); ret = backup_raw_partition("boot", tmp); if (0 != ret) return print_and_error("Error while dumping boot image!\n"); #endif sync(); ui_set_background(BACKGROUND_ICON_NONE); ui_reset_progress(); ui_print("\nBackup complete!\n"); return 0; }
int install_package(const char *root_path) { ui_set_background(BACKGROUND_ICON_INSTALLING); ui_print("查找升级包中...\n"); LOGI("升级点: %s\n", root_path); if (ensure_root_path_mounted(root_path) != 0) { LOGE("无法挂载 %s\n", root_path); return INSTALL_CORRUPT; } char path[PATH_MAX] = ""; if (translate_root_path(root_path, path, sizeof(path)) == NULL) { LOGE("错误路径 %s\n", root_path); return INSTALL_CORRUPT; } ui_print("打开升级包中...\n"); LOGI("升级文件路径: %s\n", path); /* Try to open the package. */ int err; ZipArchive zip; err = mzOpenZipArchive(path, &zip); if (err != 0) { LOGE("无法打开%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; }