diff --git a/extendedcommands.c b/extendedcommands.c index 5185859..9198720 100644 --- a/extendedcommands.c +++ b/extendedcommands.c @@ -33,6 +33,9 @@ #include "commands.h" #include "amend/amend.h" +#include "mtdutils/dump_image.h" +#include "../../external/yaffs2/yaffs2/utils/mkyaffs2image.h" + int signature_check_enabled = 1; int script_assert_enabled = 1; static const char *SDCARD_PACKAGE_FILE = "SDCARD:update.zip"; @@ -326,27 +329,76 @@ system(const char *command) return (pid == -1 ? -1 : pstat); } +int print_and_error(char* message) +{ + ui_print(message); + return 1; +} + int do_nandroid_backup(char* backup_name) { if (ensure_root_path_mounted("SDCARD:") != 0) { LOGE ("Can't mount /sdcard\n"); return 1; } - - char cmd[PATH_MAX]; - if (NULL != backup_name) - sprintf(cmd, "/sbin/nandroid-mobile.sh backup /sdcard/clockworkmod/backup/ %s", backup_name); - else - sprintf(cmd, "/sbin/nandroid-mobile.sh backup /sdcard/clockworkmod/backup/"); - ui_print("Performing backup...\n"); - int ret = system(cmd); - if (ret != 0) - { - ui_print("Error while backing up! Error code: %d\n", ret); - return ret; + if (ensure_root_path_mounted("SYSTEM:") != 0) { + LOGE ("Can't mount /system\n"); + return 1; } - ui_print("Backup complete.\n"); - return ret; + if (ensure_root_path_mounted("DATA:") != 0) { + LOGE ("Can't mount /data\n"); + return 1; + } + if (ensure_root_path_mounted("CACHE:") != 0) { + LOGE ("Can't mount /cache\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"); + + ui_print("Backing up system...\n"); + sprintf(tmp, "%s/%s", backupdir, "system.img"); + 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"); + 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"); + 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) diff --git a/mtdutils/dump_image.c b/mtdutils/dump_image.c index 30f73e9..8b0a896 100644 --- a/mtdutils/dump_image.c +++ b/mtdutils/dump_image.c @@ -24,6 +24,7 @@ #include "cutils/log.h" #include "mtdutils.h" +#include "dump_image.h" #ifdef LOG_TAG #undef LOG_TAG @@ -34,7 +35,7 @@ #define BLOCK_SIZE 2048 #define SPARE_SIZE (BLOCK_SIZE >> 5) -static void die(const char *msg, ...) { +static int die(const char *msg, ...) { int err = errno; va_list args; va_start(args, msg); @@ -48,11 +49,72 @@ static void die(const char *msg, ...) { } fprintf(stderr, "%s\n", buf); - exit(1); + return 1; } /* Read a flash partition and write it to an image file. */ +int dump_image(char* partition_name, char* filename, dump_image_callback callback) { + MtdReadContext *in; + const MtdPartition *partition; + char buf[BLOCK_SIZE + SPARE_SIZE]; + size_t partition_size; + size_t read_size; + size_t total; + int fd; + int wrote; + int len; + + if (mtd_scan_partitions() <= 0) + return die("error scanning partitions"); + + partition = mtd_find_partition_by_name(partition_name); + if (partition == NULL) + return die("can't find %s partition", partition_name); + + if (mtd_partition_info(partition, &partition_size, NULL, NULL)) { + return die("can't get info of partition %s", partition_name); + } + + if (!strcmp(filename, "-")) { + fd = fileno(stdout); + } + else { + fd = open(filename, O_WRONLY|O_CREAT|O_TRUNC, 0666); + } + + if (fd < 0) + return die("error opening %s", filename); + + in = mtd_read_partition(partition); + if (in == NULL) { + close(fd); + unlink(filename); + return die("error opening %s: %s\n", partition_name, strerror(errno)); + } + + total = 0; + while ((len = mtd_read_data(in, buf, BLOCK_SIZE)) > 0) { + wrote = write(fd, buf, len); + if (wrote != len) { + close(fd); + unlink(filename); + return die("error writing %s", filename); + } + total += BLOCK_SIZE; + if (callback != NULL) + callback(total, partition_size); + } + + mtd_read_close(in); + + if (close(fd)) { + unlink(filename); + return die("error closing %s", filename); + } + return 0; +} + int main(int argc, char **argv) { ssize_t (*read_func) (MtdReadContext *, char *, size_t); @@ -71,51 +133,5 @@ int main(int argc, char **argv) return 2; } - if (mtd_scan_partitions() <= 0) - die("error scanning partitions"); - - partition = mtd_find_partition_by_name(argv[1]); - if (partition == NULL) - die("can't find %s partition", argv[1]); - - if (mtd_partition_info(partition, &partition_size, NULL, NULL)) { - die("can't get info of partition %s", argv[1]); - } - - if (!strcmp(argv[2], "-")) { - fd = fileno(stdout); - } - else { - fd = open(argv[2], O_WRONLY|O_CREAT|O_TRUNC, 0666); - } - - if (fd < 0) - die("error opening %s", argv[2]); - - in = mtd_read_partition(partition); - if (in == NULL) { - close(fd); - unlink(argv[2]); - die("error opening %s: %s\n", argv[1], strerror(errno)); - } - - total = 0; - while ((len = mtd_read_data(in, buf, BLOCK_SIZE)) > 0) { - wrote = write(fd, buf, len); - if (wrote != len) { - close(fd); - unlink(argv[2]); - die("error writing %s", argv[2]); - } - total += BLOCK_SIZE; - } - - mtd_read_close(in); - - if (close(fd)) { - unlink(argv[2]); - die("error closing %s", argv[2]); - } - - return 0; + return dump_image(argv[1], argv[2], NULL); } diff --git a/mtdutils/dump_image.h b/mtdutils/dump_image.h new file mode 100644 index 0000000..6198322 --- /dev/null +++ b/mtdutils/dump_image.h @@ -0,0 +1,8 @@ +#ifndef DUMP_IMAGE_H +#define DUMP_IMAGE_H + +typedef void (*dump_image_callback) (int partition_dumped, int partition_size); + +int dump_image(char* partition_name, char* filename, dump_image_callback callback); + +#endif diff --git a/nandroid/Android.mk b/nandroid/Android.mk index 4b22437..e5aaef8 100644 --- a/nandroid/Android.mk +++ b/nandroid/Android.mk @@ -19,4 +19,3 @@ LOCAL_MODULE_STEM := mkfstab.sh ADDITIONAL_RECOVERY_EXECUTABLES += recovery_mkfstab include $(BUILD_PREBUILT) -include $(CLEAR_VARS)