]> git.ozlabs.org Git - petitboot/commitdiff
parsers: change parser.parse to accept a buffer
authorJeremy Kerr <jk@ozlabs.org>
Tue, 12 Mar 2013 08:13:55 +0000 (16:13 +0800)
committerJeremy Kerr <jk@ozlabs.org>
Mon, 29 Apr 2013 04:31:12 +0000 (14:31 +1000)
Rather than having each of the parsers do their own open(), read(), etc,
use the registered filenames array to find & open parser conf files.

Signed-off-by: Jeremy Kerr <jk@ozlabs.org>
discover/grub2-parser.c
discover/kboot-parser.c
discover/parser-conf.c
discover/parser-conf.h
discover/parser.c
discover/parser.h
discover/yaboot-parser.c

index 6ef5945b11c999fe87bfa813f821b0453d5d6477..3c756c1b0f5230f120253d0d62568870459af349 100644 (file)
@@ -156,11 +156,10 @@ static const char *grub2_known_names[] = {
        NULL
 };
 
        NULL
 };
 
-static int grub2_parse(struct discover_context *dc)
+static int grub2_parse(struct discover_context *dc, char *buf, int len)
 {
        struct conf_context *conf;
        struct grub2_state *state;
 {
        struct conf_context *conf;
        struct grub2_state *state;
-       int rc;
 
        conf = talloc_zero(dc, struct conf_context);
 
 
        conf = talloc_zero(dc, struct conf_context);
 
@@ -169,7 +168,6 @@ static int grub2_parse(struct discover_context *dc)
 
        conf->dc = dc;
        conf_init_global_options(conf);
 
        conf->dc = dc;
        conf_init_global_options(conf);
-       conf->conf_files = grub2_conf_files,
        conf->get_pair = conf_get_pair_space;
        conf->process_pair = grub2_process_pair;
        conf->finish = grub2_finish;
        conf->get_pair = conf_get_pair_space;
        conf->process_pair = grub2_process_pair;
        conf->finish = grub2_finish;
@@ -182,10 +180,10 @@ static int grub2_parse(struct discover_context *dc)
        state->opt = talloc_zero(conf->dc->device, struct boot_option);
        state->opt->boot_args = talloc_strdup(state->opt, "");
 
        state->opt = talloc_zero(conf->dc->device, struct boot_option);
        state->opt->boot_args = talloc_strdup(state->opt, "");
 
-       rc = conf_parse(conf);
+       conf_parse_buf(conf, buf, len);
 
        talloc_free(conf);
 
        talloc_free(conf);
-       return rc;
+       return 1;
 }
 
 struct parser __grub2_parser = {
 }
 
 struct parser __grub2_parser = {
index c828e3072ba77d41c367bc68e3cb64391f387737..b28603e3895107299b4a27b4a5e1260f97b6c0cc 100644 (file)
@@ -133,10 +133,9 @@ static const char *const kboot_ignored_names[] = {
        NULL
 };
 
        NULL
 };
 
-static int kboot_parse(struct discover_context *dc)
+static int kboot_parse(struct discover_context *dc, char *buf, int len)
 {
        struct conf_context *conf;
 {
        struct conf_context *conf;
-       int rc;
 
        conf = talloc_zero(dc, struct conf_context);
 
 
        conf = talloc_zero(dc, struct conf_context);
 
@@ -146,15 +145,14 @@ static int kboot_parse(struct discover_context *dc)
        conf->dc = dc;
        conf->global_options = kboot_global_options,
        conf_init_global_options(conf);
        conf->dc = dc;
        conf->global_options = kboot_global_options,
        conf_init_global_options(conf);
-       conf->conf_files = kboot_conf_files,
        conf->get_pair = conf_get_pair_equal;
        conf->process_pair = kboot_process_pair;
        conf->parser_info = (void *)kboot_ignored_names,
 
        conf->get_pair = conf_get_pair_equal;
        conf->process_pair = kboot_process_pair;
        conf->parser_info = (void *)kboot_ignored_names,
 
-       rc = conf_parse(conf);
+       conf_parse_buf(conf, buf, len);
 
        talloc_free(conf);
 
        talloc_free(conf);
-       return rc;
+       return 1;
 }
 
 struct parser __kboot_parser = {
 }
 
 struct parser __kboot_parser = {
index 247e29d734fdea083ee508216271a6103b62b019..94612c326a6cdd35332443b1f5846878eafdd4fd 100644 (file)
@@ -220,14 +220,15 @@ const char *conf_get_global_option(struct conf_context *conf,
  * Called from conf_parse() with data read from a conf file.
  */
 
  * Called from conf_parse() with data read from a conf file.
  */
 
-static void conf_parse_buf(struct conf_context *conf)
+void conf_parse_buf(struct conf_context *conf, char *buf,
+               int len __attribute__((unused)))
 {
        char *pos, *name, *value;
 
        assert(conf->get_pair);
        assert(conf->process_pair);
 
 {
        char *pos, *name, *value;
 
        assert(conf->get_pair);
        assert(conf->process_pair);
 
-       for (pos = conf->buf; pos;) {
+       for (pos = buf; pos;) {
                pos = conf->get_pair(conf, pos, &name, &value, '\n');
 
                if (!value)
                pos = conf->get_pair(conf, pos, &name, &value, '\n');
 
                if (!value)
@@ -245,82 +246,3 @@ static void conf_parse_buf(struct conf_context *conf)
        if (conf->finish)
                conf->finish(conf);
 }
        if (conf->finish)
                conf->finish(conf);
 }
-
-/**
- * conf_parse - The common parser entry.
- *
- * Called from the parser specific setup routines.  Searches for .conf
- * files, reads data into buffers, and calls conf_parse_buf().
- */
-
-int conf_parse(struct conf_context *conf)
-{
-       struct device *dev;
-       int fd, rc;
-       unsigned int i;
-       struct stat stat;
-       ssize_t len;
-
-       rc = 0;
-       fd = -1;
-       len = 0;
-
-       /* The parser is only run on the first file found. */
-       /* FIXME: Could try others on error, etc. */
-
-       for (i = 0; conf->conf_files[i]; i++) {
-               char *filepath = resolve_path(conf->dc,
-                       conf->conf_files[i], conf->dc->device->device_path);
-
-               pb_log("%s: try: %s\n", __func__, filepath);
-
-               fd = open(filepath, O_RDONLY);
-
-               talloc_free(filepath);
-
-               if (fd < 0) {
-                       pb_log("%s: open failed: %s\n", __func__,
-                               strerror(errno));
-                       continue;
-               }
-
-               if (fstat(fd, &stat)) {
-                       pb_log("%s: fstat failed: %s\n", __func__,
-                               strerror(errno));
-                       continue;
-               }
-
-               conf->buf = talloc_array(conf, char, stat.st_size + 1);
-
-               len = read(fd, conf->buf, stat.st_size);
-
-               if (len < 0) {
-                       pb_log("%s: read failed: %s\n", __func__,
-                               strerror(errno));
-                       continue;
-               }
-               conf->buf[len] = 0;
-
-               break;
-       }
-
-       if (fd >= 0)
-               close(fd);
-
-       if (len <= 0)
-               goto out;
-
-       dev = conf->dc->device->device;
-       if (!dev->icon_file)
-               dev->icon_file = talloc_strdup(dev,
-                       generic_icon_file(guess_device_type(conf->dc)));
-
-       conf_parse_buf(conf);
-
-       rc = 1;
-
-out:
-       pb_log("%s: %s\n", __func__, (rc ? "ok" : "failed"));
-       return rc;
-}
-
index efeb4f3d241c6a994db0fc225b1cc27b24455d6b..3704bcb4117af9dab8426bc2faf48468137fdcc5 100644 (file)
@@ -29,9 +29,7 @@ struct conf_global_option {
 struct conf_context {
        void *parser_info;
        struct discover_context *dc;
 struct conf_context {
        void *parser_info;
        struct discover_context *dc;
-       char *buf;
        struct conf_global_option *global_options;
        struct conf_global_option *global_options;
-       const char *const *conf_files;
 
        char *(*get_pair)(struct conf_context *conf, char *str, char **name_out,
                char **value_out, char terminator);
 
        char *(*get_pair)(struct conf_context *conf, char *str, char **name_out,
                char **value_out, char terminator);
@@ -40,7 +38,7 @@ struct conf_context {
        void (*finish)(struct conf_context *conf);
 };
 
        void (*finish)(struct conf_context *conf);
 };
 
-int conf_parse(struct conf_context *conf);
+void conf_parse_buf(struct conf_context *conf, char *buf, int len);
 char *conf_get_pair(struct conf_context *conf, char *str, char **name_out,
        char **value_out, char delimiter, char terminator);
 void conf_init_global_options(struct conf_context *conf);
 char *conf_get_pair(struct conf_context *conf, char *str, char **name_out,
        char **value_out, char delimiter, char terminator);
 void conf_init_global_options(struct conf_context *conf);
index 5f4e5149557678c6e0c34c59c02a42f5b5b46317..1f3674d3ee461cc24fac0f9ca5a8fc11d765fb1c 100644 (file)
@@ -1,12 +1,17 @@
 
 
+#include <fcntl.h>
 #include <stdlib.h>
 #include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
 
 #include "types/types.h"
 #include <log/log.h>
 
 #include "types/types.h"
 #include <log/log.h>
+#include <talloc/talloc.h>
 
 #include "device-handler.h"
 #include "parser.h"
 #include "parser-utils.h"
 
 #include "device-handler.h"
 #include "parser.h"
 #include "parser-utils.h"
+#include "paths.h"
 
 struct parser __grub2_parser;
 struct parser __kboot_parser;
 
 struct parser __grub2_parser;
 struct parser __kboot_parser;
@@ -21,19 +26,103 @@ static const struct parser *const parsers[] = {
        NULL
 };
 
        NULL
 };
 
+static const int max_file_size = 1024 * 1024;
+
+static int read_file(struct discover_context *ctx,
+               const char *filename, char **bufp, int *lenp)
+{
+       struct stat statbuf;
+       int rc, fd, i, len;
+       char *buf;
+
+       fd = open(filename, O_RDONLY);
+       if (fd < 0)
+               return -1;
+
+       rc = fstat(fd, &statbuf);
+       if (rc < 0)
+               goto err_close;
+
+       len = statbuf.st_size;
+       if (len > max_file_size)
+               goto err_close;
+
+       buf = talloc_array(ctx, char, len);
+       if (!buf)
+               goto err_close;
+
+       for (i = 0; i < len; i += rc) {
+               rc = read(fd, buf + i, len - i);
+
+               /* unexpected EOF: trim and return */
+               if (rc == 0) {
+                       len = i;
+                       break;
+               }
+
+               if (rc < 0)
+                       goto err_free;
+
+       }
+
+       close(fd);
+       *bufp = buf;
+       *lenp = len;
+       return 0;
+
+err_free:
+       talloc_free(buf);
+err_close:
+       close(fd);
+       return -1;
+}
+
+static void iterate_parser_files(struct discover_context *ctx,
+               const struct parser *parser)
+{
+       const char * const *filename;
+       const char *path, *url;
+       unsigned int tempfile;
+
+       if (!parser->filenames)
+               return;
+
+       for (filename = parser->filenames; *filename; filename++) {
+               int rc, len;
+               char *buf;
+
+               url = resolve_path(ctx, *filename, ctx->device->device_path);
+               if (!url)
+                       continue;
+
+               path = load_file(ctx, url, &tempfile);
+
+               if (!path)
+                       continue;
+
+               rc = read_file(ctx, path, &buf, &len);
+               if (!rc) {
+                       parser->parse(ctx, buf, len);
+                       talloc_free(buf);
+               }
+
+               if (tempfile)
+                       unlink(path);
+
+       }
+
+}
+
 void iterate_parsers(struct discover_context *ctx)
 {
        int i;
 void iterate_parsers(struct discover_context *ctx)
 {
        int i;
-       unsigned int count = 0;
 
        pb_log("trying parsers for %s\n", ctx->device->device->id);
 
        for (i = 0; parsers[i]; i++) {
                pb_log("\ttrying parser '%s'\n", parsers[i]->name);
 
        pb_log("trying parsers for %s\n", ctx->device->device->id);
 
        for (i = 0; parsers[i]; i++) {
                pb_log("\ttrying parser '%s'\n", parsers[i]->name);
-               count += parsers[i]->parse(ctx);
+               iterate_parser_files(ctx, parsers[i]);
        }
        }
-       if (!count)
-               pb_log("\tno boot_options found\n");
 }
 
 void parser_init(void)
 }
 
 void parser_init(void)
index c2f02d683d3f50b85b487752ac256f68e9abdc7b..18c9963e863021b642f7adbd840278a99fbfe53f 100644 (file)
@@ -6,7 +6,8 @@ struct discover_context;
 struct parser {
        char                    *name;
        const char * const      *filenames;
 struct parser {
        char                    *name;
        const char * const      *filenames;
-       int                     (*parse)(struct discover_context *ctx);
+       int                     (*parse)(struct discover_context *ctx,
+                                               char *buf, int len);
 };
 
 enum generic_icon_type {
 };
 
 enum generic_icon_type {
index 0477d38ee6e7715e00d70c19c2aa4ff19edf3f4d..d7a0a9f80744ef9e533b705637b1b98f87a86b24 100644 (file)
@@ -287,11 +287,10 @@ static const char *yaboot_known_names[] = {
        NULL
 };
 
        NULL
 };
 
-static int yaboot_parse(struct discover_context *dc)
+static int yaboot_parse(struct discover_context *dc, char *buf, int len)
 {
        struct conf_context *conf;
        struct yaboot_state *state;
 {
        struct conf_context *conf;
        struct yaboot_state *state;
-       int rc;
 
        conf = talloc_zero(dc, struct conf_context);
 
 
        conf = talloc_zero(dc, struct conf_context);
 
@@ -301,7 +300,6 @@ static int yaboot_parse(struct discover_context *dc)
        conf->dc = dc;
        conf->global_options = yaboot_global_options,
        conf_init_global_options(conf);
        conf->dc = dc;
        conf->global_options = yaboot_global_options,
        conf_init_global_options(conf);
-       conf->conf_files = yaboot_conf_files,
        conf->get_pair = conf_get_pair_equal;
        conf->process_pair = yaboot_process_pair;
        conf->finish = yaboot_finish;
        conf->get_pair = conf_get_pair_equal;
        conf->process_pair = yaboot_process_pair;
        conf->finish = yaboot_finish;
@@ -314,10 +312,10 @@ static int yaboot_parse(struct discover_context *dc)
        state->opt = talloc_zero(conf->dc->device, struct boot_option);
        state->opt->boot_args = talloc_strdup(state->opt, "");
 
        state->opt = talloc_zero(conf->dc->device, struct boot_option);
        state->opt->boot_args = talloc_strdup(state->opt, "");
 
-       rc = conf_parse(conf);
+       conf_parse_buf(conf, buf, len);
 
        talloc_free(conf);
 
        talloc_free(conf);
-       return rc;
+       return 1;
 }
 
 struct parser __yaboot_parser = {
 }
 
 struct parser __yaboot_parser = {