static void choose_default_backup_format() {
    static char* headers[] = {  "Default Backup Format",
                                "",
                                NULL
    };

    char **list;
    char* list_tar_default[] = { "tar (default)",
        "dup",
        NULL
    };
    char* list_dup_default[] = { "tar",
        "dup (default)",
        NULL
    };

    if (nandroid_get_default_backup_format() == NANDROID_BACKUP_FORMAT_DUP) {
        list = list_dup_default;
    } else {
        list = list_tar_default;
    }

    int chosen_item = get_menu_selection(headers, list, 0, 0);
    switch (chosen_item) {
        case 0:
            write_string_to_file(NANDROID_BACKUP_FORMAT_FILE, "tar");
            ui_print("Default backup format set to tar.\n");
            break;
        case 1:
            write_string_to_file(NANDROID_BACKUP_FORMAT_FILE, "dup");
            ui_print("Default backup format set to dedupe.\n");
            break;
    }
}
示例#2
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;
}
示例#3
0
// print backup stats summary at end of a backup
void show_backup_stats(const char* backup_path) {
    long long total_msec = timenow_msec() - nandroid_start_msec;
    long long minutes = total_msec / 60000LL;
    long long seconds = (total_msec % 60000LL) / 1000LL;

    unsigned long long final_size = Get_Folder_Size(backup_path);
    long double compression;
    if (Backup_Size == 0 || final_size == 0 || nandroid_get_default_backup_format() != NANDROID_BACKUP_FORMAT_TGZ)
        compression = 0;
    else compression = 1 - ((long double)(final_size) / (long double)(Backup_Size));

    ui_print("\nBackup complete!\n");
    ui_print("Backup time: %02lld:%02lld mn\n", minutes, seconds);
    ui_print("Backup size: %.2LfMb\n", (long double) final_size / 1048576);
    // print compression % only if it is a tar / tar.gz backup
    // keep also for tar to show it is 0% compression
    if (default_backup_handler != dedupe_compress_wrapper)
        ui_print("Compression: %.2Lf%%\n", compression * 100);
}
示例#4
0
int twrp_backup_wrapper(const char* backup_path, const char* backup_file_image, int callback) {
    Volume *v = volume_for_path(backup_path);
    if (v == NULL) {
        ui_print("Unable to find volume.\n");
        return -1;
    }

    if (!is_path_mounted(backup_path)) {
        LOGE("Unable to find mounted volume: '%s'\n", v->mount_point);
        return -1;
    }

    // Always use split format (simpler code) - Build lists of files to backup
    char tmp[PATH_MAX];
    int backup_count;
    ui_print("Breaking backup file into multiple archives...\nGenerating file lists\n");
    backup_count = Make_File_List(backup_path);
    if (backup_count < 1) {
        LOGE("Error generating file list!\n");
        return -1;
    }

    // check we are not backing up an empty volume as it would fail to restore (tar: short read)
    // check first if a filelist was generated. If not, ensure volume is 0 size. Else, it could be an error while 
    if (!file_found("/tmp/list/filelist000")) {
        ui_print("Nothing to backup. Skipping %s\n", BaseName(backup_path));
        return 0;
    }

    unsigned long long total_bsize = 0, file_size = 0;
    int index;
    int nand_starts = 1;
    last_size_update = 0;
    set_perf_mode(1);
    for (index = 0; index < backup_count; index++)
    {
        compute_twrp_backup_stats(index);
        // folder /data/media and google cached music are excluded from tar by Generate_File_Lists(...)
        if (nandroid_get_default_backup_format() == NANDROID_BACKUP_FORMAT_TAR)
            sprintf(tmp, "(tar -cpvf '%s%03i' -T /tmp/list/filelist%03i) 2> /proc/self/fd/1 ; exit $?", backup_file_image, index, index);
        else
            sprintf(tmp, "set -o pipefail ; (tar -cpv -T /tmp/list/filelist%03i | pigz -c -%d >'%s%03i') 2> /proc/self/fd/1 ; exit $?", index, compression_value.value, backup_file_image, index);

        ui_print("  * Backing up archive %i/%i\n", (index + 1), backup_count);
        FILE *fp = __popen(tmp, "r");
        if (fp == NULL) {
            LOGE("Unable to execute tar.\n");
            set_perf_mode(0);
            return -1;
        }

        while (fgets(tmp, PATH_MAX, fp) != NULL) {
#ifdef PHILZ_TOUCH_RECOVERY
            if (user_cancel_nandroid(&fp, backup_file_image, 1, &nand_starts)) {
                set_perf_mode(0);
                return -1;
            }
#endif
            tmp[PATH_MAX - 1] = '\0';
            if (callback) {
                update_size_progress(backup_file_image);
                nandroid_callback(tmp);
            }
        }

#ifdef PHILZ_TOUCH_RECOVERY
        ui_print_preset_colors(0, NULL);
#endif
        if (0 != __pclose(fp)) {
            set_perf_mode(0);
            return -1;
        }

        sprintf(tmp, "%s%03i", backup_file_image, index);
        file_size = Get_File_Size(tmp);
        if (file_size == 0) {
            LOGE("Backup file size for '%s' is 0 bytes!\n", tmp);
            set_perf_mode(0);
            return -1;
        }
        total_bsize += file_size;
    }

    __system("cd /tmp && rm -rf list");
    set_perf_mode(0);
    ui_print("Total backup size:\n  %llu bytes.\n", total_bsize);
    return 0;
}