]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
vpick: add path_uses_vpick helper method
authormaia x. <maia+git@quatern.org>
Sat, 5 Oct 2024 21:27:32 +0000 (14:27 -0700)
committerLuca Boccassi <luca.boccassi@gmail.com>
Wed, 14 May 2025 14:13:28 +0000 (15:13 +0100)
Add a path_uses_vpick helper method to determine if a path matches
the vpick format ('PATH/NAME.SUFFIX.v' or 'PATH.v/NAME___.SUFFIX'):

/* good: returns 1 */
path_uses_vpick("/var/lib/machines/mymachine.raw.v/")
path_uses_vpick("to.v/foo___.raw

/* bad: returns <= 0 */
path_uses_vpick("/")
path_uses_vpick("path/to/foo.mp4.vtt

src/shared/vpick.c
src/shared/vpick.h
src/test/test-vpick.c

index 9aa1bc6d58261161420a3dbe3283e09d2def0caf..abad029094365d36a78a60b49b906a1d9368a00d 100644 (file)
@@ -691,6 +691,41 @@ int path_pick_update_warn(
         return 1;
 }
 
+int path_uses_vpick(const char *path) {
+        _cleanup_free_ char *dir = NULL, *parent = NULL, *fname = NULL;
+        int r;
+
+        assert(path);
+
+        r = path_extract_filename(path, &fname);
+        if (r == -EADDRNOTAVAIL)
+                return 0;
+        if (r < 0)
+                return r;
+
+        /* ...PATH/NAME.SUFFIX.v */
+        if (endswith(fname, ".v"))
+                return 1;
+
+        /* ...PATH.v/NAME___.SUFFIX */
+        if (!strrstr(fname, "___"))
+                return 0;
+
+        r = path_extract_directory(path, &dir);
+        if (IN_SET(r, -EDESTADDRREQ, -EADDRNOTAVAIL)) /* only filename specified (no dir), or root or "." */
+                return 0;
+        if (r < 0)
+                return r;
+
+        r = path_extract_filename(dir, &parent);
+        if (r == -EADDRNOTAVAIL)
+                return 0;
+        if (r < 0)
+                return r;
+
+        return !!endswith(parent, ".v");
+}
+
 const PickFilter pick_filter_image_raw = {
         .type_mask = (UINT32_C(1) << DT_REG) | (UINT32_C(1) << DT_BLK),
         .architecture = _ARCHITECTURE_INVALID,
index 8373821dfab3fff4009aa40fadbf44ae16fbf08b..25361510a759bbfda1fe7bebeb48b711941e5d24 100644 (file)
@@ -57,6 +57,8 @@ int path_pick_update_warn(
                 PickFlags flags,
                 PickResult *ret);
 
+int path_uses_vpick(const char *path);
+
 extern const PickFilter pick_filter_image_raw;
 extern const PickFilter pick_filter_image_dir;
 extern const PickFilter pick_filter_image_any;
index 88646ec053eb64cb762138a5faa39ec89315286a..aeea50c603d388f791be9222a05f33a112498f5e 100644 (file)
@@ -168,4 +168,27 @@ TEST(path_pick) {
         assert_se(result.architecture == ARCHITECTURE_S390);
 }
 
+TEST(path_uses_vpick) {
+        ASSERT_OK_POSITIVE(path_uses_vpick("foo.v"));
+        ASSERT_OK_POSITIVE(path_uses_vpick("path/to/foo.v"));
+        ASSERT_OK_POSITIVE(path_uses_vpick("./path/to/foo.v"));
+        ASSERT_OK_POSITIVE(path_uses_vpick("path/to.v/foo.v"));
+        ASSERT_OK_POSITIVE(path_uses_vpick("path/to/foo.raw.v"));
+        ASSERT_OK_POSITIVE(path_uses_vpick("/var/lib/machines/mymachine.raw.v/"));
+        ASSERT_OK_POSITIVE(path_uses_vpick("path/to.v/foo___.hi/a.v"));
+        ASSERT_OK_ZERO(path_uses_vpick("path/to/foo.mp4.vtt"));
+        ASSERT_OK_ZERO(path_uses_vpick("path/to/foo.mp4.v.1"));
+        ASSERT_OK_ZERO(path_uses_vpick("path/to.v/a"));
+
+        ASSERT_OK_POSITIVE(path_uses_vpick("to.v/foo___.raw"));
+        ASSERT_OK_POSITIVE(path_uses_vpick("path/to.v/foo___.raw"));
+        ASSERT_OK_ZERO(path_uses_vpick("path/to/foo___.raw"));
+        ASSERT_OK_ZERO(path_uses_vpick("path/to.v/foo__"));
+        ASSERT_OK_ZERO(path_uses_vpick("foo___.raw"));
+
+        ASSERT_LE(path_uses_vpick("/"), 0);
+        ASSERT_LE(path_uses_vpick("."), 0);
+        ASSERT_LE(path_uses_vpick(""), 0);
+}
+
 DEFINE_TEST_MAIN(LOG_DEBUG);