+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
#include "mount-util.h"
#include "path-util.h"
#include "rm-rf.h"
+#include "stat-util.h"
#include "string-util.h"
#include "strv.h"
#include "util.h"
assert_se(!path_equal_ptr(NULL, "/a"));
}
+static void test_path_equal_root(void) {
+ /* Nail down the details of how path_equal("/", ...) works. */
+
+ assert_se(path_equal("/", "/"));
+ assert_se(path_equal("/", "//"));
+
+ assert_se(!path_equal("/", "/./"));
+ assert_se(!path_equal("/", "/../"));
+
+ assert_se(!path_equal("/", "/.../"));
+
+ /* Make sure that files_same works as expected. */
+
+ assert_se(files_same("/", "/", 0) > 0);
+ assert_se(files_same("/", "/", AT_SYMLINK_NOFOLLOW) > 0);
+ assert_se(files_same("/", "//", 0) > 0);
+ assert_se(files_same("/", "//", AT_SYMLINK_NOFOLLOW) > 0);
+
+ assert_se(files_same("/", "/./", 0) > 0);
+ assert_se(files_same("/", "/./", AT_SYMLINK_NOFOLLOW) > 0);
+ assert_se(files_same("/", "/../", 0) > 0);
+ assert_se(files_same("/", "/../", AT_SYMLINK_NOFOLLOW) > 0);
+
+ assert_se(files_same("/", "/.../", 0) == -ENOENT);
+ assert_se(files_same("/", "/.../", AT_SYMLINK_NOFOLLOW) == -ENOENT);
+
+ /* The same for path_equal_or_files_same. */
+
+ assert_se(path_equal_or_files_same("/", "/", 0));
+ assert_se(path_equal_or_files_same("/", "/", AT_SYMLINK_NOFOLLOW));
+ assert_se(path_equal_or_files_same("/", "//", 0));
+ assert_se(path_equal_or_files_same("/", "//", AT_SYMLINK_NOFOLLOW));
+
+ assert_se(path_equal_or_files_same("/", "/./", 0));
+ assert_se(path_equal_or_files_same("/", "/./", AT_SYMLINK_NOFOLLOW));
+ assert_se(path_equal_or_files_same("/", "/../", 0));
+ assert_se(path_equal_or_files_same("/", "/../", AT_SYMLINK_NOFOLLOW));
+
+ assert_se(!path_equal_or_files_same("/", "/.../", 0));
+ assert_se(!path_equal_or_files_same("/", "/.../", AT_SYMLINK_NOFOLLOW));
+}
+
static void test_find_binary(const char *self) {
char *p;
assert_se(find_binary(self, &p) == 0);
puts(p);
- assert_se(endswith(p, "/lt-test-path-util"));
+ /* libtool might prefix the binary name with "lt-" */
+ assert_se(endswith(p, "/lt-test-path-util") || endswith(p, "/test-path-util"));
assert_se(path_is_absolute(p));
free(p);
assert_se(path_make_relative("some/relative/path", "/some/path", &result) < 0);
assert_se(path_make_relative("/some/path", "some/relative/path", &result) < 0);
+ assert_se(path_make_relative("/some/dotdot/../path", "/some/path", &result) < 0);
#define test(from_dir, to_path, expected) { \
_cleanup_free_ char *z = NULL; \
test("/some/path", "/some/path/in/subdir", "in/subdir");
test("/some/path", "/", "../..");
test("/some/path", "/some/other/path", "../other/path");
+ test("/some/path/./dot", "/some/further/path", "../../further/path");
test("//extra/////slashes///won't////fool///anybody//", "////extra///slashes////are/just///fine///", "../../../are/just/fine");
}
}
static void test_path_startswith(void) {
- assert_se(path_startswith("/foo/bar/barfoo/", "/foo"));
- assert_se(path_startswith("/foo/bar/barfoo/", "/foo/"));
- assert_se(path_startswith("/foo/bar/barfoo/", "/"));
- assert_se(path_startswith("/foo/bar/barfoo/", "////"));
- assert_se(path_startswith("/foo/bar/barfoo/", "/foo//bar/////barfoo///"));
- assert_se(path_startswith("/foo/bar/barfoo/", "/foo/bar/barfoo////"));
- assert_se(path_startswith("/foo/bar/barfoo/", "/foo/bar///barfoo/"));
- assert_se(path_startswith("/foo/bar/barfoo/", "/foo////bar/barfoo/"));
- assert_se(path_startswith("/foo/bar/barfoo/", "////foo/bar/barfoo/"));
- assert_se(path_startswith("/foo/bar/barfoo/", "/foo/bar/barfoo"));
+ const char *p;
+
+ p = path_startswith("/foo/bar/barfoo/", "/foo");
+ assert_se(streq_ptr(p, "bar/barfoo/"));
+
+ p = path_startswith("/foo/bar/barfoo/", "/foo/");
+ assert_se(streq_ptr(p, "bar/barfoo/"));
+
+ p = path_startswith("/foo/bar/barfoo/", "/");
+ assert_se(streq_ptr(p, "foo/bar/barfoo/"));
+
+ p = path_startswith("/foo/bar/barfoo/", "////");
+ assert_se(streq_ptr(p, "foo/bar/barfoo/"));
+
+ p = path_startswith("/foo/bar/barfoo/", "/foo//bar/////barfoo///");
+ assert_se(streq_ptr(p, ""));
+
+ p = path_startswith("/foo/bar/barfoo/", "/foo/bar/barfoo////");
+ assert_se(streq_ptr(p, ""));
+
+ p = path_startswith("/foo/bar/barfoo/", "/foo/bar///barfoo/");
+ assert_se(streq_ptr(p, ""));
+
+ p = path_startswith("/foo/bar/barfoo/", "/foo////bar/barfoo/");
+ assert_se(streq_ptr(p, ""));
+
+ p = path_startswith("/foo/bar/barfoo/", "////foo/bar/barfoo/");
+ assert_se(streq_ptr(p, ""));
+
+ p = path_startswith("/foo/bar/barfoo/", "/foo/bar/barfoo");
+ assert_se(streq_ptr(p, ""));
assert_se(!path_startswith("/foo/bar/barfoo/", "/foo/bar/barfooa/"));
assert_se(!path_startswith("/foo/bar/barfoo/", "/foo/bar/barfooa"));
_cleanup_free_ char *dir1 = NULL, *dir1file = NULL, *dirlink1 = NULL, *dirlink1file = NULL;
_cleanup_free_ char *dir2 = NULL, *dir2file = NULL;
- assert_se(path_is_mount_point("/", AT_SYMLINK_FOLLOW) > 0);
- assert_se(path_is_mount_point("/", 0) > 0);
+ assert_se(path_is_mount_point("/", NULL, AT_SYMLINK_FOLLOW) > 0);
+ assert_se(path_is_mount_point("/", NULL, 0) > 0);
- assert_se(path_is_mount_point("/proc", AT_SYMLINK_FOLLOW) > 0);
- assert_se(path_is_mount_point("/proc", 0) > 0);
+ assert_se(path_is_mount_point("/proc", NULL, AT_SYMLINK_FOLLOW) > 0);
+ assert_se(path_is_mount_point("/proc", NULL, 0) > 0);
- assert_se(path_is_mount_point("/proc/1", AT_SYMLINK_FOLLOW) == 0);
- assert_se(path_is_mount_point("/proc/1", 0) == 0);
+ assert_se(path_is_mount_point("/proc/1", NULL, AT_SYMLINK_FOLLOW) == 0);
+ assert_se(path_is_mount_point("/proc/1", NULL, 0) == 0);
- assert_se(path_is_mount_point("/sys", AT_SYMLINK_FOLLOW) > 0);
- assert_se(path_is_mount_point("/sys", 0) > 0);
+ assert_se(path_is_mount_point("/sys", NULL, AT_SYMLINK_FOLLOW) > 0);
+ assert_se(path_is_mount_point("/sys", NULL, 0) > 0);
/* we'll create a hierarchy of different kinds of dir/file/link
* layouts:
assert_se(link1);
assert_se(symlink("file2", link2) == 0);
- assert_se(path_is_mount_point(file1, AT_SYMLINK_FOLLOW) == 0);
- assert_se(path_is_mount_point(file1, 0) == 0);
- assert_se(path_is_mount_point(link1, AT_SYMLINK_FOLLOW) == 0);
- assert_se(path_is_mount_point(link1, 0) == 0);
+ assert_se(path_is_mount_point(file1, NULL, AT_SYMLINK_FOLLOW) == 0);
+ assert_se(path_is_mount_point(file1, NULL, 0) == 0);
+ assert_se(path_is_mount_point(link1, NULL, AT_SYMLINK_FOLLOW) == 0);
+ assert_se(path_is_mount_point(link1, NULL, 0) == 0);
/* directory mountpoints */
dir1 = path_join(NULL, tmp_dir, "dir1");
assert_se(dir2);
assert_se(mkdir(dir2, 0755) == 0);
- assert_se(path_is_mount_point(dir1, AT_SYMLINK_FOLLOW) == 0);
- assert_se(path_is_mount_point(dir1, 0) == 0);
- assert_se(path_is_mount_point(dirlink1, AT_SYMLINK_FOLLOW) == 0);
- assert_se(path_is_mount_point(dirlink1, 0) == 0);
+ assert_se(path_is_mount_point(dir1, NULL, AT_SYMLINK_FOLLOW) == 0);
+ assert_se(path_is_mount_point(dir1, NULL, 0) == 0);
+ assert_se(path_is_mount_point(dirlink1, NULL, AT_SYMLINK_FOLLOW) == 0);
+ assert_se(path_is_mount_point(dirlink1, NULL, 0) == 0);
/* file in subdirectory mountpoints */
dir1file = path_join(NULL, dir1, "file");
assert_se(fd > 0);
close(fd);
- assert_se(path_is_mount_point(dir1file, AT_SYMLINK_FOLLOW) == 0);
- assert_se(path_is_mount_point(dir1file, 0) == 0);
- assert_se(path_is_mount_point(dirlink1file, AT_SYMLINK_FOLLOW) == 0);
- assert_se(path_is_mount_point(dirlink1file, 0) == 0);
+ assert_se(path_is_mount_point(dir1file, NULL, AT_SYMLINK_FOLLOW) == 0);
+ assert_se(path_is_mount_point(dir1file, NULL, 0) == 0);
+ assert_se(path_is_mount_point(dirlink1file, NULL, AT_SYMLINK_FOLLOW) == 0);
+ assert_se(path_is_mount_point(dirlink1file, NULL, 0) == 0);
/* these tests will only work as root */
if (mount(file1, file2, NULL, MS_BIND, NULL) >= 0) {
/* files */
/* capture results in vars, to avoid dangling mounts on failure */
- rf = path_is_mount_point(file2, 0);
- rt = path_is_mount_point(file2, AT_SYMLINK_FOLLOW);
- rlf = path_is_mount_point(link2, 0);
- rlt = path_is_mount_point(link2, AT_SYMLINK_FOLLOW);
+ rf = path_is_mount_point(file2, NULL, 0);
+ rt = path_is_mount_point(file2, NULL, AT_SYMLINK_FOLLOW);
+ rlf = path_is_mount_point(link2, NULL, 0);
+ rlt = path_is_mount_point(link2, NULL, AT_SYMLINK_FOLLOW);
assert_se(umount(file2) == 0);
assert_se(mount(dir2, dir1, NULL, MS_BIND, NULL) >= 0);
- rf = path_is_mount_point(dir1, 0);
- rt = path_is_mount_point(dir1, AT_SYMLINK_FOLLOW);
- rlf = path_is_mount_point(dirlink1, 0);
- rlt = path_is_mount_point(dirlink1, AT_SYMLINK_FOLLOW);
+ rf = path_is_mount_point(dir1, NULL, 0);
+ rt = path_is_mount_point(dir1, NULL, AT_SYMLINK_FOLLOW);
+ rlf = path_is_mount_point(dirlink1, NULL, 0);
+ rlt = path_is_mount_point(dirlink1, NULL, AT_SYMLINK_FOLLOW);
/* its parent is a mount point, but not /file itself */
- rl1f = path_is_mount_point(dirlink1file, 0);
- rl1t = path_is_mount_point(dirlink1file, AT_SYMLINK_FOLLOW);
+ rl1f = path_is_mount_point(dirlink1file, NULL, 0);
+ rl1t = path_is_mount_point(dirlink1file, NULL, AT_SYMLINK_FOLLOW);
assert_se(umount(dir1) == 0);
assert_se(!hidden_or_backup_file("test.dpkg-old.foo"));
}
+static void test_systemd_installation_has_version(const char *path) {
+ int r;
+ const unsigned versions[] = {0, 231, atoi(PACKAGE_VERSION), 999};
+ unsigned i;
+
+ for (i = 0; i < ELEMENTSOF(versions); i++) {
+ r = systemd_installation_has_version(path, versions[i]);
+ assert_se(r >= 0);
+ log_info("%s has systemd >= %u: %s",
+ path ?: "Current installation", versions[i], yes_no(r));
+ }
+}
+
+static void test_skip_dev_prefix(void) {
+
+ assert_se(streq(skip_dev_prefix("/"), "/"));
+ assert_se(streq(skip_dev_prefix("/dev"), ""));
+ assert_se(streq(skip_dev_prefix("/dev/"), ""));
+ assert_se(streq(skip_dev_prefix("/dev/foo"), "foo"));
+ assert_se(streq(skip_dev_prefix("/dev/foo/bar"), "foo/bar"));
+ assert_se(streq(skip_dev_prefix("//dev"), ""));
+ assert_se(streq(skip_dev_prefix("//dev//"), ""));
+ assert_se(streq(skip_dev_prefix("/dev///foo"), "foo"));
+ assert_se(streq(skip_dev_prefix("///dev///foo///bar"), "foo///bar"));
+ assert_se(streq(skip_dev_prefix("//foo"), "//foo"));
+ assert_se(streq(skip_dev_prefix("foo"), "foo"));
+}
+
int main(int argc, char **argv) {
+ log_set_max_level(LOG_DEBUG);
+ log_parse_environment();
+ log_open();
+
test_path();
+ test_path_equal_root();
test_find_binary(argv[0]);
test_prefixes();
test_path_join();
test_file_in_same_dir();
test_filename_is_valid();
test_hidden_or_backup_file();
+ test_skip_dev_prefix();
+
+ test_systemd_installation_has_version(argv[1]); /* NULL is OK */
return 0;
}