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
) || !prefix
)
87 return strjoin(prefix
, "/", p
);
90 int path_make_absolute_cwd(const char *p
, char **ret
) {
96 /* Similar to path_make_absolute(), but prefixes with the
97 * current working directory. */
99 if (path_is_absolute(p
))
102 _cleanup_free_
char *cwd
= NULL
;
104 cwd
= get_current_dir_name();
106 return negative_errno();
108 c
= strjoin(cwd
, "/", p
);
117 int path_make_relative(const char *from_dir
, const char *to_path
, char **_r
) {
125 /* Strips the common part, and adds ".." elements as necessary. */
127 if (!path_is_absolute(from_dir
))
130 if (!path_is_absolute(to_path
))
133 /* Skip the common part. */
137 from_dir
+= strspn(from_dir
, "/");
138 to_path
+= strspn(to_path
, "/");
142 /* from_dir equals to_path. */
145 /* from_dir is a parent directory of to_path. */
150 path_kill_slashes(r
);
159 a
= strcspn(from_dir
, "/");
160 b
= strcspn(to_path
, "/");
165 if (memcmp(from_dir
, to_path
, a
) != 0)
172 /* If we're here, then "from_dir" has one or more elements that need to
173 * be replaced with "..". */
175 /* Count the number of necessary ".." elements. */
176 for (n_parents
= 0;;) {
179 from_dir
+= strspn(from_dir
, "/");
184 w
= strcspn(from_dir
, "/");
186 /* If this includes ".." we can't do a simple series of "..", refuse */
187 if (w
== 2 && from_dir
[0] == '.' && from_dir
[1] == '.')
190 /* Count number of elements, except if they are "." */
191 if (w
!= 1 || from_dir
[0] != '.')
197 r
= new(char, n_parents
* 3 + strlen(to_path
) + 1);
201 for (p
= r
; n_parents
> 0; n_parents
--)
202 p
= mempcpy(p
, "../", 3);
205 path_kill_slashes(r
);
211 int path_strv_make_absolute_cwd(char **l
) {
215 /* Goes through every item in the string list and makes it
216 * absolute. This works in place and won't rollback any
217 * changes on failure. */
222 r
= path_make_absolute_cwd(*s
, &t
);
226 path_kill_slashes(t
);
227 free_and_replace(*s
, t
);
233 char **path_strv_resolve(char **l
, const char *root
) {
242 /* Goes through every item in the string list and canonicalize
243 * the path. This works in place and won't rollback any
244 * changes on failure. */
247 _cleanup_free_
char *orig
= NULL
;
250 if (!path_is_absolute(*s
)) {
257 t
= prefix_root(root
, orig
);
265 r
= chase_symlinks(t
, root
, 0, &u
);
284 x
= path_startswith(u
, root
);
286 /* restore the slash if it was lost */
287 if (!startswith(x
, "/"))
298 /* canonicalized path goes outside of
299 * prefix, keep the original path instead */
300 free_and_replace(u
, orig
);
316 char **path_strv_resolve_uniq(char **l
, const char *root
) {
321 if (!path_strv_resolve(l
, root
))
327 char *path_kill_slashes(char *path
) {
331 /* Removes redundant inner and trailing slashes. Modifies the
332 * passed string in-place.
334 * ///foo///bar/ becomes /foo/bar
337 for (f
= path
, t
= path
; *f
; f
++) {
352 /* Special rule, if we are talking of the root directory, a
353 trailing slash is good */
355 if (t
== path
&& slash
)
362 char* path_startswith(const char *path
, const char *prefix
) {
366 /* Returns a pointer to the start of the first component after the parts matched by
368 * - both paths are absolute or both paths are relative,
370 * - each component in prefix in turn matches a component in path at the same position.
371 * An empty string will be returned when the prefix and path are equivalent.
373 * Returns NULL otherwise.
376 if ((path
[0] == '/') != (prefix
[0] == '/'))
382 path
+= strspn(path
, "/");
383 prefix
+= strspn(prefix
, "/");
391 a
= strcspn(path
, "/");
392 b
= strcspn(prefix
, "/");
397 if (memcmp(path
, prefix
, a
) != 0)
405 int path_compare(const char *a
, const char *b
) {
411 /* A relative path and an abolute path must not compare as equal.
412 * Which one is sorted before the other does not really matter.
413 * Here a relative path is ordered before an absolute path. */
414 d
= (a
[0] == '/') - (b
[0] == '/');
424 if (*a
== 0 && *b
== 0)
427 /* Order prefixes first: "/foo" before "/foo/bar" */
436 /* Alphabetical sort: "/foo/aaa" before "/foo/b" */
437 d
= memcmp(a
, b
, MIN(j
, k
));
439 return (d
> 0) - (d
< 0); /* sign of d */
441 /* Sort "/foo/a" before "/foo/aaa" */
442 d
= (j
> k
) - (j
< k
); /* sign of (j - k) */
451 bool path_equal(const char *a
, const char *b
) {
452 return path_compare(a
, b
) == 0;
455 bool path_equal_or_files_same(const char *a
, const char *b
, int flags
) {
456 return path_equal(a
, b
) || files_same(a
, b
, flags
) > 0;
459 char* path_join(const char *root
, const char *path
, const char *rest
) {
463 return strjoin(root
, endswith(root
, "/") ? "" : "/",
464 path
[0] == '/' ? path
+1 : path
,
465 rest
? (endswith(path
, "/") ? "" : "/") : NULL
,
466 rest
&& rest
[0] == '/' ? rest
+1 : rest
);
469 rest
? (endswith(path
, "/") ? "" : "/") : NULL
,
470 rest
&& rest
[0] == '/' ? rest
+1 : rest
);
473 int find_binary(const char *name
, char **ret
) {
480 if (access(name
, X_OK
) < 0)
484 r
= path_make_absolute_cwd(name
, ret
);
493 * Plain getenv, not secure_getenv, because we want
494 * to actually allow the user to pick the binary.
500 last_error
= -ENOENT
;
503 _cleanup_free_
char *j
= NULL
, *element
= NULL
;
505 r
= extract_first_word(&p
, &element
, ":", EXTRACT_RELAX
|EXTRACT_DONT_COALESCE_SEPARATORS
);
511 if (!path_is_absolute(element
))
514 j
= strjoin(element
, "/", name
);
518 if (access(j
, X_OK
) >= 0) {
522 *ret
= path_kill_slashes(j
);
535 bool paths_check_timestamp(const char* const* paths
, usec_t
*timestamp
, bool update
) {
536 bool changed
= false;
537 const char* const* i
;
544 STRV_FOREACH(i
, paths
) {
548 if (stat(*i
, &stats
) < 0)
551 u
= timespec_load(&stats
.st_mtim
);
557 log_debug("timestamp of '%s' changed", *i
);
559 /* update timestamp */
570 static int binary_is_good(const char *binary
) {
571 _cleanup_free_
char *p
= NULL
, *d
= NULL
;
574 r
= find_binary(binary
, &p
);
580 /* An fsck that is linked to /bin/true is a non-existent
583 r
= readlink_malloc(p
, &d
);
584 if (r
== -EINVAL
) /* not a symlink */
589 return !PATH_IN_SET(d
, "true"
595 int fsck_exists(const char *fstype
) {
600 if (streq(fstype
, "auto"))
603 checker
= strjoina("fsck.", fstype
);
604 return binary_is_good(checker
);
607 int mkfs_exists(const char *fstype
) {
612 if (streq(fstype
, "auto"))
615 mkfs
= strjoina("mkfs.", fstype
);
616 return binary_is_good(mkfs
);
619 char *prefix_root(const char *root
, const char *path
) {
623 /* If root is passed, prefixes path with it. Otherwise returns
628 /* First, drop duplicate prefixing slashes from the path */
629 while (path
[0] == '/' && path
[1] == '/')
632 if (isempty(root
) || path_equal(root
, "/"))
635 l
= strlen(root
) + 1 + strlen(path
) + 1;
643 while (p
> n
&& p
[-1] == '/')
653 int parse_path_argument_and_warn(const char *path
, bool suppress_root
, char **arg
) {
658 * This function is intended to be used in command line
659 * parsers, to handle paths that are passed in. It makes the
660 * path absolute, and reduces it to NULL if omitted or
661 * root (the latter optionally).
663 * NOTE THAT THIS WILL FREE THE PREVIOUS ARGUMENT POINTER ON
664 * SUCCESS! Hence, do not pass in uninitialized pointers.
672 r
= path_make_absolute_cwd(path
, &p
);
674 return log_error_errno(r
, "Failed to parse path \"%s\" and make it absolute: %m", path
);
676 path_kill_slashes(p
);
677 if (suppress_root
&& path_equal(p
, "/"))
685 char* dirname_malloc(const char *path
) {
686 char *d
, *dir
, *dir2
;
706 const char *last_path_component(const char *path
) {
707 /* Finds the last component of the path, preserving the
708 * optional trailing slash that signifies a directory.
715 * This is different than basename, which returns "" when
716 * a trailing slash is present.
721 l
= k
= strlen(path
);
722 if (l
== 0) /* special case — an empty string */
725 while (k
> 0 && path
[k
-1] == '/')
728 if (k
== 0) /* the root directory */
731 while (k
> 0 && path
[k
-1] != '/')
737 bool filename_is_valid(const char *p
) {
743 if (dot_or_dot_dot(p
))
746 e
= strchrnul(p
, '/');
750 if (e
- p
> FILENAME_MAX
)
756 bool path_is_normalized(const char *p
) {
761 if (dot_or_dot_dot(p
))
764 if (startswith(p
, "../") || endswith(p
, "/..") || strstr(p
, "/../"))
767 if (strlen(p
)+1 > PATH_MAX
)
770 if (startswith(p
, "./") || endswith(p
, "/.") || strstr(p
, "/./"))
779 char *file_in_same_dir(const char *path
, const char *filename
) {
786 /* This removes the last component of path and appends
787 * filename, unless the latter is absolute anyway or the
790 if (path_is_absolute(filename
))
791 return strdup(filename
);
793 e
= strrchr(path
, '/');
795 return strdup(filename
);
797 k
= strlen(filename
);
798 ret
= new(char, (e
+ 1 - path
) + k
+ 1);
802 memcpy(mempcpy(ret
, path
, e
+ 1 - path
), filename
, k
+ 1);
806 bool hidden_or_backup_file(const char *filename
) {
811 if (filename
[0] == '.' ||
812 streq(filename
, "lost+found") ||
813 streq(filename
, "aquota.user") ||
814 streq(filename
, "aquota.group") ||
815 endswith(filename
, "~"))
818 p
= strrchr(filename
, '.');
822 /* Please, let's not add more entries to the list below. If external projects think it's a good idea to come up
823 * with always new suffixes and that everybody else should just adjust to that, then it really should be on
824 * them. Hence, in future, let's not add any more entries. Instead, let's ask those packages to instead adopt
825 * one of the generic suffixes/prefixes for hidden files or backups, possibly augmented with an additional
826 * string. Specifically: there's now:
828 * The generic suffixes "~" and ".bak" for backup files
829 * The generic prefix "." for hidden files
831 * Thus, if a new package manager "foopkg" wants its own set of ".foopkg-new", ".foopkg-old", ".foopkg-dist"
832 * or so registered, let's refuse that and ask them to use ".foopkg.new", ".foopkg.old" or ".foopkg~" instead.
835 return STR_IN_SET(p
+ 1,
855 bool is_device_path(const char *path
) {
857 /* Returns true on paths that refer to a device, either in
858 * sysfs or in /dev */
860 return path_startswith(path
, "/dev/") ||
861 path_startswith(path
, "/sys/");
864 bool is_deviceallow_pattern(const char *path
) {
865 return path_startswith(path
, "/dev/") ||
866 startswith(path
, "block-") ||
867 startswith(path
, "char-");
870 int systemd_installation_has_version(const char *root
, unsigned minimal_version
) {
874 /* Try to guess if systemd installation is later than the specified version. This
875 * is hacky and likely to yield false negatives, particularly if the installation
876 * is non-standard. False positives should be relatively rare.
879 NULSTR_FOREACH(pattern
,
880 /* /lib works for systems without usr-merge, and for systems with a sane
881 * usr-merge, where /lib is a symlink to /usr/lib. /usr/lib is necessary
882 * for Gentoo which does a merge without making /lib a symlink.
884 "lib/systemd/libsystemd-shared-*.so\0"
885 "lib64/systemd/libsystemd-shared-*.so\0"
886 "usr/lib/systemd/libsystemd-shared-*.so\0"
887 "usr/lib64/systemd/libsystemd-shared-*.so\0") {
889 _cleanup_strv_free_
char **names
= NULL
;
890 _cleanup_free_
char *path
= NULL
;
893 path
= prefix_root(root
, pattern
);
897 r
= glob_extend(&names
, path
);
903 assert_se((c
= endswith(path
, "*.so")));
904 *c
= '\0'; /* truncate the glob part */
906 STRV_FOREACH(name
, names
) {
907 /* This is most likely to run only once, hence let's not optimize anything. */
911 t
= startswith(*name
, path
);
915 t2
= endswith(t
, ".so");
919 t2
[0] = '\0'; /* truncate the suffix */
921 r
= safe_atou(t
, &version
);
923 log_debug_errno(r
, "Found libsystemd shared at \"%s.so\", but failed to parse version: %m", *name
);
927 log_debug("Found libsystemd shared at \"%s.so\", version %u (%s).",
929 version
>= minimal_version
? "OK" : "too old");
930 if (version
>= minimal_version
)
938 bool dot_or_dot_dot(const char *path
) {