nandroid in C now has a progress bar
diff --git a/Android.mk b/Android.mk
index 582c260..48fef97 100644
--- a/Android.mk
+++ b/Android.mk
@@ -8,7 +8,8 @@
# LOCAL_CPP_EXTENSION := .c
LOCAL_SRC_FILES := \
- extendedcommands.c \
+ extendedcommands.c \
+ nandroid.c \
legacy.c \
commands.c \
recovery.c \
@@ -50,7 +51,6 @@
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 @@
return 1;
}
- return do_nandroid_backup(backup_name);
+ return nandroid_backup(backup_name);
}
static int
@@ -794,7 +794,7 @@
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 @@
// 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 @@
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 @@
return NULL;
}
- int extension_length;
+ int extension_length = 0;
if (fileExtensionOrDirectory != NULL)
extension_length = strlen(fileExtensionOrDirectory);
@@ -225,7 +228,7 @@
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 @@
// 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 @@
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 @@
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 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 @@
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 <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <getopt.h>
+#include <limits.h>
+#include <linux/input.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/reboot.h>
+#include <sys/types.h>
+#include <time.h>
+#include <unistd.h>
+
+#include <sys/wait.h>
+#include <sys/limits.h>
+#include <dirent.h>
+#include <sys/stat.h>
+
+#include <signal.h>
+#include <sys/wait.h>
+
+#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 @@
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 @@
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)