100 lines
3.0 KiB
Diff
100 lines
3.0 KiB
Diff
|
|
From 3b703fe269a4a34f1b5ad1c3ce219c8c407e6fe1 Mon Sep 17 00:00:00 2001
|
||
|
|
From: Yu Watanabe <watanabe.yu+github@gmail.com>
|
||
|
|
Date: Wed, 17 Aug 2022 06:43:37 +0900
|
||
|
|
Subject: [PATCH] path-util: introduce path_glob_can_match()
|
||
|
|
|
||
|
|
---
|
||
|
|
src/basic/path-util.c | 61 +++++++++++++++++++++++++++++++++++++++++++
|
||
|
|
src/basic/path-util.h | 2 ++
|
||
|
|
2 files changed, 63 insertions(+)
|
||
|
|
|
||
|
|
diff --git a/src/basic/path-util.c b/src/basic/path-util.c
|
||
|
|
index 13d71ed..bec930f 100644
|
||
|
|
--- a/src/basic/path-util.c
|
||
|
|
+++ b/src/basic/path-util.c
|
||
|
|
@@ -1,6 +1,7 @@
|
||
|
|
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||
|
|
|
||
|
|
#include <errno.h>
|
||
|
|
+#include <fnmatch.h>
|
||
|
|
#include <limits.h>
|
||
|
|
#include <stdio.h>
|
||
|
|
#include <stdlib.h>
|
||
|
|
@@ -1395,3 +1396,63 @@ bool prefixed_path_strv_contains(char **l, const char *path) {
|
||
|
|
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
+
|
||
|
|
+int path_glob_can_match(const char *pattern, const char *prefix, char **ret) {
|
||
|
|
+ assert(pattern);
|
||
|
|
+ assert(prefix);
|
||
|
|
+
|
||
|
|
+ for (const char *a = pattern, *b = prefix;;) {
|
||
|
|
+ _cleanup_free_ char *g = NULL, *h = NULL;
|
||
|
|
+ const char *p, *q;
|
||
|
|
+ int r, s;
|
||
|
|
+
|
||
|
|
+ r = path_find_first_component(&a, /* accept_dot_dot = */ false, &p);
|
||
|
|
+ if (r < 0)
|
||
|
|
+ return r;
|
||
|
|
+
|
||
|
|
+ s = path_find_first_component(&b, /* accept_dot_dot = */ false, &q);
|
||
|
|
+ if (s < 0)
|
||
|
|
+ return s;
|
||
|
|
+
|
||
|
|
+ if (s == 0) {
|
||
|
|
+ /* The pattern matches the prefix. */
|
||
|
|
+ if (ret) {
|
||
|
|
+ char *t;
|
||
|
|
+
|
||
|
|
+ t = path_join(prefix, p);
|
||
|
|
+ if (!t)
|
||
|
|
+ return -ENOMEM;
|
||
|
|
+
|
||
|
|
+ *ret = t;
|
||
|
|
+ }
|
||
|
|
+ return true;
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
+ if (r == 0)
|
||
|
|
+ break;
|
||
|
|
+
|
||
|
|
+ if (r == s && strneq(p, q, r))
|
||
|
|
+ continue; /* common component. Check next. */
|
||
|
|
+
|
||
|
|
+ g = strndup(p, r);
|
||
|
|
+ if (!g)
|
||
|
|
+ return -ENOMEM;
|
||
|
|
+
|
||
|
|
+ if (!string_is_glob(g))
|
||
|
|
+ break;
|
||
|
|
+
|
||
|
|
+ /* We found a glob component. Check if the glob pattern matches the prefix component. */
|
||
|
|
+
|
||
|
|
+ h = strndup(q, s);
|
||
|
|
+ if (!h)
|
||
|
|
+ return -ENOMEM;
|
||
|
|
+
|
||
|
|
+ if (fnmatch(g, h, 0) != 0)
|
||
|
|
+ break;
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
+ /* The pattern does not match the prefix. */
|
||
|
|
+ if (ret)
|
||
|
|
+ *ret = NULL;
|
||
|
|
+ return false;
|
||
|
|
+}
|
||
|
|
diff --git a/src/basic/path-util.h b/src/basic/path-util.h
|
||
|
|
index 26e7362..c374a77 100644
|
||
|
|
--- a/src/basic/path-util.h
|
||
|
|
+++ b/src/basic/path-util.h
|
||
|
|
@@ -202,3 +202,5 @@ static inline const char *empty_to_root(const char *path) {
|
||
|
|
|
||
|
|
bool path_strv_contains(char **l, const char *path);
|
||
|
|
bool prefixed_path_strv_contains(char **l, const char *path);
|
||
|
|
+
|
||
|
|
+int path_glob_can_match(const char *pattern, const char *prefix, char **ret);
|
||
|
|
--
|
||
|
|
2.33.0
|
||
|
|
|