summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeremy Kerr <jk@ozlabs.org>2013-03-12 16:13:55 +0800
committerJeremy Kerr <jk@ozlabs.org>2013-04-29 14:31:12 +1000
commit06a49ebdfc795a70b938f5aee29f3c488ef9fc21 (patch)
tree57ef497f90ed6dbbccbdd0cedae6e7f0989bd150
parent39e06f5cfda0ed0c1eeb7a7604a3d05dda81ccf1 (diff)
downloadtalos-petitboot-06a49ebdfc795a70b938f5aee29f3c488ef9fc21.tar.gz
talos-petitboot-06a49ebdfc795a70b938f5aee29f3c488ef9fc21.zip
parsers: change parser.parse to accept a buffer
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>
-rw-r--r--discover/grub2-parser.c8
-rw-r--r--discover/kboot-parser.c8
-rw-r--r--discover/parser-conf.c84
-rw-r--r--discover/parser-conf.h4
-rw-r--r--discover/parser.c97
-rw-r--r--discover/parser.h3
-rw-r--r--discover/yaboot-parser.c8
7 files changed, 108 insertions, 104 deletions
diff --git a/discover/grub2-parser.c b/discover/grub2-parser.c
index 6ef5945..3c756c1 100644
--- a/discover/grub2-parser.c
+++ b/discover/grub2-parser.c
@@ -156,11 +156,10 @@ static const char *grub2_known_names[] = {
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;
- int rc;
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->conf_files = grub2_conf_files,
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, "");
- rc = conf_parse(conf);
+ conf_parse_buf(conf, buf, len);
talloc_free(conf);
- return rc;
+ return 1;
}
struct parser __grub2_parser = {
diff --git a/discover/kboot-parser.c b/discover/kboot-parser.c
index c828e30..b28603e 100644
--- a/discover/kboot-parser.c
+++ b/discover/kboot-parser.c
@@ -133,10 +133,9 @@ static const char *const kboot_ignored_names[] = {
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;
- int rc;
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->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,
- rc = conf_parse(conf);
+ conf_parse_buf(conf, buf, len);
talloc_free(conf);
- return rc;
+ return 1;
}
struct parser __kboot_parser = {
diff --git a/discover/parser-conf.c b/discover/parser-conf.c
index 247e29d..94612c3 100644
--- a/discover/parser-conf.c
+++ b/discover/parser-conf.c
@@ -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.
*/
-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);
- for (pos = conf->buf; pos;) {
+ for (pos = buf; pos;) {
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);
}
-
-/**
- * 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;
-}
-
diff --git a/discover/parser-conf.h b/discover/parser-conf.h
index efeb4f3..3704bcb 100644
--- a/discover/parser-conf.h
+++ b/discover/parser-conf.h
@@ -29,9 +29,7 @@ struct conf_global_option {
struct conf_context {
void *parser_info;
struct discover_context *dc;
- char *buf;
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);
@@ -40,7 +38,7 @@ struct conf_context {
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);
diff --git a/discover/parser.c b/discover/parser.c
index 5f4e514..1f3674d 100644
--- a/discover/parser.c
+++ b/discover/parser.c
@@ -1,12 +1,17 @@
+#include <fcntl.h>
#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.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 "paths.h"
struct parser __grub2_parser;
struct parser __kboot_parser;
@@ -21,19 +26,103 @@ static const struct parser *const parsers[] = {
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;
- 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);
- count += parsers[i]->parse(ctx);
+ iterate_parser_files(ctx, parsers[i]);
}
- if (!count)
- pb_log("\tno boot_options found\n");
}
void parser_init(void)
diff --git a/discover/parser.h b/discover/parser.h
index c2f02d6..18c9963 100644
--- a/discover/parser.h
+++ b/discover/parser.h
@@ -6,7 +6,8 @@ struct discover_context;
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 {
diff --git a/discover/yaboot-parser.c b/discover/yaboot-parser.c
index 0477d38..d7a0a9f 100644
--- a/discover/yaboot-parser.c
+++ b/discover/yaboot-parser.c
@@ -287,11 +287,10 @@ static const char *yaboot_known_names[] = {
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;
- int rc;
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->conf_files = yaboot_conf_files,
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, "");
- rc = conf_parse(conf);
+ conf_parse_buf(conf, buf, len);
talloc_free(conf);
- return rc;
+ return 1;
}
struct parser __yaboot_parser = {
OpenPOWER on IntegriCloud