summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--discover/device-handler.c45
-rw-r--r--discover/device-handler.h7
-rw-r--r--discover/event.c134
-rw-r--r--discover/event.h29
-rw-r--r--discover/parser-utils.c7
-rw-r--r--discover/udev.c101
-rw-r--r--discover/udev.h18
-rw-r--r--rules.mk2
8 files changed, 213 insertions, 130 deletions
diff --git a/discover/device-handler.c b/discover/device-handler.c
index af48f5c..908409c 100644
--- a/discover/device-handler.c
+++ b/discover/device-handler.c
@@ -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;
}
diff --git a/discover/device-handler.h b/discover/device-handler.h
index 8a469e0..796b328 100644
--- a/discover/device-handler.h
+++ b/discover/device-handler.h
@@ -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
index 0000000..1314561
--- /dev/null
+++ b/discover/event.c
@@ -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
index 0000000..20585f2
--- /dev/null
+++ b/discover/event.h
@@ -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 */
diff --git a/discover/parser-utils.c b/discover/parser-utils.c
index a91c33a..47e30d8 100644
--- a/discover/parser-utils.c
+++ b/discover/parser-utils.c
@@ -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;
diff --git a/discover/udev.c b/discover/udev.c
index dd9fc7c..1a52789 100644
--- a/discover/udev.c
+++ b/discover/udev.c
@@ -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;
}
diff --git a/discover/udev.h b/discover/udev.h
index afdbbe1..db17c45 100644
--- a/discover/udev.h
+++ b/discover/udev.h
@@ -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 */
diff --git a/rules.mk b/rules.mk
index 1212b5a..1c91661 100644
--- 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
OpenPOWER on IntegriCloud