summaryrefslogtreecommitdiffstats
path: root/devices/kboot-parser.c
diff options
context:
space:
mode:
authorJeremy Kerr <jk@ozlabs.org>2008-12-15 15:22:34 +1100
committerJeremy Kerr <jk@ozlabs.org>2008-12-15 15:22:34 +1100
commit32e6a41f33e5576716b351bd473a27939fe94fa1 (patch)
tree0d6b75ac0a02d2496416095405cb9498777c3beb /devices/kboot-parser.c
parent000a92b4fa909c432732ac3ed8f28eeeaeac70ee (diff)
downloadtalos-petitboot-32e6a41f33e5576716b351bd473a27939fe94fa1.tar.gz
talos-petitboot-32e6a41f33e5576716b351bd473a27939fe94fa1.zip
Initial support for multiple UIs
Move the device discovery code from separate udev helpers to a single process to listen on two sockets: one SOCK_DGRAM for incoming udev events, and one SOCK_STREAM for UIs to connect. Initial support for client/server infrastructure, still need to wire-up the udev messages. Signed-off-by: Jeremy Kerr <jk@ozlabs.org>
Diffstat (limited to 'devices/kboot-parser.c')
-rw-r--r--devices/kboot-parser.c288
1 files changed, 0 insertions, 288 deletions
diff --git a/devices/kboot-parser.c b/devices/kboot-parser.c
deleted file mode 100644
index df2e762..0000000
--- a/devices/kboot-parser.c
+++ /dev/null
@@ -1,288 +0,0 @@
-#define _GNU_SOURCE
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <ctype.h>
-#include <unistd.h>
-
-#include <fcntl.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-
-#include "parser.h"
-#include "params.h"
-
-#define buf_size 1024
-
-static const char *devpath;
-
-static int param_is_ignored(const char *param)
-{
- static const char *ignored_options[] =
- { "message", "timeout", "default", NULL };
- const char **str;
-
- for (str = ignored_options; *str; str++)
- if (streq(*str, param))
- return 1;
- return 0;
-}
-
-/**
- * Splits a name=value pair, with value terminated by @term (or nul). if there
- * is no '=', then only the value is populated, and *name is set to NULL. The
- * string is modified in place.
- *
- * Returns the next byte to process, or null if we've hit the end of the
- * string.
- *
- * */
-static char *get_param_pair(char *str, char **name_out, char **value_out,
- char terminator)
-{
- char *sep, *tmp, *name, *value;
-
- /* terminate the value */
- tmp = strchr(str, terminator);
- if (tmp)
- *tmp = 0;
- else
- tmp = NULL;
-
- sep = strchr(str, '=');
- if (!sep) {
- *name_out = NULL;
- *value_out = str;
- return tmp ? tmp + 1 : NULL;
- }
-
- /* terminate the name */
- *sep = 0;
-
- /* remove leading spaces */
- for (name = str; isspace(*name); name++);
- for (value = sep + 1; isspace(*value); value++);
-
- /* .. and trailing ones.. */
- for (sep--; isspace(*sep); sep--)
- *sep = 0;
- for (sep = value + strlen(value) - 1; isspace(*sep); sep--)
- *sep = 0;
-
- *name_out = name;
- *value_out = value;
-
- return tmp ? tmp + 1 : NULL;
-}
-
-struct global_option {
- char *name;
- char *value;
-};
-
-
-static struct global_option global_options[] = {
- { .name = "root" },
- { .name = "initrd" },
- { .name = "video" },
- { .name = NULL }
-};
-
-/*
- * Check if an option (name=value) is a global option. If so, store it in
- * the global options table, and return 1. Otherwise, return 0.
- */
-static int check_for_global_option(const char *name, const char *value)
-{
- int i;
-
- for (i = 0; global_options[i].name ;i++) {
- if (!strcmp(name, global_options[i].name)) {
- global_options[i].value = strdup(value);
- return 1;
- }
- }
- return 0;
-}
-
-static char *get_global_option(const char *name)
-{
- int i;
-
- for (i = 0; global_options[i].name ;i++)
- if (!strcmp(name, global_options[i].name))
- return global_options[i].value;
-
- return NULL;
-}
-
-static int parse_option(struct boot_option *opt, char *config)
-{
- char *pos, *name, *value, *root, *initrd, *cmdline, *tmp;
-
- root = initrd = cmdline = NULL;
-
- /* remove quotes around the value */
- while (*config == '"' || *config == '\'')
- config++;
-
- pos = config + strlen(config) - 1;
- while (*pos == '"' || *pos == '\'')
- *(pos--) = 0;
-
- if (!strlen(pos))
- return 0;
-
- pos = strchr(config, ' ');
-
- /* if there's no space, it's only a kernel image with no params */
- if (!pos) {
- opt->boot_image_file = resolve_path(config, devpath);
- opt->description = strdup(config);
- return 1;
- }
-
- *pos = 0;
- opt->boot_image_file = resolve_path(config, devpath);
-
- cmdline = malloc(buf_size);
- *cmdline = 0;
-
- for (pos++; pos;) {
- pos = get_param_pair(pos, &name, &value, ' ');
-
- if (!name) {
- strcat(cmdline, " ");
- strcat(cmdline, value);
-
- } else if (streq(name, "initrd")) {
- initrd = value;
-
- } else if (streq(name, "root")) {
- root = value;
-
- } else {
- strcat(cmdline, " ");
- *(value - 1) = '=';
- strcat(cmdline, name);
- }
- }
-
- if (!root)
- root = get_global_option("root");
- if (!initrd)
- initrd = get_global_option("initrd");
-
- if (initrd) {
- asprintf(&tmp, "initrd=%s %s", initrd, cmdline);
- free(cmdline);
- cmdline = tmp;
-
- opt->initrd_file = resolve_path(initrd, devpath);
- }
-
- if (root) {
- asprintf(&tmp, "root=%s %s", root, cmdline);
- free(cmdline);
- cmdline = tmp;
-
- } else if (initrd) {
- /* if there's an initrd but no root, fake up /dev/ram0 */
- asprintf(&tmp, "root=/dev/ram0 %s", cmdline);
- free(cmdline);
- cmdline = tmp;
- }
-
- pb_log("kboot cmdline: %s\n", cmdline);
- opt->boot_args = cmdline;
-
- asprintf(&opt->description, "%s %s",
- config, opt->boot_args);
-
- return 1;
-}
-
-static void parse_buf(struct device *dev, char *buf)
-{
- char *pos, *name, *value;
- int sent_device = 0;
-
- for (pos = buf; pos;) {
- struct boot_option opt;
-
- pos = get_param_pair(pos, &name, &value, '\n');
-
- pb_log("kboot param: '%s' = '%s'\n", name, value);
-
- if (name == NULL || param_is_ignored(name))
- continue;
-
- if (*name == '#')
- continue;
-
- if (check_for_global_option(name, value))
- continue;
-
- memset(&opt, 0, sizeof(opt));
- opt.name = strdup(name);
-
- if (parse_option(&opt, value))
- if (!sent_device++)
- add_device(dev);
- add_boot_option(&opt);
-
- free(opt.name);
- }
-}
-
-static int parse(const char *device)
-{
- char *filepath, *buf;
- int fd, len, rc = 0;
- struct stat stat;
- struct device *dev;
-
- devpath = device;
-
- filepath = resolve_path("/etc/kboot.conf", devpath);
-
- fd = open(filepath, O_RDONLY);
- if (fd < 0)
- goto out_free_path;
-
- if (fstat(fd, &stat))
- goto out_close;
-
- buf = malloc(stat.st_size + 1);
- if (!buf)
- goto out_close;;
-
- len = read(fd, buf, stat.st_size);
- if (len < 0)
- goto out_free_buf;
- buf[len] = 0;
-
- dev = malloc(sizeof(*dev));
- memset(dev, 0, sizeof(*dev));
- dev->id = strdup(device);
- dev->icon_file = strdup(generic_icon_file(guess_device_type()));
-
- parse_buf(dev, buf);
-
- rc = 1;
-
-out_free_buf:
- free(buf);
-out_close:
- close(fd);
-out_free_path:
- free(filepath);
- return rc;
-}
-
-struct parser kboot_parser = {
- .name = "kboot.conf parser",
- .priority = 98,
- .parse = parse
-};
OpenPOWER on IntegriCloud