From: Jeremy Kerr Date: Fri, 24 Jan 2014 06:39:37 +0000 (+0800) Subject: discover: Add support for checking directories in parser API X-Git-Tag: v1.0.0~254 X-Git-Url: http://git.ozlabs.org/?p=petitboot;a=commitdiff_plain;h=4896183708855fbfd0aa892537fbcc17ed7eb971;ds=sidebyside discover: Add support for checking directories in parser API 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 --- diff --git a/discover/grub2/builtins.c b/discover/grub2/builtins.c index 7511076..6ada2a6 100644 --- a/discover/grub2/builtins.c +++ b/discover/grub2/builtins.c @@ -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]; diff --git a/discover/parser.c b/discover/parser.c index 21b48de..74b2559 100644 --- a/discover/parser.c +++ b/discover/parser.c @@ -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) diff --git a/discover/parser.h b/discover/parser.h index 970d72c..e0e8dc6 100644 --- a/discover/parser.h +++ b/discover/parser.h @@ -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 */ diff --git a/test/parser/parser-test.h b/test/parser/parser-test.h index 7c40650..631f1e5 100644 --- a/test/parser/parser-test.h +++ b/test/parser/parser-test.h @@ -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); diff --git a/test/parser/utils.c b/test/parser/utils.c index 67401ab..838250b 100644 --- a/test/parser/utils.c +++ b/test/parser/utils.c @@ -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)