-#include <petitboot-paths.h>
+#include <fcntl.h>
#include <stdlib.h>
-#include <string.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"
-extern struct parser native_parser;
-extern struct parser yaboot_parser;
-extern struct parser kboot_parser;
+struct parser __grub2_parser;
+struct parser __kboot_parser;
+struct parser __native_parser;
+struct parser __yaboot_parser;
-/* array of parsers, ordered by priority */
-static struct parser *parsers[] = {
- &native_parser,
- &yaboot_parser,
- &kboot_parser,
+static const struct parser *const parsers[] = {
+// &__native_parser,
+ &__kboot_parser,
+ &__grub2_parser,
+ &__yaboot_parser,
NULL
};
-void iterate_parsers(const char *devpath, const char *mountpoint)
+static const int max_file_size = 1024 * 1024;
+
+static int read_file(struct discover_context *ctx,
+ const char *filename, char **bufp, int *lenp)
{
- int i;
+ struct stat statbuf;
+ int rc, fd, i, len;
+ char *buf;
- pb_log("trying parsers for %s\n", devpath);
+ 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;
- for (i = 0; parsers[i]; i++) {
- pb_log("\ttrying parser '%s'\n", parsers[i]->name);
- /* just use a dummy device path for now */
- if (parsers[i]->parse(devpath))
- return;
}
- pb_log("\tno boot_options found\n");
-}
-/* convenience functions for parsers */
-void free_device(struct device *dev)
-{
- if (!dev)
- return;
- if (dev->id)
- free(dev->id);
- if (dev->name)
- free(dev->name);
- if (dev->description)
- free(dev->description);
- if (dev->icon_file)
- free(dev->icon_file);
- free(dev);
+ close(fd);
+ *bufp = buf;
+ *lenp = len;
+ return 0;
+
+err_free:
+ talloc_free(buf);
+err_close:
+ close(fd);
+ return -1;
}
-void free_boot_option(struct boot_option *opt)
+static void iterate_parser_files(struct discover_context *ctx,
+ const struct parser *parser)
{
- if (!opt)
+ const char * const *filename;
+ const char *path, *url;
+ unsigned int tempfile;
+
+ if (!parser->filenames)
return;
- if (opt->name)
- free(opt->name);
- if (opt->description)
- free(opt->description);
- if (opt->icon_file)
- free(opt->icon_file);
- if (opt->boot_image_file)
- free(opt->boot_image_file);
- if (opt->initrd_file)
- free(opt->initrd_file);
- if (opt->boot_args)
- free(opt->boot_args);
- free(opt);
+
+ 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);
+
+ }
+
}
-const char *generic_icon_file(enum generic_icon_type type)
+void iterate_parsers(struct discover_context *ctx)
{
- switch (type) {
- case ICON_TYPE_DISK:
- return artwork_pathname("hdd.png");
- case ICON_TYPE_USB:
- return artwork_pathname("usbpen.png");
- case ICON_TYPE_OPTICAL:
- return artwork_pathname("cdrom.png");
- case ICON_TYPE_NETWORK:
- case ICON_TYPE_UNKNOWN:
- break;
+ int i;
+
+ 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);
+ iterate_parser_files(ctx, parsers[i]);
}
- return artwork_pathname("hdd.png");
}
+void parser_init(void)
+{
+}