X-Git-Url: https://git.ozlabs.org/?p=petitboot;a=blobdiff_plain;f=devices.c;fp=devices.c;h=0000000000000000000000000000000000000000;hp=77860d0546a8dcc967da4a71a2e803f91db6f836;hb=32e6a41f33e5576716b351bd473a27939fe94fa1;hpb=000a92b4fa909c432732ac3ed8f28eeeaeac70ee diff --git a/devices.c b/devices.c deleted file mode 100644 index 77860d0..0000000 --- a/devices.c +++ /dev/null @@ -1,313 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include "petitboot.h" -#include "petitboot-paths.h" -#include "devices/message.h" - -#define PBOOT_DEFAULT_ICON "tux.png" - -static const char *default_icon = artwork_pathname(PBOOT_DEFAULT_ICON); - -struct discovery_context { - /* nothing at present */ - int pad; -} _ctx; - -struct device_context { - struct discovery_context *discovery_ctx; - uint8_t action; - int device_idx; -}; - -static twin_pixmap_t *get_icon(const char *filename) -{ - /* todo: cache */ - twin_pixmap_t *icon; - - if (!filename) - filename = default_icon; - -retry: - LOG("loading icon %s ... ", filename); - icon = twin_png_to_pixmap(filename, TWIN_ARGB32); - LOG("%s\n", icon ? "ok" : "failed"); - - if (!icon && filename != default_icon) { - filename = default_icon; - LOG("reverting to default icon %s\n", filename); - goto retry; - } - - return icon; -} - -#define MAX_LEN 4096 -static char *read_string(int fd) -{ - int len; - uint32_t len_buf; - char *str, *pos; - - if (read(fd, &len_buf, sizeof(len_buf)) != sizeof(len_buf)) { - perror("read"); - return NULL; - } - - len = __be32_to_cpu(len_buf); - if (len + 1 > MAX_LEN) { - /* todo: truncate instead */ - return NULL; - } - - pos = str = malloc(len + 1); - - while (len) { - int rc = read(fd, pos, len); - if (rc <= 0) { - free(str); - LOG("read failed: %s\n", strerror(errno)); - return NULL; - } - pos += rc; - len -= rc; - } - *pos = '\0'; - - return str; -} - -static int _read_strings(int fd, void *ptr, int n_strings) -{ - char **strings = ptr; - int i, ret = TWIN_TRUE; - - for (i = 0; i < n_strings; i++) { - strings[i] = read_string(fd); - if (!strings[i]) { - ret = TWIN_FALSE; - break; - } - } - - if (!ret) - while (i-- > 0) { - free(strings[i]); - strings[i] = NULL; - } - - return ret; -} - -static void _free_strings(void *ptr, int n_strings) -{ - char **strings = ptr; - int i; - - for (i = 0; i < n_strings; i++) - free(strings[i]); - -} - -#define n_strings(x) (sizeof((x)) / sizeof(char *)) -#define read_strings(f,x) _read_strings((f), &(x), n_strings(x)) -#define free_strings(x) _free_strings(&(x), n_strings(x)) - -static int read_action(int fd, uint8_t *action) -{ - return read(fd, action, sizeof(*action)) != sizeof(*action); -} - -static int read_device(int fd, struct device_context *dev_ctx) -{ - /* name, description, icon_file */ - struct device dev; - twin_pixmap_t *icon; - int index = -1; - - if (!read_strings(fd, dev)) - return TWIN_FALSE; - - LOG("got device: '%s'\n", dev.name); - - icon = get_icon(dev.icon_file); - - if (!icon) - goto out; - - index = dev_ctx->device_idx = pboot_add_device(dev.id, dev.name, icon); - -out: - free_strings(dev); - - return index != -1; -} - -static int read_option(int fd, struct device_context *dev_ctx) -{ - struct boot_option *opt = malloc(sizeof(*opt)); - twin_pixmap_t *icon; - int index = -1; - - if (!opt) - return TWIN_FALSE; - - if (!read_strings(fd, (*opt))) - return TWIN_FALSE; - - LOG("got option: '%s'\n", opt->name); - icon = get_icon(opt->icon_file); - - if (icon) - index = pboot_add_option(dev_ctx->device_idx, opt->name, - opt->description, icon, opt); - - return index != -1; -} - -static twin_bool_t pboot_proc_client_sock(int sock, twin_file_op_t ops, - void *closure) -{ - struct device_context *dev_ctx = closure; - uint8_t action; - - if (read_action(sock, &action)) - goto out_err; - - if (action == DEV_ACTION_ADD_DEVICE) { - if (!read_device(sock, dev_ctx)) - goto out_err; - - } else if (action == DEV_ACTION_ADD_OPTION) { - if (dev_ctx->device_idx == -1) { - LOG("option, but no device has been sent?\n"); - goto out_err; - } - - if (!read_option(sock, dev_ctx)) - goto out_err; - - } else if (action == DEV_ACTION_REMOVE_DEVICE) { - char *dev_id = read_string(sock); - if (!dev_id) - goto out_err; - - LOG("remove device %s\n", dev_id); - pboot_remove_device(dev_id); - - } else { - LOG("unsupported action %d\n", action); - goto out_err; - } - - return TWIN_TRUE; - -out_err: - close(sock); - return TWIN_FALSE; -} - -static twin_bool_t pboot_proc_server_sock(int sock, twin_file_op_t ops, - void *closure) -{ - int fd; - struct discovery_context *disc_ctx = closure; - struct device_context *dev_ctx; - - fd = accept(sock, NULL, 0); - if (fd < 0) { - LOG("accept failed: %s", strerror(errno)); - return TWIN_FALSE; - } - - dev_ctx = malloc(sizeof(*dev_ctx)); - dev_ctx->discovery_ctx = disc_ctx; - dev_ctx->device_idx = -1; - dev_ctx->action = 0xff; - - twin_set_file(pboot_proc_client_sock, fd, TWIN_READ, dev_ctx); - - return TWIN_TRUE; -} - -int pboot_start_device_discovery(int udev_trigger) -{ - int sock; - struct sockaddr_un addr; - - unlink(PBOOT_DEVICE_SOCKET); - - sock = socket(PF_UNIX, SOCK_STREAM, 0); - if (sock < 0) { - perror("socket"); - return TWIN_FALSE; - } - - addr.sun_family = AF_UNIX; - strcpy(addr.sun_path, PBOOT_DEVICE_SOCKET); - - if (bind(sock, (struct sockaddr *)&addr, sizeof(addr))) { - LOG("can't bind to %s: %s", addr.sun_path, strerror(errno)); - return TWIN_FALSE; - } - - if (listen(sock, 1)) { - LOG("can't listen on socket %s: %s", - addr.sun_path, strerror(errno)); - return TWIN_FALSE; - } - - LOG("listening on %s\n", addr.sun_path); - - twin_set_file(pboot_proc_server_sock, sock, TWIN_READ, &_ctx); - - if (udev_trigger) { - int rc = system("udevtrigger"); - if (rc) - LOG("udevtrigger failed, rc %d\n", rc); - } - - return TWIN_TRUE; -} - -void pboot_exec_option(void *data) -{ - struct boot_option *opt = data; - char *kexec_opts[10]; - int i, nr_opts = 2; - - kexec_opts[0] = "/usr/sbin/kexec"; - kexec_opts[1] = "-f"; - if (opt->initrd_file && *opt->initrd_file) { - kexec_opts[nr_opts] = malloc(10 + strlen(opt->initrd_file)); - sprintf(kexec_opts[nr_opts], "--initrd=%s", opt->initrd_file); - nr_opts++; - } - if (opt->boot_args && *opt->boot_args) { - kexec_opts[nr_opts] = malloc(10 + strlen(opt->boot_args)); - sprintf(kexec_opts[nr_opts], "--command-line=%s", - opt->boot_args); - nr_opts++; - } - - kexec_opts[nr_opts++] = opt->boot_image_file; - kexec_opts[nr_opts] = NULL; - - LOG("calling kexec:\n"); - for (i = 0; i < nr_opts; i++) { - LOG("\t'%s'\n", kexec_opts[i]); - } - fflush(stdout); - - execv(kexec_opts[0], kexec_opts); - pboot_message("kexec failed: %s", strerror(errno)); - LOG("execv() failed: %s", strerror(errno)); -}