diff --git a/src/Makefile.am b/src/Makefile.am index 21d56fc74f..5fb9e88b03 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -18,6 +18,7 @@ # old automake does not provide abs_{src,build}dir variables abs_builddir = $(shell pwd) +abs_topbuilddir = $(shell cd .. && pwd) abs_srcdir = $(shell cd $(srcdir) && pwd) # No libraries with the exception of LIBXML should be listed @@ -30,6 +31,7 @@ INCLUDES = -I../gnulib/lib \ -I$(top_srcdir)/include \ -I$(top_srcdir)/src/util \ -DIN_LIBVIRT \ + -Dabs_topbuilddir="\"$(abs_topbuilddir)\"" \ $(GETTEXT_CPPFLAGS) AM_CFLAGS = $(LIBXML_CFLAGS) \ diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 4cee2eb06d..9919ca40f9 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1222,6 +1222,7 @@ virBuildPathInternal; virDirCreate; virFileAbsPath; virFileAccessibleAs; +virFileActivateDirOverride; virFileBuildPath; virFileClose; virFileDeleteTree; @@ -1230,6 +1231,8 @@ virFileExists; virFileFclose; virFileFdopen; virFileFindMountPoint; +virFileFindResource; +virFileFindResourceFull; virFileGetMountReverseSubtree; virFileGetMountSubtree; virFileHasSuffix; diff --git a/src/util/virfile.c b/src/util/virfile.c index cffcbc1b70..4e2ff32810 100644 --- a/src/util/virfile.c +++ b/src/util/virfile.c @@ -1542,6 +1542,93 @@ virFindFileInPath(const char *file) return fullpath; } + +static bool useDirOverride; + +/** + * virFileFindResourceFull: + * @filename: libvirt distributed filename without any path + * @prefix: optional string to prepend to filename + * @suffix: optional string to append to filename + * @builddir: location of the binary in the source tree build tree + * @installdir: location of the installed binary + * @envname: environment variable used to override all dirs + * + * A helper which will return a path to @filename within + * the current build tree, if the calling binary is being + * run from the source tree. Otherwise it will return the + * path in the installed location. + * + * If @envname is non-NULL it will override all other + * directory lookup + * + * Only use this with @filename files that are part of + * the libvirt tree, not 3rd party binaries/files. + * + * Returns the resolved path (caller frees) or NULL on error + */ +char * +virFileFindResourceFull(const char *filename, + const char *prefix, + const char *suffix, + const char *builddir, + const char *installdir, + const char *envname) +{ + char *ret = NULL; + const char *envval = envname ? virGetEnvBlockSUID(envname) : NULL; + + if (!prefix) + prefix = ""; + if (!suffix) + suffix = ""; + + if (envval) { + if (virAsprintf(&ret, "%s/%s%s%s", envval, prefix, filename, suffix) < 0) + return NULL; + } else if (useDirOverride) { + if (virAsprintf(&ret, "%s/%s/%s%s%s", abs_topbuilddir, builddir, prefix, filename, suffix) < 0) + return NULL; + } else { + if (virAsprintf(&ret, "%s/%s%s%s", installdir, prefix, filename, suffix) < 0) + return NULL; + } + + VIR_DEBUG("Resolved '%s' to '%s'", filename, ret); + return ret; +} + +char * +virFileFindResource(const char *filename, + const char *builddir, + const char *installdir) +{ + return virFileFindResourceFull(filename, NULL, NULL, builddir, installdir, NULL); +} + + +/** + * virFileActivateDirOverride: + * @argv0: argv[0] of the calling program + * + * Look at @argv0 and try to detect if running from + * a build directory, by looking for a 'lt-' prefix + * on the binary name, or '/.libs/' in the path + */ +void +virFileActivateDirOverride(const char *argv0) +{ + char *file = strrchr(argv0, '/'); + if (!file || file[1] == '\0') + return; + file++; + if (STRPREFIX(file, "lt-") || + strstr(argv0, "/.libs/")) { + useDirOverride = true; + VIR_DEBUG("Activating build dir override for %s", argv0); + } +} + bool virFileIsDir(const char *path) { diff --git a/src/util/virfile.h b/src/util/virfile.h index 46ef781479..5d0d6995d2 100644 --- a/src/util/virfile.h +++ b/src/util/virfile.h @@ -160,6 +160,20 @@ int virFileIsLink(const char *linkpath) char *virFindFileInPath(const char *file); +char *virFileFindResource(const char *filename, + const char *builddir, + const char *installdir) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3); +char *virFileFindResourceFull(const char *filename, + const char *prefix, + const char *suffix, + const char *builddir, + const char *installdir, + const char *envname) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(4) ATTRIBUTE_NONNULL(5); +void virFileActivateDirOverride(const char *argv0) + ATTRIBUTE_NONNULL(1); + bool virFileIsDir (const char *file) ATTRIBUTE_NONNULL(1); bool virFileExists(const char *file) ATTRIBUTE_NONNULL(1); bool virFileIsExecutable(const char *file) ATTRIBUTE_NONNULL(1);