To avoid regressions, we let callers specify whether to require a
micro version. Callers that were parsing uname() output benefit
from the defaults, whereas callers that were parsing version strings
from other sources should not change in behavior.
* src/util/util.c (virParseVersionString): Allow caller to choose
whether to fail if micro is missing.
* src/util/util.h (virParseVersionString): Update signature.
* src/esx/esx_driver.c (esxGetVersion): Update callers.
* src/lxc/lxc_driver.c (lxcVersion): Likewise.
* src/openvz/openvz_conf.c (openvzExtractVersionInfo): Likewise.
* src/uml/uml_driver.c (umlGetVersion): Likewise.
* src/vbox/vbox_MSCOMGlue.c (vboxLookupVersionInRegistry):
Likewise.
* src/vbox/vbox_tmpl.c (vboxExtractVersion): Likewise.
* src/vmware/vmware_conf.c (vmwareExtractVersion): Likewise.
* src/xenapi/xenapi_driver.c (xenapiGetVersion): Likewise.
Reported by Matthias Bolte.
---
src/esx/esx_driver.c | 2 +-
src/lxc/lxc_driver.c | 2 +-
src/openvz/openvz_conf.c | 2 +-
src/uml/uml_driver.c | 2 +-
src/util/util.c | 11 ++++++++++-
src/util/util.h | 3 ++-
src/vbox/vbox_MSCOMGlue.c | 2 +-
src/vbox/vbox_tmpl.c | 2 +-
src/vmware/vmware_conf.c | 2 +-
src/xenapi/xenapi_driver.c | 2 +-
10 files changed, 20 insertions(+), 10 deletions(-)
diff --git a/src/esx/esx_driver.c b/src/esx/esx_driver.c
index 3a140e9..a6e47a4 100644
--- a/src/esx/esx_driver.c
+++ b/src/esx/esx_driver.c
@@ -1202,7 +1202,7 @@ esxGetVersion(virConnectPtr conn, unsigned long *version)
esxPrivate *priv = conn->privateData;
if (virParseVersionString(priv->primary->service->about->version,
- version) < 0) {
+ version, false) < 0) {
ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
_("Could not parse version number from '%s'"),
priv->primary->service->about->version);
diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c
index d0f7158..7220a9b 100644
--- a/src/lxc/lxc_driver.c
+++ b/src/lxc/lxc_driver.c
@@ -2249,7 +2249,7 @@ static int lxcVersion(virConnectPtr conn ATTRIBUTE_UNUSED, unsigned
long *versio
uname(&ver);
- if (virParseVersionString(ver.release, version) < 0) {
+ if (virParseVersionString(ver.release, version, true) < 0) {
lxcError(VIR_ERR_INTERNAL_ERROR, _("Unknown release: %s"),
ver.release);
return -1;
}
diff --git a/src/openvz/openvz_conf.c b/src/openvz/openvz_conf.c
index 189279d..561cc99 100644
--- a/src/openvz/openvz_conf.c
+++ b/src/openvz/openvz_conf.c
@@ -99,7 +99,7 @@ openvzExtractVersionInfo(const char *cmdstr, int *retversion)
if ((tmp = STRSKIP(tmp, "vzctl version ")) == NULL)
goto cleanup;
- if (virParseVersionString(tmp, &version) < 0)
+ if (virParseVersionString(tmp, &version, false) < 0)
goto cleanup;
if (retversion)
diff --git a/src/uml/uml_driver.c b/src/uml/uml_driver.c
index e557fe8..a71ea21 100644
--- a/src/uml/uml_driver.c
+++ b/src/uml/uml_driver.c
@@ -1227,7 +1227,7 @@ static int umlGetVersion(virConnectPtr conn, unsigned long *version)
{
if (driver->umlVersion == 0) {
uname(&ut);
- if (virParseVersionString(ut.release, &driver->umlVersion) < 0) {
+ if (virParseVersionString(ut.release, &driver->umlVersion, true) < 0)
{
umlReportError(VIR_ERR_INTERNAL_ERROR,
_("cannot parse version %s"), ut.release);
goto cleanup;
diff --git a/src/util/util.c b/src/util/util.c
index da24859..8e12e5f 100644
--- a/src/util/util.c
+++ b/src/util/util.c
@@ -1585,6 +1585,8 @@ virParseNumber(const char **str)
* virParseVersionString:
* @str: const char pointer to the version string
* @version: unsigned long pointer to output the version number
+ * @allowMissing: true to treat 3 like 3.0.0, false to error out on
+ * missing minor or micro
*
* Parse an unsigned version number from a version string. Expecting
* 'major.minor.micro' format, ignoring an optional suffix.
@@ -1596,7 +1598,8 @@ virParseNumber(const char **str)
* Returns the 0 for success, -1 for error.
*/
int
-virParseVersionString(const char *str, unsigned long *version)
+virParseVersionString(const char *str, unsigned long *version,
+ bool allowMissing)
{
unsigned int major, minor = 0, micro = 0;
char *tmp;
@@ -1604,9 +1607,15 @@ virParseVersionString(const char *str, unsigned long *version)
if (virStrToLong_ui(str, &tmp, 10, &major) < 0)
return -1;
+ if (!allowMissing && *tmp != '.')
+ return -1;
+
if ((*tmp == '.') && virStrToLong_ui(tmp + 1, &tmp, 10,
&minor) < 0)
return -1;
+ if (!allowMissing && *tmp != '.')
+ return -1;
+
if ((*tmp == '.') && virStrToLong_ui(tmp + 1, &tmp, 10,
µ) < 0)
return -1;
diff --git a/src/util/util.h b/src/util/util.h
index 0c43f7a..1555653 100644
--- a/src/util/util.h
+++ b/src/util/util.h
@@ -168,7 +168,8 @@ int virMacAddrCompare (const char *mac1, const char *mac2);
void virSkipSpaces(const char **str);
int virParseNumber(const char **str);
-int virParseVersionString(const char *str, unsigned long *version);
+int virParseVersionString(const char *str, unsigned long *version,
+ bool allowMissing);
int virAsprintf(char **strp, const char *fmt, ...)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_FMT_PRINTF(2, 3);
int virVasprintf(char **strp, const char *fmt, va_list list)
diff --git a/src/vbox/vbox_MSCOMGlue.c b/src/vbox/vbox_MSCOMGlue.c
index 8aef266..31e14a1 100644
--- a/src/vbox/vbox_MSCOMGlue.c
+++ b/src/vbox/vbox_MSCOMGlue.c
@@ -430,7 +430,7 @@ vboxLookupVersionInRegistry(void)
}
}
- if (virParseVersionString(value, &vboxVersion) < 0) {
+ if (virParseVersionString(value, &vboxVersion, false) < 0) {
VIR_ERROR(_("Could not parse version number from '%s'"),
value);
goto cleanup;
}
diff --git a/src/vbox/vbox_tmpl.c b/src/vbox/vbox_tmpl.c
index 7fd1200..37fe248 100644
--- a/src/vbox/vbox_tmpl.c
+++ b/src/vbox/vbox_tmpl.c
@@ -929,7 +929,7 @@ static int vboxExtractVersion(vboxGlobalData *data) {
VBOX_UTF16_TO_UTF8(versionUtf16, &vboxVersion);
- if (virParseVersionString(vboxVersion, &data->version) >= 0)
+ if (virParseVersionString(vboxVersion, &data->version, false) >= 0)
ret = 0;
VBOX_UTF8_FREE(vboxVersion);
diff --git a/src/vmware/vmware_conf.c b/src/vmware/vmware_conf.c
index 4ec33ae..044784e 100644
--- a/src/vmware/vmware_conf.c
+++ b/src/vmware/vmware_conf.c
@@ -248,7 +248,7 @@ vmwareExtractVersion(struct vmware_driver *driver)
goto cleanup;
}
- if (virParseVersionString(tmp, &version) < 0) {
+ if (virParseVersionString(tmp, &version, false) < 0) {
vmwareError(VIR_ERR_INTERNAL_ERROR, "%s",
_("version parsing error"));
goto cleanup;
diff --git a/src/xenapi/xenapi_driver.c b/src/xenapi/xenapi_driver.c
index 77d17ee..0a618ab 100644
--- a/src/xenapi/xenapi_driver.c
+++ b/src/xenapi/xenapi_driver.c
@@ -302,7 +302,7 @@ xenapiGetVersion (virConnectPtr conn, unsigned long *hvVer)
}
}
if (version) {
- if (virParseVersionString(version, hvVer) < 0)
+ if (virParseVersionString(version, hvVer, false) < 0)
xenapiSessionErrorHandler(conn, VIR_ERR_INTERNAL_ERROR,
_("Couldn't parse version
info"));
else
--
1.7.4.4