nandroid in C now has a progress bar

This commit is contained in:
Koushik K. Dutta 2010-03-12 23:21:12 -08:00
parent 928d605435
commit ee57bbc1b6
11 changed files with 224 additions and 180 deletions

View File

@ -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

View File

@ -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

View File

@ -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).

View File

@ -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);

View File

@ -34,3 +34,5 @@ show_choose_zip_menu();
int
install_zip(const char* packagefilepath);
int
__system(const char *command);

183
nandroid.c Normal file
View File

@ -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;
}

8
nandroid.h Normal file
View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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();

7
ui.c
View File

@ -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)