summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/canonicalize.h10
-rw-r--r--lib/canonicalize.c42
-rw-r--r--libmount/src/tab.c14
3 files changed, 65 insertions, 1 deletions
diff --git a/include/canonicalize.h b/include/canonicalize.h
index 7a18aca09..0a292fc32 100644
--- a/include/canonicalize.h
+++ b/include/canonicalize.h
@@ -13,9 +13,19 @@
#define CANONICALIZE_H
#include "c.h" /* for PATH_MAX */
+#include "strutils.h"
extern char *canonicalize_path(const char *path);
extern char *canonicalize_path_restricted(const char *path);
extern char *canonicalize_dm_name(const char *ptname);
+extern char *absolute_path(const char *path);
+
+static inline int is_relative_path(const char *path)
+{
+ if (!path || *path == '/')
+ return 0;
+ return 1;
+}
+
#endif /* CANONICALIZE_H */
diff --git a/lib/canonicalize.c b/lib/canonicalize.c
index 49ac80246..93782e894 100644
--- a/lib/canonicalize.c
+++ b/lib/canonicalize.c
@@ -66,6 +66,47 @@ static int is_dm_devname(char *canonical, char **name)
return 1;
}
+/*
+ * This function does not cannonicalize the path! It just prepends CWD before a
+ * relative path. If the path is no relative than returns NULL. The path does
+ * not have to exist.
+ */
+char *absolute_path(const char *path)
+{
+ char cwd[PATH_MAX], *res, *p;
+ size_t psz, csz;
+
+ if (!is_relative_path(path)) {
+ errno = EINVAL;
+ return NULL;
+ }
+ if (!getcwd(cwd, sizeof(cwd)))
+ return NULL;
+
+ /* simple clean up */
+ if (startswith(path, "./"))
+ path += 2;
+ else if (strcmp(path, ".") == 0)
+ path = NULL;
+
+ if (!path || !*path)
+ return strdup(cwd);
+
+ csz = strlen(cwd);
+ psz = strlen(path);
+
+ p = res = malloc(csz + 1 + psz + 1);
+ if (!res)
+ return NULL;
+
+ memcpy(p, cwd, csz);
+ p += csz;
+ *p++ = '/';
+ memcpy(p, path, psz + 1);
+
+ return res;
+}
+
char *canonicalize_path(const char *path)
{
char *canonical, *dmname;
@@ -139,7 +180,6 @@ int main(int argc, char **argv)
fprintf(stdout, "orig: %s\n", argv[1]);
fprintf(stdout, "real: %s\n", canonicalize_path(argv[1]));
-
exit(EXIT_SUCCESS);
}
#endif
diff --git a/libmount/src/tab.c b/libmount/src/tab.c
index d7a633cba..a8d835e04 100644
--- a/libmount/src/tab.c
+++ b/libmount/src/tab.c
@@ -867,6 +867,20 @@ struct libmnt_fs *mnt_table_find_target(struct libmnt_table *tb, const char *pat
if (mnt_fs_streq_target(fs, path))
return fs;
}
+
+ /* try absolute path */
+ if (is_relative_path(path) && (cn = absolute_path(path))) {
+ DBG(TAB, ul_debugobj(tb, "lookup absolute TARGET: '%s'", cn));
+ mnt_reset_iter(&itr, direction);
+ while (mnt_table_next_fs(tb, &itr, &fs) == 0) {
+ if (mnt_fs_streq_target(fs, cn)) {
+ free(cn);
+ return fs;
+ }
+ }
+ free(cn);
+ }
+
if (!tb->cache || !(cn = mnt_resolve_path(path, tb->cache)))
return NULL;