static int img_convert(int argc, char **argv)

{

    int c, ret = 0, n, n1, bs_n, bs_i, compress, cluster_size, cluster_sectors;

    int progress = 0, flags;

    const char *fmt, *out_fmt, *cache, *out_baseimg, *out_filename;

    BlockDriver *drv, *proto_drv;

    BlockDriverState **bs = NULL, *out_bs = NULL;

    int64_t total_sectors, nb_sectors, sector_num, bs_offset;

    uint64_t bs_sectors;

    uint8_t * buf = NULL;

    const uint8_t *buf1;

    BlockDriverInfo bdi;

    QEMUOptionParameter *param = NULL, *create_options = NULL;

    QEMUOptionParameter *out_baseimg_param;

    char *options = NULL;

    const char *snapshot_name = NULL;

    float local_progress;

    int min_sparse = 8; /* Need at least 4k of zeros for sparse detection */



    fmt = NULL;

    out_fmt = "raw";

    cache = "unsafe";

    out_baseimg = NULL;

    compress = 0;

    for(;;) {

        c = getopt(argc, argv, "f:O:B:s:hce6o:pS:t:");

        if (c == -1) {

            break;

        }

        switch(c) {

        case '?':

        case 'h':

            help();

            break;

        case 'f':

            fmt = optarg;

            break;

        case 'O':

            out_fmt = optarg;

            break;

        case 'B':

            out_baseimg = optarg;

            break;

        case 'c':

            compress = 1;

            break;

        case 'e':

            error_report("option -e is deprecated, please use \'-o "

                  "encryption\' instead!");

            return 1;

        case '6':

            error_report("option -6 is deprecated, please use \'-o "

                  "compat6\' instead!");

            return 1;

        case 'o':

            options = optarg;

            break;

        case 's':

            snapshot_name = optarg;

            break;

        case 'S':

        {

            int64_t sval;

            char *end;

            sval = strtosz_suffix(optarg, &end, STRTOSZ_DEFSUFFIX_B);

            if (sval < 0 || *end) {

                error_report("Invalid minimum zero buffer size for sparse output specified");

                return 1;

            }



            min_sparse = sval / BDRV_SECTOR_SIZE;

            break;

        }

        case 'p':

            progress = 1;

            break;

        case 't':

            cache = optarg;

            break;

        }

    }



    bs_n = argc - optind - 1;

    if (bs_n < 1) {

        help();

    }



    out_filename = argv[argc - 1];



    /* Initialize before goto out */

    qemu_progress_init(progress, 2.0);



    if (options && !strcmp(options, "?")) {

        ret = print_block_option_help(out_filename, out_fmt);

        goto out;

    }



    if (bs_n > 1 && out_baseimg) {

        error_report("-B makes no sense when concatenating multiple input "

                     "images");

        ret = -1;

        goto out;

    }



    qemu_progress_print(0, 100);



    bs = g_malloc0(bs_n * sizeof(BlockDriverState *));



    total_sectors = 0;

    for (bs_i = 0; bs_i < bs_n; bs_i++) {

        bs[bs_i] = bdrv_new_open(argv[optind + bs_i], fmt, BDRV_O_FLAGS);

        if (!bs[bs_i]) {

            error_report("Could not open '%s'", argv[optind + bs_i]);

            ret = -1;

            goto out;

        }

        bdrv_get_geometry(bs[bs_i], &bs_sectors);

        total_sectors += bs_sectors;

    }



    if (snapshot_name != NULL) {

        if (bs_n > 1) {

            error_report("No support for concatenating multiple snapshot");

            ret = -1;

            goto out;

        }

        if (bdrv_snapshot_load_tmp(bs[0], snapshot_name) < 0) {

            error_report("Failed to load snapshot");

            ret = -1;

            goto out;

        }

    }



    /* Find driver and parse its options */

    drv = bdrv_find_format(out_fmt);

    if (!drv) {

        error_report("Unknown file format '%s'", out_fmt);

        ret = -1;

        goto out;

    }



    proto_drv = bdrv_find_protocol(out_filename);

    if (!proto_drv) {

        error_report("Unknown protocol '%s'", out_filename);

        ret = -1;

        goto out;

    }



    create_options = append_option_parameters(create_options,

                                              drv->create_options);

    create_options = append_option_parameters(create_options,

                                              proto_drv->create_options);



    if (options) {

        param = parse_option_parameters(options, create_options, param);

        if (param == NULL) {

            error_report("Invalid options for file format '%s'.", out_fmt);

            ret = -1;

            goto out;

        }

    } else {

        param = parse_option_parameters("", create_options, param);

    }



    set_option_parameter_int(param, BLOCK_OPT_SIZE, total_sectors * 512);

    ret = add_old_style_options(out_fmt, param, out_baseimg, NULL);

    if (ret < 0) {

        goto out;

    }



    /* Get backing file name if -o backing_file was used */

    out_baseimg_param = get_option_parameter(param, BLOCK_OPT_BACKING_FILE);

    if (out_baseimg_param) {

        out_baseimg = out_baseimg_param->value.s;

    }



    /* Check if compression is supported */

    if (compress) {

        QEMUOptionParameter *encryption =

            get_option_parameter(param, BLOCK_OPT_ENCRYPT);

        QEMUOptionParameter *preallocation =

            get_option_parameter(param, BLOCK_OPT_PREALLOC);



        if (!drv->bdrv_write_compressed) {

            error_report("Compression not supported for this file format");

            ret = -1;

            goto out;

        }



        if (encryption && encryption->value.n) {

            error_report("Compression and encryption not supported at "

                         "the same time");

            ret = -1;

            goto out;

        }



        if (preallocation && preallocation->value.s

            && strcmp(preallocation->value.s, "off"))

        {

            error_report("Compression and preallocation not supported at "

                         "the same time");

            ret = -1;

            goto out;

        }

    }



    /* Create the new image */

    ret = bdrv_create(drv, out_filename, param);

    if (ret < 0) {

        if (ret == -ENOTSUP) {

            error_report("Formatting not supported for file format '%s'",

                         out_fmt);

        } else if (ret == -EFBIG) {

            error_report("The image size is too large for file format '%s'",

                         out_fmt);

        } else {

            error_report("%s: error while converting %s: %s",

                         out_filename, out_fmt, strerror(-ret));

        }

        goto out;

    }



    flags = BDRV_O_RDWR;

    ret = bdrv_parse_cache_flags(cache, &flags);

    if (ret < 0) {

        error_report("Invalid cache option: %s", cache);

        return -1;

    }



    out_bs = bdrv_new_open(out_filename, out_fmt, flags);

    if (!out_bs) {

        ret = -1;

        goto out;

    }



    bs_i = 0;

    bs_offset = 0;

    bdrv_get_geometry(bs[0], &bs_sectors);

    buf = qemu_blockalign(out_bs, IO_BUF_SIZE);



    if (compress) {

        ret = bdrv_get_info(out_bs, &bdi);

        if (ret < 0) {

            error_report("could not get block driver info");

            goto out;

        }

        cluster_size = bdi.cluster_size;

        if (cluster_size <= 0 || cluster_size > IO_BUF_SIZE) {

            error_report("invalid cluster size");

            ret = -1;

            goto out;

        }

        cluster_sectors = cluster_size >> 9;

        sector_num = 0;



        nb_sectors = total_sectors;

        local_progress = (float)100 /

            (nb_sectors / MIN(nb_sectors, cluster_sectors));



        for(;;) {

            int64_t bs_num;

            int remainder;

            uint8_t *buf2;



            nb_sectors = total_sectors - sector_num;

            if (nb_sectors <= 0)

                break;

            if (nb_sectors >= cluster_sectors)

                n = cluster_sectors;

            else

                n = nb_sectors;



            bs_num = sector_num - bs_offset;

            assert (bs_num >= 0);

            remainder = n;

            buf2 = buf;

            while (remainder > 0) {

                int nlow;

                while (bs_num == bs_sectors) {

                    bs_i++;

                    assert (bs_i < bs_n);

                    bs_offset += bs_sectors;

                    bdrv_get_geometry(bs[bs_i], &bs_sectors);

                    bs_num = 0;

                    /* printf("changing part: sector_num=%" PRId64 ", "

                       "bs_i=%d, bs_offset=%" PRId64 ", bs_sectors=%" PRId64

                       "\n", sector_num, bs_i, bs_offset, bs_sectors); */

                }

                assert (bs_num < bs_sectors);



                nlow = (remainder > bs_sectors - bs_num) ? bs_sectors - bs_num : remainder;



                ret = bdrv_read(bs[bs_i], bs_num, buf2, nlow);

                if (ret < 0) {

                    error_report("error while reading sector %" PRId64 ": %s",

                                 bs_num, strerror(-ret));

                    goto out;

                }



                buf2 += nlow * 512;

                bs_num += nlow;



                remainder -= nlow;

            }

            assert (remainder == 0);



            if (n < cluster_sectors) {

                memset(buf + n * 512, 0, cluster_size - n * 512);

            }

            if (!buffer_is_zero(buf, cluster_size)) {

                ret = bdrv_write_compressed(out_bs, sector_num, buf,

                                            cluster_sectors);

                if (ret != 0) {

                    error_report("error while compressing sector %" PRId64

                                 ": %s", sector_num, strerror(-ret));

                    goto out;

                }

            }

            sector_num += n;

            qemu_progress_print(local_progress, 100);

        }

        /* signal EOF to align */

        bdrv_write_compressed(out_bs, 0, NULL, 0);

    } else {

        int has_zero_init = bdrv_has_zero_init(out_bs);



        sector_num = 0; // total number of sectors converted so far

        nb_sectors = total_sectors - sector_num;

        local_progress = (float)100 /

            (nb_sectors / MIN(nb_sectors, IO_BUF_SIZE / 512));



        for(;;) {

            nb_sectors = total_sectors - sector_num;

            if (nb_sectors <= 0) {

                break;

            }

            if (nb_sectors >= (IO_BUF_SIZE / 512)) {

                n = (IO_BUF_SIZE / 512);

            } else {

                n = nb_sectors;

            }



            while (sector_num - bs_offset >= bs_sectors) {

                bs_i ++;

                assert (bs_i < bs_n);

                bs_offset += bs_sectors;

                bdrv_get_geometry(bs[bs_i], &bs_sectors);

                /* printf("changing part: sector_num=%" PRId64 ", bs_i=%d, "

                  "bs_offset=%" PRId64 ", bs_sectors=%" PRId64 "\n",

                   sector_num, bs_i, bs_offset, bs_sectors); */

            }



            if (n > bs_offset + bs_sectors - sector_num) {

                n = bs_offset + bs_sectors - sector_num;

            }



            if (has_zero_init) {

                /* If the output image is being created as a copy on write image,

                   assume that sectors which are unallocated in the input image

                   are present in both the output's and input's base images (no

                   need to copy them). */

                if (out_baseimg) {

                    if (!bdrv_is_allocated(bs[bs_i], sector_num - bs_offset,

                                           n, &n1)) {

                        sector_num += n1;

                        continue;

                    }

                    /* The next 'n1' sectors are allocated in the input image. Copy

                       only those as they may be followed by unallocated sectors. */

                    n = n1;

                }

            } else {

                n1 = n;

            }



            ret = bdrv_read(bs[bs_i], sector_num - bs_offset, buf, n);

            if (ret < 0) {

                error_report("error while reading sector %" PRId64 ": %s",

                             sector_num - bs_offset, strerror(-ret));

                goto out;

            }

            /* NOTE: at the same time we convert, we do not write zero

               sectors to have a chance to compress the image. Ideally, we

               should add a specific call to have the info to go faster */

            buf1 = buf;

            while (n > 0) {

                /* If the output image is being created as a copy on write image,

                   copy all sectors even the ones containing only NUL bytes,

                   because they may differ from the sectors in the base image.



                   If the output is to a host device, we also write out

                   sectors that are entirely 0, since whatever data was

                   already there is garbage, not 0s. */

                if (!has_zero_init || out_baseimg ||

                    is_allocated_sectors_min(buf1, n, &n1, min_sparse)) {

                    ret = bdrv_write(out_bs, sector_num, buf1, n1);

                    if (ret < 0) {

                        error_report("error while writing sector %" PRId64

                                     ": %s", sector_num, strerror(-ret));

                        goto out;

                    }

                }

                sector_num += n1;

                n -= n1;

                buf1 += n1 * 512;

            }

            qemu_progress_print(local_progress, 100);

        }

    }

out:

    qemu_progress_end();

    free_option_parameters(create_options);

    free_option_parameters(param);

    qemu_vfree(buf);

    if (out_bs) {

        bdrv_delete(out_bs);

    }

    if (bs) {

        for (bs_i = 0; bs_i < bs_n; bs_i++) {

            if (bs[bs_i]) {

                bdrv_delete(bs[bs_i]);

            }

        }

        g_free(bs);

    }

    if (ret) {

        return 1;

    }

    return 0;

}

static int img_convert(int argc, char **argv)

{

    int c, ret = 0, n, n1, bs_n, bs_i, compress, cluster_size, cluster_sectors;

    int progress = 0, flags;

    const char *fmt, *out_fmt, *cache, *out_baseimg, *out_filename;

    BlockDriver *drv, *proto_drv;

    BlockDriverState **bs = NULL, *out_bs = NULL;

    int64_t total_sectors, nb_sectors, sector_num, bs_offset;

    uint64_t bs_sectors;

    uint8_t * buf = NULL;

    const uint8_t *buf1;

    BlockDriverInfo bdi;

    QEMUOptionParameter *param = NULL, *create_options = NULL;

    QEMUOptionParameter *out_baseimg_param;

    char *options = NULL;

    const char *snapshot_name = NULL;

    float local_progress;

    int min_sparse = 8; 



    fmt = NULL;

    out_fmt = "raw";

    cache = "unsafe";

    out_baseimg = NULL;

    compress = 0;

    for(;;) {

        c = getopt(argc, argv, "f:O:B:s:hce6o:pS:t:");

        if (c == -1) {

            break;

        }

        switch(c) {

        case '?':

        case 'h':

            help();

            break;

        case 'f':

            fmt = optarg;

            break;

        case 'O':

            out_fmt = optarg;

            break;

        case 'B':

            out_baseimg = optarg;

            break;

        case 'c':

            compress = 1;

            break;

        case 'e':

            error_report("option -e is deprecated, please use \'-o "

                  "encryption\' instead!");

            return 1;

        case '6':

            error_report("option -6 is deprecated, please use \'-o "

                  "compat6\' instead!");

            return 1;

        case 'o':

            options = optarg;

            break;

        case 's':

            snapshot_name = optarg;

            break;

        case 'S':

        {

            int64_t sval;

            char *end;

            sval = strtosz_suffix(optarg, &end, STRTOSZ_DEFSUFFIX_B);

            if (sval < 0 || *end) {

                error_report("Invalid minimum zero buffer size for sparse output specified");

                return 1;

            }



            min_sparse = sval / BDRV_SECTOR_SIZE;

            break;

        }

        case 'p':

            progress = 1;

            break;

        case 't':

            cache = optarg;

            break;

        }

    }



    bs_n = argc - optind - 1;

    if (bs_n < 1) {

        help();

    }



    out_filename = argv[argc - 1];



    

    qemu_progress_init(progress, 2.0);



    if (options && !strcmp(options, "?")) {

        ret = print_block_option_help(out_filename, out_fmt);

        goto out;

    }



    if (bs_n > 1 && out_baseimg) {

        error_report("-B makes no sense when concatenating multiple input "

                     "images");

        ret = -1;

        goto out;

    }



    qemu_progress_print(0, 100);



    bs = g_malloc0(bs_n * sizeof(BlockDriverState *));



    total_sectors = 0;

    for (bs_i = 0; bs_i < bs_n; bs_i++) {

        bs[bs_i] = bdrv_new_open(argv[optind + bs_i], fmt, BDRV_O_FLAGS);

        if (!bs[bs_i]) {

            error_report("Could not open '%s'", argv[optind + bs_i]);

            ret = -1;

            goto out;

        }

        bdrv_get_geometry(bs[bs_i], &bs_sectors);

        total_sectors += bs_sectors;

    }



    if (snapshot_name != NULL) {

        if (bs_n > 1) {

            error_report("No support for concatenating multiple snapshot");

            ret = -1;

            goto out;

        }

        if (bdrv_snapshot_load_tmp(bs[0], snapshot_name) < 0) {

            error_report("Failed to load snapshot");

            ret = -1;

            goto out;

        }

    }



    

    drv = bdrv_find_format(out_fmt);

    if (!drv) {

        error_report("Unknown file format '%s'", out_fmt);

        ret = -1;

        goto out;

    }



    proto_drv = bdrv_find_protocol(out_filename);

    if (!proto_drv) {

        error_report("Unknown protocol '%s'", out_filename);

        ret = -1;

        goto out;

    }



    create_options = append_option_parameters(create_options,

                                              drv->create_options);

    create_options = append_option_parameters(create_options,

                                              proto_drv->create_options);



    if (options) {

        param = parse_option_parameters(options, create_options, param);

        if (param == NULL) {

            error_report("Invalid options for file format '%s'.", out_fmt);

            ret = -1;

            goto out;

        }

    } else {

        param = parse_option_parameters("", create_options, param);

    }



    set_option_parameter_int(param, BLOCK_OPT_SIZE, total_sectors * 512);

    ret = add_old_style_options(out_fmt, param, out_baseimg, NULL);

    if (ret < 0) {

        goto out;

    }



    

    out_baseimg_param = get_option_parameter(param, BLOCK_OPT_BACKING_FILE);

    if (out_baseimg_param) {

        out_baseimg = out_baseimg_param->value.s;

    }



    

    if (compress) {

        QEMUOptionParameter *encryption =

            get_option_parameter(param, BLOCK_OPT_ENCRYPT);

        QEMUOptionParameter *preallocation =

            get_option_parameter(param, BLOCK_OPT_PREALLOC);



        if (!drv->bdrv_write_compressed) {

            error_report("Compression not supported for this file format");

            ret = -1;

            goto out;

        }



        if (encryption && encryption->value.n) {

            error_report("Compression and encryption not supported at "

                         "the same time");

            ret = -1;

            goto out;

        }



        if (preallocation && preallocation->value.s

            && strcmp(preallocation->value.s, "off"))

        {

            error_report("Compression and preallocation not supported at "

                         "the same time");

            ret = -1;

            goto out;

        }

    }



    

    ret = bdrv_create(drv, out_filename, param);

    if (ret < 0) {

        if (ret == -ENOTSUP) {

            error_report("Formatting not supported for file format '%s'",

                         out_fmt);

        } else if (ret == -EFBIG) {

            error_report("The image size is too large for file format '%s'",

                         out_fmt);

        } else {

            error_report("%s: error while converting %s: %s",

                         out_filename, out_fmt, strerror(-ret));

        }

        goto out;

    }



    flags = BDRV_O_RDWR;

    ret = bdrv_parse_cache_flags(cache, &flags);

    if (ret < 0) {

        error_report("Invalid cache option: %s", cache);

        return -1;

    }



    out_bs = bdrv_new_open(out_filename, out_fmt, flags);

    if (!out_bs) {

        ret = -1;

        goto out;

    }



    bs_i = 0;

    bs_offset = 0;

    bdrv_get_geometry(bs[0], &bs_sectors);

    buf = qemu_blockalign(out_bs, IO_BUF_SIZE);



    if (compress) {

        ret = bdrv_get_info(out_bs, &bdi);

        if (ret < 0) {

            error_report("could not get block driver info");

            goto out;

        }

        cluster_size = bdi.cluster_size;

        if (cluster_size <= 0 || cluster_size > IO_BUF_SIZE) {

            error_report("invalid cluster size");

            ret = -1;

            goto out;

        }

        cluster_sectors = cluster_size >> 9;

        sector_num = 0;



        nb_sectors = total_sectors;

        local_progress = (float)100 /

            (nb_sectors / MIN(nb_sectors, cluster_sectors));



        for(;;) {

            int64_t bs_num;

            int remainder;

            uint8_t *buf2;



            nb_sectors = total_sectors - sector_num;

            if (nb_sectors <= 0)

                break;

            if (nb_sectors >= cluster_sectors)

                n = cluster_sectors;

            else

                n = nb_sectors;



            bs_num = sector_num - bs_offset;

            assert (bs_num >= 0);

            remainder = n;

            buf2 = buf;

            while (remainder > 0) {

                int nlow;

                while (bs_num == bs_sectors) {

                    bs_i++;

                    assert (bs_i < bs_n);

                    bs_offset += bs_sectors;

                    bdrv_get_geometry(bs[bs_i], &bs_sectors);

                    bs_num = 0;

                    





                }

                assert (bs_num < bs_sectors);



                nlow = (remainder > bs_sectors - bs_num) ? bs_sectors - bs_num : remainder;



                ret = bdrv_read(bs[bs_i], bs_num, buf2, nlow);

                if (ret < 0) {

                    error_report("error while reading sector %" PRId64 ": %s",

                                 bs_num, strerror(-ret));

                    goto out;

                }



                buf2 += nlow * 512;

                bs_num += nlow;



                remainder -= nlow;

            }

            assert (remainder == 0);



            if (n < cluster_sectors) {

                memset(buf + n * 512, 0, cluster_size - n * 512);

            }

            if (!buffer_is_zero(buf, cluster_size)) {

                ret = bdrv_write_compressed(out_bs, sector_num, buf,

                                            cluster_sectors);

                if (ret != 0) {

                    error_report("error while compressing sector %" PRId64

                                 ": %s", sector_num, strerror(-ret));

                    goto out;

                }

            }

            sector_num += n;

            qemu_progress_print(local_progress, 100);

        }

        

        bdrv_write_compressed(out_bs, 0, NULL, 0);

    } else {

        int has_zero_init = bdrv_has_zero_init(out_bs);



        sector_num = 0; 

        nb_sectors = total_sectors - sector_num;

        local_progress = (float)100 /

            (nb_sectors / MIN(nb_sectors, IO_BUF_SIZE / 512));



        for(;;) {

            nb_sectors = total_sectors - sector_num;

            if (nb_sectors <= 0) {

                break;

            }

            if (nb_sectors >= (IO_BUF_SIZE / 512)) {

                n = (IO_BUF_SIZE / 512);

            } else {

                n = nb_sectors;

            }



            while (sector_num - bs_offset >= bs_sectors) {

                bs_i ++;

                assert (bs_i < bs_n);

                bs_offset += bs_sectors;

                bdrv_get_geometry(bs[bs_i], &bs_sectors);

                





            }



            if (n > bs_offset + bs_sectors - sector_num) {

                n = bs_offset + bs_sectors - sector_num;

            }



            if (has_zero_init) {

                







                if (out_baseimg) {

                    if (!bdrv_is_allocated(bs[bs_i], sector_num - bs_offset,

                                           n, &n1)) {

                        sector_num += n1;

                        continue;

                    }

                    



                    n = n1;

                }

            } else {

                n1 = n;

            }



            ret = bdrv_read(bs[bs_i], sector_num - bs_offset, buf, n);

            if (ret < 0) {

                error_report("error while reading sector %" PRId64 ": %s",

                             sector_num - bs_offset, strerror(-ret));

                goto out;

            }

            





            buf1 = buf;

            while (n > 0) {

                













                if (!has_zero_init || out_baseimg ||

                    is_allocated_sectors_min(buf1, n, &n1, min_sparse)) {

                    ret = bdrv_write(out_bs, sector_num, buf1, n1);

                    if (ret < 0) {

                        error_report("error while writing sector %" PRId64

                                     ": %s", sector_num, strerror(-ret));

                        goto out;

                    }

                }

                sector_num += n1;

                n -= n1;

                buf1 += n1 * 512;

            }

            qemu_progress_print(local_progress, 100);

        }

    }

out:

    qemu_progress_end();

    free_option_parameters(create_options);

    free_option_parameters(param);

    qemu_vfree(buf);

    if (out_bs) {

        bdrv_delete(out_bs);

    }

    if (bs) {

        for (bs_i = 0; bs_i < bs_n; bs_i++) {

            if (bs[bs_i]) {

                bdrv_delete(bs[bs_i]);

            }

        }

        g_free(bs);

    }

    if (ret) {

        return 1;

    }

    return 0;

}

    if (options && !strcmp(options, "?")) {     if (options && !strcmp(options, "?")) {
static int FUNC_0(int VAR_0, char **VAR_1)

{

    int VAR_2, VAR_3 = 0, VAR_4, VAR_5, VAR_6, VAR_7, VAR_8, VAR_9, VAR_10;

    int VAR_11 = 0, VAR_12;

    const char *VAR_13, *VAR_14, *VAR_15, *VAR_16, *VAR_17;

    BlockDriver *drv, *proto_drv;

    BlockDriverState **bs = NULL, *out_bs = NULL;

    int64_t total_sectors, nb_sectors, sector_num, bs_offset;

    uint64_t bs_sectors;

    uint8_t * buf = NULL;

    const uint8_t *VAR_18;

    BlockDriverInfo bdi;

    QEMUOptionParameter *param = NULL, *create_options = NULL;

    QEMUOptionParameter *out_baseimg_param;

    char *VAR_19 = NULL;

    const char *VAR_20 = NULL;

    float VAR_21;

    int VAR_22 = 8; 



    VAR_13 = NULL;

    VAR_14 = "raw";

    VAR_15 = "unsafe";

    VAR_16 = NULL;

    VAR_8 = 0;

    for(;;) {

        VAR_2 = getopt(VAR_0, VAR_1, "f:O:B:s:hce6o:pS:t:");

        if (VAR_2 == -1) {

            break;

        }

        switch(VAR_2) {

        case '?':

        case 'h':

            help();

            break;

        case 'f':

            VAR_13 = optarg;

            break;

        case 'O':

            VAR_14 = optarg;

            break;

        case 'B':

            VAR_16 = optarg;

            break;

        case 'VAR_2':

            VAR_8 = 1;

            break;

        case 'e':

            error_report("option -e is deprecated, please use \'-o "

                  "encryption\' instead!");

            return 1;

        case '6':

            error_report("option -6 is deprecated, please use \'-o "

                  "compat6\' instead!");

            return 1;

        case 'o':

            VAR_19 = optarg;

            break;

        case 's':

            VAR_20 = optarg;

            break;

        case 'S':

        {

            int64_t sval;

            char *VAR_23;

            sval = strtosz_suffix(optarg, &VAR_23, STRTOSZ_DEFSUFFIX_B);

            if (sval < 0 || *VAR_23) {

                error_report("Invalid minimum zero buffer size for sparse output specified");

                return 1;

            }



            VAR_22 = sval / BDRV_SECTOR_SIZE;

            break;

        }

        case 'p':

            VAR_11 = 1;

            break;

        case 't':

            VAR_15 = optarg;

            break;

        }

    }



    VAR_6 = VAR_0 - optind - 1;

    if (VAR_6 < 1) {

        help();

    }



    VAR_17 = VAR_1[VAR_0 - 1];



    

    qemu_progress_init(VAR_11, 2.0);



    if (VAR_19 && !strcmp(VAR_19, "?")) {

        VAR_3 = print_block_option_help(VAR_17, VAR_14);

        goto out;

    }



    if (VAR_6 > 1 && VAR_16) {

        error_report("-B makes no sense when concatenating multiple input "

                     "images");

        VAR_3 = -1;

        goto out;

    }



    qemu_progress_print(0, 100);



    bs = g_malloc0(VAR_6 * sizeof(BlockDriverState *));



    total_sectors = 0;

    for (VAR_7 = 0; VAR_7 < VAR_6; VAR_7++) {

        bs[VAR_7] = bdrv_new_open(VAR_1[optind + VAR_7], VAR_13, BDRV_O_FLAGS);

        if (!bs[VAR_7]) {

            error_report("Could not open '%s'", VAR_1[optind + VAR_7]);

            VAR_3 = -1;

            goto out;

        }

        bdrv_get_geometry(bs[VAR_7], &bs_sectors);

        total_sectors += bs_sectors;

    }



    if (VAR_20 != NULL) {

        if (VAR_6 > 1) {

            error_report("No support for concatenating multiple snapshot");

            VAR_3 = -1;

            goto out;

        }

        if (bdrv_snapshot_load_tmp(bs[0], VAR_20) < 0) {

            error_report("Failed to load snapshot");

            VAR_3 = -1;

            goto out;

        }

    }



    

    drv = bdrv_find_format(VAR_14);

    if (!drv) {

        error_report("Unknown file format '%s'", VAR_14);

        VAR_3 = -1;

        goto out;

    }



    proto_drv = bdrv_find_protocol(VAR_17);

    if (!proto_drv) {

        error_report("Unknown protocol '%s'", VAR_17);

        VAR_3 = -1;

        goto out;

    }



    create_options = append_option_parameters(create_options,

                                              drv->create_options);

    create_options = append_option_parameters(create_options,

                                              proto_drv->create_options);



    if (VAR_19) {

        param = parse_option_parameters(VAR_19, create_options, param);

        if (param == NULL) {

            error_report("Invalid VAR_19 for file format '%s'.", VAR_14);

            VAR_3 = -1;

            goto out;

        }

    } else {

        param = parse_option_parameters("", create_options, param);

    }



    set_option_parameter_int(param, BLOCK_OPT_SIZE, total_sectors * 512);

    VAR_3 = add_old_style_options(VAR_14, param, VAR_16, NULL);

    if (VAR_3 < 0) {

        goto out;

    }



    

    out_baseimg_param = get_option_parameter(param, BLOCK_OPT_BACKING_FILE);

    if (out_baseimg_param) {

        VAR_16 = out_baseimg_param->value.s;

    }



    

    if (VAR_8) {

        QEMUOptionParameter *encryption =

            get_option_parameter(param, BLOCK_OPT_ENCRYPT);

        QEMUOptionParameter *preallocation =

            get_option_parameter(param, BLOCK_OPT_PREALLOC);



        if (!drv->bdrv_write_compressed) {

            error_report("Compression not supported for this file format");

            VAR_3 = -1;

            goto out;

        }



        if (encryption && encryption->value.VAR_4) {

            error_report("Compression and encryption not supported at "

                         "the same time");

            VAR_3 = -1;

            goto out;

        }



        if (preallocation && preallocation->value.s

            && strcmp(preallocation->value.s, "off"))

        {

            error_report("Compression and preallocation not supported at "

                         "the same time");

            VAR_3 = -1;

            goto out;

        }

    }



    

    VAR_3 = bdrv_create(drv, VAR_17, param);

    if (VAR_3 < 0) {

        if (VAR_3 == -ENOTSUP) {

            error_report("Formatting not supported for file format '%s'",

                         VAR_14);

        } else if (VAR_3 == -EFBIG) {

            error_report("The image size is too large for file format '%s'",

                         VAR_14);

        } else {

            error_report("%s: error while converting %s: %s",

                         VAR_17, VAR_14, strerror(-VAR_3));

        }

        goto out;

    }



    VAR_12 = BDRV_O_RDWR;

    VAR_3 = bdrv_parse_cache_flags(VAR_15, &VAR_12);

    if (VAR_3 < 0) {

        error_report("Invalid VAR_15 option: %s", VAR_15);

        return -1;

    }



    out_bs = bdrv_new_open(VAR_17, VAR_14, VAR_12);

    if (!out_bs) {

        VAR_3 = -1;

        goto out;

    }



    VAR_7 = 0;

    bs_offset = 0;

    bdrv_get_geometry(bs[0], &bs_sectors);

    buf = qemu_blockalign(out_bs, IO_BUF_SIZE);



    if (VAR_8) {

        VAR_3 = bdrv_get_info(out_bs, &bdi);

        if (VAR_3 < 0) {

            error_report("could not get block driver info");

            goto out;

        }

        VAR_9 = bdi.VAR_9;

        if (VAR_9 <= 0 || VAR_9 > IO_BUF_SIZE) {

            error_report("invalid cluster size");

            VAR_3 = -1;

            goto out;

        }

        VAR_10 = VAR_9 >> 9;

        sector_num = 0;



        nb_sectors = total_sectors;

        VAR_21 = (float)100 /

            (nb_sectors / MIN(nb_sectors, VAR_10));



        for(;;) {

            int64_t bs_num;

            int VAR_24;

            uint8_t *buf2;



            nb_sectors = total_sectors - sector_num;

            if (nb_sectors <= 0)

                break;

            if (nb_sectors >= VAR_10)

                VAR_4 = VAR_10;

            else

                VAR_4 = nb_sectors;



            bs_num = sector_num - bs_offset;

            assert (bs_num >= 0);

            VAR_24 = VAR_4;

            buf2 = buf;

            while (VAR_24 > 0) {

                int VAR_25;

                while (bs_num == bs_sectors) {

                    VAR_7++;

                    assert (VAR_7 < VAR_6);

                    bs_offset += bs_sectors;

                    bdrv_get_geometry(bs[VAR_7], &bs_sectors);

                    bs_num = 0;

                    





                }

                assert (bs_num < bs_sectors);



                VAR_25 = (VAR_24 > bs_sectors - bs_num) ? bs_sectors - bs_num : VAR_24;



                VAR_3 = bdrv_read(bs[VAR_7], bs_num, buf2, VAR_25);

                if (VAR_3 < 0) {

                    error_report("error while reading sector %" PRId64 ": %s",

                                 bs_num, strerror(-VAR_3));

                    goto out;

                }



                buf2 += VAR_25 * 512;

                bs_num += VAR_25;



                VAR_24 -= VAR_25;

            }

            assert (VAR_24 == 0);



            if (VAR_4 < VAR_10) {

                memset(buf + VAR_4 * 512, 0, VAR_9 - VAR_4 * 512);

            }

            if (!buffer_is_zero(buf, VAR_9)) {

                VAR_3 = bdrv_write_compressed(out_bs, sector_num, buf,

                                            VAR_10);

                if (VAR_3 != 0) {

                    error_report("error while compressing sector %" PRId64

                                 ": %s", sector_num, strerror(-VAR_3));

                    goto out;

                }

            }

            sector_num += VAR_4;

            qemu_progress_print(VAR_21, 100);

        }

        

        bdrv_write_compressed(out_bs, 0, NULL, 0);

    } else {

        int VAR_26 = bdrv_has_zero_init(out_bs);



        sector_num = 0; 

        nb_sectors = total_sectors - sector_num;

        VAR_21 = (float)100 /

            (nb_sectors / MIN(nb_sectors, IO_BUF_SIZE / 512));



        for(;;) {

            nb_sectors = total_sectors - sector_num;

            if (nb_sectors <= 0) {

                break;

            }

            if (nb_sectors >= (IO_BUF_SIZE / 512)) {

                VAR_4 = (IO_BUF_SIZE / 512);

            } else {

                VAR_4 = nb_sectors;

            }



            while (sector_num - bs_offset >= bs_sectors) {

                VAR_7 ++;

                assert (VAR_7 < VAR_6);

                bs_offset += bs_sectors;

                bdrv_get_geometry(bs[VAR_7], &bs_sectors);

                





            }



            if (VAR_4 > bs_offset + bs_sectors - sector_num) {

                VAR_4 = bs_offset + bs_sectors - sector_num;

            }



            if (VAR_26) {

                







                if (VAR_16) {

                    if (!bdrv_is_allocated(bs[VAR_7], sector_num - bs_offset,

                                           VAR_4, &VAR_5)) {

                        sector_num += VAR_5;

                        continue;

                    }

                    



                    VAR_4 = VAR_5;

                }

            } else {

                VAR_5 = VAR_4;

            }



            VAR_3 = bdrv_read(bs[VAR_7], sector_num - bs_offset, buf, VAR_4);

            if (VAR_3 < 0) {

                error_report("error while reading sector %" PRId64 ": %s",

                             sector_num - bs_offset, strerror(-VAR_3));

                goto out;

            }

            





            VAR_18 = buf;

            while (VAR_4 > 0) {

                













                if (!VAR_26 || VAR_16 ||

                    is_allocated_sectors_min(VAR_18, VAR_4, &VAR_5, VAR_22)) {

                    VAR_3 = bdrv_write(out_bs, sector_num, VAR_18, VAR_5);

                    if (VAR_3 < 0) {

                        error_report("error while writing sector %" PRId64

                                     ": %s", sector_num, strerror(-VAR_3));

                        goto out;

                    }

                }

                sector_num += VAR_5;

                VAR_4 -= VAR_5;

                VAR_18 += VAR_5 * 512;

            }

            qemu_progress_print(VAR_21, 100);

        }

    }

out:

    qemu_progress_end();

    free_option_parameters(create_options);

    free_option_parameters(param);

    qemu_vfree(buf);

    if (out_bs) {

        bdrv_delete(out_bs);

    }

    if (bs) {

        for (VAR_7 = 0; VAR_7 < VAR_6; VAR_7++) {

            if (bs[VAR_7]) {

                bdrv_delete(bs[VAR_7]);

            }

        }

        g_free(bs);

    }

    if (VAR_3) {

        return 1;

    }

    return 0;

}

static int FUNC_0(int VAR_0, char **VAR_1)
{ int VAR_2, VAR_3 = 0, VAR_4, VAR_5, VAR_6, VAR_7, VAR_8, VAR_9, VAR_10; int VAR_11 = 0, VAR_12; const char *VAR_13, *VAR_14, *VAR_15, *VAR_16, *VAR_17; BlockDriver *drv, *proto_drv; BlockDriverState **bs = NULL, *out_bs = NULL; int64_t total_sectors, nb_sectors, sector_num, bs_offset; uint64_t bs_sectors; uint8_t * buf = NULL; const uint8_t *VAR_18; BlockDriverInfo bdi; QEMUOptionParameter *param = NULL, *create_options = NULL; QEMUOptionParameter *out_baseimg_param; char *VAR_19 = NULL; const char *VAR_20 = NULL; float VAR_21; int VAR_22 = 8; VAR_13 = NULL; VAR_14 = "raw"; VAR_15 = "unsafe"; VAR_16 = NULL; VAR_8 = 0; for(;;) { VAR_2 = getopt(VAR_0, VAR_1, "f:O:B:s:hce6o:pS:t:"); if (VAR_2 == -1) { break; } switch(VAR_2) { case '?':
case 'h':
help(); break; case 'f':
VAR_13 = optarg; break; case 'O':
VAR_14 = optarg; break; case 'B':
VAR_16 = optarg; break; case 'VAR_2':
VAR_8 = 1; break; case 'e':
error_report("option -e is deprecated, please use \'-o "
"encryption\' instead!"); return 1; case '6':
error_report("option -6 is deprecated, please use \'-o "
"compat6\' instead!"); return 1; case 'o':
VAR_19 = optarg; break; case 's':
VAR_20 = optarg; break; case 'S':
{ int64_t sval; char *VAR_23; sval = strtosz_suffix(optarg, &VAR_23, STRTOSZ_DEFSUFFIX_B); if (sval < 0 || *VAR_23) { error_report("Invalid minimum zero buffer size for sparse output specified"); return 1; } VAR_22 = sval / BDRV_SECTOR_SIZE; break; } case 'p':
VAR_11 = 1; break; case 't':
VAR_15 = optarg; break; } } VAR_6 = VAR_0 - optind - 1; if (VAR_6 < 1) { help(); } VAR_17 = VAR_1[VAR_0 - 1]; qemu_progress_init(VAR_11, 2.0); if (VAR_19 && !strcmp(VAR_19, "?")) { VAR_3 = print_block_option_help(VAR_17, VAR_14); goto out; } if (VAR_6 > 1 && VAR_16) { error_report("-B makes no sense when concatenating multiple input "
"images"); VAR_3 = -1; goto out; } qemu_progress_print(0, 100); bs = g_malloc0(VAR_6 * sizeof(BlockDriverState *)); total_sectors = 0; for (VAR_7 = 0; VAR_7 < VAR_6; VAR_7++) { bs[VAR_7] = bdrv_new_open(VAR_1[optind + VAR_7], VAR_13, BDRV_O_FLAGS); if (!bs[VAR_7]) { error_report("Could not open '%s'", VAR_1[optind + VAR_7]); VAR_3 = -1; goto out; } bdrv_get_geometry(bs[VAR_7], &bs_sectors); total_sectors += bs_sectors; } if (VAR_20 != NULL) { if (VAR_6 > 1) { error_report("No support for concatenating multiple snapshot"); VAR_3 = -1; goto out; } if (bdrv_snapshot_load_tmp(bs[0], VAR_20) < 0) { error_report("Failed to load snapshot"); VAR_3 = -1; goto out; } } drv = bdrv_find_format(VAR_14); if (!drv) { error_report("Unknown file format '%s'", VAR_14); VAR_3 = -1; goto out; } proto_drv = bdrv_find_protocol(VAR_17); if (!proto_drv) { error_report("Unknown protocol '%s'", VAR_17); VAR_3 = -1; goto out; } create_options = append_option_parameters(create_options,
drv->create_options); create_options = append_option_parameters(create_options,
proto_drv->create_options); if (VAR_19) { param = parse_option_parameters(VAR_19, create_options, param); if (param == NULL) { error_report("Invalid VAR_19 for file format '%s'.", VAR_14); VAR_3 = -1; goto out; } } else { param = parse_option_parameters("", create_options, param); } set_option_parameter_int(param, BLOCK_OPT_SIZE, total_sectors * 512); VAR_3 = add_old_style_options(VAR_14, param, VAR_16, NULL); if (VAR_3 < 0) { goto out; } out_baseimg_param = get_option_parameter(param, BLOCK_OPT_BACKING_FILE); if (out_baseimg_param) { VAR_16 = out_baseimg_param->value.s; } if (VAR_8) { QEMUOptionParameter *encryption =
get_option_parameter(param, BLOCK_OPT_ENCRYPT); QEMUOptionParameter *preallocation =
get_option_parameter(param, BLOCK_OPT_PREALLOC); if (!drv->bdrv_write_compressed) { error_report("Compression not supported for this file format"); VAR_3 = -1; goto out; } if (encryption && encryption->value.VAR_4) { error_report("Compression and encryption not supported at "
"the same time"); VAR_3 = -1; goto out; } if (preallocation && preallocation->value.s
&& strcmp(preallocation->value.s, "off"))
{ error_report("Compression and preallocation not supported at "
"the same time"); VAR_3 = -1; goto out; } } VAR_3 = bdrv_create(drv, VAR_17, param); if (VAR_3 < 0) { if (VAR_3 == -ENOTSUP) { error_report("Formatting not supported for file format '%s'",
VAR_14); } else if (VAR_3 == -EFBIG) { error_report("The image size is too large for file format '%s'",
VAR_14); } else { error_report("%s: error while converting %s: %s",
VAR_17, VAR_14, strerror(-VAR_3)); } goto out; } VAR_12 = BDRV_O_RDWR; VAR_3 = bdrv_parse_cache_flags(VAR_15, &VAR_12); if (VAR_3 < 0) { error_report("Invalid VAR_15 option: %s", VAR_15); return -1; } out_bs = bdrv_new_open(VAR_17, VAR_14, VAR_12); if (!out_bs) { VAR_3 = -1; goto out; } VAR_7 = 0; bs_offset = 0; bdrv_get_geometry(bs[0], &bs_sectors); buf = qemu_blockalign(out_bs, IO_BUF_SIZE); if (VAR_8) { VAR_3 = bdrv_get_info(out_bs, &bdi); if (VAR_3 < 0) { error_report("could not get block driver info"); goto out; } VAR_9 = bdi.VAR_9; if (VAR_9 <= 0 || VAR_9 > IO_BUF_SIZE) { error_report("invalid cluster size"); VAR_3 = -1; goto out; } VAR_10 = VAR_9 >> 9; sector_num = 0; nb_sectors = total_sectors; VAR_21 = (float)100 /
(nb_sectors / MIN(nb_sectors, VAR_10)); for(;;) { int64_t bs_num; int VAR_24; uint8_t *buf2; nb_sectors = total_sectors - sector_num; if (nb_sectors <= 0)
break; if (nb_sectors >= VAR_10)
VAR_4 = VAR_10; else
VAR_4 = nb_sectors; bs_num = sector_num - bs_offset; assert (bs_num >= 0); VAR_24 = VAR_4; buf2 = buf; while (VAR_24 > 0) { int VAR_25; while (bs_num == bs_sectors) { VAR_7++; assert (VAR_7 < VAR_6); bs_offset += bs_sectors; bdrv_get_geometry(bs[VAR_7], &bs_sectors); bs_num = 0; } assert (bs_num < bs_sectors); VAR_25 = (VAR_24 > bs_sectors - bs_num) ? bs_sectors - bs_num : VAR_24; VAR_3 = bdrv_read(bs[VAR_7], bs_num, buf2, VAR_25); if (VAR_3 < 0) { error_report("error while reading sector %" PRId64 ": %s",
bs_num, strerror(-VAR_3)); goto out; } buf2 += VAR_25 * 512; bs_num += VAR_25; VAR_24 -= VAR_25; } assert (VAR_24 == 0); if (VAR_4 < VAR_10) { memset(buf + VAR_4 * 512, 0, VAR_9 - VAR_4 * 512); } if (!buffer_is_zero(buf, VAR_9)) { VAR_3 = bdrv_write_compressed(out_bs, sector_num, buf,
VAR_10); if (VAR_3 != 0) { error_report("error while compressing sector %" PRId64
": %s", sector_num, strerror(-VAR_3)); goto out; } } sector_num += VAR_4; qemu_progress_print(VAR_21, 100); } bdrv_write_compressed(out_bs, 0, NULL, 0); } else { int VAR_26 = bdrv_has_zero_init(out_bs); sector_num = 0; nb_sectors = total_sectors - sector_num; VAR_21 = (float)100 /
(nb_sectors / MIN(nb_sectors, IO_BUF_SIZE / 512)); for(;;) { nb_sectors = total_sectors - sector_num; if (nb_sectors <= 0) { break; } if (nb_sectors >= (IO_BUF_SIZE / 512)) { VAR_4 = (IO_BUF_SIZE / 512); } else { VAR_4 = nb_sectors; } while (sector_num - bs_offset >= bs_sectors) { VAR_7 ++; assert (VAR_7 < VAR_6); bs_offset += bs_sectors; bdrv_get_geometry(bs[VAR_7], &bs_sectors); } if (VAR_4 > bs_offset + bs_sectors - sector_num) { VAR_4 = bs_offset + bs_sectors - sector_num; } if (VAR_26) { if (VAR_16) { if (!bdrv_is_allocated(bs[VAR_7], sector_num - bs_offset,
VAR_4, &VAR_5)) { sector_num += VAR_5; continue; } VAR_4 = VAR_5; } } else { VAR_5 = VAR_4; } VAR_3 = bdrv_read(bs[VAR_7], sector_num - bs_offset, buf, VAR_4); if (VAR_3 < 0) { error_report("error while reading sector %" PRId64 ": %s",
sector_num - bs_offset, strerror(-VAR_3)); goto out; } VAR_18 = buf; while (VAR_4 > 0) { if (!VAR_26 || VAR_16 ||
is_allocated_sectors_min(VAR_18, VAR_4, &VAR_5, VAR_22)) { VAR_3 = bdrv_write(out_bs, sector_num, VAR_18, VAR_5); if (VAR_3 < 0) { error_report("error while writing sector %" PRId64
": %s", sector_num, strerror(-VAR_3)); goto out; } } sector_num += VAR_5; VAR_4 -= VAR_5; VAR_18 += VAR_5 * 512; } qemu_progress_print(VAR_21, 100); } } out:
qemu_progress_end(); free_option_parameters(create_options); free_option_parameters(param); qemu_vfree(buf); if (out_bs) { bdrv_delete(out_bs); } if (bs) { for (VAR_7 = 0; VAR_7 < VAR_6; VAR_7++) { if (bs[VAR_7]) { bdrv_delete(bs[VAR_7]); } } g_free(bs); } if (VAR_3) { return 1; } return 0; }