static int uncomment_all_params(char *data, size_t **ret) { size_t count = 0; char *tmp; size_t *params = 0; tmp = data; while (tmp && *tmp) { tmp = strchr(tmp, '\n'); if (!tmp) break; tmp++; /* Uncomment any lines starting #some_var */ if (*tmp == '#' && c_isalpha(*(tmp + 1))) { if (VIR_EXPAND_N(params, count, 1) < 0) { VIR_FREE(params); return -1; } *tmp = ' '; params[count-1] = (tmp + 1) - data; } } if (VIR_EXPAND_N(params, count, 1) < 0) { VIR_FREE(params); return -1; } params[count-1] = 0; *ret = params; return count; }
static int virStorageBackendSheepdogAddVolume(virConnectPtr conn ATTRIBUTE_UNUSED, virStoragePoolObjPtr pool, const char *diskInfo) { virStorageVolDefPtr vol = NULL; if (diskInfo == NULL) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Missing disk info when adding volume")); goto error; } if (VIR_ALLOC(vol) < 0 || VIR_STRDUP(vol->name, diskInfo) < 0) goto error; vol->type = VIR_STORAGE_VOL_NETWORK; if (virStorageBackendSheepdogRefreshVol(conn, pool, vol) < 0) goto error; if (VIR_EXPAND_N(pool->volumes.objs, pool->volumes.count, 1) < 0) goto error; pool->volumes.objs[pool->volumes.count - 1] = vol; return 0; error: virStorageVolDefFree(vol); return -1; }
/* Ensure addr fits in the address set, by expanding it if needed. * This will only grow if the flags say that we need a normal * hot-pluggable PCI slot. If we need a different type of slot, it * will fail. * * Return value: * -1 = OOM * 0 = no action performed * >0 = number of buses added */ int virDomainPCIAddressSetGrow(virDomainPCIAddressSetPtr addrs, virDevicePCIAddressPtr addr, virDomainPCIConnectFlags flags) { int add; size_t i; add = addr->bus - addrs->nbuses + 1; i = addrs->nbuses; if (add <= 0) return 0; /* auto-grow only works when we're adding plain PCI devices */ if (!(flags & VIR_PCI_CONNECT_TYPE_PCI)) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Cannot automatically add a new PCI bus for a " "device requiring a slot other than standard PCI.")); return -1; } if (VIR_EXPAND_N(addrs->buses, addrs->nbuses, add) < 0) return -1; for (; i < addrs->nbuses; i++) { /* Any time we auto-add a bus, we will want a multi-slot * bus. Currently the only type of bus we will auto-add is a * pci-bridge, which is hot-pluggable and provides standard * PCI slots. */ virDomainPCIAddressBusSetModel(&addrs->buses[i], VIR_DOMAIN_CONTROLLER_MODEL_PCI_BRIDGE); } return add; }
static int virNetServerAddClient(virNetServerPtr srv, virNetServerClientPtr client) { virObjectLock(srv); if (srv->nclients >= srv->nclients_max) { virReportError(VIR_ERR_RPC, _("Too many active clients (%zu), dropping connection from %s"), srv->nclients_max, virNetServerClientRemoteAddrString(client)); goto error; } if (virNetServerClientInit(client) < 0) goto error; if (VIR_EXPAND_N(srv->clients, srv->nclients, 1) < 0) goto error; srv->clients[srv->nclients-1] = client; virObjectRef(client); virNetServerClientSetDispatcher(client, virNetServerDispatchNewMessage, srv); virNetServerClientInitKeepAlive(client, srv->keepaliveInterval, srv->keepaliveCount); virObjectUnlock(srv); return 0; error: virObjectUnlock(srv); return -1; }
static int virLXCControllerSetupLoopDevices(virLXCControllerPtr ctrl) { size_t i; int ret = -1; for (i = 0 ; i < ctrl->def->nfss ; i++) { int fd; if (ctrl->def->fss[i]->type != VIR_DOMAIN_FS_TYPE_FILE) continue; fd = virLXCControllerSetupLoopDevice(ctrl->def->fss[i]); if (fd < 0) goto cleanup; VIR_DEBUG("Saving loop fd %d", fd); if (VIR_EXPAND_N(ctrl->loopDevFds, ctrl->nloopDevs, 1) < 0) { VIR_FORCE_CLOSE(fd); virReportOOMError(); goto cleanup; } ctrl->loopDevFds[ctrl->nloopDevs - 1] = fd; } VIR_DEBUG("Setup all loop devices"); ret = 0; cleanup: return ret; }
static int virCloseCallbacksGetOne(void *payload, const void *key, void *opaque) { struct virCloseCallbacksData *data = opaque; virDriverCloseDefPtr closeDef = payload; const char *uuidstr = key; unsigned char uuid[VIR_UUID_BUFLEN]; if (virUUIDParse(uuidstr, uuid) < 0) return 0; VIR_DEBUG("conn=%p, thisconn=%p, uuid=%s, cb=%p", closeDef->conn, data->conn, uuidstr, closeDef->cb); if (data->conn != closeDef->conn || !closeDef->cb) return 0; if (VIR_EXPAND_N(data->list->entries, data->list->nentries, 1) < 0) { data->oom = true; return 0; } memcpy(data->list->entries[data->list->nentries - 1].uuid, uuid, VIR_UUID_BUFLEN); data->list->entries[data->list->nentries - 1].callback = closeDef->cb; return 0; }
/** * virCapabilitiesHostSecModelAddBaseLabel * @secmodel: Security model to add a base label for * @type: virtualization type * @label: base label * * Returns non-zero on error. */ extern int virCapabilitiesHostSecModelAddBaseLabel(virCapsHostSecModelPtr secmodel, const char *type, const char *label) { char *t = NULL, *l = NULL; if (type == NULL || label == NULL) return -1; if (VIR_STRDUP(t, type) < 0) goto no_memory; if (VIR_STRDUP(l, label) < 0) goto no_memory; if (VIR_EXPAND_N(secmodel->labels, secmodel->nlabels, 1) < 0) goto no_memory; secmodel->labels[secmodel->nlabels - 1].type = t; secmodel->labels[secmodel->nlabels - 1].label = l; return 0; no_memory: VIR_FREE(l); VIR_FREE(t); return -1; }
int virNWFilterVarValueAddValue(virNWFilterVarValuePtr val, char *value) { char *tmp; int rc = -1; switch (val->valType) { case NWFILTER_VALUE_TYPE_SIMPLE: /* switch to array */ tmp = val->u.simple.value; if (VIR_ALLOC_N(val->u.array.values, 2) < 0) { val->u.simple.value = tmp; return -1; } val->valType = NWFILTER_VALUE_TYPE_ARRAY; val->u.array.nValues = 2; val->u.array.values[0] = tmp; val->u.array.values[1] = value; rc = 0; break; case NWFILTER_VALUE_TYPE_ARRAY: if (VIR_EXPAND_N(val->u.array.values, val->u.array.nValues, 1) < 0) return -1; val->u.array.values[val->u.array.nValues - 1] = value; rc = 0; break; case NWFILTER_VALUE_TYPE_LAST: break; } return rc; }
int qemuMonitorTestAddItem(qemuMonitorTestPtr test, const char *command_name, const char *response) { qemuMonitorTestItemPtr item; if (VIR_ALLOC(item) < 0) goto no_memory; if (!(item->command_name = strdup(command_name)) || !(item->response = strdup(response))) goto no_memory; virMutexLock(&test->lock); if (VIR_EXPAND_N(test->items, test->nitems, 1) < 0) { virMutexUnlock(&test->lock); goto no_memory; } test->items[test->nitems - 1] = item; virMutexUnlock(&test->lock); return 0; no_memory: virReportOOMError(); qemuMonitorTestItemFree(item); return -1; }
static int lxcIdmapWalkCallback(const char *name, virConfValuePtr value, void *data) { virDomainDefPtr def = data; virDomainIdMapEntryPtr idmap = NULL; char type; unsigned long start, target, count; /* LXC 3.0 uses "lxc.idmap", while legacy used "lxc.id_map" */ if (STRNEQ(name, "lxc.idmap") || !value->str) { if (!value->str || STRNEQ(name, "lxc.id_map")) return 0; } if (sscanf(value->str, "%c %lu %lu %lu", &type, &target, &start, &count) != 4) { virReportError(VIR_ERR_INTERNAL_ERROR, _("invalid %s: '%s'"), name, value->str); return -1; } if (type == 'u') { if (VIR_EXPAND_N(def->idmap.uidmap, def->idmap.nuidmap, 1) < 0) return -1; idmap = &def->idmap.uidmap[def->idmap.nuidmap - 1]; } else if (type == 'g') { if (VIR_EXPAND_N(def->idmap.gidmap, def->idmap.ngidmap, 1) < 0) return -1; idmap = &def->idmap.gidmap[def->idmap.ngidmap - 1]; } else { return -1; } idmap->start = start; idmap->target = target; idmap->count = count; return 0; }
static int virNWFilterVarCombIterAddVariable(virNWFilterVarCombIterEntryPtr cie, virNWFilterHashTablePtr hash, const virNWFilterVarAccess *varAccess) { virNWFilterVarValuePtr varValue; unsigned int maxValue = 0, minValue = 0; const char *varName = virNWFilterVarAccessGetVarName(varAccess); varValue = virHashLookup(hash->hashTable, varName); if (varValue == NULL) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Could not find value for variable '%s'"), varName); return -1; } switch (virNWFilterVarAccessGetType(varAccess)) { case VIR_NWFILTER_VAR_ACCESS_ELEMENT: maxValue = virNWFilterVarAccessGetIndex(varAccess); minValue = maxValue; break; case VIR_NWFILTER_VAR_ACCESS_ITERATOR: maxValue = virNWFilterVarValueGetCardinality(varValue) - 1; minValue = 0; break; case VIR_NWFILTER_VAR_ACCESS_LAST: return -1; } if (cie->nVarNames == 0) { cie->maxValue = maxValue; cie->minValue = minValue; cie->curValue = minValue; } else { if (cie->maxValue != maxValue) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Cardinality of list items must be " "the same for processing them in " "parallel")); return -1; } } if (VIR_EXPAND_N(cie->varNames, cie->nVarNames, 1) < 0) return -1; cie->varNames[cie->nVarNames - 1] = varName; return 0; }
static int virNetServerAddClient(virNetServerPtr srv, virNetServerClientPtr client) { virObjectLock(srv); if (srv->nclients >= srv->nclients_max) { virReportError(VIR_ERR_RPC, _("Too many active clients (%zu), dropping connection from %s"), srv->nclients_max, virNetServerClientRemoteAddrString(client)); goto error; } if (virNetServerClientInit(client) < 0) goto error; if (VIR_EXPAND_N(srv->clients, srv->nclients, 1) < 0) goto error; srv->clients[srv->nclients-1] = client; virObjectRef(client); if (virNetServerClientNeedAuth(client)) virNetServerTrackPendingAuthLocked(srv); if (srv->nclients_unauth_max && srv->nclients_unauth == srv->nclients_unauth_max) { /* Temporarily stop accepting new clients */ VIR_DEBUG("Temporarily suspending services " "due to max_anonymous_clients"); virNetServerUpdateServicesLocked(srv, false); } if (srv->nclients == srv->nclients_max) { /* Temporarily stop accepting new clients */ VIR_DEBUG("Temporarily suspending services due to max_clients"); virNetServerUpdateServicesLocked(srv, false); } virNetServerClientSetDispatcher(client, virNetServerDispatchNewMessage, srv); virNetServerClientInitKeepAlive(client, srv->keepaliveInterval, srv->keepaliveCount); virObjectUnlock(srv); return 0; error: virObjectUnlock(srv); return -1; }
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 && ((processor_type = strndup(cur, eol - cur)) == NULL)) goto no_memory; 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 no_memory; } processor = &ret->processor[ret->nprocessor - 1]; virSkipSpaces(&cur); if (eol && ((processor->processor_socket_destination = strndup (cur, eol - cur)) == NULL)) goto no_memory; if (processor_type && !(processor->processor_type = strdup(processor_type))) goto no_memory; base = cur; } VIR_FREE(processor_type); return 0; no_memory: VIR_FREE(processor_type); return -1; }
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; }
static int virLXCControllerAddConsole(virLXCControllerPtr ctrl, int hostFd) { if (VIR_EXPAND_N(ctrl->consoles, ctrl->nconsoles, 1) < 0) { virReportOOMError(); return -1; } ctrl->consoles[ctrl->nconsoles-1].hostFd = hostFd; ctrl->consoles[ctrl->nconsoles-1].hostWatch = -1; ctrl->consoles[ctrl->nconsoles-1].contFd = -1; ctrl->consoles[ctrl->nconsoles-1].contWatch = -1; ctrl->consoles[ctrl->nconsoles-1].epollFd = -1; ctrl->consoles[ctrl->nconsoles-1].epollWatch = -1; return 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; }
/** * virTypedParamsReplaceString: * @params: pointer to the array of typed parameters * @nparams: number of parameters in the @params array * @name: name of the parameter to set * @value: the value to store into the parameter * * Sets new value @value to parameter called @name with char * type. If the * parameter does not exist yet in @params, it is automatically created and * @naprams is incremented by one. Otherwise current value of the parameter * is freed on success. The function creates its own copy of @value string, * which needs to be freed using virTypedParamsFree or virTypedParamsClear. * * Returns 0 on success, -1 on error. */ int virTypedParamsReplaceString(virTypedParameterPtr *params, int *nparams, const char *name, const char *value) { char *str = NULL; char *old = NULL; size_t n = *nparams; virTypedParameterPtr param; param = virTypedParamsGet(*params, n, name); if (param) { if (param->type != VIR_TYPED_PARAM_STRING) { virReportError(VIR_ERR_INVALID_ARG, _("Parameter '%s' is not a string"), param->field); goto error; } old = param->value.s; } else { if (VIR_EXPAND_N(*params, n, 1) < 0) goto error; param = *params + n - 1; } if (VIR_STRDUP(str, value) < 0) goto error; if (virTypedParameterAssign(param, name, VIR_TYPED_PARAM_STRING, str) < 0) { param->value.s = old; VIR_FREE(str); goto error; } VIR_FREE(old); *nparams = n; return 0; error: return -1; }
int virProcessGetNamespaces(pid_t pid, size_t *nfdlist, int **fdlist) { int ret = -1; char *nsfile = NULL; size_t i = 0; const char *ns[] = { "user", "ipc", "uts", "net", "pid", "mnt" }; *nfdlist = 0; *fdlist = NULL; for (i = 0; i < ARRAY_CARDINALITY(ns); i++) { int fd; if (virAsprintf(&nsfile, "/proc/%llu/ns/%s", (unsigned long long)pid, ns[i]) < 0) goto cleanup; if ((fd = open(nsfile, O_RDONLY)) >= 0) { if (VIR_EXPAND_N(*fdlist, *nfdlist, 1) < 0) { VIR_FORCE_CLOSE(fd); goto cleanup; } (*fdlist)[(*nfdlist)-1] = fd; } VIR_FREE(nsfile); } ret = 0; cleanup: VIR_FREE(nsfile); if (ret < 0) { for (i = 0; i < *nfdlist; i++) VIR_FORCE_CLOSE((*fdlist)[i]); VIR_FREE(*fdlist); } return ret; }
static virNetSSHAuthMethodPtr virNetSSHSessionAuthMethodNew(virNetSSHSessionPtr sess) { virNetSSHAuthMethodPtr auth; if (VIR_ALLOC(auth) < 0) goto error; if (VIR_EXPAND_N(sess->auths, sess->nauths, 1) < 0) goto error; sess->auths[sess->nauths - 1] = auth; return auth; error: VIR_FREE(auth); return NULL; }
int virNetClientAddProgram(virNetClientPtr client, virNetClientProgramPtr prog) { virNetClientLock(client); if (VIR_EXPAND_N(client->programs, client->nprograms, 1) < 0) goto no_memory; client->programs[client->nprograms-1] = prog; virNetClientProgramRef(prog); virNetClientUnlock(client); return 0; no_memory: virReportOOMError(); virNetClientUnlock(client); return -1; }
static int virNetServerDispatchNewClient(virNetServerServicePtr svc ATTRIBUTE_UNUSED, virNetServerClientPtr client, void *opaque) { virNetServerPtr srv = opaque; virNetServerLock(srv); if (srv->nclients >= srv->nclients_max) { virNetError(VIR_ERR_RPC, _("Too many active clients (%zu), dropping connection from %s"), srv->nclients_max, virNetServerClientRemoteAddrString(client)); goto error; } if (virNetServerClientInit(client) < 0) goto error; if (srv->clientInitHook && srv->clientInitHook(srv, client) < 0) goto error; if (VIR_EXPAND_N(srv->clients, srv->nclients, 1) < 0) { virReportOOMError(); goto error; } srv->clients[srv->nclients-1] = client; virNetServerClientRef(client); virNetServerClientSetDispatcher(client, virNetServerDispatchNewMessage, srv); virNetServerClientInitKeepAlive(client, srv->keepaliveInterval, srv->keepaliveCount); virNetServerUnlock(srv); return 0; error: virNetServerUnlock(srv); return -1; }
int virNetClientAddStream(virNetClientPtr client, virNetClientStreamPtr st) { virNetClientLock(client); if (VIR_EXPAND_N(client->streams, client->nstreams, 1) < 0) goto no_memory; client->streams[client->nstreams-1] = st; virNetClientStreamRef(st); virNetClientUnlock(client); return 0; no_memory: virReportOOMError(); virNetClientUnlock(client); return -1; }
static int virSysinfoParseProcessor(const char *base, virSysinfoDefPtr ret) { char *tmp_base; char *manufacturer = NULL; char *procline = NULL; int result = -1; virSysinfoProcessorDefPtr processor; if (!(tmp_base=virSysinfoParseLine(base, "vendor_id", &manufacturer))) goto cleanup; /* Find processor N: line and gather the processor manufacturer, version, serial number, and family */ while ((tmp_base = strstr(tmp_base, "processor ")) && (tmp_base = virSysinfoParseLine(tmp_base, "processor ", &procline))) { if (VIR_EXPAND_N(ret->processor, ret->nprocessor, 1) < 0) { virReportOOMError(); goto cleanup; } processor = &ret->processor[ret->nprocessor - 1]; processor->processor_manufacturer = strdup(manufacturer); if (!virSysinfoParseDelimited(procline, "version", &processor->processor_version, '=', ',') || !virSysinfoParseDelimited(procline, "identification", &processor->processor_serial_number, '=', ',') || !virSysinfoParseDelimited(procline, "machine", &processor->processor_family, '=', '\n')) goto cleanup; } result = 0; cleanup: VIR_FREE(manufacturer); VIR_FREE(procline); return result; }
static int lxcAddFSDef(virDomainDefPtr def, int type, const char *src, const char *dst, bool readonly, unsigned long long usage) { virDomainFSDefPtr fsDef = NULL; if (!(fsDef = lxcCreateFSDef(type, src, dst, readonly, usage))) goto error; if (VIR_EXPAND_N(def->fss, def->nfss, 1) < 0) goto error; def->fss[def->nfss - 1] = fsDef; return 0; error: virDomainFSDefFree(fsDef); return -1; }
static int virThreadPoolExpand(virThreadPoolPtr pool, size_t gain, bool priority) { virThreadPtr *workers = priority ? &pool->prioWorkers : &pool->workers; size_t *curWorkers = priority ? &pool->nPrioWorkers : &pool->nWorkers; size_t i = 0; struct virThreadPoolWorkerData *data = NULL; if (VIR_EXPAND_N(*workers, *curWorkers, gain) < 0) return -1; for (i = 0; i < gain; i++) { if (VIR_ALLOC(data) < 0) goto error; data->pool = pool; data->cond = priority ? &pool->prioCond : &pool->cond; data->priority = priority; if (virThreadCreateFull(&(*workers)[i], false, virThreadPoolWorker, pool->jobFuncName, true, data) < 0) { VIR_FREE(data); virReportSystemError(errno, "%s", _("Failed to create thread")); goto error; } } return 0; error: *curWorkers -= gain - i; return -1; }
/* * Appends data for a reply onto the outgoing buffer */ static int qemuMonitorTestAddReponse(qemuMonitorTestPtr test, const char *response) { size_t want = strlen(response) + 2; size_t have = test->outgoingCapacity - test->outgoingLength; if (have < want) { size_t need = want - have; if (VIR_EXPAND_N(test->outgoing, test->outgoingCapacity, need) < 0) { virReportOOMError(); return -1; } } want -= 2; memcpy(test->outgoing + test->outgoingLength, response, want); memcpy(test->outgoing + test->outgoingLength + want, "\r\n", 2); test->outgoingLength += want + 2; return 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) { goto no_memory; } 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) && ((memory->memory_size = strndup(cur, eol - cur)) == NULL)) goto no_memory; } if ((cur = strstr(base, "Form Factor: ")) != NULL) { cur += 13; eol = strchr(cur, '\n'); virSkipSpacesBackwards(cur, &eol); if ((eol) && ((memory->memory_form_factor = strndup(cur, eol - cur)) == NULL)) goto no_memory; } if ((cur = strstr(base, "Locator: ")) != NULL) { cur += 9; eol = strchr(cur, '\n'); virSkipSpacesBackwards(cur, &eol); if ((eol) && ((memory->memory_locator = strndup(cur, eol - cur)) == NULL)) goto no_memory; } if ((cur = strstr(base, "Bank Locator: ")) != NULL) { cur += 14; eol = strchr(cur, '\n'); virSkipSpacesBackwards(cur, &eol); if ((eol) && ((memory->memory_bank_locator = strndup(cur, eol - cur)) == NULL)) goto no_memory; } if ((cur = strstr(base, "Type: ")) != NULL) { cur += 6; eol = strchr(cur, '\n'); virSkipSpacesBackwards(cur, &eol); if ((eol) && ((memory->memory_type = strndup(cur, eol - cur)) == NULL)) goto no_memory; } if ((cur = strstr(base, "Type Detail: ")) != NULL) { cur += 13; eol = strchr(cur, '\n'); virSkipSpacesBackwards(cur, &eol); if ((eol) && ((memory->memory_type_detail = strndup(cur, eol - cur)) == NULL)) goto no_memory; } if ((cur = strstr(base, "Speed: ")) != NULL) { cur += 7; eol = strchr(cur, '\n'); virSkipSpacesBackwards(cur, &eol); if ((eol) && ((memory->memory_speed = strndup(cur, eol - cur)) == NULL)) goto no_memory; } if ((cur = strstr(base, "Manufacturer: ")) != NULL) { cur += 14; eol = strchr(cur, '\n'); virSkipSpacesBackwards(cur, &eol); if ((eol) && ((memory->memory_manufacturer = strndup(cur, eol - cur)) == NULL)) goto no_memory; } if ((cur = strstr(base, "Serial Number: ")) != NULL) { cur += 15; eol = strchr(cur, '\n'); virSkipSpacesBackwards(cur, &eol); if ((eol) && ((memory->memory_serial_number = strndup(cur, eol - cur)) == NULL)) goto no_memory; } if ((cur = strstr(base, "Part Number: ")) != NULL) { cur += 13; eol = strchr(cur, '\n'); virSkipSpacesBackwards(cur, &eol); if ((eol) && ((memory->memory_part_number = strndup(cur, eol - cur)) == NULL)) goto no_memory; } next: base += strlen("Memory Device"); } return 0; no_memory: return -1; }
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) { goto no_memory; } processor = &ret->processor[ret->nprocessor - 1]; if ((cur = strstr(base, "Socket Designation: ")) != NULL) { cur += 20; eol = strchr(cur, '\n'); virSkipSpacesBackwards(cur, &eol); if ((eol) && ((processor->processor_socket_destination = strndup(cur, eol - cur)) == NULL)) goto no_memory; } if ((cur = strstr(base, "Type: ")) != NULL) { cur += 6; eol = strchr(cur, '\n'); virSkipSpacesBackwards(cur, &eol); if ((eol) && ((processor->processor_type = strndup(cur, eol - cur)) == NULL)) goto no_memory; } if ((cur = strstr(base, "Family: ")) != NULL) { cur += 8; eol = strchr(cur, '\n'); virSkipSpacesBackwards(cur, &eol); if ((eol) && ((processor->processor_family = strndup(cur, eol - cur)) == NULL)) goto no_memory; } if ((cur = strstr(base, "Manufacturer: ")) != NULL) { cur += 14; eol = strchr(cur, '\n'); virSkipSpacesBackwards(cur, &eol); if ((eol) && ((processor->processor_manufacturer = strndup(cur, eol - cur)) == NULL)) goto no_memory; } if ((cur = strstr(base, "Signature: ")) != NULL) { cur += 11; eol = strchr(cur, '\n'); virSkipSpacesBackwards(cur, &eol); if ((eol) && ((processor->processor_signature = strndup(cur, eol - cur)) == NULL)) goto no_memory; } if ((cur = strstr(base, "Version: ")) != NULL) { cur += 9; eol = strchr(cur, '\n'); virSkipSpacesBackwards(cur, &eol); if ((eol) && ((processor->processor_version = strndup(cur, eol - cur)) == NULL)) goto no_memory; } if ((cur = strstr(base, "External Clock: ")) != NULL) { cur += 16; eol = strchr(cur, '\n'); virSkipSpacesBackwards(cur, &eol); if ((eol) && ((processor->processor_external_clock = strndup(cur, eol - cur)) == NULL)) goto no_memory; } if ((cur = strstr(base, "Max Speed: ")) != NULL) { cur += 11; eol = strchr(cur, '\n'); virSkipSpacesBackwards(cur, &eol); if ((eol) && ((processor->processor_max_speed = strndup(cur, eol - cur)) == NULL)) goto no_memory; } if ((cur = strstr(base, "Status: ")) != NULL) { cur += 8; eol = strchr(cur, '\n'); virSkipSpacesBackwards(cur, &eol); if ((eol) && ((processor->processor_status = strndup(cur, eol - cur)) == NULL)) goto no_memory; } if ((cur = strstr(base, "Serial Number: ")) != NULL) { cur += 15; eol = strchr(cur, '\n'); virSkipSpacesBackwards(cur, &eol); if ((eol) && ((processor->processor_serial_number = strndup(cur, eol - cur)) == NULL)) goto no_memory; } if ((cur = strstr(base, "Part Number: ")) != NULL) { cur += 13; eol = strchr(cur, '\n'); virSkipSpacesBackwards(cur, &eol); if ((eol) && ((processor->processor_part_number = strndup(cur, eol - cur)) == NULL)) goto no_memory; } base += strlen("Processor Information"); } return 0; no_memory: return -1; }
/** * 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; }
static int virSysinfoParseProcessor(const char *base, virSysinfoDefPtr ret) { char *cur, *eol, *tmp_base; char *manufacturer; const char *tmp; virSysinfoProcessorDefPtr processor; if ((cur = strstr(base, "vendor_id")) != NULL) { cur = strchr(cur, ':') + 1; eol = strchr(cur, '\n'); virSkipSpacesBackwards(cur, &eol); if ((eol) && ((tmp = strndup(cur, eol - cur)) == NULL)) goto no_memory; virSkipSpaces(&tmp); manufacturer = (char *) tmp; } /* Find processor N: line and gather the processor manufacturer, version, * serial number, and family */ 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 no_memory; } processor = &ret->processor[ret->nprocessor - 1]; /* Set the processor manufacturer */ processor->processor_manufacturer = manufacturer; if ((cur = strstr(base, "version =")) != NULL) { cur += sizeof("version ="); eol = strchr(cur, ','); if ((eol) && ((processor->processor_version = strndup(cur, eol - cur)) == NULL)) goto no_memory; } if ((cur = strstr(base, "identification =")) != NULL) { cur += sizeof("identification ="); eol = strchr(cur, ','); if ((eol) && ((processor->processor_serial_number = strndup(cur, eol - cur)) == NULL)) goto no_memory; } if ((cur = strstr(base, "machine =")) != NULL) { cur += sizeof("machine ="); eol = strchr(cur, '\n'); if ((eol) && ((processor->processor_family = strndup(cur, eol - cur)) == NULL)) goto no_memory; } base = cur; } return 0; no_memory: return -1; }