summaryrefslogtreecommitdiff
path: root/src/basic/path-util.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/basic/path-util.c')
-rw-r--r--src/basic/path-util.c45
1 files changed, 39 insertions, 6 deletions
diff --git a/src/basic/path-util.c b/src/basic/path-util.c
index 6c06bd2acb..ab4778d4ed 100644
--- a/src/basic/path-util.c
+++ b/src/basic/path-util.c
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
@@ -222,8 +223,8 @@ int path_strv_make_absolute_cwd(char **l) {
if (r < 0)
return r;
- free(*s);
- *s = t;
+ path_kill_slashes(t);
+ free_and_replace(*s, t);
}
return 0;
@@ -537,7 +538,7 @@ bool paths_check_timestamp(const char* const* paths, usec_t *timestamp, bool upd
assert(timestamp);
- if (paths == NULL)
+ if (!paths)
return false;
STRV_FOREACH(i, paths) {
@@ -702,6 +703,37 @@ char* dirname_malloc(const char *path) {
return dir2;
}
+const char *last_path_component(const char *path) {
+ /* Finds the last component of the path, preserving the
+ * optional trailing slash that signifies a directory.
+ * a/b/c → c
+ * a/b/c/ → c/
+ * / → /
+ * // → /
+ * /foo/a → a
+ * /foo/a/ → a/
+ * This is different than basename, which returns "" when
+ * a trailing slash is present.
+ */
+
+ unsigned l, k;
+
+ l = k = strlen(path);
+ if (l == 0) /* special case — an empty string */
+ return path;
+
+ while (k > 0 && path[k-1] == '/')
+ k--;
+
+ if (k == 0) /* the root directory */
+ return path + l - 1;
+
+ while (k > 0 && path[k-1] != '/')
+ k--;
+
+ return path + k;
+}
+
bool filename_is_valid(const char *p) {
const char *e;
@@ -721,7 +753,7 @@ bool filename_is_valid(const char *p) {
return true;
}
-bool path_is_safe(const char *p) {
+bool path_is_normalized(const char *p) {
if (isempty(p))
return false;
@@ -735,7 +767,6 @@ bool path_is_safe(const char *p) {
if (strlen(p)+1 > PATH_MAX)
return false;
- /* The following two checks are not really dangerous, but hey, they still are confusing */
if (startswith(p, "./") || endswith(p, "/.") || strstr(p, "/./"))
return false;
@@ -851,7 +882,9 @@ int systemd_installation_has_version(const char *root, unsigned minimal_version)
* for Gentoo which does a merge without making /lib a symlink.
*/
"lib/systemd/libsystemd-shared-*.so\0"
- "usr/lib/systemd/libsystemd-shared-*.so\0") {
+ "lib64/systemd/libsystemd-shared-*.so\0"
+ "usr/lib/systemd/libsystemd-shared-*.so\0"
+ "usr/lib64/systemd/libsystemd-shared-*.so\0") {
_cleanup_strv_free_ char **names = NULL;
_cleanup_free_ char *path = NULL;