summaryrefslogtreecommitdiffstats
path: root/devices.c
diff options
context:
space:
mode:
Diffstat (limited to 'devices.c')
-rw-r--r--devices.c313
1 files changed, 0 insertions, 313 deletions
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 <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <asm/byteorder.h>
-
-#include <libtwin/twin_png.h>
-#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));
-}
OpenPOWER on IntegriCloud