static void qemu_rbd_parse_filename(const char *filename, QDict *options,

                                    Error **errp)

{

    const char *start;

    char *p, *buf, *keypairs;

    char *found_str;

    size_t max_keypair_size;

    Error *local_err = NULL;



    if (!strstart(filename, "rbd:", &start)) {

        error_setg(errp, "File name must start with 'rbd:'");

        return;

    }



    max_keypair_size = strlen(start) + 1;

    buf = g_strdup(start);

    keypairs = g_malloc0(max_keypair_size);

    p = buf;



    found_str = qemu_rbd_next_tok(RBD_MAX_POOL_NAME_SIZE, p,

                                  '/', "pool name", &p, &local_err);

    if (local_err) {

        goto done;

    }

    if (!p) {

        error_setg(errp, "Pool name is required");

        goto done;

    }

    qemu_rbd_unescape(found_str);

    qdict_put(options, "pool", qstring_from_str(found_str));



    if (strchr(p, '@')) {

        found_str = qemu_rbd_next_tok(RBD_MAX_IMAGE_NAME_SIZE, p,

                                      '@', "object name", &p, &local_err);

        if (local_err) {

            goto done;

        }

        qemu_rbd_unescape(found_str);

        qdict_put(options, "image", qstring_from_str(found_str));



        found_str = qemu_rbd_next_tok(RBD_MAX_SNAP_NAME_SIZE, p,

                                      ':', "snap name", &p, &local_err);

        if (local_err) {

            goto done;

        }

        qemu_rbd_unescape(found_str);

        qdict_put(options, "snapshot", qstring_from_str(found_str));

    } else {

        found_str = qemu_rbd_next_tok(RBD_MAX_IMAGE_NAME_SIZE, p,

                                      ':', "object name", &p, &local_err);

        if (local_err) {

            goto done;

        }

        qemu_rbd_unescape(found_str);

        qdict_put(options, "image", qstring_from_str(found_str));

    }

    if (!p) {

        goto done;

    }



    found_str = qemu_rbd_next_tok(RBD_MAX_CONF_NAME_SIZE, p,

                                  '\0', "configuration", &p, &local_err);

    if (local_err) {

        goto done;

    }



    p = found_str;



    /* The following are essentially all key/value pairs, and we treat

     * 'id' and 'conf' a bit special.  Key/value pairs may be in any order. */

    while (p) {

        char *name, *value;

        name = qemu_rbd_next_tok(RBD_MAX_CONF_NAME_SIZE, p,

                                 '=', "conf option name", &p, &local_err);

        if (local_err) {

            break;

        }



        if (!p) {

            error_setg(errp, "conf option %s has no value", name);

            break;

        }



        qemu_rbd_unescape(name);



        value = qemu_rbd_next_tok(RBD_MAX_CONF_VAL_SIZE, p,

                                  ':', "conf option value", &p, &local_err);

        if (local_err) {

            break;

        }

        qemu_rbd_unescape(value);



        if (!strcmp(name, "conf")) {

            qdict_put(options, "conf", qstring_from_str(value));

        } else if (!strcmp(name, "id")) {

            qdict_put(options, "user" , qstring_from_str(value));

        } else {

            /* FIXME: This is pretty ugly, and not the right way to do this.

             *        These should be contained in a structure, and then

             *        passed explicitly as individual key/value pairs to

             *        rados.  Consider this legacy code that needs to be

             *        updated. */

            char *tmp = g_malloc0(max_keypair_size);

            /* only use a delimiter if it is not the first keypair found */

            /* These are sets of unknown key/value pairs we'll pass along

             * to ceph */

            if (keypairs[0]) {

                snprintf(tmp, max_keypair_size, ":%s=%s", name, value);

                pstrcat(keypairs, max_keypair_size, tmp);

            } else {

                snprintf(keypairs, max_keypair_size, "%s=%s", name, value);

            }

            g_free(tmp);

        }

    }



    if (keypairs[0]) {

        qdict_put(options, "keyvalue-pairs", qstring_from_str(keypairs));

    }





done:

    if (local_err) {

        error_propagate(errp, local_err);

    }

    g_free(buf);

    g_free(keypairs);

    return;

}

static void qemu_rbd_parse_filename(const char *filename, QDict *options,

                                    Error **errp)

{

    const char *start;

    char *p, *buf, *keypairs;

    char *found_str;

    size_t max_keypair_size;

    Error *local_err = NULL;



    if (!strstart(filename, "rbd:", &start)) {

        error_setg(errp, "File name must start with 'rbd:'");

        return;

    }



    max_keypair_size = strlen(start) + 1;

    buf = g_strdup(start);

    keypairs = g_malloc0(max_keypair_size);

    p = buf;



    found_str = qemu_rbd_next_tok(RBD_MAX_POOL_NAME_SIZE, p,

                                  '/', "pool name", &p, &local_err);

    if (local_err) {

        goto done;

    }

    if (!p) {

        error_setg(errp, "Pool name is required");

        goto done;

    }

    qemu_rbd_unescape(found_str);

    qdict_put(options, "pool", qstring_from_str(found_str));



    if (strchr(p, '@')) {

        found_str = qemu_rbd_next_tok(RBD_MAX_IMAGE_NAME_SIZE, p,

                                      '@', "object name", &p, &local_err);

        if (local_err) {

            goto done;

        }

        qemu_rbd_unescape(found_str);

        qdict_put(options, "image", qstring_from_str(found_str));



        found_str = qemu_rbd_next_tok(RBD_MAX_SNAP_NAME_SIZE, p,

                                      ':', "snap name", &p, &local_err);

        if (local_err) {

            goto done;

        }

        qemu_rbd_unescape(found_str);

        qdict_put(options, "snapshot", qstring_from_str(found_str));

    } else {

        found_str = qemu_rbd_next_tok(RBD_MAX_IMAGE_NAME_SIZE, p,

                                      ':', "object name", &p, &local_err);

        if (local_err) {

            goto done;

        }

        qemu_rbd_unescape(found_str);

        qdict_put(options, "image", qstring_from_str(found_str));

    }

    if (!p) {

        goto done;

    }



    found_str = qemu_rbd_next_tok(RBD_MAX_CONF_NAME_SIZE, p,

                                  '\0', "configuration", &p, &local_err);

    if (local_err) {

        goto done;

    }



    p = found_str;



    



    while (p) {

        char *name, *value;

        name = qemu_rbd_next_tok(RBD_MAX_CONF_NAME_SIZE, p,

                                 '=', "conf option name", &p, &local_err);

        if (local_err) {

            break;

        }



        if (!p) {

            error_setg(errp, "conf option %s has no value", name);

            break;

        }



        qemu_rbd_unescape(name);



        value = qemu_rbd_next_tok(RBD_MAX_CONF_VAL_SIZE, p,

                                  ':', "conf option value", &p, &local_err);

        if (local_err) {

            break;

        }

        qemu_rbd_unescape(value);



        if (!strcmp(name, "conf")) {

            qdict_put(options, "conf", qstring_from_str(value));

        } else if (!strcmp(name, "id")) {

            qdict_put(options, "user" , qstring_from_str(value));

        } else {

            









            char *tmp = g_malloc0(max_keypair_size);

            

            



            if (keypairs[0]) {

                snprintf(tmp, max_keypair_size, ":%s=%s", name, value);

                pstrcat(keypairs, max_keypair_size, tmp);

            } else {

                snprintf(keypairs, max_keypair_size, "%s=%s", name, value);

            }

            g_free(tmp);

        }

    }



    if (keypairs[0]) {

        qdict_put(options, "keyvalue-pairs", qstring_from_str(keypairs));

    }





done:

    if (local_err) {

        error_propagate(errp, local_err);

    }

    g_free(buf);

    g_free(keypairs);

    return;

}

static void FUNC_0(const char *VAR_0, QDict *VAR_1,

                                    Error **VAR_2)

{

    const char *VAR_3;

    char *VAR_4, *VAR_5, *VAR_6;

    char *VAR_7;

    size_t max_keypair_size;

    Error *local_err = NULL;



    if (!strstart(VAR_0, "rbd:", &VAR_3)) {

        error_setg(VAR_2, "File VAR_8 must VAR_3 with 'rbd:'");

        return;

    }



    max_keypair_size = strlen(VAR_3) + 1;

    VAR_5 = g_strdup(VAR_3);

    VAR_6 = g_malloc0(max_keypair_size);

    VAR_4 = VAR_5;



    VAR_7 = qemu_rbd_next_tok(RBD_MAX_POOL_NAME_SIZE, VAR_4,

                                  '/', "pool VAR_8", &VAR_4, &local_err);

    if (local_err) {

        goto done;

    }

    if (!VAR_4) {

        error_setg(VAR_2, "Pool VAR_8 is required");

        goto done;

    }

    qemu_rbd_unescape(VAR_7);

    qdict_put(VAR_1, "pool", qstring_from_str(VAR_7));



    if (strchr(VAR_4, '@')) {

        VAR_7 = qemu_rbd_next_tok(RBD_MAX_IMAGE_NAME_SIZE, VAR_4,

                                      '@', "object VAR_8", &VAR_4, &local_err);

        if (local_err) {

            goto done;

        }

        qemu_rbd_unescape(VAR_7);

        qdict_put(VAR_1, "image", qstring_from_str(VAR_7));



        VAR_7 = qemu_rbd_next_tok(RBD_MAX_SNAP_NAME_SIZE, VAR_4,

                                      ':', "snap VAR_8", &VAR_4, &local_err);

        if (local_err) {

            goto done;

        }

        qemu_rbd_unescape(VAR_7);

        qdict_put(VAR_1, "snapshot", qstring_from_str(VAR_7));

    } else {

        VAR_7 = qemu_rbd_next_tok(RBD_MAX_IMAGE_NAME_SIZE, VAR_4,

                                      ':', "object VAR_8", &VAR_4, &local_err);

        if (local_err) {

            goto done;

        }

        qemu_rbd_unescape(VAR_7);

        qdict_put(VAR_1, "image", qstring_from_str(VAR_7));

    }

    if (!VAR_4) {

        goto done;

    }



    VAR_7 = qemu_rbd_next_tok(RBD_MAX_CONF_NAME_SIZE, VAR_4,

                                  '\0', "configuration", &VAR_4, &local_err);

    if (local_err) {

        goto done;

    }



    VAR_4 = VAR_7;



    



    while (VAR_4) {

        char *VAR_8, *VAR_9;

        VAR_8 = qemu_rbd_next_tok(RBD_MAX_CONF_NAME_SIZE, VAR_4,

                                 '=', "conf option VAR_8", &VAR_4, &local_err);

        if (local_err) {

            break;

        }



        if (!VAR_4) {

            error_setg(VAR_2, "conf option %s has no VAR_9", VAR_8);

            break;

        }



        qemu_rbd_unescape(VAR_8);



        VAR_9 = qemu_rbd_next_tok(RBD_MAX_CONF_VAL_SIZE, VAR_4,

                                  ':', "conf option VAR_9", &VAR_4, &local_err);

        if (local_err) {

            break;

        }

        qemu_rbd_unescape(VAR_9);



        if (!strcmp(VAR_8, "conf")) {

            qdict_put(VAR_1, "conf", qstring_from_str(VAR_9));

        } else if (!strcmp(VAR_8, "id")) {

            qdict_put(VAR_1, "user" , qstring_from_str(VAR_9));

        } else {

            









            char *VAR_10 = g_malloc0(max_keypair_size);

            

            



            if (VAR_6[0]) {

                snprintf(VAR_10, max_keypair_size, ":%s=%s", VAR_8, VAR_9);

                pstrcat(VAR_6, max_keypair_size, VAR_10);

            } else {

                snprintf(VAR_6, max_keypair_size, "%s=%s", VAR_8, VAR_9);

            }

            g_free(VAR_10);

        }

    }



    if (VAR_6[0]) {

        qdict_put(VAR_1, "keyvalue-pairs", qstring_from_str(VAR_6));

    }





done:

    if (local_err) {

        error_propagate(VAR_2, local_err);

    }

    g_free(VAR_5);

    g_free(VAR_6);

    return;

}

static void FUNC_0(const char *VAR_0, QDict *VAR_1,
Error **VAR_2)
{ const char *VAR_3; char *VAR_4, *VAR_5, *VAR_6; char *VAR_7; size_t max_keypair_size; Error *local_err = NULL; if (!strstart(VAR_0, "rbd:", &VAR_3)) { error_setg(VAR_2, "File VAR_8 must VAR_3 with 'rbd:'"); return; } max_keypair_size = strlen(VAR_3) + 1; VAR_5 = g_strdup(VAR_3); VAR_6 = g_malloc0(max_keypair_size); VAR_4 = VAR_5; VAR_7 = qemu_rbd_next_tok(RBD_MAX_POOL_NAME_SIZE, VAR_4,
'/', "pool VAR_8", &VAR_4, &local_err); if (local_err) { goto done; } if (!VAR_4) { error_setg(VAR_2, "Pool VAR_8 is required"); goto done; } qemu_rbd_unescape(VAR_7); qdict_put(VAR_1, "pool", qstring_from_str(VAR_7)); if (strchr(VAR_4, '@')) { VAR_7 = qemu_rbd_next_tok(RBD_MAX_IMAGE_NAME_SIZE, VAR_4,
'@', "object VAR_8", &VAR_4, &local_err); if (local_err) { goto done; } qemu_rbd_unescape(VAR_7); qdict_put(VAR_1, "image", qstring_from_str(VAR_7)); VAR_7 = qemu_rbd_next_tok(RBD_MAX_SNAP_NAME_SIZE, VAR_4,
':', "snap VAR_8", &VAR_4, &local_err); if (local_err) { goto done; } qemu_rbd_unescape(VAR_7); qdict_put(VAR_1, "snapshot", qstring_from_str(VAR_7)); } else { VAR_7 = qemu_rbd_next_tok(RBD_MAX_IMAGE_NAME_SIZE, VAR_4,
':', "object VAR_8", &VAR_4, &local_err); if (local_err) { goto done; } qemu_rbd_unescape(VAR_7); qdict_put(VAR_1, "image", qstring_from_str(VAR_7)); } if (!VAR_4) { goto done; } VAR_7 = qemu_rbd_next_tok(RBD_MAX_CONF_NAME_SIZE, VAR_4,
'\0', "configuration", &VAR_4, &local_err); if (local_err) { goto done; } VAR_4 = VAR_7; while (VAR_4) { char *VAR_8, *VAR_9; VAR_8 = qemu_rbd_next_tok(RBD_MAX_CONF_NAME_SIZE, VAR_4,
'=', "conf option VAR_8", &VAR_4, &local_err); if (local_err) { break; } if (!VAR_4) { error_setg(VAR_2, "conf option %s has no VAR_9", VAR_8); break; } qemu_rbd_unescape(VAR_8); VAR_9 = qemu_rbd_next_tok(RBD_MAX_CONF_VAL_SIZE, VAR_4,
':', "conf option VAR_9", &VAR_4, &local_err); if (local_err) { break; } qemu_rbd_unescape(VAR_9); if (!strcmp(VAR_8, "conf")) { qdict_put(VAR_1, "conf", qstring_from_str(VAR_9)); } else if (!strcmp(VAR_8, "id")) { qdict_put(VAR_1, "user" , qstring_from_str(VAR_9)); } else { char *VAR_10 = g_malloc0(max_keypair_size); if (VAR_6[0]) { snprintf(VAR_10, max_keypair_size, ":%s=%s", VAR_8, VAR_9); pstrcat(VAR_6, max_keypair_size, VAR_10); } else { snprintf(VAR_6, max_keypair_size, "%s=%s", VAR_8, VAR_9); } g_free(VAR_10); } } if (VAR_6[0]) { qdict_put(VAR_1, "keyvalue-pairs", qstring_from_str(VAR_6)); } done:
if (local_err) { error_propagate(VAR_2, local_err); } g_free(VAR_5); g_free(VAR_6); return; }