Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
0
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;
}
Ejemplo n.º 3
0
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;
}
Ejemplo n.º 4
0
int nandroid_restore_datamedia(const char* backup_path) {
    char tmp[PATH_MAX];
    ui_print("\n>> Restoring /data/media...\n");
    if (is_data_media_volume_path(backup_path)) {
        // non fatal failure
        LOGE("  - can't restore folder to its self, skipping...\n");
        return 0;
    }

    Volume *v = volume_for_path("/data");
    if (v == NULL)
        return -1;

    sprintf(tmp, "%s/%s", get_primary_storage_path(), NANDROID_HIDE_PROGRESS_FILE);
    ensure_path_mounted(tmp);
    int callback = !file_found(tmp);

    struct stat s;
    char backup_file_image[PATH_MAX];
    const char *filesystems[] = { "yaffs2", "ext2", "ext3", "ext4", "vfat", "exfat", "rfs", "f2fs", "auto", NULL };
    const char *filesystem;
    int i = 0;
    nandroid_restore_handler restore_handler = NULL;
    while ((filesystem = filesystems[i]) != NULL) {
        sprintf(backup_file_image, "%s/datamedia.%s.tar", backup_path, filesystem);
        if (0 == stat(backup_file_image, &s)) {
            restore_handler = tar_extract_wrapper;
            sprintf(tmp, "cd / ; set -o pipefail ; cat %s* | tar -xpv ; exit $?", backup_file_image);
            break;
        }
        sprintf(backup_file_image, "%s/datamedia.%s.tar.gz", backup_path, filesystem);
        if (0 == stat(backup_file_image, &s)) {
            restore_handler = tar_gzip_extract_wrapper;
            sprintf(tmp, "cd / ; set -o pipefail ; cat %s* | pigz -d -c | tar -xpv ; exit $?", backup_file_image);
            break;
        }
        i++;
    }

    if (filesystem == NULL || restore_handler == NULL) {
        LOGE("No backup found, skipping...\n");
        return 0;
    }

    if (0 != format_unknown_device(NULL, "/data/media", NULL))
        return print_and_error("Error while erasing /data/media\n", NANDROID_ERROR_GENERAL);

    // data can be unmounted by format_unknown_device()
    if (0 != ensure_path_mounted("/data"))
        return -1;

    if (0 != do_tar_extract(tmp, backup_file_image, "/data", callback))
        return print_and_error("Failed to restore /data/media!\n", NANDROID_ERROR_GENERAL);

    ui_print("Restore of /data/media completed.\n");
    return 0;
}
Ejemplo n.º 5
0
int nandroid_backup_sd(const char* backup_path)
{
    ui_set_background(BACKGROUND_ICON_INSTALLING);
    
    if (ensure_path_mounted(backup_path) != 0) {
        return print_and_error("Can't mount backup path.\n");
    }
    
    Volume* volume = volume_for_path(backup_path);
    if (NULL == volume) {
      if (strstr(backup_path, "/sdcard") == backup_path && is_data_media())
          volume = volume_for_path("/data");
      else
          return print_and_error("Unable to find volume for backup path.\n");
    }
    int ret;
    struct statfs s;
    if (NULL != volume) {
        if (0 != (ret = statfs(volume->mount_point, &s)))
            return print_and_error("Unable to stat backup path.\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);
    Volume *vol = volume_for_path("/sd-ext");
    if (vol == NULL || 0 != stat(vol->device, &s))
    {
        ui_print("No sd-ext found. Skipping backup of sd-ext.\n");
    }
    else
    {
        if (0 != ensure_path_mounted("/sd-ext"))
            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, "/sd-ext")))
            return ret;
    }
    
    sync();
    ui_set_background(BACKGROUND_ICON_NONE);
    ui_reset_progress();
    ui_print("\nBackup complete!\n");
    return 0;
}
Ejemplo n.º 6
0
int nandroid_advanced_backup(const char* backup_path, const char *root)
{
    if (ensure_path_mounted(backup_path) != 0) {
        return print_and_error("Can't mount backup path.\n");
    }
    
    Volume* volume = volume_for_path(backup_path);
    if (NULL == volume) {
      if (strstr(backup_path, "/sdcard") == backup_path && is_data_media())
          volume = volume_for_path("/data");
      else
          return print_and_error("Unable to find volume for backup path.\n");
    }
    int ret;
    struct statfs s;
    if (NULL != volume) {
        if (0 != (ret = statfs(volume->mount_point, &s)))
            return print_and_error("Unable to stat backup path.\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(backup_path, root)))
        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_print("\nBackup complete!\n");
    return 0;

}
Ejemplo n.º 7
0
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;
}
Ejemplo n.º 8
0
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;
}
Ejemplo n.º 9
0
// backup /data/media support
// we reach here only if backup_data_media == 1
// backup_data_media can be set to 1 only in "custom backup and restore" menu AND if is_data_media() && !twrp_backup_mode.value
int nandroid_backup_datamedia(const char* backup_path) {
    char tmp[PATH_MAX];
    ui_print("\n>> Backing up /data/media...\n");
    if (is_data_media_volume_path(backup_path)) {
        // non fatal failure
        LOGE("  - can't backup folder to its self, skipping...\n");
        return 0;
    }

    if (0 != ensure_path_mounted("/data"))
        return -1;

    sprintf(tmp, "%s/%s", get_primary_storage_path(), NANDROID_HIDE_PROGRESS_FILE);
    ensure_path_mounted(tmp);
    int callback = !file_found(tmp);

    compute_directory_stats("/data/media");
    Volume *v = volume_for_path("/data");
    if (v == NULL)
        return -1;

    char backup_file_image[PATH_MAX];
    sprintf(backup_file_image, "%s/datamedia.%s", backup_path, v->fs_type == NULL ? "auto" : v->fs_type);

    int fmt;
    fmt = nandroid_get_default_backup_format();
    if (fmt == NANDROID_BACKUP_FORMAT_TAR) {
        sprintf(tmp, "cd / ; touch %s.tar ; set -o pipefail ; (tar -cpv data/media | split -a 1 -b 1000000000 /proc/self/fd/0 %s.tar.) 2> /proc/self/fd/1 ; exit $?",
                backup_file_image, backup_file_image);
    } else if (fmt == NANDROID_BACKUP_FORMAT_TGZ) {
        sprintf(tmp, "cd / ; touch %s.tar.gz ; set -o pipefail ; (tar -cpv data/media | pigz -c -%d | split -a 1 -b 1000000000 /proc/self/fd/0 %s.tar.gz.) 2> /proc/self/fd/1 ; exit $?",
                backup_file_image, compression_value.value, backup_file_image);
    } else {
        // non fatal failure
        LOGE("  - backup format must be tar(.gz), skipping...\n");
        return 0;
    }

    int ret;
    ret = do_tar_compress(tmp, callback, backup_file_image);

    ensure_path_unmounted("/data");

    if (0 != ret)
        return print_and_error("Failed to backup /data/media!\n", ret);

    ui_print("Backup of /data/media completed.\n");
    return 0;
}
Ejemplo n.º 10
0
int nandroid_backup_androidSecure(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");
    
    struct stat st;
    if (0 != stat("/mnt/sdcard/.android_secure", &st))
    {
        ui_print("No /mnt/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;
    }

    sync();
    ui_set_background(BACKGROUND_ICON_NONE);
    ui_reset_progress();
    ui_print("\nBackup complete!\n");
    return 0;
}
Ejemplo n.º 11
0
int nandroid_restore_sd(const char* backup_path, int restore_sdext)
{
    ui_set_background(BACKGROUND_ICON_INSTALLING);
    ui_show_indeterminate_progress();
    yaffs_files_total = 0;

    if (ensure_path_mounted(backup_path) != 0)
        return print_and_error("Can't mount backup path\n");
    
    char tmp[PATH_MAX];
    
    int ret;

    if (restore_sdext && 0 != (ret = nandroid_restore_partition(backup_path, "/sd-ext")))
        return ret;

    sync();
    ui_set_background(BACKGROUND_ICON_NONE);
    ui_reset_progress();
    ui_print("\nRestore complete!\n");
    return 0;
}
Ejemplo n.º 12
0
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;
}
Ejemplo n.º 13
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;
}
Ejemplo n.º 14
0
int nandroid_restore(const char* backup_path, int restore_boot, int restore_system, int restore_data, int restore_cache, int restore_sdext, int restore_wimax)
{
    ui_set_background(BACKGROUND_ICON_INSTALLING);
    ui_show_indeterminate_progress();
    yaffs_files_total = 0;

    if (ensure_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;

    if (restore_boot && NULL != volume_for_path("/boot") && 0 != (ret = nandroid_restore_partition(backup_path, "/boot")))
        return ret;
    
    struct stat s;
    Volume *vol = volume_for_path("/wimax");
    if (restore_wimax && vol != NULL && 0 == stat(vol->device, &s))
    {
        char serialno[PROPERTY_VALUE_MAX];
        
        serialno[0] = 0;
        property_get("ro.serialno", serialno, "");
        sprintf(tmp, "%s/wimax.%s.img", backup_path, serialno);

        struct stat st;
        if (0 != stat(tmp, &st))
        {
            ui_print("WARNING: WiMAX partition exists, but nandroid\n");
            ui_print("         backup does not contain WiMAX image.\n");
            ui_print("         You should create a new backup to\n");
            ui_print("         protect your WiMAX keys.\n");
        }
        else
        {
            ui_print("Erasing WiMAX before restore...\n");
            if (0 != (ret = format_volume("/wimax")))
                return print_and_error("Error while formatting wimax!\n");
            ui_print("Restoring WiMAX image...\n");
            if (0 != (ret = restore_raw_partition(vol->fs_type, vol->device, tmp)))
                return ret;
        }
    }

    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;
        
    if (has_datadata()) {
        if (restore_data && 0 != (ret = nandroid_restore_partition(backup_path, "/datadata")))
            return ret;
    }

    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;
#ifdef RECOVERY_HAVE_SD_EXT
    if (restore_sdext && 0 != (ret = nandroid_restore_partition(backup_path, "/sd-ext")))
        return ret;
#endif
    sync();
    ui_set_background(BACKGROUND_ICON_NONE);
    ui_reset_progress();
    ui_print("\nRestore complete!\n");
    return 0;
}
Ejemplo n.º 15
0
int nandroid_backup(const char* backup_path)
{
    ui_set_background(BACKGROUND_ICON_INSTALLING);
    
    if (ensure_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(backup_path, "/boot")))
        return ret;

    if (0 != (ret = nandroid_backup_partition(backup_path, "/recovery")))
        return ret;

    Volume *vol = volume_for_path("/wimax");
    if (vol != NULL && 0 == stat(vol->device, &s))
    {
        char serialno[PROPERTY_VALUE_MAX];
        ui_print("Backing up WiMAX...\n");
        serialno[0] = 0;
        property_get("ro.serialno", serialno, "");
        sprintf(tmp, "%s/wimax.%s.img", backup_path, serialno);
        ret = backup_raw_partition(vol->fs_type, vol->device, tmp);
        if (0 != ret)
            return print_and_error("Error while dumping WiMAX image!\n");
    }

    if (0 != (ret = nandroid_backup_partition(backup_path, "/system")))
        return ret;

    if (0 != (ret = nandroid_backup_partition(backup_path, "/data")))
        return ret;

    if (has_datadata()) {
        if (0 != (ret = nandroid_backup_partition(backup_path, "/datadata")))
            return ret;
    }

    if (0 != stat("/sdcard/.android_secure", &s))
    {
        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 (0 != (ret = nandroid_backup_partition_extended(backup_path, "/cache", 0)))
        return ret;
#ifdef RECOVERY_HAVE_SD_EXT
    vol = volume_for_path("/sd-ext");
    if (vol == NULL || 0 != stat(vol->device, &s))
    {
        ui_print("No sd-ext found. Skipping backup of sd-ext.\n");
    }
    else
    {
        if (0 != ensure_path_mounted("/sd-ext"))
            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, "/sd-ext")))
            return ret;
    }
#endif
    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_NONE);
    ui_reset_progress();
    ui_print("\nBackup complete!\n");
    return 0;
}
Ejemplo n.º 16
0
// custom raw restore handler
// used to restore efs in raw mode or modem.bin files
// for now, only called directly from outside functions (not from nandroid_restore())
// user selects an image file to restore, so backup_file_image path is already mounted
int dd_raw_restore_handler(const char* backup_file_image, const char* root) {
    ui_print("\n>> Restoring %s...\n", root);
    Volume *vol = volume_for_path(root);
    if (vol == NULL || vol->fs_type == NULL) {
        ui_print("volume not found! Skipping raw restore of %s...\n", root);
        return 0;
    }

    ui_set_background(BACKGROUND_ICON_INSTALLING);
    ui_show_indeterminate_progress();

    // make sure we  have a valid image file name
    int i = 0;
    char errmsg[PATH_MAX];
    char tmp[PATH_MAX];
    char filename[PATH_MAX];
    const char *raw_image_format[] = { ".img", ".bin", NULL };

    sprintf(filename, "%s", BaseName(backup_file_image));
    while (raw_image_format[i] != NULL) {
        if (strlen(filename) > strlen(raw_image_format[i]) &&
                    strcmp(filename + strlen(filename) - strlen(raw_image_format[i]), raw_image_format[i]) == 0 &&
                    strncmp(filename, vol->mount_point + 1, strlen(vol->mount_point)-1) == 0) {
            break;
        }
        i++;
    }

    if (raw_image_format[i] == NULL) {
        sprintf(errmsg, "invalid image file! Failed to restore %s to %s\n", filename, root);
        return print_and_error(errmsg, NANDROID_ERROR_GENERAL);
    }

    //make sure file exists
    if (!file_found(backup_file_image)) {
        sprintf(errmsg, "%s not found. Skipping restore of %s\n", backup_file_image, root);
        return print_and_error(errmsg, NANDROID_ERROR_GENERAL);
    }

    //restore raw image
    int ret = 0;
    char* device_mmcblk;

    ui_print("Restoring %s to %s\n", filename, vol->mount_point);
    if (strstr(vol->blk_device, "/dev/block/mmcblk") != NULL || strstr(vol->blk_device, "/dev/block/mtdblock") != NULL) {
        sprintf(tmp, "raw-backup.sh -r '%s' %s %s", backup_file_image, vol->blk_device, vol->mount_point);
    } else if (vol->blk_device2 != NULL &&
            (strstr(vol->blk_device2, "/dev/block/mmcblk") != NULL || strstr(vol->blk_device2, "/dev/block/mtdblock") != NULL)) {
        sprintf(tmp, "raw-backup.sh -r '%s' %s %s", backup_file_image, vol->blk_device2, vol->mount_point);
    } else if ((device_mmcblk = readlink_device_blk(root)) != NULL) {
        sprintf(tmp, "raw-backup.sh -r '%s' %s %s", backup_file_image, device_mmcblk, vol->mount_point);
        free(device_mmcblk);
    } else {
        sprintf(errmsg, "raw restore: no device found (%s)\n", root);
        return print_and_error(errmsg, NANDROID_ERROR_GENERAL);
    }

    ret = __system(tmp);
    if (0 != ret) {
        sprintf(errmsg, "failed raw restore of %s to %s\n", filename, root);
        print_and_error(errmsg, ret);
    } else {
        finish_nandroid_job();
    }

    sprintf(tmp, "%s/log.txt", DirName(backup_file_image));
    ui_print_custom_logtail(tmp, 3);
    return ret;
}
void dumping_odin_image(const char* root)
{
	if (strcmp(get_type_internal_fs(root), "rfs")) {
		ui_print("You can use this only for RFS filesystem!\n");
		return -1;
	}

    struct statfs s;
    if (0 != 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 < 400)
        ui_print("There may not be enough free space to complete dump... continuing...\n");

	int n_odin_ifile=0;
	const char* odin_ifile[3] = { "factoryfs.rfs", "datafs.rfs", "cache.rfs" };
    char backup_path[PATH_MAX], sdev[32], *st;
	if (!strcmp(root, "DATA:")) n_odin_ifile = 1;
	else if (!strcmp(root, "CACHE:")) n_odin_ifile = 2;

    char tar_file[PATH_MAX];
    time_t t = time(NULL);
    struct tm *tmp = localtime(&t);
    if (tmp == NULL)
    {
        struct timeval tp;
        gettimeofday(&tp, NULL);
        sprintf(tar_file, "%d", tp.tv_sec);
    }
    else
    {
        strftime(tar_file, sizeof(tar_file), "%F.%H.%M.%S", tmp);
    }

	ensure_root_path_unmounted(root);

    if (ensure_root_path_mounted("SDCARD:") != 0) {
        LOGE ("Can't mount /sdcard\n");
        return;
    }

    if (0 != __system("mkdir -p /sdcard/ebrecovery/odin/tmp")) {
		ui_print("Can't create tmp folder for backup\n");
		return -1;
	}

    strcpy(sdev, get_dev_for_root(root));
    if (st = strstr(sdev, "stl")) {
    	memcpy(st, "bml", 3);
    }
    else {
    	ui_print("Mistake in device name %s\n", sdev);
    	return -1;
    }

    ui_print("Dumping %s..\n", root);
    sprintf(backup_path, "fdump -t %s /sdcard/ebrecovery/odin/tmp/%s", sdev, odin_ifile[n_odin_ifile]);
    if (0 != __system(backup_path)) {
		ui_print("Can't create odin image [%s]\n", odin_ifile[n_odin_ifile]);
		return -1;
	}

    sprintf(backup_path, "cd /sdcard/ebrecovery/odin/tmp && tar -cf ../%s.tar %s", tar_file, odin_ifile[n_odin_ifile]);
    if (0 != __system(backup_path)) {
		ui_print("Can't create odin image [%s]\n", odin_ifile[n_odin_ifile]);
		return -1;
	}

    __system("rm -r /sdcard/ebrecovery/odin/tmp");

    ui_print("Done\n");
}
Ejemplo n.º 18
0
int nandroid_backup(const char* backup_path)
{
    nandroid_backup_bitfield = 0;
    ui_set_background(BACKGROUND_ICON_INSTALLING);
    refresh_default_backup_handler();
    
    if (ensure_path_mounted(backup_path) != 0) {
        return print_and_error("Can't mount backup path.\n");
    }
    
    Volume* volume = volume_for_path(backup_path);
    if (NULL == volume)
        return print_and_error("Unable to find volume for backup path.\n");
    if (is_data_media_volume_path(volume->mount_point))
        volume = volume_for_path("/data");
    int ret;
    struct statfs s;
    if (NULL != volume) {
        if (0 != (ret = statfs(volume->mount_point, &s)))
            return print_and_error("Unable to stat backup path.\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];
    ensure_directory(backup_path);

    if (0 != (ret = nandroid_backup_partition(backup_path, "/boot")))
        return ret;

    if (0 != (ret = nandroid_backup_partition(backup_path, "/recovery")))
        return ret;

    Volume *vol = volume_for_path("/wimax");
    if (vol != NULL && 0 == stat(vol->device, &s))
    {
        char serialno[PROPERTY_VALUE_MAX];
        ui_print("Backing up WiMAX...\n");
        serialno[0] = 0;
        property_get("ro.serialno", serialno, "");
        sprintf(tmp, "%s/wimax.%s.img", backup_path, serialno);
        ret = backup_raw_partition(vol->fs_type, vol->device, tmp);
        if (0 != ret)
            return print_and_error("Error while dumping WiMAX image!\n");
    }

    if (0 != (ret = nandroid_backup_partition(backup_path, "/system")))
        return ret;

    if (0 != (ret = nandroid_backup_partition(backup_path, "/preload")))
        return ret;

    if (0 != (ret = nandroid_backup_partition(backup_path, "/data")))
        return ret;

    if (has_datadata()) {
        if (0 != (ret = nandroid_backup_partition(backup_path, "/datadata")))
            return ret;
    }

    if (is_data_media() || 0 != stat("/sdcard/.android_secure", &s)) {
        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 (0 != (ret = nandroid_backup_partition_extended(backup_path, "/cache", 0)))
        return ret;

    vol = volume_for_path("/sd-ext");
    if (vol == NULL || 0 != stat(vol->device, &s))
    {
        ui_print("No sd-ext found. Skipping backup of sd-ext.\n");
    }
    else
    {
        if (0 != ensure_path_mounted("/sd-ext"))
            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, "/sd-ext")))
            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;
    }
    
    sprintf(tmp, "chmod -R 777 %s ; chmod -R u+r,u+w,g+r,g+w,o+r,o+w /sdcard/clockworkmod ; chmod u+x,g+x,o+x /sdcard/clockworkmod/backup ; chmod u+x,g+x,o+x /sdcard/clockworkmod/blobs", backup_path);
    __system(tmp);
    sync();
    ui_set_background(BACKGROUND_ICON_NONE);
    ui_reset_progress();
    ui_print("\nBackup complete!\n");
    return 0;
}
Ejemplo n.º 19
0
int nandroid_backup_flags(const char* backup_path, int flags)
{
    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 = read_raw_image("boot", tmp);
    if (0 != ret)
        return print_and_error("Error while dumping boot image!\n");

    ui_print("Backing up recovery...\n");
    sprintf(tmp, "%s/%s", backup_path, "recovery.img");
    ret = read_raw_image("recovery", tmp);
    if (0 != ret)
        return print_and_error("Error while dumping recovery image!\n");
#endif

    if (0 != (ret = nandroid_backup_partition(backup_path, "SYSTEM:")))
          return ret;

    if (0 != (ret = nandroid_backup_partition(backup_path, "DATA:")))
        return ret;

#ifdef HAS_DATADATA
    if (0 != (ret = nandroid_backup_partition(backup_path, "DATADATA:")))
        return ret;
#endif

    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 (0 != (ret = nandroid_backup_partition_extended(backup_path, "CACHE:", 0)))
        return ret;

      if (0 != stat(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;
    }

    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;
}
Ejemplo n.º 20
0
int twrp_backup(const char* backup_path) {
    // keep this for extra security and keep close to stock code
    // refresh_default_backup_handler() mounts /sdcard. We stat it in nandroid_backup_partition_extended() for callback
    nandroid_backup_bitfield = 0;
    refresh_default_backup_handler();

    if (ensure_path_mounted(backup_path) != 0)
        return print_and_error("Can't mount backup path.\n", NANDROID_ERROR_GENERAL);

    int ret;
    struct statfs s;

    // refresh size stats for backup_path
    // this will also ensure volume for backup path != NULL
    if (0 != Get_Size_Via_statfs(backup_path))
        return print_and_error("Unable to stat backup path.\n", NANDROID_ERROR_GENERAL);

    // estimate backup size and ensure we have enough free space available on backup_path
    if (check_backup_size(backup_path) < 0)
        return print_and_error("Not enough free space: backup cancelled.\n", NANDROID_ERROR_GENERAL);

    // moved after backup size check to fix pause before showing low space prompt
    // this is caused by friendly log view triggering on ui_set_background(BACKGROUND_ICON_INSTALLING) call
    // also, it is expected to have the background installing icon when we actually start backup
    ui_set_background(BACKGROUND_ICON_INSTALLING);
    nandroid_start_msec = timenow_msec(); // starts backup monitoring timer for total backup time
#ifdef PHILZ_TOUCH_RECOVERY
    last_key_ev = nandroid_start_msec; // support dim screen timeout during nandroid operation
#endif

    char tmp[PATH_MAX];
    ensure_directory(backup_path, 0755);

    if (backup_boot && volume_for_path(BOOT_PARTITION_MOUNT_POINT) != NULL &&
            0 != (ret = nandroid_backup_partition(backup_path, BOOT_PARTITION_MOUNT_POINT)))
        return print_and_error(NULL, ret);

    if (backup_recovery && volume_for_path("/recovery") != NULL &&
            0 != (ret = nandroid_backup_partition(backup_path, "/recovery")))
        return print_and_error(NULL, ret);

#ifdef BOARD_USE_MTK_LAYOUT
    if ((backup_boot || backup_recovery) && volume_for_path("/uboot") != NULL &&
            0 != (ret = nandroid_backup_partition(backup_path, "/uboot")))
        return print_and_error(NULL, ret);
#endif

    Volume *vol = volume_for_path("/efs");
    if (backup_efs &&  NULL != vol) {
        if (0 != (ret = nandroid_backup_partition(backup_path, "/efs")))
            return print_and_error(NULL, ret);
    }

    vol = volume_for_path("/misc");
    if (backup_misc && NULL != vol) {
        if (0 != (ret = nandroid_backup_partition(backup_path, "/misc")))
            return print_and_error(NULL, ret);
    }

    vol = volume_for_path("/modem");
    if (backup_modem && NULL != vol) {
        if (0 != (ret = nandroid_backup_partition(backup_path, "/modem")))
            return print_and_error(NULL, ret);
    }

    vol = volume_for_path("/radio");
    if (backup_radio && NULL != vol) {
        if (0 != (ret = nandroid_backup_partition(backup_path, "/radio")))
            return print_and_error(NULL, ret);
    }

    if (backup_system && 0 != (ret = nandroid_backup_partition(backup_path, "/system")))
        return print_and_error(NULL, ret);

    vol = volume_for_path("/preload");
    if (backup_preload && NULL != vol) {
        if (0 != (ret = nandroid_backup_partition(backup_path, "/preload")))
            return print_and_error(NULL, ret);
    }

    if (backup_data && 0 != (ret = nandroid_backup_partition(backup_path, "/data")))
        return print_and_error(NULL, ret);

    if (has_datadata()) {
        if (backup_data && 0 != (ret = nandroid_backup_partition(backup_path, "/datadata")))
            return print_and_error(NULL, ret);
    }

    // handle .android_secure on external and internal storage
    set_android_secure_path(tmp);
    if (backup_data && android_secure_ext) {
        if (0 != (ret = nandroid_backup_partition_extended(backup_path, tmp, 0)))
            return print_and_error(NULL, ret);
    }

    if (backup_cache && 0 != (ret = nandroid_backup_partition_extended(backup_path, "/cache", 0)))
        return print_and_error(NULL, ret);

    if (backup_sdext) {
        if (0 != ensure_path_mounted("/sd-ext")) {
            LOGI("No sd-ext found. Skipping backup of sd-ext.\n");
        } else if (0 != (ret = nandroid_backup_partition(backup_path, "/sd-ext"))) {
            return print_and_error(NULL, ret);
        }
    }

    // handle extra partitions
    int i;
    int extra_partitions_num = get_extra_partitions_state();
    for (i = 0; i < extra_partitions_num; ++i) {
        if (extra_partition[i].backup_state && 0 != (ret = nandroid_backup_partition(backup_path, extra_partition[i].mount_point)))
            return print_and_error(NULL, ret);
    }

    if (enable_md5sum.value) {
        if (0 != (ret = gen_twrp_md5sum(backup_path)))
            return print_and_error(NULL, ret);
    }

    sprintf(tmp, "chmod -R 777 %s", backup_path);
    __system(tmp);

    finish_nandroid_job();
    show_backup_stats(backup_path);
    if (reboot_after_nandroid)
        reboot_main_system(ANDROID_RB_RESTART, 0, 0);
    return 0;
}
Ejemplo n.º 21
0
int nandroid_backup(const char* backup_path)
{
    nandroid_backup_bitfield = 0;
    ui_set_background(BACKGROUND_ICON_INSTALLING);
    refresh_default_backup_handler();
    
    if (ensure_path_mounted(backup_path) != 0) {
        return print_and_error("Can't mount backup path.\n");
    }
    
    Volume* volume = volume_for_path(backup_path);
    if (NULL == volume)
        return print_and_error("Unable to find volume for backup path.\n");
    if (is_data_media_volume_path(volume->mount_point))
        volume = volume_for_path("/data");
    int ret;
    struct statfs s;
    if (NULL != volume) {
        if (0 != (ret = statfs(volume->mount_point, &s)))
            return print_and_error("Unable to stat backup path.\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];
    ensure_directory(backup_path);

    if (backup_boot && 0 != (ret = nandroid_backup_partition(backup_path, "/boot")))
        return ret;

    if (backup_recovery && 0 != (ret = nandroid_backup_partition(backup_path, "/recovery")))
        return ret;

    Volume *vol = volume_for_path("/wimax");
    if (backup_wimax && vol != NULL && 0 == stat(vol->device, &s))
    {
        char serialno[PROPERTY_VALUE_MAX];
        ui_print("Backing up WiMAX...\n");
        serialno[0] = 0;
        property_get("ro.serialno", serialno, "");
        sprintf(tmp, "%s/wimax.%s.img", backup_path, serialno);
        ret = backup_raw_partition(vol->fs_type, vol->device, tmp);
        if (0 != ret)
            return print_and_error("Error while dumping WiMAX image!\n");
    }

    //2 copies of efs are made: tarball and raw backup
    if (backup_efs) {
        //first backup in raw format, returns 0 on success (or if skipped), else 1
        if (0 != custom_backup_raw_handler(backup_path, "/efs")) {
            ui_print("EFS raw image backup failed! Trying tar backup...\n");
        }
        //second backup in tar format
        sprintf(tmp, "%s/efs_tar", backup_path);
        ensure_directory(tmp);
        if (0 != (ret = nandroid_backup_partition(tmp, "/efs")))
            return ret;
    }
    
    if (backup_modem) {
        if (0 != (ret = nandroid_backup_partition(backup_path, "/modem")))
            return ret;
    }

    if (backup_system && 0 != (ret = nandroid_backup_partition(backup_path, "/system")))
        return ret;


    if (is_custom_backup && backup_preload) {
        if (0 != (ret = nandroid_backup_partition(backup_path, "/preload"))) {
            ui_print("Failed to backup /preload!\n");
            return ret;
        }
    }
    else if (!is_custom_backup
#ifdef PHILZ_TOUCH_RECOVERY
                && nandroid_add_preload
#endif
            )
    {
        if (0 != (ret = nandroid_backup_partition(backup_path, "/preload"))) {
            ui_print("Failed to backup preload! Try to disable it.\n");
            ui_print("Skipping /preload...\n");
            //return ret;
        }
    }

    if (backup_data && 0 != (ret = nandroid_backup_partition(backup_path, "/data")))
        return ret;

    if (has_datadata()) {
        if (backup_data && 0 != (ret = nandroid_backup_partition(backup_path, "/datadata")))
            return ret;
    }

    if (is_data_media() || 0 != stat("/sdcard/.android_secure", &s)) {
        ui_print("No /sdcard/.android_secure found. Skipping backup of applications on external storage.\n");
    }
    else {
        if (backup_data && 0 != (ret = nandroid_backup_partition_extended(backup_path, "/sdcard/.android_secure", 0)))
            return ret;
    }

    if (backup_cache && 0 != (ret = nandroid_backup_partition_extended(backup_path, "/cache", 0)))
        return ret;

    if (backup_sdext) {
        vol = volume_for_path("/sd-ext");
        if (vol == NULL || 0 != stat(vol->device, &s))
        {
            ui_print("No sd-ext found. Skipping backup of sd-ext.\n");
        }
        else
        {
            if (0 != ensure_path_mounted("/sd-ext"))
                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, "/sd-ext")))
                return ret;
        }
    }

#ifdef PHILZ_TOUCH_RECOVERY
    if (enable_md5sum)
#endif
    {
        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;
        }
    }

    sprintf(tmp, "chmod -R 777 %s ; chmod -R u+r,u+w,g+r,g+w,o+r,o+w /sdcard/clockworkmod ; chmod u+x,g+x,o+x /sdcard/clockworkmod/backup ; chmod u+x,g+x,o+x /sdcard/clockworkmod/blobs", backup_path);
    __system(tmp);
    sync();
    ui_set_background(BACKGROUND_ICON_NONE);
    ui_reset_progress();
    ui_print("\nBackup complete!\n");
    return 0;
}
Ejemplo n.º 22
0
int twrp_restore(const char* backup_path) {
    Backup_Size = 0; // by default, do not calculate size

    // progress bar will be of indeterminate progress
    // setting nandroid_files_total = 0 will force this in nandroid_callback()
    ui_set_background(BACKGROUND_ICON_INSTALLING);
    nandroid_files_total = 0;
    nandroid_start_msec = timenow_msec();
#ifdef PHILZ_TOUCH_RECOVERY
    // support dim screen timeout during nandroid operation
    last_key_ev = timenow_msec();
#endif
    if (ensure_path_mounted(backup_path) != 0)
        return print_and_error("Can't mount backup path\n", NANDROID_ERROR_GENERAL);

    char tmp[PATH_MAX];
    if (enable_md5sum.value) {
        if (0 != check_twrp_md5sum(backup_path))
            return print_and_error("MD5 mismatch!\n", NANDROID_ERROR_GENERAL);
    }

    ui_show_indeterminate_progress(); // call after verify_nandroid_md5sum() as it will reset the progress

    int ret;

    if (backup_boot && volume_for_path(BOOT_PARTITION_MOUNT_POINT) != NULL &&
            0 != (ret = nandroid_restore_partition(backup_path, BOOT_PARTITION_MOUNT_POINT)))
        return print_and_error(NULL, ret);

    if (backup_recovery && volume_for_path("/recovery") != NULL &&
            0 != (ret = nandroid_restore_partition(backup_path, "/recovery")))
        return print_and_error(NULL, ret);

#ifdef BOARD_USE_MTK_LAYOUT
    if ((backup_boot || backup_recovery) && volume_for_path("/uboot") != NULL &&
            0 != (ret = nandroid_restore_partition(backup_path, "/uboot")))
        return print_and_error(NULL, ret);
#endif

    Volume *vol = volume_for_path("/efs");
    if (backup_efs == RESTORE_EFS_TAR && vol != NULL) {
        if (0 != (ret = nandroid_restore_partition(backup_path, "/efs")))
            return print_and_error(NULL, ret);
    }

    vol = volume_for_path("/misc");
    if (backup_misc && vol != NULL) {
        if (0 != (ret = nandroid_restore_partition(backup_path, "/misc")))
            return print_and_error(NULL, ret);
    }

    vol = volume_for_path("/modem");
    if (backup_modem == RAW_IMG_FILE && vol != NULL) {
        if (0 != (ret = nandroid_restore_partition(backup_path, "/modem")))
            return print_and_error(NULL, ret);
    }

    vol = volume_for_path("/radio");
    if (backup_radio == RAW_IMG_FILE && vol != NULL) {
        if (0 != (ret = nandroid_restore_partition(backup_path, "/radio")))
            return print_and_error(NULL, ret);
    }

    if (backup_system && 0 != (ret = nandroid_restore_partition(backup_path, "/system")))
        return print_and_error(NULL, ret);

    vol = volume_for_path("/preload");
    if (backup_preload && vol != NULL) {
        if (0 != (ret = nandroid_restore_partition(backup_path, "/preload")))
            return print_and_error(NULL, ret);
    }

    if (backup_data && 0 != (ret = nandroid_restore_partition(backup_path, "/data")))
        return print_and_error(NULL, ret);
        
    if (has_datadata()) {
        if (backup_data && 0 != (ret = nandroid_restore_partition(backup_path, "/datadata")))
            return print_and_error(NULL, ret);
    }

    // handle .android_secure on external and internal storage
    set_android_secure_path(tmp);
    if (backup_data && android_secure_ext) {
        if (0 != (ret = nandroid_restore_partition_extended(backup_path, tmp, 0)))
            return print_and_error(NULL, ret);
    }

    if (backup_cache && 0 != (ret = nandroid_restore_partition_extended(backup_path, "/cache", 0)))
        return print_and_error(NULL, ret);

    if (backup_sdext && 0 != (ret = nandroid_restore_partition(backup_path, "/sd-ext")))
        return print_and_error(NULL, ret);

    // handle extra partitions
    int i;
    int extra_partitions_num = get_extra_partitions_state();
    for (i = 0; i < extra_partitions_num; ++i) {
        if (extra_partition[i].backup_state && 0 != (ret = nandroid_restore_partition(backup_path, extra_partition[i].mount_point)))
            return print_and_error(NULL, ret);
    }

    finish_nandroid_job();
    show_restore_stats();
    if (reboot_after_nandroid)
        reboot_main_system(ANDROID_RB_RESTART, 0, 0);
    return 0;
}
Ejemplo n.º 23
0
int nandroid_backup(const char* backup_path)
{
    nandroid_backup_bitfield = 0;
    ui_set_background(BACKGROUND_ICON_INSTALLING);
    refresh_default_backup_handler();

    if (ensure_path_mounted(backup_path) != 0) {
        return print_and_error("无法挂载备份时需要的存储器.\n");
    }

    Volume* volume = volume_for_path(backup_path);
    if (NULL == volume)
        return print_and_error("找不到备份需要的存储器.\n");
    if (is_data_media_volume_path(volume->mount_point))
        volume = volume_for_path("/data");
    int ret;
    struct statfs s;
    if (NULL != volume) {
        if (0 != (ret = statfs(volume->mount_point, &s)))
            return print_and_error("找不到备份路径,因此无法开始.\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("可能是你的机器空间不足了,继续中...\n");
    }
    char tmp[PATH_MAX];
    ensure_directory(backup_path);

    if (0 != (ret = nandroid_backup_partition(backup_path, "/boot")))
        return ret;

    if (0 != (ret = nandroid_backup_partition(backup_path, "/uboot")))
        return ret;

    if (0 != (ret = nandroid_backup_partition(backup_path, "/recovery")))
        return ret;

    Volume *vol = volume_for_path("/wimax");
    if (vol != NULL && 0 == stat(vol->device, &s))
    {
        char serialno[PROPERTY_VALUE_MAX];
        ui_print("正在备份WiMAX...\n");
        serialno[0] = 0;
        property_get("ro.serialno", serialno, "");
        sprintf(tmp, "%s/wimax.%s.img", backup_path, serialno);
        ret = backup_raw_partition(vol->fs_type, vol->device, tmp);
        if (0 != ret)
            return print_and_error("打包或生成WiMAX镜像失败\n");
    }

    if (0 != (ret = nandroid_backup_partition(backup_path, "/system")))
        return ret;

    if (0 != (ret = nandroid_backup_partition(backup_path, "/data")))
        return ret;

    if (has_datadata()) {
        if (0 != (ret = nandroid_backup_partition(backup_path, "/datadata")))
            return ret;
    }

    if (is_data_media() || 0 != stat("/sdcard/.android_secure", &s)) {
        ui_print("没找到 /sdcard/.android_secure. 跳过外部程序备份.\n");
    }
    else {
        if (0 != (ret = nandroid_backup_partition_extended(backup_path, "/sdcard/.android_secure", 0)))
            return ret;
    }

    if (0 != (ret = nandroid_backup_partition_extended(backup_path, "/cache", 0)))
        return ret;

    vol = volume_for_path("/sd-ext");
    if (vol == NULL || 0 != stat(vol->device, &s))
    {
        ui_print("没找到SD-EXT,因此跳过该处备份.\n");
    }
    else
    {
        if (0 != ensure_path_mounted("/sd-ext"))
            ui_print("没法挂载SD-EXT,可能是你的机器不支持该选项,跳过该部分的备份\n");
        else if (0 != (ret = nandroid_backup_partition(backup_path, "/sd-ext")))
            return ret;
    }

    ui_print("生成md5 校验值...\n");
    sprintf(tmp, "nandroid-md5.sh %s", backup_path);
    if (0 != (ret = __system(tmp))) {
        ui_print("MD5校验值生成失败\n");
        return ret;
    }

    sprintf(tmp, "cp /tmp/recovery.log %s/recovery.log", backup_path);
    __system(tmp);

    sprintf(tmp, "chmod -R 777 %s ; chmod -R u+r,u+w,g+r,g+w,o+r,o+w /sdcard/clockworkmod ; chmod u+x,g+x,o+x /sdcard/clockworkmod/backup ; chmod u+x,g+x,o+x /sdcard/clockworkmod/blobs", backup_path);
    __system(tmp);
    sync();
    ui_set_background(BACKGROUND_ICON_NONE);
    ui_reset_progress();
    ui_print("\n备份完成!\n");
    return 0;
}
Ejemplo n.º 24
0
int nandroid_restore(const char* backup_path, int restore_boot, int restore_system, int restore_data, int restore_cache, int restore_sdext, int restore_wimax)
{
    ui_set_background(BACKGROUND_ICON_INSTALLING);
    ui_show_indeterminate_progress();
    nandroid_files_total = 0;

    if (ensure_path_mounted(backup_path) != 0)
        return print_and_error("挂载分区失败\n");

    char tmp[PATH_MAX];

    ui_print("检查MD5 校验值...\n");
    sprintf(tmp, "cd %s && md5sum -c nandroid.md5", backup_path);
    if (0 != __system(tmp))
        return print_and_error("MD5不合法\n");

    int ret;

    if (restore_boot)
    {
        if (NULL != volume_for_path("/boot") && 0 != (ret = nandroid_restore_partition(backup_path, "/boot")))
            return ret;

        if (NULL != volume_for_path("/uboot") && 0 != (ret = nandroid_restore_partition(backup_path, "/uboot")))
            return ret;

        if (NULL != volume_for_path("/recovery") && 0 != (ret = nandroid_restore_partition(backup_path, "/recovery")))
            return ret;
    }
    
    struct stat s;
    Volume *vol = volume_for_path("/wimax");
    if (restore_wimax && vol != NULL && 0 == stat(vol->device, &s))
    {
        char serialno[PROPERTY_VALUE_MAX];

        serialno[0] = 0;
        property_get("ro.serialno", serialno, "");
        sprintf(tmp, "%s/wimax.%s.img", backup_path, serialno);

        struct stat st;
        if (0 != stat(tmp, &st))
        {
            ui_print("警告: WiMAX分区存在,但是\n");
            ui_print("        不存在可恢复的WiMAX 镜像.\n");
            ui_print("        亦需要重新做一个备份 \n");
            ui_print("        来保护你的WiMAX keys.\n");
        }
        else
        {
            ui_print("恢复之前先清除WiMAX...\n");
            if (0 != (ret = format_volume("/wimax")))
                return print_and_error("抹掉wimax失败!\n");
            ui_print("恢复WiMAX 镜像...\n");
            if (0 != (ret = restore_raw_partition(vol->fs_type, vol->device, tmp)))
                return ret;
        }
    }

    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;

    if (has_datadata()) {
        if (restore_data && 0 != (ret = nandroid_restore_partition(backup_path, "/datadata")))
            return ret;
    }

    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, "/sd-ext")))
        return ret;

    sync();
    ui_set_background(BACKGROUND_ICON_NONE);
    ui_reset_progress();
    ui_print("\n恢复完成!\n");
    return 0;
}
Ejemplo n.º 25
0
int nandroid_backup(const char* backup_path) {
    nandroid_backup_bitfield = 0;
    ui_set_background(BACKGROUND_ICON_INSTALLING);
    refresh_default_backup_handler();

    if (ensure_path_mounted(backup_path) != 0) {
#ifndef USE_CHINESE_FONT
        return print_and_error("Can't mount backup path.\n");
#else
        return print_and_error("无法挂载备份路径。\n");
#endif
    }

    Volume* volume;
    if (is_data_media_volume_path(backup_path))
        volume = volume_for_path("/data");
    else
        volume = volume_for_path(backup_path);
    if (NULL == volume)
#ifndef USE_CHINESE_FONT
        return print_and_error("Unable to find volume for backup path.\n");
#else
        return print_and_error("无法找到备份路径所在卷。\n");
#endif
    int ret;
    struct statfs sfs;
    struct stat s;
    if (NULL != volume) {
        if (0 != (ret = statfs(volume->mount_point, &sfs)))
#ifndef USE_CHINESE_FONT
            return print_and_error("Unable to stat backup path.\n");
#else
            return print_and_error("无法统计备份路径。\n");
#endif
        uint64_t bavail = sfs.f_bavail;
        uint64_t bsize = sfs.f_bsize;
        uint64_t sdcard_free = bavail * bsize;
        uint64_t sdcard_free_mb = sdcard_free / (uint64_t)(1024 * 1024);
#ifndef USE_CHINESE_FONT
        ui_print("SD Card space free: %lluMB\n", sdcard_free_mb);
#else
        ui_print("SD 卡剩余空间: %lluMB\n", sdcard_free_mb);
#endif
        if (sdcard_free_mb < 150)
#ifndef USE_CHINESE_FONT
            ui_print("There may not be enough free space to complete backup... continuing...\n");
#else
            ui_print("可能没有足够的空间完成备份... 继续...\n");
#endif
    }
    char tmp[PATH_MAX];
    ensure_directory(backup_path);

    if (0 != (ret = nandroid_backup_partition(backup_path, "/boot")))
        return ret;

    if (0 != (ret = nandroid_backup_partition(backup_path, "/recovery")))
        return ret;

    Volume *vol = volume_for_path("/wimax");
    if (vol != NULL && 0 == stat(vol->blk_device, &s)) {
        char serialno[PROPERTY_VALUE_MAX];
#ifndef USE_CHINESE_FONT
        ui_print("Backing up WiMAX...\n");
#else
        ui_print("正在备份 WiMAX...\n");
#endif
        serialno[0] = 0;
        property_get("ro.serialno", serialno, "");
        sprintf(tmp, "%s/wimax.%s.img", backup_path, serialno);
        ret = backup_raw_partition(vol->fs_type, vol->blk_device, tmp);
        if (0 != ret)
#ifndef USE_CHINESE_FONT
            return print_and_error("Error while dumping WiMAX image!\n");
#else
            return print_and_error("导出 WiMAX 镜像时出错!\n");
#endif
    }

    if (0 != (ret = nandroid_backup_partition(backup_path, "/system")))
        return ret;

    if (0 != (ret = nandroid_backup_partition(backup_path, "/data")))
        return ret;

    if (has_datadata()) {
        if (0 != (ret = nandroid_backup_partition(backup_path, "/datadata")))
            return ret;
    }

    if (is_data_media() || 0 != stat(get_android_secure_path(), &s)) {
#ifndef USE_CHINESE_FONT
        ui_print("No .android_secure found. Skipping backup of applications on external storage.\n");
#else
        ui_print("未找到 .android_secure。跳过备份安装在外置存储卡上的应用程序。\n");
#endif
    } else {
        if (0 != (ret = nandroid_backup_partition_extended(backup_path, get_android_secure_path(), 0)))
            return ret;
    }

    if (0 != (ret = nandroid_backup_partition_extended(backup_path, "/cache", 0)))
        return ret;

    vol = volume_for_path("/sd-ext");
    if (vol == NULL || 0 != stat(vol->blk_device, &s)) {
#ifndef USE_CHINESE_FONT
        LOGI("No sd-ext found. Skipping backup of sd-ext.\n");
#else
        LOGI("未找到 sd-ext。跳过对 sd-ext 的备份。\n");
#endif
    } else {
        if (0 != ensure_path_mounted("/sd-ext"))
#ifndef USE_CHINESE_FONT
            LOGI("Could not mount sd-ext. sd-ext backup may not be supported on this device. Skipping backup of sd-ext.\n");
#else
            LOGI("无法挂载 sd-ext。此设备可能不支持对 sd-ext 进行备份,跳过对sd-ext的备份。\n");
#endif
        else if (0 != (ret = nandroid_backup_partition(backup_path, "/sd-ext")))
            return ret;
    }
Ejemplo n.º 26
0
int nandroid_restore(const char* backup_path, int restore_boot, int restore_system, int restore_data, int restore_cache, int restore_sdext, int restore_wimax)
{
    ui_set_background(BACKGROUND_ICON_INSTALLING);
    ui_show_indeterminate_progress();

    if (ensure_path_mounted(backup_path) != 0)
        return print_and_error("Can't mount backup path\n");
    
    char tmp[PATH_MAX];

#ifdef PHILZ_TOUCH_RECOVERY
    if (enable_md5sum)
#endif
    {
        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;

    if (restore_boot && NULL != volume_for_path("/boot") && 0 != (ret = nandroid_restore_partition(backup_path, "/boot")))
        return ret;

    if (backup_recovery && 0 != (ret = nandroid_restore_partition(backup_path, "/recovery")))
        return ret;

    struct stat s;
    Volume *vol = volume_for_path("/wimax");
    if (restore_wimax && vol != NULL && 0 == stat(vol->device, &s))
    {
        char serialno[PROPERTY_VALUE_MAX];
        
        serialno[0] = 0;
        property_get("ro.serialno", serialno, "");
        sprintf(tmp, "%s/wimax.%s.img", backup_path, serialno);

        struct stat st;
        if (0 != stat(tmp, &st))
        {
            ui_print("WARNING: WiMAX partition exists, but nandroid\n");
            ui_print("         backup does not contain WiMAX image.\n");
            ui_print("         You should create a new backup to\n");
            ui_print("         protect your WiMAX keys.\n");
        }
        else
        {
            ui_print("Erasing WiMAX before restore...\n");
            if (0 != (ret = format_volume("/wimax")))
                return print_and_error("Error while formatting wimax!\n");
            ui_print("Restoring WiMAX image...\n");
            if (0 != (ret = restore_raw_partition(vol->fs_type, vol->device, tmp)))
                return ret;
        }
    }

    // restore of raw efs image files (efs_time-stamp.img) is done elsewhere
    // as it needs to pass in a filename (instead of a folder) as backup_path
    // this could be done here since efs is processed alone, but must be done before md5 checksum!
    if (backup_efs == RESTORE_EFS_TAR && 0 != (ret = nandroid_restore_partition(backup_path, "/efs")))
        return ret;
        
    if (backup_modem == RAW_IMG_FILE && 0 != (ret = nandroid_restore_partition(backup_path, "/modem")))
        return ret;
    else if (backup_modem == RAW_BIN_FILE) {
        sprintf(tmp, "%s/modem.bin", backup_path);
        custom_restore_raw_handler(tmp, "/modem");
    }

    if (restore_system && 0 != (ret = nandroid_restore_partition(backup_path, "/system")))
        return ret;

    if (is_custom_backup && backup_preload) {
        if (0 != (ret = nandroid_restore_partition(backup_path, "/preload"))) {
            ui_print("Failed to restore /preload!\n");
            return ret;
        }
    }
    else if (!is_custom_backup
#ifdef PHILZ_TOUCH_RECOVERY
                && nandroid_add_preload
#endif
            )
    {
        if (restore_system && 0 != (ret = nandroid_restore_partition(backup_path, "/preload"))) {
            ui_print("Failed to restore preload! Try to disable it.\n");
            ui_print("Skipping /preload...\n");
            //return ret;
        }
    }

    if (restore_data && 0 != (ret = nandroid_restore_partition(backup_path, "/data")))
        return ret;
        
    if (has_datadata()) {
        if (restore_data && 0 != (ret = nandroid_restore_partition(backup_path, "/datadata")))
            return ret;
    }

    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, "/sd-ext")))
        return ret;

    sync();
    ui_set_background(BACKGROUND_ICON_NONE);
    ui_reset_progress();
    ui_print("\nRestore complete!\n");
    return 0;
}
Ejemplo n.º 27
0
int nandroid_backup(const char* backup_path)
{
    ui_set_background(BACKGROUND_ICON_INSTALLING);
    
    if (ensure_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卡剩余空间: %lluMB\n", sdcard_free_mb);
    if (sdcard_free_mb < 150)
        ui_print("可能没有足够的空间完成备份... 继续...\n");
    
    char tmp[PATH_MAX];
    sprintf(tmp, "mkdir -p %s", backup_path);
    __system(tmp);

    if (0 != (ret = nandroid_backup_partition(backup_path, "/boot")))
        return ret;

    if (0 != (ret = nandroid_backup_partition(backup_path, "/recovery")))
        return ret;

    Volume *vol = volume_for_path("/wimax");
    if (vol != NULL && 0 == stat(vol->device, &s))
    {
        char serialno[PROPERTY_VALUE_MAX];
        ui_print("Backing up WiMAX...\n");
        serialno[0] = 0;
        property_get("ro.serialno", serialno, "");
        sprintf(tmp, "%s/wimax.%s.img", backup_path, serialno);
        ret = backup_raw_partition(vol->device, tmp);
        if (0 != ret)
            return print_and_error("Error while dumping WiMAX image!\n");
    }

    if (0 != (ret = nandroid_backup_partition(backup_path, "/system")))
        return ret;

    if (0 != (ret = nandroid_backup_partition(backup_path, "/data")))
        return ret;

    if (has_datadata()) {
        if (0 != (ret = nandroid_backup_partition(backup_path, "/datadata")))
            return ret;
    }

    if (0 != stat("/sdcard/.android_secure", &s))
    {
        ui_print("没有发现 /sdcard/.android_secure. 放弃备份SD卡上安装的程序.\n");
    }
    else
    {
        if (0 != (ret = nandroid_backup_partition_extended(backup_path, "/sdcard/.android_secure", 0)))
            return ret;
    }

    if (0 != (ret = nandroid_backup_partition_extended(backup_path, "/cache", 0)))
        return ret;

    vol = volume_for_path("/sd-ext");
    if (vol == NULL || 0 != stat(vol->device, &s))
    {
        ui_print("没有发现sd-ext. 放弃备份sd-ext.\n");
    }
    else
    {
        if (0 != ensure_path_mounted("/sd-ext"))
            ui_print("不能挂载sd-ext. sd-ext备份可能不支持此设备. 放弃备份sd-ext.\n");
        else if (0 != (ret = nandroid_backup_partition(backup_path, "/sd-ext")))
            return ret;
    }

    ui_print("生成md5校验...\n");
    sprintf(tmp, "nandroid-md5.sh %s", backup_path);
    if (0 != (ret = __system(tmp))) {
        ui_print("生成md5时出错!\n");
        return ret;
    }
    
    sync();
    ui_set_background(BACKGROUND_ICON_NONE);
    ui_reset_progress();
    ui_print("\n备份完成!\n");
    return 0;
}