diff --git a/daemon/remote.c b/daemon/remote.c index 3b8ccd99d5..b158b8b24c 100644 --- a/daemon/remote.c +++ b/daemon/remote.c @@ -44,6 +44,7 @@ #include "virnetserverservice.h" #include "virnetserver.h" #include "virfile.h" +#include "virtypedparam.h" #include "remote_protocol.h" #include "qemu_protocol.h" diff --git a/po/POTFILES.in b/po/POTFILES.in index 3e8359a5e7..ca1db70688 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -135,6 +135,7 @@ src/util/virpidfile.c src/util/virsocketaddr.c src/util/virterror.c src/util/virtime.c +src/util/virtypedparam.c src/util/xml.c src/vbox/vbox_MSCOMGlue.c src/vbox/vbox_XPCOMCGlue.c diff --git a/src/Makefile.am b/src/Makefile.am index 0a1221ac67..c459f2dbba 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -87,6 +87,7 @@ UTIL_SOURCES = \ util/virfile.c util/virfile.h \ util/virnodesuspend.c util/virnodesuspend.h \ util/virpidfile.c util/virpidfile.h \ + util/virtypedparam.c util/virtypedparam.h \ util/xml.c util/xml.h \ util/virterror.c util/virterror_internal.h \ util/virkeycode.c util/virkeycode.h \ diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index a0530b13ff..6e94b3a102 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1146,7 +1146,6 @@ virStrToLong_ull; virStrcpy; virStrncpy; virTrimSpaces; -virTypedParameterArrayClear; virVasprintf; @@ -1177,6 +1176,13 @@ virFileFdopen; virFileRewrite; +# virkeycode.h +virKeycodeSetTypeFromString; +virKeycodeSetTypeToString; +virKeycodeValueFromString; +virKeycodeValueTranslate; + + # virnetclient.h virNetClientHasPassFD; @@ -1391,12 +1397,6 @@ virSetError; virSetErrorLogPriorityFunc; virStrerror; -# virkeycode.h -virKeycodeSetTypeToString; -virKeycodeSetTypeFromString; -virKeycodeValueFromString; -virKeycodeValueTranslate; - # virtime.h virTimeFieldsNow; @@ -1411,6 +1411,12 @@ virTimeStringThen; virTimeStringThenRaw; +# virtypedparam.h +virTypedParameterArrayClear; +virTypedParameterArrayValidate; +virTypedParameterAssign; + + # xml.h virXMLChildElementCount; virXMLParseHelper; diff --git a/src/util/util.c b/src/util/util.c index fdfceaafd2..c00c2f918d 100644 --- a/src/util/util.c +++ b/src/util/util.c @@ -1,7 +1,7 @@ /* * utils.c: common, generic utility functions * - * Copyright (C) 2006-2011 Red Hat, Inc. + * Copyright (C) 2006-2012 Red Hat, Inc. * Copyright (C) 2006 Daniel P. Berrange * Copyright (C) 2006, 2007 Binary Karma * Copyright (C) 2006 Shuveb Hussain @@ -2630,17 +2630,3 @@ or other application using the libvirt API.\n\ return 0; } - -void -virTypedParameterArrayClear(virTypedParameterPtr params, int nparams) -{ - int i; - - if (!params) - return; - - for (i = 0; i < nparams; i++) { - if (params[i].type == VIR_TYPED_PARAM_STRING) - VIR_FREE(params[i].value.s); - } -} diff --git a/src/util/util.h b/src/util/util.h index a380144e53..94d92828f5 100644 --- a/src/util/util.h +++ b/src/util/util.h @@ -1,7 +1,7 @@ /* * utils.h: common, generic utility functions * - * Copyright (C) 2010-2011 Red Hat, Inc. + * Copyright (C) 2010-2012 Red Hat, Inc. * Copyright (C) 2006, 2007 Binary Karma * Copyright (C) 2006 Shuveb Hussain * @@ -258,6 +258,4 @@ int virEmitXMLWarning(int fd, const char *name, const char *cmd) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3); -void virTypedParameterArrayClear(virTypedParameterPtr params, int nparams); - #endif /* __VIR_UTIL_H__ */ diff --git a/src/util/virtypedparam.c b/src/util/virtypedparam.c new file mode 100644 index 0000000000..f71aa25a06 --- /dev/null +++ b/src/util/virtypedparam.c @@ -0,0 +1,187 @@ +/* + * virtypedparam.c: utility functions for dealing with virTypedParameters + * + * Copyright (C) 2011-2012 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include +#include "virtypedparam.h" + +#include + +#include "memory.h" +#include "util.h" +#include "virterror_internal.h" + +#define VIR_FROM_THIS VIR_FROM_NONE + +#define virUtilError(code, ...) \ + virReportErrorHelper(VIR_FROM_NONE, code, __FILE__, \ + __FUNCTION__, __LINE__, __VA_ARGS__) + +VIR_ENUM_DECL(virTypedParameter) +VIR_ENUM_IMPL(virTypedParameter, VIR_TYPED_PARAM_STRING + 1, + "unknown", + "int", + "uint", + "llong", + "ullong", + "double", + "boolean", + "string") + +void +virTypedParameterArrayClear(virTypedParameterPtr params, int nparams) +{ + int i; + + if (!params) + return; + + for (i = 0; i < nparams; i++) { + if (params[i].type == VIR_TYPED_PARAM_STRING) + VIR_FREE(params[i].value.s); + } +} + +/* Validate that PARAMS contains only recognized parameter names with + * correct types, and with no duplicates. Pass in as many name/type + * pairs as appropriate, and pass NULL to end the list of accepted + * parameters. Return 0 on success, -1 on failure with error message + * already issued. */ +int +virTypedParameterArrayValidate(virTypedParameterPtr params, int nparams, ...) +{ + va_list ap; + int ret = -1; + int i, j; + const char *name; + int type; + + va_start(ap, nparams); + + /* Yes, this is quadratic, but since we reject duplicates and + * unknowns, it is constrained by the number of var-args passed + * in, which is expected to be small enough to not be + * noticeable. */ + for (i = 0; i < nparams; i++) { + va_end(ap); + va_start(ap, nparams); + + name = va_arg(ap, const char *); + while (name) { + type = va_arg(ap, int); + if (STREQ(params[i].field, name)) { + if (params[i].type != type) { + const char *badtype; + + badtype = virTypedParameterTypeToString(params[i].type); + if (!badtype) + badtype = virTypedParameterTypeToString(0); + virUtilError(VIR_ERR_INVALID_ARG, + _("invalid type '%s' for parameter '%s', " + "expected '%s'"), + badtype, params[i].field, + virTypedParameterTypeToString(type)); + } + break; + } + name = va_arg(ap, const char *); + } + if (!name) { + virUtilError(VIR_ERR_INVALID_ARG, + _("parameter '%s' not supported"), + params[i].field); + goto cleanup; + } + for (j = 0; j < i; j++) { + if (STREQ(params[i].field, params[j].field)) { + virUtilError(VIR_ERR_INVALID_ARG, + _("parameter '%s' occurs multiple times"), + params[i].field); + goto cleanup; + } + } + } + + ret = 0; +cleanup: + va_end(ap); + return ret; + +} + +/* Assign name, type, and the appropriately typed arg to param; in the + * case of a string, the caller is assumed to have malloc'd a string, + * or can pass NULL to have this function malloc an empty string. + * Return 0 on success, -1 after an error message on failure. */ +int +virTypedParameterAssign(virTypedParameterPtr param, const char *name, + int type, ...) +{ + va_list ap; + int ret = -1; + + va_start(ap, type); + + if (virStrcpyStatic(param->field, name) == NULL) { + virUtilError(VIR_ERR_INTERNAL_ERROR, _("Field name '%s' too long"), + name); + goto cleanup; + } + param->type = type; + switch (type) + { + case VIR_TYPED_PARAM_INT: + param->value.i = va_arg(ap, int); + break; + case VIR_TYPED_PARAM_UINT: + param->value.ui = va_arg(ap, unsigned int); + break; + case VIR_TYPED_PARAM_LLONG: + param->value.l = va_arg(ap, long long int); + break; + case VIR_TYPED_PARAM_ULLONG: + param->value.ul = va_arg(ap, unsigned long long int); + break; + case VIR_TYPED_PARAM_DOUBLE: + param->value.d = va_arg(ap, double); + break; + case VIR_TYPED_PARAM_BOOLEAN: + param->value.b = !!va_arg(ap, int); + break; + case VIR_TYPED_PARAM_STRING: + param->value.s = va_arg(ap, char *); + if (!param->value.s) + param->value.s = strdup(""); + if (!param->value.s) { + virReportOOMError(); + goto cleanup; + } + break; + default: + virUtilError(VIR_ERR_INTERNAL_ERROR, + _("unexpected type %d for field %s"), type, name); + goto cleanup; + } + + ret = 0; +cleanup: + va_end(ap); + return ret; +} diff --git a/src/util/virtypedparam.h b/src/util/virtypedparam.h new file mode 100644 index 0000000000..52cbe78d1d --- /dev/null +++ b/src/util/virtypedparam.h @@ -0,0 +1,37 @@ +/* + * virtypedparam.h: managing typed parameters + * + * Copyright (C) 2011-2012 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + + +#ifndef __VIR_TYPED_PARAM_H_ +# define __VIR_TYPED_PARAM_H_ + +# include "internal.h" + +void virTypedParameterArrayClear(virTypedParameterPtr params, int nparams); + +int virTypedParameterArrayValidate(virTypedParameterPtr params, int nparams, + /* const char *name, int type ... */ ...) + ATTRIBUTE_SENTINEL; + +int virTypedParameterAssign(virTypedParameterPtr param, const char *name, + int type, /* TYPE arg */ ...); + +#endif /* __VIR_TYPED_PARAM_H */ diff --git a/tools/virsh.c b/tools/virsh.c index c511e2a6a4..032a4e08e4 100644 --- a/tools/virsh.c +++ b/tools/virsh.c @@ -62,6 +62,7 @@ #include "virnetdevbandwidth.h" #include "util/bitmap.h" #include "conf/domain_conf.h" +#include "virtypedparam.h" static char *progname;