static int nbd_receive_list(QIOChannel *ioc, char **name, Error **errp)

{

    uint64_t magic;

    uint32_t opt;

    uint32_t type;

    uint32_t len;

    uint32_t namelen;

    int error;



    *name = NULL;

    if (read_sync(ioc, &magic, sizeof(magic)) != sizeof(magic)) {

        error_setg(errp, "failed to read list option magic");

        return -1;

    }

    magic = be64_to_cpu(magic);

    if (magic != NBD_REP_MAGIC) {

        error_setg(errp, "Unexpected option list magic");

        return -1;

    }

    if (read_sync(ioc, &opt, sizeof(opt)) != sizeof(opt)) {

        error_setg(errp, "failed to read list option");

        return -1;

    }

    opt = be32_to_cpu(opt);

    if (opt != NBD_OPT_LIST) {

        error_setg(errp, "Unexpected option type %" PRIx32 " expected %x",

                   opt, NBD_OPT_LIST);

        return -1;

    }



    if (read_sync(ioc, &type, sizeof(type)) != sizeof(type)) {

        error_setg(errp, "failed to read list option type");

        return -1;

    }

    type = be32_to_cpu(type);

    error = nbd_handle_reply_err(ioc, opt, type, errp);

    if (error <= 0) {

        return error;

    }



    if (read_sync(ioc, &len, sizeof(len)) != sizeof(len)) {

        error_setg(errp, "failed to read option length");

        return -1;

    }

    len = be32_to_cpu(len);



    if (type == NBD_REP_ACK) {

        if (len != 0) {

            error_setg(errp, "length too long for option end");

            return -1;

        }

    } else if (type == NBD_REP_SERVER) {

        if (len < sizeof(namelen) || len > NBD_MAX_BUFFER_SIZE) {

            error_setg(errp, "incorrect option length");

            return -1;

        }

        if (read_sync(ioc, &namelen, sizeof(namelen)) != sizeof(namelen)) {

            error_setg(errp, "failed to read option name length");

            return -1;

        }

        namelen = be32_to_cpu(namelen);

        len -= sizeof(namelen);

        if (len < namelen) {

            error_setg(errp, "incorrect option name length");

            return -1;

        }

        if (namelen > 255) {

            error_setg(errp, "export name length too long %" PRIu32, namelen);

            return -1;

        }



        *name = g_new0(char, namelen + 1);

        if (read_sync(ioc, *name, namelen) != namelen) {

            error_setg(errp, "failed to read export name");

            g_free(*name);

            *name = NULL;

            return -1;

        }

        (*name)[namelen] = '\0';

        len -= namelen;

        if (len) {

            char *buf = g_malloc(len + 1);

            if (read_sync(ioc, buf, len) != len) {

                error_setg(errp, "failed to read export description");

                g_free(*name);

                g_free(buf);

                *name = NULL;

                return -1;

            }

            buf[len] = '\0';

            TRACE("Ignoring export description: %s", buf);

            g_free(buf);

        }

    } else {

        error_setg(errp, "Unexpected reply type %" PRIx32 " expected %x",

                   type, NBD_REP_SERVER);

        return -1;

    }

    return 1;

}

static int nbd_receive_list(QIOChannel *ioc, char **name, Error **errp)

{

    uint64_t magic;

    uint32_t opt;

    uint32_t type;

    uint32_t len;

    uint32_t namelen;

    int error;



    *name = NULL;

    if (read_sync(ioc, &magic, sizeof(magic)) != sizeof(magic)) {

        error_setg(errp, "failed to read list option magic");

        return -1;

    }

    magic = be64_to_cpu(magic);

    if (magic != NBD_REP_MAGIC) {

        error_setg(errp, "Unexpected option list magic");

        return -1;

    }

    if (read_sync(ioc, &opt, sizeof(opt)) != sizeof(opt)) {

        error_setg(errp, "failed to read list option");

        return -1;

    }

    opt = be32_to_cpu(opt);

    if (opt != NBD_OPT_LIST) {

        error_setg(errp, "Unexpected option type %" PRIx32 " expected %x",

                   opt, NBD_OPT_LIST);

        return -1;

    }



    if (read_sync(ioc, &type, sizeof(type)) != sizeof(type)) {

        error_setg(errp, "failed to read list option type");

        return -1;

    }

    type = be32_to_cpu(type);

    error = nbd_handle_reply_err(ioc, opt, type, errp);

    if (error <= 0) {

        return error;

    }



    if (read_sync(ioc, &len, sizeof(len)) != sizeof(len)) {

        error_setg(errp, "failed to read option length");

        return -1;

    }

    len = be32_to_cpu(len);



    if (type == NBD_REP_ACK) {

        if (len != 0) {

            error_setg(errp, "length too long for option end");

            return -1;

        }

    } else if (type == NBD_REP_SERVER) {

        if (len < sizeof(namelen) || len > NBD_MAX_BUFFER_SIZE) {

            error_setg(errp, "incorrect option length");

            return -1;

        }

        if (read_sync(ioc, &namelen, sizeof(namelen)) != sizeof(namelen)) {

            error_setg(errp, "failed to read option name length");

            return -1;

        }

        namelen = be32_to_cpu(namelen);

        len -= sizeof(namelen);

        if (len < namelen) {

            error_setg(errp, "incorrect option name length");

            return -1;

        }

        if (namelen > 255) {

            error_setg(errp, "export name length too long %" PRIu32, namelen);

            return -1;

        }



        *name = g_new0(char, namelen + 1);

        if (read_sync(ioc, *name, namelen) != namelen) {

            error_setg(errp, "failed to read export name");

            g_free(*name);

            *name = NULL;

            return -1;

        }

        (*name)[namelen] = '\0';

        len -= namelen;

        if (len) {

            char *buf = g_malloc(len + 1);

            if (read_sync(ioc, buf, len) != len) {

                error_setg(errp, "failed to read export description");

                g_free(*name);

                g_free(buf);

                *name = NULL;

                return -1;

            }

            buf[len] = '\0';

            TRACE("Ignoring export description: %s", buf);

            g_free(buf);

        }

    } else {

        error_setg(errp, "Unexpected reply type %" PRIx32 " expected %x",

                   type, NBD_REP_SERVER);

        return -1;

    }

    return 1;

}

static int FUNC_0(QIOChannel *VAR_0, char **VAR_1, Error **VAR_2)

{

    uint64_t magic;

    uint32_t opt;

    uint32_t type;

    uint32_t len;

    uint32_t namelen;

    int VAR_3;



    *VAR_1 = NULL;

    if (read_sync(VAR_0, &magic, sizeof(magic)) != sizeof(magic)) {

        error_setg(VAR_2, "failed to read list option magic");

        return -1;

    }

    magic = be64_to_cpu(magic);

    if (magic != NBD_REP_MAGIC) {

        error_setg(VAR_2, "Unexpected option list magic");

        return -1;

    }

    if (read_sync(VAR_0, &opt, sizeof(opt)) != sizeof(opt)) {

        error_setg(VAR_2, "failed to read list option");

        return -1;

    }

    opt = be32_to_cpu(opt);

    if (opt != NBD_OPT_LIST) {

        error_setg(VAR_2, "Unexpected option type %" PRIx32 " expected %x",

                   opt, NBD_OPT_LIST);

        return -1;

    }



    if (read_sync(VAR_0, &type, sizeof(type)) != sizeof(type)) {

        error_setg(VAR_2, "failed to read list option type");

        return -1;

    }

    type = be32_to_cpu(type);

    VAR_3 = nbd_handle_reply_err(VAR_0, opt, type, VAR_2);

    if (VAR_3 <= 0) {

        return VAR_3;

    }



    if (read_sync(VAR_0, &len, sizeof(len)) != sizeof(len)) {

        error_setg(VAR_2, "failed to read option length");

        return -1;

    }

    len = be32_to_cpu(len);



    if (type == NBD_REP_ACK) {

        if (len != 0) {

            error_setg(VAR_2, "length too long for option end");

            return -1;

        }

    } else if (type == NBD_REP_SERVER) {

        if (len < sizeof(namelen) || len > NBD_MAX_BUFFER_SIZE) {

            error_setg(VAR_2, "incorrect option length");

            return -1;

        }

        if (read_sync(VAR_0, &namelen, sizeof(namelen)) != sizeof(namelen)) {

            error_setg(VAR_2, "failed to read option VAR_1 length");

            return -1;

        }

        namelen = be32_to_cpu(namelen);

        len -= sizeof(namelen);

        if (len < namelen) {

            error_setg(VAR_2, "incorrect option VAR_1 length");

            return -1;

        }

        if (namelen > 255) {

            error_setg(VAR_2, "export VAR_1 length too long %" PRIu32, namelen);

            return -1;

        }



        *VAR_1 = g_new0(char, namelen + 1);

        if (read_sync(VAR_0, *VAR_1, namelen) != namelen) {

            error_setg(VAR_2, "failed to read export VAR_1");

            g_free(*VAR_1);

            *VAR_1 = NULL;

            return -1;

        }

        (*VAR_1)[namelen] = '\0';

        len -= namelen;

        if (len) {

            char *VAR_4 = g_malloc(len + 1);

            if (read_sync(VAR_0, VAR_4, len) != len) {

                error_setg(VAR_2, "failed to read export description");

                g_free(*VAR_1);

                g_free(VAR_4);

                *VAR_1 = NULL;

                return -1;

            }

            VAR_4[len] = '\0';

            TRACE("Ignoring export description: %s", VAR_4);

            g_free(VAR_4);

        }

    } else {

        error_setg(VAR_2, "Unexpected reply type %" PRIx32 " expected %x",

                   type, NBD_REP_SERVER);

        return -1;

    }

    return 1;

}

static int FUNC_0(QIOChannel *VAR_0, char **VAR_1, Error **VAR_2)
{ uint64_t magic; uint32_t opt; uint32_t type; uint32_t len; uint32_t namelen; int VAR_3; *VAR_1 = NULL; if (read_sync(VAR_0, &magic, sizeof(magic)) != sizeof(magic)) { error_setg(VAR_2, "failed to read list option magic"); return -1; } magic = be64_to_cpu(magic); if (magic != NBD_REP_MAGIC) { error_setg(VAR_2, "Unexpected option list magic"); return -1; } if (read_sync(VAR_0, &opt, sizeof(opt)) != sizeof(opt)) { error_setg(VAR_2, "failed to read list option"); return -1; } opt = be32_to_cpu(opt); if (opt != NBD_OPT_LIST) { error_setg(VAR_2, "Unexpected option type %" PRIx32 " expected %x",
opt, NBD_OPT_LIST); return -1; } if (read_sync(VAR_0, &type, sizeof(type)) != sizeof(type)) { error_setg(VAR_2, "failed to read list option type"); return -1; } type = be32_to_cpu(type); VAR_3 = nbd_handle_reply_err(VAR_0, opt, type, VAR_2); if (VAR_3 <= 0) { return VAR_3; } if (read_sync(VAR_0, &len, sizeof(len)) != sizeof(len)) { error_setg(VAR_2, "failed to read option length"); return -1; } len = be32_to_cpu(len); if (type == NBD_REP_ACK) { if (len != 0) { error_setg(VAR_2, "length too long for option end"); return -1; } } else if (type == NBD_REP_SERVER) { if (len < sizeof(namelen) || len > NBD_MAX_BUFFER_SIZE) { error_setg(VAR_2, "incorrect option length"); return -1; } if (read_sync(VAR_0, &namelen, sizeof(namelen)) != sizeof(namelen)) { error_setg(VAR_2, "failed to read option VAR_1 length"); return -1; } namelen = be32_to_cpu(namelen); len -= sizeof(namelen); if (len < namelen) { error_setg(VAR_2, "incorrect option VAR_1 length"); return -1; } if (namelen > 255) { error_setg(VAR_2, "export VAR_1 length too long %" PRIu32, namelen); return -1; } *VAR_1 = g_new0(char, namelen + 1); if (read_sync(VAR_0, *VAR_1, namelen) != namelen) { error_setg(VAR_2, "failed to read export VAR_1"); g_free(*VAR_1); *VAR_1 = NULL; return -1; } (*VAR_1)[namelen] = '\0'; len -= namelen; if (len) { char *VAR_4 = g_malloc(len + 1); if (read_sync(VAR_0, VAR_4, len) != len) { error_setg(VAR_2, "failed to read export description"); g_free(*VAR_1); g_free(VAR_4); *VAR_1 = NULL; return -1; } VAR_4[len] = '\0'; TRACE("Ignoring export description: %s", VAR_4); g_free(VAR_4); } } else { error_setg(VAR_2, "Unexpected reply type %" PRIx32 " expected %x",
type, NBD_REP_SERVER); return -1; } return 1; }