summaryrefslogtreecommitdiffstats
path: root/discover/parser.c
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 /discover/parser.c
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>
Diffstat (limited to 'discover/parser.c')
-rw-r--r--discover/parser.c97
1 files changed, 93 insertions, 4 deletions
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)
OpenPOWER on IntegriCloud