#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
-#include <string.h>
-#include <sys/stat.h>
#include <unistd.h>
/* When we include libgen.h because we need dirname() we immediately
#include "glob-util.h"
#include "log.h"
#include "macro.h"
-#include "missing.h"
+#include "nulstr-util.h"
#include "parse-util.h"
#include "path-util.h"
#include "stat-util.h"
if (path_is_absolute(p) || isempty(prefix))
return strdup(p);
- if (endswith(prefix, "/"))
- return strjoin(prefix, p);
- else
- return strjoin(prefix, "/", p);
+ return path_join(prefix, p);
}
int safe_getcwd(char **ret) {
return 0;
}
+char* path_startswith_strv(const char *p, char **set) {
+ char **s, *t;
+
+ STRV_FOREACH(s, set) {
+ t = path_startswith(p, *s);
+ if (t)
+ return t;
+ }
+
+ return NULL;
+}
+
int path_strv_make_absolute_cwd(char **l) {
char **s;
int r;
if (root) {
orig = *s;
- t = prefix_root(root, orig);
+ t = path_join(root, orig);
if (!t) {
enomem = true;
continue;
} else
t = *s;
- r = chase_symlinks(t, root, 0, &u);
+ r = chase_symlinks(t, root, 0, &u, NULL);
if (r == -ENOENT) {
if (root) {
u = TAKE_PTR(orig);
return path;
}
+int path_simplify_and_warn(
+ char *path,
+ unsigned flag,
+ const char *unit,
+ const char *filename,
+ unsigned line,
+ const char *lvalue) {
+
+ bool fatal = flag & PATH_CHECK_FATAL;
+
+ assert(!FLAGS_SET(flag, PATH_CHECK_ABSOLUTE | PATH_CHECK_RELATIVE));
+
+ if (!utf8_is_valid(path))
+ return log_syntax_invalid_utf8(unit, LOG_ERR, filename, line, path);
+
+ if (flag & (PATH_CHECK_ABSOLUTE | PATH_CHECK_RELATIVE)) {
+ bool absolute;
+
+ absolute = path_is_absolute(path);
+
+ if (!absolute && (flag & PATH_CHECK_ABSOLUTE))
+ return log_syntax(unit, LOG_ERR, filename, line, SYNTHETIC_ERRNO(EINVAL),
+ "%s= path is not absolute%s: %s",
+ lvalue, fatal ? "" : ", ignoring", path);
+
+ if (absolute && (flag & PATH_CHECK_RELATIVE))
+ return log_syntax(unit, LOG_ERR, filename, line, SYNTHETIC_ERRNO(EINVAL),
+ "%s= path is absolute%s: %s",
+ lvalue, fatal ? "" : ", ignoring", path);
+ }
+
+ path_simplify(path, true);
+
+ if (!path_is_valid(path))
+ return log_syntax(unit, LOG_ERR, filename, line, SYNTHETIC_ERRNO(EINVAL),
+ "%s= path has invalid length (%zu bytes)%s.",
+ lvalue, strlen(path), fatal ? "" : ", ignoring");
+
+ if (!path_is_normalized(path))
+ return log_syntax(unit, LOG_ERR, filename, line, SYNTHETIC_ERRNO(EINVAL),
+ "%s= path is not normalized%s: %s",
+ lvalue, fatal ? "" : ", ignoring", path);
+
+ return 0;
+}
+
char* path_startswith(const char *path, const char *prefix) {
assert(path);
assert(prefix);
if (!path_is_absolute(element))
continue;
- j = strjoin(element, "/", name);
+ j = path_join(element, name);
if (!j)
return -ENOMEM;
if (access(j, X_OK) >= 0) {
/* Found it! */
- if (ret) {
- *ret = path_simplify(j, false);
- j = NULL;
- }
+ if (ret)
+ *ret = path_simplify(TAKE_PTR(j), false);
return 0;
}
- last_error = -errno;
+ /* PATH entries which we don't have access to are ignored, as per tradition. */
+ if (errno != EACCES)
+ last_error = -errno;
}
return last_error;
return binary_is_good(mkfs);
}
-char *prefix_root(const char *root, const char *path) {
- char *n, *p;
- size_t l;
-
- /* If root is passed, prefixes path with it. Otherwise returns
- * it as is. */
-
- assert(path);
-
- /* First, drop duplicate prefixing slashes from the path */
- while (path[0] == '/' && path[1] == '/')
- path++;
-
- if (empty_or_root(root))
- return strdup(path);
-
- l = strlen(root) + 1 + strlen(path) + 1;
-
- n = new(char, l);
- if (!n)
- return NULL;
-
- p = stpcpy(n, root);
-
- while (p > n && p[-1] == '/')
- p--;
-
- if (path[0] != '/')
- *(p++) = '/';
-
- strcpy(p, path);
- return n;
-}
-
int parse_path_argument_and_warn(const char *path, bool suppress_root, char **arg) {
char *p;
int r;
_cleanup_free_ char *path = NULL;
char *c, **name;
- path = prefix_root(root, pattern);
+ path = path_join(root, pattern);
if (!path)
return -ENOMEM;
- r = glob_extend(&names, path);
+ r = glob_extend(&names, path, 0);
if (r == -ENOENT)
continue;
if (r < 0)
return root[strspn(root, "/")] == 0;
}
-int path_simplify_and_warn(
- char *path,
- unsigned flag,
- const char *unit,
- const char *filename,
- unsigned line,
- const char *lvalue) {
-
- bool absolute, fatal = flag & PATH_CHECK_FATAL;
-
- assert(!FLAGS_SET(flag, PATH_CHECK_ABSOLUTE | PATH_CHECK_RELATIVE));
-
- if (!utf8_is_valid(path)) {
- log_syntax_invalid_utf8(unit, LOG_ERR, filename, line, path);
- return -EINVAL;
- }
+bool path_strv_contains(char **l, const char *path) {
+ char **i;
- if (flag & (PATH_CHECK_ABSOLUTE | PATH_CHECK_RELATIVE)) {
- absolute = path_is_absolute(path);
-
- if (!absolute && (flag & PATH_CHECK_ABSOLUTE)) {
- log_syntax(unit, LOG_ERR, filename, line, 0,
- "%s= path is not absolute%s: %s",
- lvalue, fatal ? "" : ", ignoring", path);
- return -EINVAL;
- }
-
- if (absolute && (flag & PATH_CHECK_RELATIVE)) {
- log_syntax(unit, LOG_ERR, filename, line, 0,
- "%s= path is absolute%s: %s",
- lvalue, fatal ? "" : ", ignoring", path);
- return -EINVAL;
- }
- }
+ STRV_FOREACH(i, l)
+ if (path_equal(*i, path))
+ return true;
- path_simplify(path, true);
+ return false;
+}
- if (!path_is_normalized(path)) {
- log_syntax(unit, LOG_ERR, filename, line, 0,
- "%s= path is not normalized%s: %s",
- lvalue, fatal ? "" : ", ignoring", path);
- return -EINVAL;
- }
+bool prefixed_path_strv_contains(char **l, const char *path) {
+ char **i, *j;
- if (!path_is_valid(path)) {
- log_syntax(unit, LOG_ERR, filename, line, 0,
- "%s= path has invalid length (%zu bytes)%s.",
- lvalue, strlen(path), fatal ? "" : ", ignoring");
- return -EINVAL;
+ STRV_FOREACH(i, l) {
+ j = *i;
+ if (*j == '-')
+ j++;
+ if (*j == '+')
+ j++;
+ if (path_equal(j, path))
+ return true;
}
- return 0;
+ return false;
}