diff --git a/Android.mk b/Android.mk index 582c260..48fef97 100644 --- a/Android.mk +++ b/Android.mk @@ -8,7 +8,8 @@ commands_recovery_local_path := $(LOCAL_PATH) # LOCAL_CPP_EXTENSION := .c LOCAL_SRC_FILES := \ - extendedcommands.c \ + extendedcommands.c \ + nandroid.c \ legacy.c \ commands.c \ recovery.c \ @@ -50,7 +51,6 @@ LOCAL_STATIC_LIBRARIES += libstdc++ libc include $(BUILD_EXECUTABLE) include $(commands_recovery_local_path)/amend/Android.mk -include $(commands_recovery_local_path)/nandroid/Android.mk include $(commands_recovery_local_path)/minui/Android.mk include $(commands_recovery_local_path)/minzip/Android.mk include $(commands_recovery_local_path)/mtdutils/Android.mk diff --git a/commands.c b/commands.c index 7b2c2c1..2687f63 100644 --- a/commands.c +++ b/commands.c @@ -779,7 +779,7 @@ cmd_backup_rom(const char *name, void *cookie, int argc, const char *argv[], return 1; } - return do_nandroid_backup(backup_name); + return nandroid_backup(backup_name); } static int @@ -794,7 +794,7 @@ cmd_restore_rom(const char *name, void *cookie, int argc, const char *argv[], return 1; } - return do_nandroid_restore(argv[0]); + return nandroid_restore(argv[0]); } static int diff --git a/common.h b/common.h index d962a0a..ddc9f68 100644 --- a/common.h +++ b/common.h @@ -33,6 +33,8 @@ void ui_clear_key_queue(); // so keep the output short and not too cryptic. void ui_print(const char *fmt, ...); +void ui_reset_text_col(); + // Display some header text followed by a menu of items, which appears // at the top of the screen (in place of any scrolling ui_print() // output, if necessary). diff --git a/extendedcommands.c b/extendedcommands.c index f595884..c63aa73 100644 --- a/extendedcommands.c +++ b/extendedcommands.c @@ -37,6 +37,9 @@ #include "../../external/yaffs2/yaffs2/utils/mkyaffs2image.h" #include "../../external/yaffs2/yaffs2/utils/unyaffs.h" +#include "extendedcommands.h" +#include "nandroid.h" + int signature_check_enabled = 1; int script_assert_enabled = 1; static const char *SDCARD_PACKAGE_FILE = "SDCARD:update.zip"; @@ -120,7 +123,7 @@ char** gather_files(const char* directory, const char* fileExtensionOrDirectory, struct dirent *de; int total = 0; int i; - char** files; + char** files = NULL; int pass; *numFiles = 0; int dirLen = strlen(directory); @@ -131,7 +134,7 @@ char** gather_files(const char* directory, const char* fileExtensionOrDirectory, return NULL; } - int extension_length; + int extension_length = 0; if (fileExtensionOrDirectory != NULL) extension_length = strlen(fileExtensionOrDirectory); @@ -225,7 +228,7 @@ char* choose_file_menu(const char* directory, const char* fileExtensionOrDirecto int dir_len = strlen(directory); char** files = gather_files(directory, fileExtensionOrDirectory, &numFiles); - char** dirs; + char** dirs = NULL; if (fileExtensionOrDirectory != NULL) dirs = gather_files(directory, NULL, &numDirs); int total = numDirs + numFiles; @@ -291,10 +294,10 @@ void show_choose_zip_menu() // This was pulled from bionic: The default system command always looks // for shell in /system/bin/sh. This is bad. #define _PATH_BSHELL "/sbin/sh" -#define system recovery_system + extern char **environ; int -system(const char *command) +__system(const char *command) { pid_t pid; sig_t intsave, quitsave; @@ -335,124 +338,11 @@ int print_and_error(char* message) return 1; } -// TODO : Separate file for Nandroid? -int do_nandroid_backup(char* backup_name) -{ - if (ensure_root_path_mounted("SDCARD:") != 0) { - LOGE ("Can't mount /sdcard\n"); - return 1; - } - - struct timeval tp; - gettimeofday(&tp, NULL); - - char backupdir[PATH_MAX]; - char tmp[PATH_MAX]; - if (NULL != backup_name) - sprintf(backupdir, "/sdcard/clockworkmod/backup/%s", backup_name); - else - sprintf(backupdir, "/sdcard/clockworkmod/backup/%d", tp.tv_sec); - - sprintf(tmp, "mkdir -p %s", backupdir); - system(tmp); - - int ret; - ui_print("Backing up boot...\n"); - sprintf(tmp, "%s/%s", backupdir, "boot.img"); - ret = dump_image("boot", tmp, NULL); - if (0 != ret) - return print_and_error("Error while dumping boot image!\n"); - - // TODO: Wrap this up in a loop? - ui_print("Backing up system...\n"); - sprintf(tmp, "%s/%s", backupdir, "system.img"); - if (ensure_root_path_mounted("SYSTEM:") != 0) - return print_and_error("Can't mount /system!\n"); - ret = mkyaffs2image("/system", tmp, 0, NULL); - ensure_root_path_unmounted("SYSTEM:"); - if (0 != ret) - return print_and_error("Error while making a yaffs2 image of system!\n"); - - ui_print("Backing up data...\n"); - sprintf(tmp, "%s/%s", backupdir, "data.img"); - if (ensure_root_path_mounted("DATA:") != 0) - return print_and_error("Can't mount /data!\n"); - ret = mkyaffs2image("/data", tmp, 0, NULL); - ensure_root_path_unmounted("DATA:"); - if (0 != ret) - return print_and_error("Error while making a yaffs2 image of data!\n"); - - ui_print("Backing up cache...\n"); - sprintf(tmp, "%s/%s", backupdir, "cache.img"); - if (ensure_root_path_mounted("CACHE:") != 0) - return print_and_error("Can't mount /cache!\n"); - ret = mkyaffs2image("/cache", tmp, 0, NULL); - ensure_root_path_unmounted("CACHE:"); - if (0 != ret) - return print_and_error("Error while making a yaffs2 image of cache!\n"); - - sprintf(tmp, "md5sum %s/*img > %s/nandroid.md5", backupdir, backupdir); - system(tmp); - - return 0; -} - -int do_nandroid_restore(char* backup_path) -{ - if (ensure_root_path_mounted("SDCARD:") != 0) { - LOGE ("Can't mount /sdcard\n"); - return 1; - } - - char tmp[PATH_MAX]; - - ui_print("Checking MD5 sums...\n"); - sprintf(tmp, "md5sum -c %s/nandroid.md5", backup_path); - if (0 != system(tmp)) - return print_and_error("MD5 mismatch!\n"); - - // TODO: put this in a loop? - ui_print("Restoring system...\n"); - if (0 != ensure_root_path_unmounted("SYSTEM:")) - return print_and_error("Can't unmount /system!\n"); - if (0 != format_root_device("SYSTEM:")) - return print_and_error("Error while formatting /system!\n"); - if (ensure_root_path_mounted("SYSTEM:") != 0) - return print_and_error("Can't mount /system!\n"); - sprintf(tmp, "%s/system.img", backup_path); - if (0 != unyaffs(tmp, "/system", NULL)) - return print_and_error("Error while restoring /system!\n"); - - ui_print("Restoring data...\n"); - if (0 != ensure_root_path_unmounted("DATA:")) - return print_and_error("Can't unmount /data!\n"); - if (0 != format_root_device("DATA:")) - return print_and_error("Error while formatting /data!\n"); - if (ensure_root_path_mounted("DATA:") != 0) - return print_and_error("Can't mount /data!\n"); - sprintf(tmp, "%s/data.img", backup_path); - if (0 != unyaffs(tmp, "/data", NULL)) - return print_and_error("Error while restoring /data!\n"); - - ui_print("Restoring cache...\n"); - if (0 != ensure_root_path_unmounted("CACHE:")) - return print_and_error("Can't unmount /cache!\n"); - if (0 != format_root_device("CACHE:")) - return print_and_error("Error while formatting /cache!\n"); - if (ensure_root_path_mounted("CACHE:") != 0) - return print_and_error("Can't mount /cache!\n"); - sprintf(tmp, "%s/cache.img", backup_path); - if (0 != unyaffs(tmp, "/cache", NULL)) - return print_and_error("Error while restoring /cache!\n"); - - return 0; -} - void show_nandroid_restore_menu() { if (ensure_root_path_mounted("SDCARD:") != 0) { LOGE ("Can't mount /sdcard\n"); - return 1; + return; } static char* headers[] = { "Choose an image to restore", @@ -463,7 +353,7 @@ void show_nandroid_restore_menu() char* file = choose_file_menu("/sdcard/clockworkmod/backup/", NULL, headers); if (file == NULL) return; - do_nandroid_restore(file); + nandroid_restore(file); } void do_mount_usb_storage() @@ -514,7 +404,7 @@ int run_script_from_buffer(char* script_data, int script_len, char* filename) int ret = execCommandList((ExecContext *)1, commands); if (ret != 0) { int num = ret; - char *line, *next = script_data; + char *line = NULL, *next = script_data; while (next != NULL && ret-- > 0) { line = next; next = memchr(line, '\n', script_data + script_len - line); diff --git a/extendedcommands.h b/extendedcommands.h index 8a5a1f2..65b1a7a 100644 --- a/extendedcommands.h +++ b/extendedcommands.h @@ -34,3 +34,5 @@ show_choose_zip_menu(); int install_zip(const char* packagefilepath); +int +__system(const char *command); diff --git a/nandroid.c b/nandroid.c new file mode 100644 index 0000000..08f3ec2 --- /dev/null +++ b/nandroid.c @@ -0,0 +1,183 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + +#include "bootloader.h" +#include "common.h" +#include "cutils/properties.h" +#include "firmware.h" +#include "install.h" +#include "minui/minui.h" +#include "minzip/DirUtil.h" +#include "roots.h" +#include "recovery_ui.h" + +#include "commands.h" +#include "amend/amend.h" + +#include "mtdutils/dump_image.h" +#include "../../external/yaffs2/yaffs2/utils/mkyaffs2image.h" +#include "../../external/yaffs2/yaffs2/utils/unyaffs.h" + +#include "extendedcommands.h" +#include "nandroid.h" + +int yaffs_files_total = 0; +int yaffs_files_count = 0; +void yaffs_callback(char* filename) +{ + char* justfile = basename(filename); + if (strlen(justfile) < 30) + ui_print(basename(filename)); + yaffs_files_count++; + if (yaffs_files_total != 0) + ui_set_progress((float)yaffs_files_count / (float)yaffs_files_total); + ui_reset_text_col(); +} + +void compute_directory_stats(char* directory) +{ + char tmp[PATH_MAX]; + sprintf(tmp, "find %s | wc -l > /tmp/dircount", directory); + __system(tmp); + char count_text[100]; + FILE* f = fopen("/tmp/dircount", "r"); + fread(count_text, 1, sizeof(count_text), f); + fclose(f); + yaffs_files_count = 0; + yaffs_files_total = atoi(count_text); + ui_reset_progress(); + ui_show_progress(1, 0); +} + +int nandroid_backup(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"); + + char tmp[PATH_MAX]; + sprintf(tmp, "mkdir -p %s", backup_path); + __system(tmp); + + int ret; + ui_print("Backing up boot...\n"); + sprintf(tmp, "%s/%s", backup_path, "boot.img"); + ret = dump_image("boot", tmp, NULL); + if (0 != ret) + return print_and_error("Error while dumping boot image!\n"); + + // TODO: Wrap this up in a loop? + ui_print("Backing up system...\n"); + sprintf(tmp, "%s/%s", backup_path, "system.img"); + if (ensure_root_path_mounted("SYSTEM:") != 0) + return print_and_error("Can't mount /system!\n"); + compute_directory_stats("/system"); + ret = mkyaffs2image("/system", tmp, 0, yaffs_callback); + ensure_root_path_unmounted("SYSTEM:"); + if (0 != ret) + return print_and_error("Error while making a yaffs2 image of system!\n"); + + ui_print("Backing up data...\n"); + sprintf(tmp, "%s/%s", backup_path, "data.img"); + if (ensure_root_path_mounted("DATA:") != 0) + return print_and_error("Can't mount /data!\n"); + compute_directory_stats("/data"); + ret = mkyaffs2image("/data", tmp, 0, yaffs_callback); + ensure_root_path_unmounted("DATA:"); + if (0 != ret) + return print_and_error("Error while making a yaffs2 image of data!\n"); + + ui_print("Backing up cache...\n"); + sprintf(tmp, "%s/%s", backup_path, "cache.img"); + if (ensure_root_path_mounted("CACHE:") != 0) + return print_and_error("Can't mount /cache!\n"); + compute_directory_stats("/cache"); + ret = mkyaffs2image("/cache", tmp, 0, yaffs_callback); + ensure_root_path_unmounted("CACHE:"); + if (0 != ret) + return print_and_error("Error while making a yaffs2 image of cache!\n"); + + sprintf(tmp, "md5sum %s/*img > %s/nandroid.md5", backup_path, backup_path); + __system(tmp); + + ui_set_background(BACKGROUND_ICON_NONE); + ui_reset_progress(); + ui_print("Backup complete!\n"); + return 0; +} + +int nandroid_restore(char* backup_path) +{ + 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, "md5sum -c %s/nandroid.md5", backup_path); + if (0 != __system(tmp)) + return print_and_error("MD5 mismatch!\n"); + + // TODO: put this in a loop? + ui_print("Restoring system...\n"); + if (0 != ensure_root_path_unmounted("SYSTEM:")) + return print_and_error("Can't unmount /system!\n"); + if (0 != format_root_device("SYSTEM:")) + return print_and_error("Error while formatting /system!\n"); + if (ensure_root_path_mounted("SYSTEM:") != 0) + return print_and_error("Can't mount /system!\n"); + sprintf(tmp, "%s/system.img", backup_path); + if (0 != unyaffs(tmp, "/system", yaffs_callback)) + return print_and_error("Error while restoring /system!\n"); + + ui_print("Restoring data...\n"); + if (0 != ensure_root_path_unmounted("DATA:")) + return print_and_error("Can't unmount /data!\n"); + if (0 != format_root_device("DATA:")) + return print_and_error("Error while formatting /data!\n"); + if (ensure_root_path_mounted("DATA:") != 0) + return print_and_error("Can't mount /data!\n"); + sprintf(tmp, "%s/data.img", backup_path); + if (0 != unyaffs(tmp, "/data", yaffs_callback)) + return print_and_error("Error while restoring /data!\n"); + + ui_print("Restoring cache...\n"); + if (0 != ensure_root_path_unmounted("CACHE:")) + return print_and_error("Can't unmount /cache!\n"); + if (0 != format_root_device("CACHE:")) + return print_and_error("Error while formatting /cache!\n"); + if (ensure_root_path_mounted("CACHE:") != 0) + return print_and_error("Can't mount /cache!\n"); + sprintf(tmp, "%s/cache.img", backup_path); + if (0 != unyaffs(tmp, "/cache", yaffs_callback)) + return print_and_error("Error while restoring /cache!\n"); + + ui_set_background(BACKGROUND_ICON_NONE); + ui_reset_progress(); + ui_print("Restore complete!\n"); + return 0; +} diff --git a/nandroid.h b/nandroid.h new file mode 100644 index 0000000..3f6c5a8 --- /dev/null +++ b/nandroid.h @@ -0,0 +1,8 @@ +#ifndef NANDROID_H +#define NANDROID_H + +int nandroid_main(int argc, char** argv); +int nandroid_backup(char* backup_path); +int nandroid_restore(char* backup_path); + +#endif \ No newline at end of file diff --git a/nandroid/Android.mk b/nandroid/Android.mk deleted file mode 100644 index e5aaef8..0000000 --- a/nandroid/Android.mk +++ /dev/null @@ -1,21 +0,0 @@ -LOCAL_PATH := $(call my-dir) -include $(CLEAR_VARS) -LOCAL_MODULE := recovery_nandroid -LOCAL_MODULE_TAGS := eng -LOCAL_MODULE_CLASS := RECOVERY_EXECUTABLES -LOCAL_MODULE_PATH := $(TARGET_RECOVERY_ROOT_OUT)/sbin -LOCAL_SRC_FILES := nandroid-mobile.sh -LOCAL_MODULE_STEM := nandroid-mobile.sh -ADDITIONAL_RECOVERY_EXECUTABLES += recovery_nandroid -include $(BUILD_PREBUILT) - -include $(CLEAR_VARS) -LOCAL_MODULE := recovery_mkfstab -LOCAL_MODULE_TAGS := eng -LOCAL_MODULE_CLASS := RECOVERY_EXECUTABLES -LOCAL_MODULE_PATH := $(TARGET_RECOVERY_ROOT_OUT)/sbin -LOCAL_SRC_FILES := mkfstab.sh -LOCAL_MODULE_STEM := mkfstab.sh -ADDITIONAL_RECOVERY_EXECUTABLES += recovery_mkfstab -include $(BUILD_PREBUILT) - diff --git a/nandroid/mkfstab.sh b/nandroid/mkfstab.sh deleted file mode 100755 index 649ae2f..0000000 --- a/nandroid/mkfstab.sh +++ /dev/null @@ -1,33 +0,0 @@ -#!/sbin/sh - -cat /proc/mtd | while read mtdentry -do - mtd=$(echo $mtdentry | awk '{print $1}') - mtd=$(echo $mtd | sed s/mtd//) - mtd=$(echo $mtd | sed s/://) - exist=$(ls -l /dev/block/mtdblock$mtd) 2> /dev/null - if [ -z "$exist" ] - then - continue - fi - partition=$(echo $mtdentry | awk '{print $4}') - partition=$(echo $partition | sed s/\"//g) - mount=$partition - type= - if [ "$partition" = "system" ] - then - type=yaffs2 - elif [ "$partition" = "userdata" ] - then - type=yaffs2 - mount=data - elif [ "$partition" == "cache" ] - then - type=yaffs2 - else - continue - fi - - echo "/dev/block/mtdblock$mtd /$mount $type rw" -done -echo "/dev/block/mmcblk0p1" /sdcard vfat rw \ No newline at end of file diff --git a/recovery.c b/recovery.c index 440167b..a160ce7 100644 --- a/recovery.c +++ b/recovery.c @@ -446,7 +446,13 @@ prompt_and_wait() show_install_update_menu(); break; case ITEM_BACKUP: - do_nandroid_backup(NULL); + { + struct timeval tp; + gettimeofday(&tp, NULL); + char backup_path[PATH_MAX]; + sprintf(backup_path, "/sdcard/clockworkmod/backup/%d", tp.tv_sec); + nandroid_backup(backup_path); + } break; case ITEM_RESTORE: show_nandroid_restore_menu(); diff --git a/ui.c b/ui.c index 02824d9..e704d05 100644 --- a/ui.c +++ b/ui.c @@ -480,6 +480,13 @@ void ui_print(const char *fmt, ...) pthread_mutex_unlock(&gUpdateMutex); } +void ui_reset_text_col() +{ + pthread_mutex_lock(&gUpdateMutex); + text_col = 0; + pthread_mutex_unlock(&gUpdateMutex); +} + #define MENU_ITEM_HEADER " - " #define MENU_ITEM_HEADER_LENGTH strlen(MENU_ITEM_HEADER)