Exemplo n.º 1
0
static int
virSysinfoParseSystem(const char *base, virSysinfoDefPtr ret)
{
    char *eol = NULL;
    const char *cur;

    if ((cur = strstr(base, "platform")) == NULL)
        return 0;

    base = cur;
    /* Account for format 'platform    : XXXX'*/
    cur = strchr(cur, ':') + 1;
    eol = strchr(cur, '\n');
    virSkipSpaces(&cur);
    if (eol && VIR_STRNDUP(ret->system_family, cur, eol - cur) < 0)
        return -1;

    if ((cur = strstr(base, "model")) != NULL) {
        cur = strchr(cur, ':') + 1;
        eol = strchr(cur, '\n');
        virSkipSpaces(&cur);
        if (eol && VIR_STRNDUP(ret->system_serial, cur, eol - cur) < 0)
            return -1;
    }

    if ((cur = strstr(base, "machine")) != NULL) {
        cur = strchr(cur, ':') + 1;
        eol = strchr(cur, '\n');
        virSkipSpaces(&cur);
        if (eol && VIR_STRNDUP(ret->system_version, cur, eol - cur) < 0)
            return -1;
    }

    return 0;
}
Exemplo n.º 2
0
/**
 * virConfParseString:
 * @ctxt: the parsing context
 *
 * Parse one string
 *
 * Returns a pointer to the string or NULL in case of error
 */
static char *
virConfParseString(virConfParserCtxtPtr ctxt)
{
    const char *base;
    char *ret = NULL;

    if (CUR == '\'') {
        NEXT;
        base = ctxt->cur;
        while ((ctxt->cur < ctxt->end) && (CUR != '\'') && (!IS_EOL(CUR)))
            NEXT;
        if (CUR != '\'') {
            virConfError(ctxt, VIR_ERR_CONF_SYNTAX, _("unterminated string"));
            return NULL;
        }
        if (VIR_STRNDUP(ret, base, ctxt->cur - base) < 0)
            return NULL;
        NEXT;
    } else if ((ctxt->cur + 6 < ctxt->end) &&
               (STRPREFIX(ctxt->cur, "\"\"\""))) {
        /* String starts with python-style triple quotes """ */
        ctxt->cur += 3;
        base = ctxt->cur;

        /* Find the ending triple quotes */
        while ((ctxt->cur + 2 < ctxt->end) &&
               !(STRPREFIX(ctxt->cur, "\"\"\""))) {
            if (CUR == '\n')
                ctxt->line++;
            NEXT;
        }

        if (!STRPREFIX(ctxt->cur, "\"\"\"")) {
            virConfError(ctxt, VIR_ERR_CONF_SYNTAX, _("unterminated string"));
            return NULL;
        }
        if (VIR_STRNDUP(ret, base, ctxt->cur - base) < 0)
            return NULL;
        ctxt->cur += 3;
    } else if (CUR == '"') {
        NEXT;
        base = ctxt->cur;
        while ((ctxt->cur < ctxt->end) && (CUR != '"') && (!IS_EOL(CUR)))
            NEXT;
        if (CUR != '"') {
            virConfError(ctxt, VIR_ERR_CONF_SYNTAX, _("unterminated string"));
            return NULL;
        }
        if (VIR_STRNDUP(ret, base, ctxt->cur - base) < 0)
            return NULL;
        NEXT;
    }
    return ret;
}
Exemplo n.º 3
0
static int
virSysinfoParseBIOS(const char *base, virSysinfoBIOSDefPtr *bios)
{
    int ret = -1;
    const char *cur, *eol = NULL;
    virSysinfoBIOSDefPtr def;

    if ((cur = strstr(base, "BIOS Information")) == NULL)
        return 0;

    if (VIR_ALLOC(def) < 0)
        return ret;

    base = cur;
    if ((cur = strstr(base, "Vendor: ")) != NULL) {
        cur += 8;
        eol = strchr(cur, '\n');
        if (eol && VIR_STRNDUP(def->vendor, cur, eol - cur) < 0)
            goto cleanup;
    }
    if ((cur = strstr(base, "Version: ")) != NULL) {
        cur += 9;
        eol = strchr(cur, '\n');
        if (eol && VIR_STRNDUP(def->version, cur, eol - cur) < 0)
            goto cleanup;
    }
    if ((cur = strstr(base, "Release Date: ")) != NULL) {
        cur += 14;
        eol = strchr(cur, '\n');
        if (eol && VIR_STRNDUP(def->date, cur, eol - cur) < 0)
            goto cleanup;
    }
    if ((cur = strstr(base, "BIOS Revision: ")) != NULL) {
        cur += 15;
        eol = strchr(cur, '\n');
        if (eol && VIR_STRNDUP(def->release, cur, eol - cur) < 0)
            goto cleanup;
    }

    if (!def->vendor && !def->version &&
        !def->date && !def->release) {
        virSysinfoBIOSDefFree(def);
        def = NULL;
    }

    *bios = def;
    def = NULL;
    ret = 0;
 cleanup:
    virSysinfoBIOSDefFree(def);
    return ret;
}
Exemplo n.º 4
0
static int
virSysinfoParseSystem(const char *base, virSysinfoSystemDefPtr *sysdef)
{
    int ret = -1;
    char *eol = NULL;
    const char *cur;
    virSysinfoSystemDefPtr def;

    if ((cur = strstr(base, "platform")) == NULL)
        return 0;

    if (VIR_ALLOC(def) < 0)
        return ret;

    base = cur;
    /* Account for format 'platform    : XXXX'*/
    cur = strchr(cur, ':') + 1;
    eol = strchr(cur, '\n');
    virSkipSpaces(&cur);
    if (eol && VIR_STRNDUP(def->family, cur, eol - cur) < 0)
        goto cleanup;

    if ((cur = strstr(base, "model")) != NULL) {
        cur = strchr(cur, ':') + 1;
        eol = strchr(cur, '\n');
        virSkipSpaces(&cur);
        if (eol && VIR_STRNDUP(def->serial, cur, eol - cur) < 0)
            goto cleanup;
    }

    if ((cur = strstr(base, "machine")) != NULL) {
        cur = strchr(cur, ':') + 1;
        eol = strchr(cur, '\n');
        virSkipSpaces(&cur);
        if (eol && VIR_STRNDUP(def->version, cur, eol - cur) < 0)
            goto cleanup;
    }

    if (!def->manufacturer && !def->product && !def->version &&
        !def->serial && !def->uuid && !def->sku && !def->family) {
        virSysinfoSystemDefFree(def);
        def = NULL;
    }

    *sysdef = def;
    def = NULL;
    ret = 0;
 cleanup:
    virSysinfoSystemDefFree(def);
    return ret;
}
Exemplo n.º 5
0
static int
virSysinfoParseProcessor(const char *base, virSysinfoDefPtr ret)
{
    const char *cur;
    char *eol, *tmp_base;
    virSysinfoProcessorDefPtr processor;
    char *processor_type = NULL;

    if (!(tmp_base = strstr(base, "Processor")))
        return 0;

    base = tmp_base;
    eol = strchr(base, '\n');
    cur = strchr(base, ':') + 1;
    virSkipSpaces(&cur);
    if (eol && VIR_STRNDUP(processor_type, cur, eol - cur) < 0)
        goto error;
    base = cur;

    while ((tmp_base = strstr(base, "processor")) != NULL) {
        base = tmp_base;
        eol = strchr(base, '\n');
        cur = strchr(base, ':') + 1;

        if (VIR_EXPAND_N(ret->processor, ret->nprocessor, 1) < 0)
            goto error;
        processor = &ret->processor[ret->nprocessor - 1];

        virSkipSpaces(&cur);
        if (eol &&
            VIR_STRNDUP(processor->processor_socket_destination,
                        cur, eol - cur) < 0)
            goto error;

        if (processor_type &&
            VIR_STRDUP(processor->processor_type, processor_type) < 0)
            goto error;

        base = cur;
    }

    VIR_FREE(processor_type);
    return 0;

error:
    VIR_FREE(processor_type);
    return -1;
}
Exemplo n.º 6
0
static int
vmwareParsePath(const char *path, char **directory, char **filename)
{
    char *separator;

    separator = strrchr(path, '/');

    if (separator != NULL) {
        separator++;

        if (*separator == '\0') {
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           _("path '%s' doesn't reference a file"), path);
            return -1;
        }

        if (VIR_STRNDUP(*directory, path, separator - path - 1) < 0)
            goto error;
        if (VIR_STRDUP(*filename, separator) < 0) {
            VIR_FREE(*directory);
            goto error;
        }

    } else {
        if (VIR_STRDUP(*filename, path) < 0)
            goto error;
    }

    return 0;

 error:
    return -1;
}
Exemplo n.º 7
0
static int virJSONParserHandleNumber(void *ctx,
                                     const char *s,
                                     yajl_size_t l)
{
    virJSONParserPtr parser = ctx;
    char *str;
    virJSONValuePtr value;

    if (VIR_STRNDUP(str, s, l) < 0)
        return -1;
    value = virJSONValueNewNumber(str);
    VIR_FREE(str);

    VIR_DEBUG("parser=%p str=%s", parser, str);

    if (!value)
        return 0;

    if (virJSONParserInsertValue(parser, value) < 0) {
        virJSONValueFree(value);
        return 0;
    }

    return 1;
}
Exemplo n.º 8
0
/**
 * virConfParseName:
 * @ctxt: the parsing context
 *
 * Parse one name
 *
 * Returns a copy of the new string, NULL in case of error
 */
static char *
virConfParseName(virConfParserCtxtPtr ctxt)
{
    const char *base;
    char *ret;

    SKIP_BLANKS;
    base = ctxt->cur;
    /* TODO: probably need encoding support and UTF-8 parsing ! */
    if (!c_isalpha(CUR) &&
            !((ctxt->conf->flags & VIR_CONF_FLAG_VMX_FORMAT) && (CUR == '.'))) {
        virConfError(ctxt, VIR_ERR_CONF_SYNTAX, _("expecting a name"));
        return NULL;
    }
    while ((ctxt->cur < ctxt->end) &&
            (c_isalnum(CUR) || (CUR == '_') ||
             ((ctxt->conf->flags & VIR_CONF_FLAG_VMX_FORMAT) &&
              ((CUR == ':') || (CUR == '.') || (CUR == '-'))) ||
             ((ctxt->conf->flags & VIR_CONF_FLAG_LXC_FORMAT) &&
              (CUR == '.'))))
        NEXT;
    if (VIR_STRNDUP(ret, base, ctxt->cur - base) < 0)
        return NULL;
    return ret;
}
Exemplo n.º 9
0
int
virDomainCapsCPUModelsAdd(virDomainCapsCPUModelsPtr cpuModels,
                          const char *name,
                          ssize_t nameLen,
                          virDomainCapsCPUUsable usable,
                          char **blockers)
{
    char *nameCopy = NULL;
    char **blockersCopy = NULL;

    if (VIR_STRNDUP(nameCopy, name, nameLen) < 0)
        goto error;

    if (virStringListCopy(&blockersCopy, (const char **)blockers) < 0)
        goto error;

    if (virDomainCapsCPUModelsAddSteal(cpuModels, &nameCopy,
                                       usable, &blockersCopy) < 0)
        goto error;

    return 0;

 error:
    VIR_FREE(nameCopy);
    virStringListFree(blockersCopy);
    return -1;
}
Exemplo n.º 10
0
static int
virSysinfoParseProcessor(const char *base, virSysinfoDefPtr ret)
{
    const char *cur;
    char *eol, *tmp_base;
    virSysinfoProcessorDefPtr processor;

    while ((tmp_base = strstr(base, "processor")) != NULL) {
        base = tmp_base;
        eol = strchr(base, '\n');
        cur = strchr(base, ':') + 1;

        if (VIR_EXPAND_N(ret->processor, ret->nprocessor, 1) < 0) {
            return -1;
        }
        processor = &ret->processor[ret->nprocessor - 1];

        virSkipSpaces(&cur);
        if (eol && VIR_STRNDUP(processor->processor_socket_destination,
                               cur, eol - cur) < 0)
            return -1;

        if ((cur = strstr(base, "cpu")) != NULL) {
            cur = strchr(cur, ':') + 1;
            eol = strchr(cur, '\n');
            virSkipSpaces(&cur);
            if (eol && VIR_STRNDUP(processor->processor_type,
                                   cur, eol - cur) < 0)
                return -1;
        }

        if ((cur = strstr(base, "revision")) != NULL) {
            cur = strchr(cur, ':') + 1;
            eol = strchr(cur, '\n');
            virSkipSpaces(&cur);
            if (eol && VIR_STRNDUP(processor->processor_version,
                                   cur, eol - cur) < 0)
                return -1;
        }

        base = cur;
    }

    return 0;
}
Exemplo n.º 11
0
static int
bhyveParsePCISlot(const char *slotdef,
                  unsigned *pcislot,
                  unsigned *bus,
                  unsigned *function)
{
    /* slot[:function] | bus:slot:function */
    const char *curr = NULL;
    const char *next = NULL;
    unsigned values[3];
    size_t i;

    curr = slotdef;
    for (i = 0; i < 3; i++) {
       char *val = NULL;

       next = strchr(curr, ':');

       if (VIR_STRNDUP(val, curr, next? next - curr : -1) < 0)
           goto error;

       if (virStrToLong_ui(val, NULL, 10, &values[i]) < 0)
           goto error;

       VIR_FREE(val);

       if (!next)
           break;

       curr = next +1;
    }

    *bus = 0;
    *pcislot = 0;
    *function = 0;

    switch (i + 1) {
    case 2:
        /* pcislot[:function] */
        *function = values[1];
    case 1:
        *pcislot = values[0];
        break;
    case 3:
        /* bus:pcislot:function */
        *bus = values[0];
        *pcislot = values[1];
        *function = values[2];
        break;
    }

    return 0;
 error:
    return -1;
}
Exemplo n.º 12
0
static int
virSysinfoParseSystem(const char *base, virSysinfoDefPtr ret)
{
    const char *cur, *eol = NULL;

    if ((cur = strstr(base, "System Information")) == NULL)
        return 0;

    base = cur;
    if ((cur = strstr(base, "Manufacturer: ")) != NULL) {
        cur += 14;
        eol = strchr(cur, '\n');
        if (eol && VIR_STRNDUP(ret->system_manufacturer, cur, eol - cur) < 0)
            return -1;
    }
    if ((cur = strstr(base, "Product Name: ")) != NULL) {
        cur += 14;
        eol = strchr(cur, '\n');
        if (eol && VIR_STRNDUP(ret->system_product, cur, eol - cur) < 0)
            return -1;
    }
    if ((cur = strstr(base, "Version: ")) != NULL) {
        cur += 9;
        eol = strchr(cur, '\n');
        if (eol && VIR_STRNDUP(ret->system_version, cur, eol - cur) < 0)
            return -1;
    }
    if ((cur = strstr(base, "Serial Number: ")) != NULL) {
        cur += 15;
        eol = strchr(cur, '\n');
        if (eol && VIR_STRNDUP(ret->system_serial, cur, eol - cur) < 0)
            return -1;
    }
    if ((cur = strstr(base, "UUID: ")) != NULL) {
        cur += 6;
        eol = strchr(cur, '\n');
        if (eol && VIR_STRNDUP(ret->system_uuid, cur, eol - cur) < 0)
            return -1;
    }
    if ((cur = strstr(base, "SKU Number: ")) != NULL) {
        cur += 12;
        eol = strchr(cur, '\n');
        if (eol && VIR_STRNDUP(ret->system_sku, cur, eol - cur) < 0)
            return -1;
    }
    if ((cur = strstr(base, "Family: ")) != NULL) {
        cur += 8;
        eol = strchr(cur, '\n');
        if (eol && VIR_STRNDUP(ret->system_family, cur, eol - cur) < 0)
            return -1;
    }

    return 0;
}
Exemplo n.º 13
0
/**
 * sexpr_string:
 * @str:  the input string, assumed to be UTF-8
 * @len:  the length in bytes of the input
 *
 * Parse the input S-Expression and return a pointer to the result
 *
 * Returns the S-Expression pointer or NULL in case of error
 */
struct sexpr *
sexpr_string(const char *str, ssize_t len)
{
    struct sexpr *ret = sexpr_new();

    if (ret == NULL)
        return ret;
    ret->kind = SEXPR_VALUE;

    if (VIR_STRNDUP(ret->u.value, str, len) < 0)
        VIR_FREE(ret);

    return ret;
}
Exemplo n.º 14
0
static int
virSysinfoParseBIOS(const char *base, virSysinfoDefPtr ret)
{
    const char *cur, *eol = NULL;

    if ((cur = strstr(base, "BIOS Information")) == NULL)
        return 0;

    base = cur;
    if ((cur = strstr(base, "Vendor: ")) != NULL) {
        cur += 8;
        eol = strchr(cur, '\n');
        if (eol && VIR_STRNDUP(ret->bios_vendor, cur, eol - cur) < 0)
            return -1;
    }
    if ((cur = strstr(base, "Version: ")) != NULL) {
        cur += 9;
        eol = strchr(cur, '\n');
        if (eol && VIR_STRNDUP(ret->bios_version, cur, eol - cur) < 0)
            return -1;
    }
    if ((cur = strstr(base, "Release Date: ")) != NULL) {
        cur += 14;
        eol = strchr(cur, '\n');
        if (eol && VIR_STRNDUP(ret->bios_date, cur, eol - cur) < 0)
            return -1;
    }
    if ((cur = strstr(base, "BIOS Revision: ")) != NULL) {
        cur += 15;
        eol = strchr(cur, '\n');
        if (eol && VIR_STRNDUP(ret->bios_release, cur, eol - cur) < 0)
            return -1;
    }

    return 0;
}
Exemplo n.º 15
0
/**
 * virConfParseStatement:
 * @ctxt: the parsing context
 *
 * Parse one statement in the conf file
 *
 * Returns 0 in case of success and -1 in case of error
 */
static int
virConfParseStatement(virConfParserCtxtPtr ctxt)
{
    const char *base;
    char *name;
    virConfValuePtr value;
    char *comm = NULL;

    SKIP_BLANKS_AND_EOL;
    if (CUR == '#') {
        return virConfParseComment(ctxt);
    }
    name = virConfParseName(ctxt);
    if (name == NULL)
        return -1;
    SKIP_BLANKS;
    if (CUR != '=') {
        virConfError(ctxt, VIR_ERR_CONF_SYNTAX, _("expecting an assignment"));
        VIR_FREE(name);
        return -1;
    }
    NEXT;
    SKIP_BLANKS;
    value = virConfParseValue(ctxt);
    if (value == NULL) {
        VIR_FREE(name);
        return -1;
    }
    SKIP_BLANKS;
    if (CUR == '#') {
        NEXT;
        base = ctxt->cur;
        while ((ctxt->cur < ctxt->end) && (!IS_EOL(CUR))) NEXT;
        if (VIR_STRNDUP(comm, base, ctxt->cur - base) < 0) {
            VIR_FREE(name);
            virConfFreeValue(value);
            return -1;
        }
    }
    if (virConfAddEntry(ctxt->conf, name, value, comm) == NULL) {
        VIR_FREE(name);
        virConfFreeValue(value);
        VIR_FREE(comm);
        return -1;
    }
    return 0;
}
Exemplo n.º 16
0
virJSONValuePtr virJSONValueNewStringLen(const char *data, size_t length)
{
    virJSONValuePtr val;

    if (!data)
        return virJSONValueNewNull();

    if (VIR_ALLOC(val) < 0)
        return NULL;

    val->type = VIR_JSON_TYPE_STRING;
    if (VIR_STRNDUP(val->data.string, data, length) < 0) {
        VIR_FREE(val);
        return NULL;
    }

    return val;
}
Exemplo n.º 17
0
static int virJSONParserHandleMapKey(void *ctx,
                                     const unsigned char *stringVal,
                                     yajl_size_t stringLen)
{
    virJSONParserPtr parser = ctx;
    virJSONParserStatePtr state;

    VIR_DEBUG("parser=%p key=%p", parser, (const char *)stringVal);

    if (!parser->nstate)
        return 0;

    state = &parser->state[parser->nstate-1];
    if (state->key)
        return 0;
    if (VIR_STRNDUP(state->key, (const char *)stringVal, stringLen) < 0)
        return 0;
    return 1;
}
Exemplo n.º 18
0
/**
 * virConfParseComment:
 * @ctxt: the parsing context
 *
 * Parse one standalone comment in the configuration file
 *
 * Returns 0 in case of success and -1 in case of error
 */
static int
virConfParseComment(virConfParserCtxtPtr ctxt)
{
    const char *base;
    char *comm;

    if (CUR != '#')
        return -1;
    NEXT;
    base = ctxt->cur;
    while ((ctxt->cur < ctxt->end) && (!IS_EOL(CUR))) NEXT;
    if (VIR_STRNDUP(comm, base, ctxt->cur - base) < 0)
        return -1;
    if (virConfAddEntry(ctxt->conf, NULL, NULL, comm) == NULL) {
        VIR_FREE(comm);
        return -1;
    }
    return 0;
}
Exemplo n.º 19
0
static char *
virSysinfoParseDelimited(const char *base, const char *name, char **value,
                         char delim1, char delim2)
{
    const char *start;
    char *end;

    if (delim1 != delim2 &&
        (start = strstr(base, name)) &&
        (start = strchr(start, delim1))) {
        start += 1;
        end = strchrnul(start, delim2);
        virSkipSpaces(&start);
        if (VIR_STRNDUP(*value, start, end - start) < 0)
            return NULL;
        virTrimSpaces(*value, NULL);
        return end;
    }
    return NULL;
}
Exemplo n.º 20
0
int
virDomainCapsCPUModelsAdd(virDomainCapsCPUModelsPtr cpuModels,
                          const char *name,
                          ssize_t nameLen,
                          virDomainCapsCPUUsable usable)
{
    char *copy = NULL;

    if (VIR_STRNDUP(copy, name, nameLen) < 0)
        goto error;

    if (virDomainCapsCPUModelsAddSteal(cpuModels, &copy, usable) < 0)
        goto error;

    return 0;

 error:
    VIR_FREE(copy);
    return -1;
}
Exemplo n.º 21
0
static int
virSysinfoParseMemory(const char *base, virSysinfoDefPtr ret)
{
    const char *cur, *tmp_base;
    char *eol;
    virSysinfoMemoryDefPtr memory;

    while ((tmp_base = strstr(base, "Memory Device")) != NULL) {
        base = tmp_base;
        eol = NULL;

        if (VIR_EXPAND_N(ret->memory, ret->nmemory, 1) < 0)
            return -1;
        memory = &ret->memory[ret->nmemory - 1];

        if ((cur = strstr(base, "Size: ")) != NULL) {
            cur += 6;
            eol = strchr(cur, '\n');
            if (STREQLEN(cur, "No Module Installed", eol - cur))
                goto next;

            virSkipSpacesBackwards(cur, &eol);
            if (eol && VIR_STRNDUP(memory->memory_size, cur, eol - cur) < 0)
                return -1;
        }
        if ((cur = strstr(base, "Form Factor: ")) != NULL) {
            cur += 13;
            eol = strchr(cur, '\n');
            virSkipSpacesBackwards(cur, &eol);
            if (eol && VIR_STRNDUP(memory->memory_form_factor,
                                   cur, eol - cur) < 0)
                return -1;
        }
        if ((cur = strstr(base, "Locator: ")) != NULL) {
            cur += 9;
            eol = strchr(cur, '\n');
            virSkipSpacesBackwards(cur, &eol);
            if (eol && VIR_STRNDUP(memory->memory_locator, cur, eol - cur) < 0)
                return -1;
        }
        if ((cur = strstr(base, "Bank Locator: ")) != NULL) {
            cur += 14;
            eol = strchr(cur, '\n');
            virSkipSpacesBackwards(cur, &eol);
            if (eol && VIR_STRNDUP(memory->memory_bank_locator,
                                   cur, eol - cur) < 0)
                return -1;
        }
        if ((cur = strstr(base, "Type: ")) != NULL) {
            cur += 6;
            eol = strchr(cur, '\n');
            virSkipSpacesBackwards(cur, &eol);
            if (eol && VIR_STRNDUP(memory->memory_type, cur, eol - cur) < 0)
                return -1;
        }
        if ((cur = strstr(base, "Type Detail: ")) != NULL) {
            cur += 13;
            eol = strchr(cur, '\n');
            virSkipSpacesBackwards(cur, &eol);
            if (eol && VIR_STRNDUP(memory->memory_type_detail, cur, eol - cur) < 0)
                return -1;
        }
        if ((cur = strstr(base, "Speed: ")) != NULL) {
            cur += 7;
            eol = strchr(cur, '\n');
            virSkipSpacesBackwards(cur, &eol);
            if (eol && VIR_STRNDUP(memory->memory_speed, cur, eol - cur) < 0)
                return -1;
        }
        if ((cur = strstr(base, "Manufacturer: ")) != NULL) {
            cur += 14;
            eol = strchr(cur, '\n');
            virSkipSpacesBackwards(cur, &eol);
            if (eol && VIR_STRNDUP(memory->memory_manufacturer, cur, eol - cur) < 0)
                return -1;
        }
        if ((cur = strstr(base, "Serial Number: ")) != NULL) {
            cur += 15;
            eol = strchr(cur, '\n');
            virSkipSpacesBackwards(cur, &eol);
            if (eol && VIR_STRNDUP(memory->memory_serial_number,
                                   cur, eol - cur) < 0)
                return -1;
        }
        if ((cur = strstr(base, "Part Number: ")) != NULL) {
            cur += 13;
            eol = strchr(cur, '\n');
            virSkipSpacesBackwards(cur, &eol);
            if (eol && VIR_STRNDUP(memory->memory_part_number, cur, eol - cur) < 0)
                return -1;
        }

    next:
        base += strlen("Memory Device");
    }

    return 0;
}
Exemplo n.º 22
0
static int
virSysinfoParseProcessor(const char *base, virSysinfoDefPtr ret)
{
    const char *cur, *tmp_base;
    char *eol;
    virSysinfoProcessorDefPtr processor;

    while ((tmp_base = strstr(base, "Processor Information")) != NULL) {
        base = tmp_base;
        eol = NULL;

        if (VIR_EXPAND_N(ret->processor, ret->nprocessor, 1) < 0)
            return -1;
        processor = &ret->processor[ret->nprocessor - 1];

        if ((cur = strstr(base, "Socket Designation: ")) != NULL) {
            cur += 20;
            eol = strchr(cur, '\n');
            virSkipSpacesBackwards(cur, &eol);
            if (eol && VIR_STRNDUP(processor->processor_socket_destination,
                                   cur, eol - cur) < 0)
                return -1;
        }
        if ((cur = strstr(base, "Type: ")) != NULL) {
            cur += 6;
            eol = strchr(cur, '\n');
            virSkipSpacesBackwards(cur, &eol);
            if (eol && VIR_STRNDUP(processor->processor_type, cur, eol - cur) < 0)
                return -1;
        }
        if ((cur = strstr(base, "Family: ")) != NULL) {
            cur += 8;
            eol = strchr(cur, '\n');
            virSkipSpacesBackwards(cur, &eol);
            if (eol && VIR_STRNDUP(processor->processor_family, cur, eol - cur) < 0)
                return -1;
        }
        if ((cur = strstr(base, "Manufacturer: ")) != NULL) {
            cur += 14;
            eol = strchr(cur, '\n');
            virSkipSpacesBackwards(cur, &eol);
            if (eol && VIR_STRNDUP(processor->processor_manufacturer,
                                   cur, eol - cur) < 0)
                return -1;
        }
        if ((cur = strstr(base, "Signature: ")) != NULL) {
            cur += 11;
            eol = strchr(cur, '\n');
            virSkipSpacesBackwards(cur, &eol);
            if (eol && VIR_STRNDUP(processor->processor_signature,
                                   cur, eol - cur) < 0)
                return -1;
        }
        if ((cur = strstr(base, "Version: ")) != NULL) {
            cur += 9;
            eol = strchr(cur, '\n');
            virSkipSpacesBackwards(cur, &eol);
            if (eol && VIR_STRNDUP(processor->processor_version,
                                   cur, eol - cur) < 0)
                return -1;
        }
        if ((cur = strstr(base, "External Clock: ")) != NULL) {
            cur += 16;
            eol = strchr(cur, '\n');
            virSkipSpacesBackwards(cur, &eol);
            if (eol && VIR_STRNDUP(processor->processor_external_clock,
                                   cur, eol - cur) < 0)
                return -1;
        }
        if ((cur = strstr(base, "Max Speed: ")) != NULL) {
            cur += 11;
            eol = strchr(cur, '\n');
            virSkipSpacesBackwards(cur, &eol);
            if (eol && VIR_STRNDUP(processor->processor_max_speed,
                                   cur, eol - cur) < 0)
                return -1;
        }
        if ((cur = strstr(base, "Status: ")) != NULL) {
            cur += 8;
            eol = strchr(cur, '\n');
            virSkipSpacesBackwards(cur, &eol);
            if (eol && VIR_STRNDUP(processor->processor_status, cur, eol - cur) < 0)
                return -1;
        }
        if ((cur = strstr(base, "Serial Number: ")) != NULL) {
            cur += 15;
            eol = strchr(cur, '\n');
            virSkipSpacesBackwards(cur, &eol);
            if (eol && VIR_STRNDUP(processor->processor_serial_number,
                                   cur, eol - cur) < 0)
                return -1;
        }
        if ((cur = strstr(base, "Part Number: ")) != NULL) {
            cur += 13;
            eol = strchr(cur, '\n');
            virSkipSpacesBackwards(cur, &eol);
            if (eol && VIR_STRNDUP(processor->processor_part_number,
                                   cur, eol - cur) < 0)
                return -1;
        }

        base += strlen("Processor Information");
    }

    return 0;
}
Exemplo n.º 23
0
static int
bhyveParseBhyvePCIArg(virDomainDefPtr def,
                      virDomainXMLOptionPtr xmlopt,
                      unsigned caps,
                      unsigned *nvirtiodisk,
                      unsigned *nahcidisk,
                      const char *arg)
{
    /* -s slot,emulation[,conf] */
    const char *separator = NULL;
    char *slotdef = NULL;
    char *emulation = NULL;
    char *conf = NULL;
    unsigned pcislot, bus, function;

    separator = strchr(arg, ',');

    if (!separator)
        goto error;
    else
        separator++; /* Skip comma */

    if (VIR_STRNDUP(slotdef, arg, separator - arg - 1) < 0)
        goto error;

    conf = strchr(separator+1, ',');
    if (conf)
        conf++; /* Skip initial comma */

    if (VIR_STRNDUP(emulation, separator, conf? conf - separator - 1 : -1) < 0)
        goto error;

    if (bhyveParsePCISlot(slotdef, &pcislot, &bus, &function) < 0)
        goto error;

    if (STREQ(emulation, "ahci-cd"))
        bhyveParsePCIDisk(def, caps, pcislot, bus, function,
                          VIR_DOMAIN_DISK_BUS_SATA,
                          VIR_DOMAIN_DISK_DEVICE_CDROM,
                          nvirtiodisk,
                          nahcidisk,
                          conf);
    else if (STREQ(emulation, "ahci-hd"))
        bhyveParsePCIDisk(def, caps, pcislot, bus, function,
                          VIR_DOMAIN_DISK_BUS_SATA,
                          VIR_DOMAIN_DISK_DEVICE_DISK,
                          nvirtiodisk,
                          nahcidisk,
                          conf);
    else if (STREQ(emulation, "virtio-blk"))
        bhyveParsePCIDisk(def, caps, pcislot, bus, function,
                          VIR_DOMAIN_DISK_BUS_VIRTIO,
                          VIR_DOMAIN_DISK_DEVICE_DISK,
                          nvirtiodisk,
                          nahcidisk,
                          conf);
    else if (STREQ(emulation, "virtio-net"))
        bhyveParsePCINet(def, xmlopt, caps, pcislot, bus, function, conf);

    VIR_FREE(emulation);
    VIR_FREE(slotdef);
    return 0;
 error:
    VIR_FREE(emulation);
    VIR_FREE(slotdef);
    return -1;
}
Exemplo n.º 24
0
static int
virStorageBackendIQNFound(const char *initiatoriqn,
                          char **ifacename)
{
    int ret = IQN_MISSING, fd = -1;
    char ebuf[64];
    FILE *fp = NULL;
    char *line = NULL, *newline = NULL, *iqn = NULL, *token = NULL;
    virCommandPtr cmd = virCommandNewArgList(ISCSIADM,
                                             "--mode", "iface", NULL);

    if (VIR_ALLOC_N(line, LINE_SIZE) != 0) {
        ret = IQN_ERROR;
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("Could not allocate memory for output of '%s'"),
                       ISCSIADM);
        goto out;
    }

    memset(line, 0, LINE_SIZE);

    virCommandSetOutputFD(cmd, &fd);
    if (virCommandRunAsync(cmd, NULL) < 0) {
        ret = IQN_ERROR;
        goto out;
    }

    if ((fp = VIR_FDOPEN(fd, "r")) == NULL) {
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("Failed to open stream for file descriptor "
                         "when reading output from '%s': '%s'"),
                       ISCSIADM, virStrerror(errno, ebuf, sizeof(ebuf)));
        ret = IQN_ERROR;
        goto out;
    }

    while (fgets(line, LINE_SIZE, fp) != NULL) {
        newline = strrchr(line, '\n');
        if (newline == NULL) {
            ret = IQN_ERROR;
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           _("Unexpected line > %d characters "
                             "when parsing output of '%s'"),
                           LINE_SIZE, ISCSIADM);
            goto out;
        }
        *newline = '\0';

        iqn = strrchr(line, ',');
        if (iqn == NULL)
            continue;
        iqn++;

        if (STREQ(iqn, initiatoriqn)) {
            token = strchr(line, ' ');
            if (!token) {
                ret = IQN_ERROR;
                virReportError(VIR_ERR_INTERNAL_ERROR,
                               _("Missing space when parsing output "
                                 "of '%s'"), ISCSIADM);
                goto out;
            }
            if (VIR_STRNDUP(*ifacename, line, token - line) < 0) {
                ret = IQN_ERROR;
                goto out;
            }
            VIR_DEBUG("Found interface '%s' with IQN '%s'", *ifacename, iqn);
            ret = IQN_FOUND;
            break;
        }
    }

    if (virCommandWait(cmd, NULL) < 0)
        ret = IQN_ERROR;

 out:
    if (ret == IQN_MISSING)
        VIR_DEBUG("Could not find interface with IQN '%s'", iqn);

    VIR_FREE(line);
    VIR_FORCE_FCLOSE(fp);
    VIR_FORCE_CLOSE(fd);
    virCommandFree(cmd);

    return ret;
}
Exemplo n.º 25
0
/**
 * virStringSearch:
 * @str: string to search
 * @regexp: POSIX Extended regular expression pattern used for matching
 * @max_matches: maximum number of substrings to return
 * @result: pointer to an array to be filled with NULL terminated list of matches
 *
 * Performs a POSIX extended regex search against a string and return all matching substrings.
 * The @result value should be freed with virStringListFree() when no longer
 * required.
 *
 * @code
 *  char *source = "6853a496-1c10-472e-867a-8244937bd6f0
 *                  773ab075-4cd7-4fc2-8b6e-21c84e9cb391
 *                  bbb3c75c-d60f-43b0-b802-fd56b84a4222
 *                  60c04aa1-0375-4654-8d9f-e149d9885273
 *                  4548d465-9891-4c34-a184-3b1c34a26aa8";
 *  char **matches = NULL;
 *  virStringSearch(source,
 *                  "([a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12})",
 *                  3,
 *                  &matches);
 *
 *  // matches[0] == "6853a496-1c10-472e-867a-8244937bd6f0";
 *  // matches[1] == "773ab075-4cd7-4fc2-8b6e-21c84e9cb391";
 *  // matches[2] == "bbb3c75c-d60f-43b0-b802-fd56b84a4222"
 *  // matches[3] == NULL;
 *
 *  virStringListFree(matches);
 * @endcode
 *
 * Returns: -1 on error, or number of matches
 */
ssize_t
virStringSearch(const char *str,
                const char *regexp,
                size_t max_matches,
                char ***matches)
{
    regex_t re;
    regmatch_t rem;
    size_t nmatches = 0;
    ssize_t ret = -1;
    int rv = -1;

    *matches = NULL;

    VIR_DEBUG("search '%s' for '%s'", str, regexp);

    if ((rv = regcomp(&re, regexp, REG_EXTENDED)) != 0) {
        char error[100];
        regerror(rv, &re, error, sizeof(error));
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("Error while compiling regular expression '%s': %s"),
                       regexp, error);
        return -1;
    }

    if (re.re_nsub != 1) {
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("Regular expression '%s' must have exactly 1 match group, not %zu"),
                       regexp, re.re_nsub);
        goto cleanup;
    }

    /* '*matches' must always be NULL terminated in every iteration
     * of the loop, so start by allocating 1 element
     */
    if (VIR_EXPAND_N(*matches, nmatches, 1) < 0)
        goto cleanup;

    while ((nmatches - 1) < max_matches) {
        char *match;

        if (regexec(&re, str, 1, &rem, 0) != 0)
            break;

        if (VIR_EXPAND_N(*matches, nmatches, 1) < 0)
            goto cleanup;

        if (VIR_STRNDUP(match, str + rem.rm_so,
                        rem.rm_eo - rem.rm_so) < 0)
            goto cleanup;

        VIR_DEBUG("Got '%s'", match);

        (*matches)[nmatches-2] = match;

        str = str + rem.rm_eo;
    }

    ret = nmatches - 1; /* don't count the trailing null */

 cleanup:
    regfree(&re);
    if (ret < 0) {
        virStringListFree(*matches);
        *matches = NULL;
    }
    return ret;
}
Exemplo n.º 26
0
static int
bhyveParsePCIDisk(virDomainDefPtr def,
                  unsigned caps ATTRIBUTE_UNUSED,
                  unsigned pcislot,
                  unsigned pcibus,
                  unsigned function,
                  int bus,
                  int device,
                  unsigned *nvirtiodisk,
                  unsigned *nahcidisk,
                  char *config)
{
    /* -s slot,virtio-blk|ahci-cd|ahci-hd,/path/to/file */
    const char *separator = NULL;
    int idx = -1;
    virDomainDiskDefPtr disk = NULL;

    if (VIR_ALLOC(disk) < 0)
        goto cleanup;
    if (VIR_ALLOC(disk->src) < 0)
        goto error;

    disk->bus = bus;
    disk->device = device;

    disk->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI;
    disk->info.addr.pci.slot = pcislot;
    disk->info.addr.pci.bus = pcibus;
    disk->info.addr.pci.function = function;

    if (STRPREFIX(config, "/dev/"))
        disk->src->type = VIR_STORAGE_TYPE_BLOCK;
    else
        disk->src->type = VIR_STORAGE_TYPE_FILE;

    if (!config)
        goto error;

    separator = strchr(config, ',');
    if (VIR_STRNDUP(disk->src->path, config,
                    separator? separator - config : -1) < 0)
        goto error;

    if (bus == VIR_DOMAIN_DISK_BUS_VIRTIO) {
        idx = *nvirtiodisk;
        *nvirtiodisk += 1;
        if (VIR_STRDUP(disk->dst, "vda") < 0)
            goto error;
    } else if (bus == VIR_DOMAIN_DISK_BUS_SATA) {
        idx = *nahcidisk;
        *nahcidisk += 1;
        if (VIR_STRDUP(disk->dst, "sda") < 0)
            goto error;
    }

    if (idx > 'z' - 'a') {
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                       _("too many disks"));
        goto error;
    }

    disk->dst[2] = 'a' + idx;

    if (VIR_APPEND_ELEMENT(def->disks, def->ndisks, disk) < 0)
        goto error;

 cleanup:
    return 0;

 error:
    virDomainDiskDefFree(disk);
    return -1;
}
Exemplo n.º 27
0
static int
bhyveParsePCINet(virDomainDefPtr def,
                 virDomainXMLOptionPtr xmlopt,
                 unsigned caps ATTRIBUTE_UNUSED,
                 unsigned pcislot,
                 unsigned pcibus,
                 unsigned function,
                 const char *config)
{
    /* -s slot,virtio-net,tapN[,mac=xx:xx:xx:xx:xx:xx] */

    virDomainNetDefPtr net = NULL;
    const char *separator = NULL;
    const char *mac = NULL;

    if (VIR_ALLOC(net) < 0)
        goto cleanup;

    /* Let's just assume it is VIR_DOMAIN_NET_TYPE_ETHERNET, it could also be
     * a bridge, but this is the most generic option. */
    net->type = VIR_DOMAIN_NET_TYPE_ETHERNET;

    net->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI;
    net->info.addr.pci.slot = pcislot;
    net->info.addr.pci.bus = pcibus;
    net->info.addr.pci.function = function;

    if (!config)
        goto error;

    if (!STRPREFIX(config, "tap")) {
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                       _("Only tap devices supported"));
        goto error;
    }

    separator = strchr(config, ',');
    if (VIR_STRNDUP(net->ifname, config,
                    separator? separator - config : -1) < 0)
        goto error;

    if (!separator)
        goto cleanup;

    if (!STRPREFIX(++separator, "mac=")) {
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                       _("Only mac option can be specified for virt-net"));
        goto error;
    }
    mac = separator + 4;

    if (virMacAddrParse(mac, &net->mac) < 0) {
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("unable to parse mac address '%s'"),
                       mac);
        goto cleanup;
     }

 cleanup:
    if (!mac)
        virDomainNetGenerateMAC(xmlopt, &net->mac);

    if (VIR_APPEND_ELEMENT(def->nets, def->nnets, net) < 0)
        goto error;
    return 0;

 error:
    virDomainNetDefFree(net);
    return -1;
}
Exemplo n.º 28
0
/**
 * _string2sexpr:
 * @buffer: a zero terminated buffer containing an S-Expression in UTF-8
 * @end: pointer to an index in the buffer for the already parsed bytes
 *
 * Internal routine implementing the parse of S-Expression
 * Note that failure in this function is catastrophic.  If it returns
 * NULL, you've leaked memory and you're currently OOM.  It will always
 * parse an SEXPR given a buffer
 *
 * Returns a pointer to the resulting parsed S-Expression, or NULL in case of
 *         hard error.
 */
static struct sexpr *
_string2sexpr(const char *buffer, size_t * end)
{
    const char *ptr = buffer + *end;
    struct sexpr *ret = sexpr_new();

    if (ret == NULL)
        return NULL;

    ptr = trim(ptr);

    if (ptr[0] == '(') {
        ret->kind = SEXPR_NIL;

        ptr = trim(ptr + 1);
        while (*ptr && *ptr != ')') {
            struct sexpr *tmp;
            size_t tmp_len = 0;

            tmp = _string2sexpr(ptr, &tmp_len);
            if (tmp == NULL)
                goto error;
            if (append(ret, tmp) < 0) {
                sexpr_free(tmp);
                goto error;
            }
            ptr = trim(ptr + tmp_len);
        }

        if (*ptr == ')') {
            ptr++;
        }
    } else {
        const char *start;

        if (*ptr == '\'') {
            ptr++;
            start = ptr;

            while (*ptr && *ptr != '\'') {
                if (*ptr == '\\' && ptr[1])
                    ptr++;
                ptr++;
            }

            if (VIR_STRNDUP(ret->u.value, start, ptr - start) < 0)
                goto error;

            if (*ptr == '\'')
                ptr++;
        } else {
            start = ptr;

            while (*ptr && !c_isspace(*ptr)
                   && *ptr != ')' && *ptr != '(') {
                ptr++;
            }

            if (VIR_STRNDUP(ret->u.value, start, ptr - start) < 0)
                goto error;
        }

        ret->kind = SEXPR_VALUE;
        if (ret->u.value == NULL)
            goto error;
    }

    *end = ptr - buffer;

    return ret;

  error:
    sexpr_free(ret);
    return NULL;
}
Exemplo n.º 29
0
static int
virStorageBackendLogicalMakeVol(virStoragePoolObjPtr pool,
                                char **const groups,
                                void *data)
{
    virStorageVolDefPtr vol = NULL;
    bool is_new_vol = false;
    unsigned long long offset, size, length;
    const char *regex_unit = "(\\S+)\\((\\S+)\\)";
    char *regex = NULL;
    regex_t *reg = NULL;
    regmatch_t *vars = NULL;
    char *p = NULL;
    size_t i;
    int err, nextents, nvars, ret = -1;
    const char *attrs = groups[9];

    /* Skip inactive volume */
    if (attrs[4] != 'a')
        return 0;

    /*
     * Skip thin pools(t). These show up in normal lvs output
     * but do not have a corresponding /dev/$vg/$lv device that
     * is created by udev. This breaks assumptions in later code.
     */
    if (attrs[0] == 't')
        return 0;

    /* See if we're only looking for a specific volume */
    if (data != NULL) {
        vol = data;
        if (STRNEQ(vol->name, groups[0]))
            return 0;
    }

    /* Or filling in more data on an existing volume */
    if (vol == NULL)
        vol = virStorageVolDefFindByName(pool, groups[0]);

    /* Or a completely new volume */
    if (vol == NULL) {
        if (VIR_ALLOC(vol) < 0)
            return -1;

        is_new_vol = true;
        vol->type = VIR_STORAGE_VOL_BLOCK;

        if (VIR_STRDUP(vol->name, groups[0]) < 0)
            goto cleanup;

        if (VIR_REALLOC_N(pool->volumes.objs,
                          pool->volumes.count + 1))
            goto cleanup;
    }

    if (vol->target.path == NULL) {
        if (virAsprintf(&vol->target.path, "%s/%s",
                        pool->def->target.path, vol->name) < 0)
            goto cleanup;
    }

    /* Skips the backingStore of lv created with "--virtualsize",
     * its original device "/dev/$vgname/$lvname_vorigin" is
     * just for lvm internal use, one should never use it.
     *
     * (lvs outputs "[$lvname_vorigin] for field "origin" if the
     *  lv is created with "--virtualsize").
     */
    if (groups[1] && !STREQ(groups[1], "") && (groups[1][0] != '[')) {
        if (virAsprintf(&vol->backingStore.path, "%s/%s",
                        pool->def->target.path, groups[1]) < 0)
            goto cleanup;

        vol->backingStore.format = VIR_STORAGE_POOL_LOGICAL_LVM2;
    }

    if (!vol->key && VIR_STRDUP(vol->key, groups[2]) < 0)
        goto cleanup;

    if (virStorageBackendUpdateVolInfo(vol, 1) < 0)
        goto cleanup;

    nextents = 1;
    if (STREQ(groups[4], VIR_STORAGE_VOL_LOGICAL_SEGTYPE_STRIPED)) {
        if (virStrToLong_i(groups[5], NULL, 10, &nextents) < 0) {
            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                           _("malformed volume extent stripes value"));
            goto cleanup;
        }
    }

    /* Finally fill in extents information */
    if (VIR_REALLOC_N(vol->source.extents,
                      vol->source.nextent + nextents) < 0)
        goto cleanup;

    if (virStrToLong_ull(groups[6], NULL, 10, &length) < 0) {
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       "%s", _("malformed volume extent length value"));
        goto cleanup;
    }
    if (virStrToLong_ull(groups[7], NULL, 10, &size) < 0) {
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       "%s", _("malformed volume extent size value"));
        goto cleanup;
    }
    if (virStrToLong_ull(groups[8], NULL, 10, &vol->allocation) < 0) {
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       "%s", _("malformed volume allocation value"));
        goto cleanup;
    }

    /* Now parse the "devices" field separately */
    if (VIR_STRDUP(regex, regex_unit) < 0)
        goto cleanup;

    for (i = 1; i < nextents; i++) {
        if (VIR_REALLOC_N(regex, strlen(regex) + strlen(regex_unit) + 2) < 0)
            goto cleanup;
        /* "," is the separator of "devices" field */
        strcat(regex, ",");
        strncat(regex, regex_unit, strlen(regex_unit));
    }

    if (VIR_ALLOC(reg) < 0)
        goto cleanup;

    /* Each extent has a "path:offset" pair, and vars[0] will
     * be the whole matched string.
     */
    nvars = (nextents * 2) + 1;
    if (VIR_ALLOC_N(vars, nvars) < 0)
        goto cleanup;

    err = regcomp(reg, regex, REG_EXTENDED);
    if (err != 0) {
        char error[100];
        regerror(err, reg, error, sizeof(error));
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("Failed to compile regex %s"),
                       error);
        goto cleanup;
    }

    err = regexec(reg, groups[3], nvars, vars, 0);
    regfree(reg);
    if (err != 0) {
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                       _("malformed volume extent devices value"));
        goto cleanup;
    }

    p = groups[3];

    /* vars[0] is skipped */
    for (i = 0; i < nextents; i++) {
        size_t j;
        int len;
        char *offset_str = NULL;

        j = (i * 2) + 1;
        len = vars[j].rm_eo - vars[j].rm_so;
        p[vars[j].rm_eo] = '\0';

        if (VIR_STRNDUP(vol->source.extents[vol->source.nextent].path,
                        p + vars[j].rm_so, len) < 0)
            goto cleanup;

        len = vars[j + 1].rm_eo - vars[j + 1].rm_so;
        if (VIR_STRNDUP(offset_str, p + vars[j + 1].rm_so, len) < 0)
            goto cleanup;

        if (virStrToLong_ull(offset_str, NULL, 10, &offset) < 0) {
            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                           _("malformed volume extent offset value"));
            VIR_FREE(offset_str);
            goto cleanup;
        }

        VIR_FREE(offset_str);

        vol->source.extents[vol->source.nextent].start = offset * size;
        vol->source.extents[vol->source.nextent].end = (offset * size) + length;
        vol->source.nextent++;
    }

    if (is_new_vol)
        pool->volumes.objs[pool->volumes.count++] = vol;

    ret = 0;

cleanup:
    VIR_FREE(regex);
    VIR_FREE(reg);
    VIR_FREE(vars);
    if (is_new_vol && (ret == -1))
        virStorageVolDefFree(vol);
    return ret;
}
Exemplo n.º 30
0
/**
 * virConfParseString:
 * @ctxt: the parsing context
 *
 * Parse one string
 *
 * Returns a pointer to the string or NULL in case of error
 */
static char *
virConfParseString(virConfParserCtxtPtr ctxt)
{
    const char *base;
    char *ret = NULL;

    if (CUR == '\'') {
        NEXT;
        base = ctxt->cur;
        while ((ctxt->cur < ctxt->end) && (CUR != '\'') && (!IS_EOL(CUR)))
            NEXT;
        if (CUR != '\'') {
            virConfError(ctxt, VIR_ERR_CONF_SYNTAX, _("unterminated string"));
            return NULL;
        }
        if (VIR_STRNDUP(ret, base, ctxt->cur - base) < 0)
            return NULL;
        NEXT;
    } else if ((ctxt->cur + 6 < ctxt->end) &&
               (STRPREFIX(ctxt->cur, "\"\"\""))) {
        /* String starts with python-style triple quotes """ */
        ctxt->cur += 3;
        base = ctxt->cur;

        /* Find the ending triple quotes */
        while ((ctxt->cur + 2 < ctxt->end) &&
                !(STRPREFIX(ctxt->cur, "\"\"\""))) {
            if (CUR == '\n')
                ctxt->line++;
            NEXT;
        }

        if (!STRPREFIX(ctxt->cur, "\"\"\"")) {
            virConfError(ctxt, VIR_ERR_CONF_SYNTAX, _("unterminated string"));
            return NULL;
        }
        if (VIR_STRNDUP(ret, base, ctxt->cur - base) < 0)
            return NULL;
        ctxt->cur += 3;
    } else if (CUR == '"') {
        NEXT;
        base = ctxt->cur;
        while ((ctxt->cur < ctxt->end) && (CUR != '"') && (!IS_EOL(CUR)))
            NEXT;
        if (CUR != '"') {
            virConfError(ctxt, VIR_ERR_CONF_SYNTAX, _("unterminated string"));
            return NULL;
        }
        if (VIR_STRNDUP(ret, base, ctxt->cur - base) < 0)
            return NULL;
        NEXT;
    } else if (ctxt->conf->flags & VIR_CONF_FLAG_LXC_FORMAT) {
        base = ctxt->cur;
        /* LXC config format doesn't support comments after the value */
        while ((ctxt->cur < ctxt->end) && (!IS_EOL(CUR)))
            NEXT;
        /* Reverse to exclude the trailing blanks from the value */
        while ((ctxt->cur > base) && (c_isblank(CUR)))
            ctxt->cur--;
        if (VIR_STRNDUP(ret, base, ctxt->cur - base) < 0)
            return NULL;
    }
    return ret;
}