discover: Add support for checking directories in parser API
authorJeremy Kerr <jk@ozlabs.org>
Fri, 24 Jan 2014 06:39:37 +0000 (14:39 +0800)
committerJeremy Kerr <jk@ozlabs.org>
Thu, 30 Jan 2014 13:59:10 +0000 (21:59 +0800)
This change adds a function to the parser API:

  int parser_check_dir(struct discover_context *ctx,
   struct discover_device *dev, const char *dirname)

- which allows parsers to check for the presence of a directory (path of
'dirname') on the device ('dev'). We use this in the GRUB2 parser to
implement the `test -d` check.

Signed-off-by: Jeremy Kerr <jk@ozlabs.org>
discover/grub2/builtins.c
discover/parser.c
discover/parser.h
test/parser/parser-test.h
test/parser/utils.c

index 75110760082ec51324f685e5c5b84bebac5e5745..6ada2a64c130ae05c66c12c15753e84e0af684e2 100644 (file)
@@ -154,6 +154,15 @@ static bool builtin_test_op_file(struct grub2_script *script, char op,
        return result;
 }
 
+static bool builtin_test_op_dir(struct grub2_script *script, char op,
+               const char *dir)
+{
+       if (op != 'd')
+               return false;
+
+       return parser_check_dir(script->ctx, script->ctx->device, dir) == 0;
+}
+
 static bool builtin_test_op(struct grub2_script *script,
                int argc, char **argv, int *consumed)
 {
@@ -207,6 +216,11 @@ static bool builtin_test_op(struct grub2_script *script,
                        *consumed = 2;
                        return builtin_test_op_file(script, op[1], a1);
                }
+
+               if (!strcmp(op, "-d")) {
+                       *consumed = 2;
+                       return builtin_test_op_dir(script, op[1], a1);
+               }
        }
 
        op = argv[0];
index 21b48debcb31d52e4f788040c1ce391e4ded7fc6..74b2559c8ab9776d138bddc7a8ea51ef9625351d 100644 (file)
@@ -49,6 +49,25 @@ int parser_request_file(struct discover_context *ctx,
        return rc;
 }
 
+int parser_check_dir(struct discover_context *ctx,
+               struct discover_device *dev, const char *dirname)
+{
+       struct stat statbuf;
+       char *path;
+       int rc;
+
+       if (!dev->mount_path)
+               return -1;
+
+       path = local_path(ctx, dev, dirname);
+
+       rc = stat(path, &statbuf);
+       if (!rc)
+               return -1;
+
+       return S_ISDIR(statbuf.st_mode) ? 0 : -1;
+}
+
 int parser_replace_file(struct discover_context *ctx,
                struct discover_device *dev, const char *filename,
                char *buf, int len)
index 970d72c05b6814f33c80ff674eef68e378c67c9f..e0e8dc67c9a948d21723e9eec954a9b669de8418 100644 (file)
@@ -62,5 +62,7 @@ int parser_replace_file(struct discover_context *ctx,
                char *buf, int len);
 int parser_request_url(struct discover_context *ctx, struct pb_url *url,
                char **buf, int *len);
+int parser_check_dir(struct discover_context *ctx,
+               struct discover_device *dev, const char *dirname);
 
 #endif /* _PARSER_H */
index 7c406504e3d6fde9f0ffaab29643911ac64d39ca..631f1e52ae765139742c1033cee51c11f2937c8d 100644 (file)
@@ -36,6 +36,8 @@ void test_remove_device(struct parser_test *test, struct discover_device *dev);
 
 void test_add_file_data(struct parser_test *test, struct discover_device *dev,
                const char *filename, const void *data, int size);
+void test_add_dir(struct parser_test *test, struct discover_device *dev,
+               const char *dirname);
 void test_set_event_source(struct parser_test *test);
 void test_set_event_param(struct event *event, const char *name,
                const char *value);
index 67401abc9e0d8fa5d95cfb2ed9f1b27ba2fce35e..838250b50dc1708fdd81578e5ac99b50fc1ad89a 100644 (file)
@@ -26,6 +26,10 @@ struct p_item {
 
 struct test_file {
        struct discover_device  *dev;
+       enum {
+               TEST_FILE,
+               TEST_DIR,
+       }                       type;
        const char              *name;
        void                    *data;
        int                     size;
@@ -158,6 +162,7 @@ void test_add_file_data(struct parser_test *test, struct discover_device *dev,
        struct test_file *file;
 
        file = talloc_zero(test, struct test_file);
+       file->type = TEST_FILE;
        file->dev = dev;
        file->name = filename;
        file->data = talloc_memdup(test, data, size);
@@ -165,6 +170,18 @@ void test_add_file_data(struct parser_test *test, struct discover_device *dev,
        list_add(&test->files, &file->list);
 }
 
+void test_add_dir(struct parser_test *test, struct discover_device *dev,
+               const char *dirname)
+{
+       struct test_file *file;
+
+       file = talloc_zero(test, struct test_file);
+       file->type = TEST_DIR;
+       file->dev = dev;
+       file->name = dirname;
+       list_add(&test->files, &file->list);
+}
+
 void test_set_event_source(struct parser_test *test)
 {
         test->ctx->event = talloc_zero(test->ctx, struct event);
@@ -189,6 +206,8 @@ int parser_request_file(struct discover_context *ctx,
                        continue;
                if (strcmp(file->name, filename))
                        continue;
+               if (file->type != TEST_FILE)
+                       continue;
 
                /* the read_file() interface always adds a trailing null
                 * for string-safety; do the same here */
@@ -203,6 +222,25 @@ int parser_request_file(struct discover_context *ctx,
        return -1;
 }
 
+int parser_check_dir(struct discover_context *ctx,
+               struct discover_device *dev, const char *dirname)
+{
+       struct parser_test *test = ctx->test_data;
+       struct test_file *file;
+
+       printf("%s: %s\n", __func__, dirname);
+
+       list_for_each_entry(&test->files, file, list) {
+               if (file->dev != dev)
+                       continue;
+               if (strcmp(file->name, dirname))
+                       continue;
+               return file->type == TEST_DIR ? 0 : -1;
+       }
+
+       return -1;
+}
+
 int parser_replace_file(struct discover_context *ctx,
                struct discover_device *dev, const char *filename,
                char *buf, int len)