1 /* SPDX-License-Identifier: LGPL-2.1+ */
3 This file is part of systemd.
5 Copyright 2010-2012 Lennart Poettering
7 systemd is free software; you can redistribute it and/or modify it
8 under the terms of the GNU Lesser General Public License as published by
9 the Free Software Foundation; either version 2.1 of the License, or
10 (at your option) any later version.
12 systemd is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
17 You should have received a copy of the GNU Lesser General Public License
18 along with systemd; If not, see <http://www.gnu.org/licenses/>.
29 /* When we include libgen.h because we need dirname() we immediately
30 * undefine basename() since libgen.h defines it as a macro to the
31 * POSIX version which is really broken. We prefer GNU basename(). */
35 #include "alloc-util.h"
36 #include "extract-word.h"
38 #include "glob-util.h"
42 #include "parse-util.h"
43 #include "path-util.h"
44 #include "stat-util.h"
45 #include "string-util.h"
47 #include "time-util.h"
49 bool path_is_absolute(const char *p
) {
53 bool is_path(const char *p
) {
54 return !!strchr(p
, '/');
57 int path_split_and_make_absolute(const char *p
, char ***ret
) {
64 l
= strv_split(p
, ":");
68 r
= path_strv_make_absolute_cwd(l
);
78 char *path_make_absolute(const char *p
, const char *prefix
) {
81 /* Makes every item in the list an absolute path by prepending
82 * the prefix, if specified and necessary */
84 if (path_is_absolute(p
) || isempty(prefix
))
87 if (endswith(prefix
, "/"))
88 return strjoin(prefix
, p
);
90 return strjoin(prefix
, "/", p
);
93 int path_make_absolute_cwd(const char *p
, char **ret
) {
99 /* Similar to path_make_absolute(), but prefixes with the
100 * current working directory. */
102 if (path_is_absolute(p
))
105 _cleanup_free_
char *cwd
= NULL
;
107 cwd
= get_current_dir_name();
109 return negative_errno();
111 c
= strjoin(cwd
, "/", p
);
120 int path_make_relative(const char *from_dir
, const char *to_path
, char **_r
) {
128 /* Strips the common part, and adds ".." elements as necessary. */
130 if (!path_is_absolute(from_dir
))
133 if (!path_is_absolute(to_path
))
136 /* Skip the common part. */
140 from_dir
+= strspn(from_dir
, "/");
141 to_path
+= strspn(to_path
, "/");
145 /* from_dir equals to_path. */
148 /* from_dir is a parent directory of to_path. */
153 path_kill_slashes(r
);
162 a
= strcspn(from_dir
, "/");
163 b
= strcspn(to_path
, "/");
168 if (memcmp(from_dir
, to_path
, a
) != 0)
175 /* If we're here, then "from_dir" has one or more elements that need to
176 * be replaced with "..". */
178 /* Count the number of necessary ".." elements. */
179 for (n_parents
= 0;;) {
182 from_dir
+= strspn(from_dir
, "/");
187 w
= strcspn(from_dir
, "/");
189 /* If this includes ".." we can't do a simple series of "..", refuse */
190 if (w
== 2 && from_dir
[0] == '.' && from_dir
[1] == '.')
193 /* Count number of elements, except if they are "." */
194 if (w
!= 1 || from_dir
[0] != '.')
200 r
= new(char, n_parents
* 3 + strlen(to_path
) + 1);
204 for (p
= r
; n_parents
> 0; n_parents
--)
205 p
= mempcpy(p
, "../", 3);
208 path_kill_slashes(r
);
214 int path_strv_make_absolute_cwd(char **l
) {
218 /* Goes through every item in the string list and makes it
219 * absolute. This works in place and won't rollback any
220 * changes on failure. */
225 r
= path_make_absolute_cwd(*s
, &t
);
229 path_kill_slashes(t
);
230 free_and_replace(*s
, t
);
236 char **path_strv_resolve(char **l
, const char *root
) {
245 /* Goes through every item in the string list and canonicalize
246 * the path. This works in place and won't rollback any
247 * changes on failure. */
250 _cleanup_free_
char *orig
= NULL
;
253 if (!path_is_absolute(*s
)) {
260 t
= prefix_root(root
, orig
);
268 r
= chase_symlinks(t
, root
, 0, &u
);
287 x
= path_startswith(u
, root
);
289 /* restore the slash if it was lost */
290 if (!startswith(x
, "/"))
301 /* canonicalized path goes outside of
302 * prefix, keep the original path instead */
303 free_and_replace(u
, orig
);
319 char **path_strv_resolve_uniq(char **l
, const char *root
) {
324 if (!path_strv_resolve(l
, root
))
330 char *path_kill_slashes(char *path
) {
334 /* Removes redundant inner and trailing slashes. Modifies the
335 * passed string in-place.
337 * ///foo///bar/ becomes /foo/bar
340 for (f
= path
, t
= path
; *f
; f
++) {
355 /* Special rule, if we are talking of the root directory, a
356 trailing slash is good */
358 if (t
== path
&& slash
)
365 char* path_startswith(const char *path
, const char *prefix
) {
369 /* Returns a pointer to the start of the first component after the parts matched by
371 * - both paths are absolute or both paths are relative,
373 * - each component in prefix in turn matches a component in path at the same position.
374 * An empty string will be returned when the prefix and path are equivalent.
376 * Returns NULL otherwise.
379 if ((path
[0] == '/') != (prefix
[0] == '/'))
385 path
+= strspn(path
, "/");
386 prefix
+= strspn(prefix
, "/");
394 a
= strcspn(path
, "/");
395 b
= strcspn(prefix
, "/");
400 if (memcmp(path
, prefix
, a
) != 0)
408 int path_compare(const char *a
, const char *b
) {
414 /* A relative path and an abolute path must not compare as equal.
415 * Which one is sorted before the other does not really matter.
416 * Here a relative path is ordered before an absolute path. */
417 d
= (a
[0] == '/') - (b
[0] == '/');
427 if (*a
== 0 && *b
== 0)
430 /* Order prefixes first: "/foo" before "/foo/bar" */
439 /* Alphabetical sort: "/foo/aaa" before "/foo/b" */
440 d
= memcmp(a
, b
, MIN(j
, k
));
442 return (d
> 0) - (d
< 0); /* sign of d */
444 /* Sort "/foo/a" before "/foo/aaa" */
445 d
= (j
> k
) - (j
< k
); /* sign of (j - k) */
454 bool path_equal(const char *a
, const char *b
) {
455 return path_compare(a
, b
) == 0;
458 bool path_equal_or_files_same(const char *a
, const char *b
, int flags
) {
459 return path_equal(a
, b
) || files_same(a
, b
, flags
) > 0;
462 char* path_join(const char *root
, const char *path
, const char *rest
) {
466 return strjoin(root
, endswith(root
, "/") ? "" : "/",
467 path
[0] == '/' ? path
+1 : path
,
468 rest
? (endswith(path
, "/") ? "" : "/") : NULL
,
469 rest
&& rest
[0] == '/' ? rest
+1 : rest
);
472 rest
? (endswith(path
, "/") ? "" : "/") : NULL
,
473 rest
&& rest
[0] == '/' ? rest
+1 : rest
);
476 int find_binary(const char *name
, char **ret
) {
483 if (access(name
, X_OK
) < 0)
487 r
= path_make_absolute_cwd(name
, ret
);
496 * Plain getenv, not secure_getenv, because we want
497 * to actually allow the user to pick the binary.
503 last_error
= -ENOENT
;
506 _cleanup_free_
char *j
= NULL
, *element
= NULL
;
508 r
= extract_first_word(&p
, &element
, ":", EXTRACT_RELAX
|EXTRACT_DONT_COALESCE_SEPARATORS
);
514 if (!path_is_absolute(element
))
517 j
= strjoin(element
, "/", name
);
521 if (access(j
, X_OK
) >= 0) {
525 *ret
= path_kill_slashes(j
);
538 bool paths_check_timestamp(const char* const* paths
, usec_t
*timestamp
, bool update
) {
539 bool changed
= false;
540 const char* const* i
;
547 STRV_FOREACH(i
, paths
) {
551 if (stat(*i
, &stats
) < 0)
554 u
= timespec_load(&stats
.st_mtim
);
560 log_debug("timestamp of '%s' changed", *i
);
562 /* update timestamp */
573 static int binary_is_good(const char *binary
) {
574 _cleanup_free_
char *p
= NULL
, *d
= NULL
;
577 r
= find_binary(binary
, &p
);
583 /* An fsck that is linked to /bin/true is a non-existent
586 r
= readlink_malloc(p
, &d
);
587 if (r
== -EINVAL
) /* not a symlink */
592 return !PATH_IN_SET(d
, "true"
598 int fsck_exists(const char *fstype
) {
603 if (streq(fstype
, "auto"))
606 checker
= strjoina("fsck.", fstype
);
607 return binary_is_good(checker
);
610 int mkfs_exists(const char *fstype
) {
615 if (streq(fstype
, "auto"))
618 mkfs
= strjoina("mkfs.", fstype
);
619 return binary_is_good(mkfs
);
622 char *prefix_root(const char *root
, const char *path
) {
626 /* If root is passed, prefixes path with it. Otherwise returns
631 /* First, drop duplicate prefixing slashes from the path */
632 while (path
[0] == '/' && path
[1] == '/')
635 if (isempty(root
) || path_equal(root
, "/"))
638 l
= strlen(root
) + 1 + strlen(path
) + 1;
646 while (p
> n
&& p
[-1] == '/')
656 int parse_path_argument_and_warn(const char *path
, bool suppress_root
, char **arg
) {
661 * This function is intended to be used in command line
662 * parsers, to handle paths that are passed in. It makes the
663 * path absolute, and reduces it to NULL if omitted or
664 * root (the latter optionally).
666 * NOTE THAT THIS WILL FREE THE PREVIOUS ARGUMENT POINTER ON
667 * SUCCESS! Hence, do not pass in uninitialized pointers.
675 r
= path_make_absolute_cwd(path
, &p
);
677 return log_error_errno(r
, "Failed to parse path \"%s\" and make it absolute: %m", path
);
679 path_kill_slashes(p
);
680 if (suppress_root
&& path_equal(p
, "/"))
688 char* dirname_malloc(const char *path
) {
689 char *d
, *dir
, *dir2
;
709 const char *last_path_component(const char *path
) {
710 /* Finds the last component of the path, preserving the
711 * optional trailing slash that signifies a directory.
718 * This is different than basename, which returns "" when
719 * a trailing slash is present.
724 l
= k
= strlen(path
);
725 if (l
== 0) /* special case — an empty string */
728 while (k
> 0 && path
[k
-1] == '/')
731 if (k
== 0) /* the root directory */
734 while (k
> 0 && path
[k
-1] != '/')
740 bool filename_is_valid(const char *p
) {
746 if (dot_or_dot_dot(p
))
749 e
= strchrnul(p
, '/');
753 if (e
- p
> FILENAME_MAX
)
759 bool path_is_normalized(const char *p
) {
764 if (dot_or_dot_dot(p
))
767 if (startswith(p
, "../") || endswith(p
, "/..") || strstr(p
, "/../"))
770 if (strlen(p
)+1 > PATH_MAX
)
773 if (startswith(p
, "./") || endswith(p
, "/.") || strstr(p
, "/./"))
782 char *file_in_same_dir(const char *path
, const char *filename
) {
789 /* This removes the last component of path and appends
790 * filename, unless the latter is absolute anyway or the
793 if (path_is_absolute(filename
))
794 return strdup(filename
);
796 e
= strrchr(path
, '/');
798 return strdup(filename
);
800 k
= strlen(filename
);
801 ret
= new(char, (e
+ 1 - path
) + k
+ 1);
805 memcpy(mempcpy(ret
, path
, e
+ 1 - path
), filename
, k
+ 1);
809 bool hidden_or_backup_file(const char *filename
) {
814 if (filename
[0] == '.' ||
815 streq(filename
, "lost+found") ||
816 streq(filename
, "aquota.user") ||
817 streq(filename
, "aquota.group") ||
818 endswith(filename
, "~"))
821 p
= strrchr(filename
, '.');
825 /* Please, let's not add more entries to the list below. If external projects think it's a good idea to come up
826 * with always new suffixes and that everybody else should just adjust to that, then it really should be on
827 * them. Hence, in future, let's not add any more entries. Instead, let's ask those packages to instead adopt
828 * one of the generic suffixes/prefixes for hidden files or backups, possibly augmented with an additional
829 * string. Specifically: there's now:
831 * The generic suffixes "~" and ".bak" for backup files
832 * The generic prefix "." for hidden files
834 * Thus, if a new package manager "foopkg" wants its own set of ".foopkg-new", ".foopkg-old", ".foopkg-dist"
835 * or so registered, let's refuse that and ask them to use ".foopkg.new", ".foopkg.old" or ".foopkg~" instead.
838 return STR_IN_SET(p
+ 1,
858 bool is_device_path(const char *path
) {
860 /* Returns true on paths that refer to a device, either in
861 * sysfs or in /dev */
863 return path_startswith(path
, "/dev/") ||
864 path_startswith(path
, "/sys/");
867 bool is_deviceallow_pattern(const char *path
) {
868 return path_startswith(path
, "/dev/") ||
869 startswith(path
, "block-") ||
870 startswith(path
, "char-");
873 int systemd_installation_has_version(const char *root
, unsigned minimal_version
) {
877 /* Try to guess if systemd installation is later than the specified version. This
878 * is hacky and likely to yield false negatives, particularly if the installation
879 * is non-standard. False positives should be relatively rare.
882 NULSTR_FOREACH(pattern
,
883 /* /lib works for systems without usr-merge, and for systems with a sane
884 * usr-merge, where /lib is a symlink to /usr/lib. /usr/lib is necessary
885 * for Gentoo which does a merge without making /lib a symlink.
887 "lib/systemd/libsystemd-shared-*.so\0"
888 "lib64/systemd/libsystemd-shared-*.so\0"
889 "usr/lib/systemd/libsystemd-shared-*.so\0"
890 "usr/lib64/systemd/libsystemd-shared-*.so\0") {
892 _cleanup_strv_free_
char **names
= NULL
;
893 _cleanup_free_
char *path
= NULL
;
896 path
= prefix_root(root
, pattern
);
900 r
= glob_extend(&names
, path
);
906 assert_se((c
= endswith(path
, "*.so")));
907 *c
= '\0'; /* truncate the glob part */
909 STRV_FOREACH(name
, names
) {
910 /* This is most likely to run only once, hence let's not optimize anything. */
914 t
= startswith(*name
, path
);
918 t2
= endswith(t
, ".so");
922 t2
[0] = '\0'; /* truncate the suffix */
924 r
= safe_atou(t
, &version
);
926 log_debug_errno(r
, "Found libsystemd shared at \"%s.so\", but failed to parse version: %m", *name
);
930 log_debug("Found libsystemd shared at \"%s.so\", version %u (%s).",
932 version
>= minimal_version
? "OK" : "too old");
933 if (version
>= minimal_version
)
941 bool dot_or_dot_dot(const char *path
) {