From: Zbigniew Jędrzejewski-Szmek Date: Sun, 2 Oct 2016 13:51:27 +0000 (+0200) Subject: path-util: add a function to peek into a container and guess elogind version X-Git-Tag: v232.2~52 X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=commitdiff_plain;h=6a4cd88ce4bfa430a184c2f2b968aa5a21574d34;ds=sidebyside path-util: add a function to peek into a container and guess elogind version This is a bit crude and only works for new elogind versions which have libelogind-shared. --- diff --git a/src/basic/path-util.c b/src/basic/path-util.c index 123b4ce8c..369a2b2a0 100644 --- a/src/basic/path-util.c +++ b/src/basic/path-util.c @@ -822,3 +822,69 @@ bool is_device_path(const char *path) { path_startswith(path, "/sys/"); } #endif // 0 + +int systemd_installation_has_version(const char *root, unsigned minimal_version) { + const char *pattern; + int r; + + /* Try to guess if systemd installation is later than the specified version. This + * is hacky and likely to yield false negatives, particularly if the installation + * is non-standard. False positives should be relatively rare. + */ + + NULSTR_FOREACH(pattern, + /* /lib works for systems without usr-merge, and for systems with a sane + * usr-merge, where /lib is a symlink to /usr/lib. /usr/lib is necessary + * for Gentoo which does a merge without making /lib a symlink. + */ + "lib/systemd/libsystemd-shared-*.so\0" + "usr/lib/systemd/libsystemd-shared-*.so\0") { + + _cleanup_strv_free_ char **names = NULL; + _cleanup_free_ char *path = NULL; + char *c, **name; + + path = prefix_root(root, pattern); + if (!path) + return -ENOMEM; + + r = glob_extend(&names, path); + if (r == -ENOENT) + continue; + if (r < 0) + return r; + + assert_se((c = endswith(path, "*.so"))); + *c = '\0'; /* truncate the glob part */ + + STRV_FOREACH(name, names) { + /* This is most likely to run only once, hence let's not optimize anything. */ + char *t, *t2; + unsigned version; + + t = startswith(*name, path); + if (!t) + continue; + + t2 = endswith(t, ".so"); + if (!t2) + continue; + + t2[0] = '\0'; /* truncate the suffix */ + + r = safe_atou(t, &version); + if (r < 0) { + log_debug_errno(r, "Found libsystemd shared at \"%s.so\", but failed to parse version: %m", *name); + continue; + } + + log_debug("Found libsystemd shared at \"%s.so\", version %u (%s).", + *name, version, + version >= minimal_version ? "OK" : "too old"); + if (version >= minimal_version) + return true; + } + } + + return false; +} diff --git a/src/basic/path-util.h b/src/basic/path-util.h index 540a69c62..786276c01 100644 --- a/src/basic/path-util.h +++ b/src/basic/path-util.h @@ -141,3 +141,5 @@ bool hidden_or_backup_file(const char *filename) _pure_; #if 0 /// UNNEEDED by elogind bool is_device_path(const char *path); #endif // 0 + +int systemd_installation_has_version(const char *root, unsigned minimal_version);