Value* FormatFn(const char* name, State* state, int argc, Expr* argv[]) {
    char* result = NULL;
    if (argc != 1) {
        return ErrorAbort(state, "%s() expects 1 arg, got %d", name, argc);
    }
    
    char *path;
    if (ReadArgs(state, argv, 1, &path) < 0) {
        return NULL;
    }
    
    ui_print("Formatting %s...\n", path);
    if (0 != format_volume(path)) {
        free(path);
        return StringValue(strdup(""));
    }
    
    if (strcmp(path, "/data") == 0 && has_datadata()) {
        ui_print("Formatting /datadata...\n", path);
        if (0 != format_volume("/datadata")) {
            free(path);
            return StringValue(strdup(""));
        }
        if (0 != format_volume(get_android_secure_path())) {
            free(path);
            return StringValue(strdup(""));
        }
    }

done:
    return StringValue(strdup(path));
}
static void
wipe_data(int confirm) {
    if (confirm && !confirm_selection( "Confirm wipe of all user data?", "Yes - Wipe all user data"))
        return;

    ui_print("\n-- Wiping data...\n");
    device_wipe_data();
    erase_volume("/data");
    erase_volume("/cache");
    if (has_datadata()) {
        erase_volume("/datadata");
    }
    if (volume_for_path("/sd-ext") != NULL) erase_volume("/sd-ext");
    erase_volume(get_android_secure_path());
    ui_print("Data wipe complete.\n");
}
// remove static to be able to call it from ors menu
void
wipe_data(int confirm) {
    const char* headers[] = {
        "Wipe all user data ?",
        "   data | cache | datadata",
        "   sd-ext| android_secure",
        "",
        NULL
    };

    if (confirm && !confirm_with_headers(headers, "Yes - Wipe all user data")) {
        return;
    }

    ui_print("\n-- Wiping data...\n");
    device_wipe_data();
    erase_volume("/data");
    erase_volume("/cache");
    if (has_datadata()) {
        erase_volume("/datadata");
    }

    erase_volume("/sd-ext");

    // erase .android_secure from /sdcard or /storage/sdcard0
    erase_volume(get_android_secure_path());

    // erase .android_secure from any secondary storage
    char buf[80];
    char** extra_paths = get_extra_storage_paths();
    int num_extra_volumes = get_num_extra_volumes();
    int i;
    if (extra_paths != NULL) {
        for(i = 0; i < num_extra_volumes; i++) {
            sprintf(buf, "%s/.android_secure", extra_paths[i]);
            erase_volume(buf);
        }
        free_string_array(extra_paths);
    }
    ui_print("Data wipe complete.\n");
}
Beispiel #4
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;
    }
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("Can't mount backup path\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 && 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->blk_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->blk_device, tmp)))
                return ret;
        }
    }

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

	if (volume_for_path("/preload") != NULL)
	{
	    if (restore_system && 0 != (ret = nandroid_restore_partition(backup_path, "/preload")))
    	    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, get_android_secure_path(), 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;
}
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;
    if (is_data_media_volume_path(backup_path))
        volume = volume_for_path("/data");
    else
        volume = volume_for_path(backup_path);
    if (NULL == volume)
        return print_and_error("Unable to find volume for backup path.\n");
    int ret;
    struct statfs sfs;
    struct stat s;
    if (NULL != volume) {
        if (0 != (ret = statfs(volume->mount_point, &sfs)))
            return print_and_error("Unable to stat backup path.\n");
        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);
        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->blk_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->blk_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 (volume_for_path("/preload") != NULL)
	{
	    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(get_android_secure_path(), &s)) {
        ui_print("没发现.android_secure目录. 跳过备份安装到扩展卡上的程序.\n");
    }
    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))
    {
        LOGI("没有sd-ext分区. 跳过.\n");
    }
    else
    {
        if (0 != ensure_path_mounted("/sd-ext"))
            LOGI("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("创建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;
}