Make udev_event a generic event
authorGeoff Levand <geoffrey.levand@am.sony.com>
Sun, 12 Apr 2009 15:11:53 +0000 (15:11 +0000)
committerJeremy Kerr <jk@ozlabs.org>
Tue, 30 Jun 2009 07:29:20 +0000 (15:29 +0800)
The struct udev_event can be used as a generic event, so rename it
struct event and move it from udev.h into a new file event.h.
Also, rename the emums UDEV_ACTION_ADD and UDEV_ACTION_REMOVE
to ACTION_UDEV_ADD and ACTION_UDEV_REMOVE.

Signed-off-by: Geoff Levand <geoffrey.levand@am.sony.com>
Signed-off-by: Jeremy Kerr <jk@ozlabs.org>
discover/device-handler.c
discover/device-handler.h
discover/event.c [new file with mode: 0644]
discover/event.h [new file with mode: 0644]
discover/parser-utils.c
discover/udev.c
discover/udev.h
rules.mk

index af48f5c6ea0648a81db4842c948011f6decde855..908409c6540ff52c71b3962d700486a38d309f76 100644 (file)
@@ -15,6 +15,7 @@
 
 #include "device-handler.h"
 #include "discover-server.h"
+#include "event.h"
 #include "parser.h"
 #include "udev.h"
 #include "paths.h"
@@ -63,7 +64,7 @@ static void device_handler_remove(struct device_handler *handler,
                if (handler->devices[i] == device)
                        break;
 
-       if (i < handler->n_devices) {
+       if (i == handler->n_devices) {
                assert(0 && "unknown device");
                return;
        }
@@ -91,7 +92,7 @@ static struct device *device_handler_find(struct device_handler *handler,
                        && streq(handler->devices[i]->id, id))
                        return handler->devices[i];
 
-       assert(0 && "unknown device");
+       pb_log("%s: unknown device: %s\n", __func__, id);
        return NULL;
 }
 
@@ -141,7 +142,7 @@ static void setup_device_links(struct discover_context *ctx)
                char *enc, *dir, *path;
                const char *value;
 
-               value = udev_event_param(ctx->event, link->env);
+               value = event_get_param(ctx->event, link->env);
                if (!value || !*value)
                        continue;
 
@@ -266,8 +267,8 @@ static int destroy_context(void *arg)
        return 0;
 }
 
-static int handle_add_event(struct device_handler *handler,
-               struct udev_event *event)
+static int handle_add_udev_event(struct device_handler *handler,
+               struct event *event)
 {
        struct discover_context *ctx;
        const char *devname;
@@ -282,7 +283,7 @@ static int handle_add_event(struct device_handler *handler,
 
        ctx->id = talloc_strdup(ctx, event->device);
 
-       devname = udev_event_param(ctx->event, "DEVNAME");
+       devname = event_get_param(ctx->event, "DEVNAME");
        if (!devname) {
                pb_log("no devname for %s?\n", event->device);
                return 0;
@@ -315,8 +316,8 @@ static int handle_add_event(struct device_handler *handler,
        return 0;
 }
 
-static int handle_remove_event(struct device_handler *handler,
-               struct udev_event *event)
+static int handle_remove_udev_event(struct device_handler *handler,
+               struct event *event)
 {
        struct discover_context *ctx;
 
@@ -335,17 +336,29 @@ static int handle_remove_event(struct device_handler *handler,
 }
 
 int device_handler_event(struct device_handler *handler,
-               struct udev_event *event)
+               struct event *event)
 {
-       int rc;
+       int rc = 0;
 
-       switch (event->action) {
-       case UDEV_ACTION_ADD:
-               rc = handle_add_event(handler, event);
+       switch (event->type) {
+       case EVENT_TYPE_UDEV:
+               switch (event->action) {
+               case EVENT_ACTION_ADD:
+                       rc = handle_add_udev_event(handler, event);
+                       break;
+               case EVENT_ACTION_REMOVE:
+                       rc = handle_remove_udev_event(handler, event);
+                       break;
+               default:
+                       pb_log("%s unknown action: %d\n", __func__,
+                               event->action);
+                       break;
+               }
                break;
-
-       case UDEV_ACTION_REMOVE:
-               rc = handle_remove_event(handler, event);
+       case EVENT_TYPE_USER:
+               break;
+       default:
+               pb_log("%s unknown type: %d\n", __func__, event->type);
                break;
        }
 
index 8a469e0fe4c5361a46b8c91127514887240afae5..796b328649bdcfc515d0e8d338d0109a38f5ec5d 100644 (file)
@@ -5,14 +5,14 @@
 
 struct device_handler;
 struct discover_server;
-struct udev_event;
+struct event;
 struct device;
 
 struct discover_context {
        char *id;
        char *device_path;
        char *mount_path;
-       struct udev_event *event;
+       struct event *event;
        struct device *device;
        char **links;
        int n_links;
@@ -28,7 +28,6 @@ int device_handler_get_device_count(const struct device_handler *handler);
 const struct device *device_handler_get_device(
        const struct device_handler *handler, unsigned int index);
 
-int device_handler_event(struct device_handler *handler,
-               struct udev_event *event);
+int device_handler_event(struct device_handler *handler, struct event *event);
 
 #endif /* _DEVICE_HANDLER_H */
diff --git a/discover/event.c b/discover/event.c
new file mode 100644 (file)
index 0000000..1314561
--- /dev/null
@@ -0,0 +1,134 @@
+#if defined(HAVE_CONFIG_H)
+#include "config.h"
+#endif
+
+#define _GNU_SOURCE
+#include <string.h>
+
+#include <log/log.h>
+#include <talloc/talloc.h>
+
+#include "event.h"
+
+#define streq(a, b) (!strcasecmp((a), (b)))
+
+/**
+ * event_parse_ad_header - Parse an <action>@<device> event header.
+ *
+ * The buffer is modified in place.
+ * Returns zero on success.
+ */
+
+static int event_parse_ad_header(char *buf, int len, enum event_action *action,
+       char **device)
+{
+       char *sep;
+
+       *action = 0;
+       *device = NULL;
+
+       /* we should see an <action>@<device>\0 at the head of the buffer */
+       sep = strchr(buf, '@');
+       if (!sep) {
+               pb_log("%s: bad header: %s\n", __func__, buf);
+               return -1;
+       }
+
+       /* terminate the action string */
+       *sep = '\0';
+       len -= sep - buf + 1;
+
+       if (streq(buf, "add"))
+               *action = EVENT_ACTION_ADD;
+       else if (streq(buf, "remove"))
+               *action = EVENT_ACTION_REMOVE;
+       else {
+               pb_log("%s: unknown action: %s\n", __func__, buf);
+               return -1;
+       }
+
+       if (!*(sep + 1)) {
+               pb_log("%s: bad device: %s\n", __func__, buf);
+               return -1;
+       }
+
+       *device = sep + 1;
+       return 0;
+}
+
+/**
+ * event_parse_params - Parse a <name>=<value> buffer.
+ *
+ * The buffer is not modified.
+ */
+
+static void event_parse_params(struct event *event, const char *buf, int len)
+{
+       int param_len, name_len, value_len;
+       struct param *param;
+       char *sep;
+
+       for (; len > 0; len -= param_len + 1, buf += param_len + 1) {
+
+               /* find the length of the whole parameter */
+               param_len = strnlen(buf, len);
+               if (!param_len) {
+                       /* multiple NULs? skip over */
+                       param_len = 1;
+                       continue;
+               }
+
+               /* find the separator */
+               sep = memchr(buf, '=', param_len);
+               if (!sep)
+                       continue;
+
+               name_len = sep - buf;
+               value_len = param_len - name_len - 1;
+
+               /* update the params array */
+               event->params = talloc_realloc(event, event->params,
+                                       struct param, ++event->n_params);
+               param = &event->params[event->n_params - 1];
+
+               param->name = talloc_strndup(event, buf, name_len);
+               param->value = talloc_strndup(event, sep + 1, value_len);
+       }
+}
+
+int event_parse_ad_message(struct event *event, char *buf, int len)
+{
+       int result;
+       char *device;
+       enum event_action action;
+       int device_len;
+
+       result = event_parse_ad_header(buf, len, &action, &device);
+
+       if (result)
+               return -1;
+
+       device_len = strlen(device);
+
+       /* now we have an action and a device, we can construct the event */
+       event->action = action;
+       event->device = talloc_strndup(event, device, device_len);
+       event->n_params = 0;
+       event->params = NULL;
+
+       len -= device_len + 1;
+       event_parse_params(event, device + device_len + 1, len);
+
+       return 0;
+}
+
+const char *event_get_param(const struct event *event, const char *name)
+{
+       int i;
+
+       for (i = 0; i < event->n_params; i++)
+               if (!strcasecmp(event->params[i].name, name))
+                       return event->params[i].value;
+
+       return NULL;
+}
diff --git a/discover/event.h b/discover/event.h
new file mode 100644 (file)
index 0000000..20585f2
--- /dev/null
@@ -0,0 +1,29 @@
+#ifndef _PB_EVENT_H
+#define _PB_EVENT_H
+
+enum event_type {
+       EVENT_TYPE_UDEV = 10,
+       EVENT_TYPE_USER,
+};
+
+enum event_action {
+       EVENT_ACTION_ADD = 20,
+       EVENT_ACTION_REMOVE,
+};
+
+struct event {
+       enum event_type type;
+       enum event_action action;
+       char *device;
+
+       struct param {
+               char *name;
+               char *value;
+       } *params;
+       int n_params;
+};
+
+int event_parse_ad_message(struct event *event, char *buf, int len);
+const char *event_get_param(const struct event *event, const char *name);
+
+#endif /* _PB_EVENT_H */
index a91c33a457760ce31ec57705fef78dfe5b890adf..47e30d8055040cb28b9b876ff7d88ffa4cb45ac6 100644 (file)
@@ -5,6 +5,7 @@
 #include <talloc/talloc.h>
 
 #include "pb-protocol/pb-protocol.h"
+#include "event.h"
 #include "udev.h"
 #include "device-handler.h"
 #include "parser-utils.h"
@@ -42,13 +43,13 @@ const char *generic_icon_file(enum generic_icon_type type)
 
 enum generic_icon_type guess_device_type(struct discover_context *ctx)
 {
-       struct udev_event *event;
+       struct event *event;
        const char *type, *bus;
 
        event = ctx->event;
 
-       type = udev_event_param(event, "ID_TYPE");
-       bus = udev_event_param(event, "ID_BUS");
+       type = event_get_param(event, "ID_TYPE");
+       bus = event_get_param(event, "ID_BUS");
 
        if (type && streq(type, "cd"))
                return ICON_TYPE_OPTICAL;
index dd9fc7ccea6d77cd8fbb8a5fa33a9cbf01cfbedb..1a527895878d4de36f17406c3fe7ad44c1ceb07d 100644 (file)
@@ -13,6 +13,7 @@
 #include <waiter/waiter.h>
 #include <log/log.h>
 
+#include "event.h"
 #include "udev.h"
 #include "pb-discover.h"
 #include "device-handler.h"
@@ -26,52 +27,7 @@ struct udev {
        int socket;
 };
 
-static void parse_event_params(struct udev_event *event, char *buf, int len)
-{
-       int param_len, name_len, value_len;
-       struct param *param;
-       char *sep;
-
-       for (; len > 0; len -= param_len + 1, buf += param_len + 1) {
-
-               /* find the length of the whole parameter */
-               param_len = strnlen(buf, len);
-               if (!param_len) {
-                       /* multiple NULs? skip over */
-                       param_len = 1;
-                       continue;
-               }
-
-               /* find the separator */
-               sep = memchr(buf, '=', param_len);
-               if (!sep)
-                       continue;
-
-               name_len = sep - buf;
-               value_len = param_len - name_len - 1;
-
-               /* update the params array */
-               event->params = talloc_realloc(event, event->params,
-                                       struct param, ++event->n_params);
-               param = &event->params[event->n_params - 1];
-
-               param->name = talloc_strndup(event, buf, name_len);
-               param->value = talloc_strndup(event, sep + 1, value_len);
-       }
-}
-
-const char *udev_event_param(struct udev_event *event, const char *name)
-{
-       int i;
-
-       for (i = 0; i < event->n_params; i++)
-               if (!strcasecmp(event->params[i].name, name))
-                       return event->params[i].value;
-
-       return NULL;
-}
-
-static void print_event(struct udev_event *event)
+static void udev_print_event(struct event *event)
 {
        const char *action, *params[] = {
                "DEVNAME", "ID_TYPE", "ID_BUS", "ID_FS_UUID", "ID_FS_LABEL",
@@ -79,63 +35,32 @@ static void print_event(struct udev_event *event)
        };
        int i;
 
-       action = event->action == UDEV_ACTION_ADD ? "add" : "remove";
+       action = event->action == EVENT_ACTION_ADD ? "add" : "remove";
 
        pb_log("udev %s event:\n", action);
        pb_log("\tdevice: %s\n", event->device);
 
        for (i = 0; params[i]; i++)
                pb_log("\t%-12s => %s\n",
-                               params[i], udev_event_param(event, params[i]));
+                               params[i], event_get_param(event, params[i]));
 
 }
 
-static void handle_udev_message(struct udev *udev, char *buf, int len)
+static void udev_handle_message(struct udev *udev, char *buf, int len)
 {
-       char *sep, *device;
-       enum udev_action action;
-       struct udev_event *event;
-       int device_len;
-
-       /* we should see an <action>@<device>\0 at the head of the buffer */
-       sep = strchr(buf, '@');
-       if (!sep)
-               return;
-
-       /* terminate the action string */
-       *sep = '\0';
-       len -= sep - buf + 1;
+       int result;
+       struct event *event;
 
-       if (!strcmp(buf, "add")) {
-               action = UDEV_ACTION_ADD;
+       event = talloc(udev, struct event);
+       event->type = EVENT_TYPE_UDEV;
 
-       } else if (!strcmp(buf, "remove")) {
-               action = UDEV_ACTION_REMOVE;
-
-       } else {
-               return;
-       }
+       result = event_parse_ad_message(event, buf, len);
 
-       /* initialise the device string */
-       device = sep + 1;
-       device_len = strnlen(device, len);
-       if (!device_len)
+       if (result)
                return;
 
-       /* now we have an action and a device, we can construct an event */
-       event = talloc(udev, struct udev_event);
-       event->action = action;
-       event->device = talloc_strndup(event, device, device_len);
-       event->n_params = 0;
-       event->params = NULL;
-
-       len -= device_len + 1;
-       parse_event_params(event, device + device_len + 1, len);
-
-       print_event(event);
-
+       udev_print_event(event);
        device_handler_event(udev->handler, event);
-
        talloc_free(event);
 
        return;
@@ -157,7 +82,7 @@ static int udev_process(void *arg)
        if (len == 0)
                return 0;
 
-       handle_udev_message(udev, buf, len);
+       udev_handle_message(udev, buf, len);
 
        return 0;
 }
index afdbbe18667c1158e1f7523930e12e2f04f1b00a..db17c45e45f1cdc3f1b91bea01f4ef4d540297bb 100644 (file)
@@ -1,29 +1,11 @@
 #ifndef _UDEV_H
 #define _UDEV_H
 
-enum udev_action {
-       UDEV_ACTION_ADD,
-       UDEV_ACTION_REMOVE,
-};
-
-struct udev_event {
-       enum udev_action action;
-       char *device;
-
-       struct param {
-               char *name;
-               char *value;
-       } *params;
-       int n_params;
-};
-
 struct udev;
 struct device_handler;
 
 struct udev *udev_init(struct device_handler *handler);
 int udev_trigger(struct udev *udev);
-
 void udev_destroy(struct udev *udev);
 
-const char *udev_event_param(struct udev_event *event, const char *name);
 #endif /* _UDEV_H */
index 1212b5a3cf8b5fd7d9eb2ed13e0a33dfac74145c..1c91661cc722924fa253ffbd67bbb3a85a2a04b4 100644 (file)
--- a/rules.mk
+++ b/rules.mk
@@ -40,7 +40,7 @@ waiter_objs = lib/waiter/waiter.o
 # daemon objs
 parser_objs = discover/parser.o discover/parser-conf.o discover/paths.o \
        $(foreach p, $(parsers), discover/$(p)-parser.o)
-discover_objs =  discover/udev.o discover/discover-server.o \
+discover_objs = discover/event.o  discover/udev.o discover/discover-server.o \
        discover/device-handler.o discover/paths.o discover/parser-utils.o
 
 # client objs