discover: Add 'plugin' user-event
[petitboot] / discover / event.c
index 1314561c9eda23e19cfc016604ae71d207d9ae09..047e9281fe8feabd8790d833780f4e9abe159bc6 100644 (file)
@@ -2,7 +2,6 @@
 #include "config.h"
 #endif
 
-#define _GNU_SOURCE
 #include <string.h>
 
 #include <log/log.h>
 static int event_parse_ad_header(char *buf, int len, enum event_action *action,
        char **device)
 {
+       int headerlen;
        char *sep;
 
        *action = 0;
        *device = NULL;
+       headerlen = strnlen(buf, len);
+
+       if (!headerlen) {
+               pb_log("%s: bad header, no data\n", __func__);
+               return -1;
+       }
 
        /* we should see an <action>@<device>\0 at the head of the buffer */
        sep = strchr(buf, '@');
@@ -36,12 +42,21 @@ static int event_parse_ad_header(char *buf, int len, enum event_action *action,
 
        /* 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 if (streq(buf, "url"))
+               *action = EVENT_ACTION_URL;
+       else if (streq(buf, "dhcp"))
+               *action = EVENT_ACTION_DHCP;
+       else if (streq(buf, "boot"))
+               *action = EVENT_ACTION_BOOT;
+       else if (streq(buf, "sync"))
+               *action = EVENT_ACTION_SYNC;
+       else if (streq(buf, "plugin"))
+               *action = EVENT_ACTION_PLUGIN;
        else {
                pb_log("%s: unknown action: %s\n", __func__, buf);
                return -1;
@@ -53,7 +68,7 @@ static int event_parse_ad_header(char *buf, int len, enum event_action *action,
        }
 
        *device = sep + 1;
-       return 0;
+       return headerlen;
 }
 
 /**
@@ -78,46 +93,46 @@ static void event_parse_params(struct event *event, const char *buf, int len)
                        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];
 
+               sep = memchr(buf, '=', param_len);
+               if (!sep) {
+                       name_len = param_len;
+                       value_len = 0;
+                       param->value = "";
+               } else {
+                       name_len = sep - buf;
+                       value_len = param_len - name_len - 1;
+                       param->value = talloc_strndup(event, sep + 1,
+                                       value_len);
+               }
                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;
+       int headerlen;
+       char *device;
 
-       result = event_parse_ad_header(buf, len, &action, &device);
+       headerlen = event_parse_ad_header(buf, len, &action, &device);
 
-       if (result)
+       if (headerlen <= 0)
                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->device = talloc_strdup(event, device);
        event->n_params = 0;
        event->params = NULL;
 
-       len -= device_len + 1;
-       event_parse_params(event, device + device_len + 1, len);
+       len -= headerlen + 1;
+       buf += headerlen + 1;
+       event_parse_params(event, buf, len);
 
        return 0;
 }
@@ -132,3 +147,27 @@ const char *event_get_param(const struct event *event, const char *name)
 
        return NULL;
 }
+
+void event_set_param(struct event *event, const char *name, const char *value)
+{
+       struct param *param;
+       int i;
+
+       /* if it's already present, replace the value of the old param */
+       for (i = 0; i < event->n_params; i++) {
+               param = &event->params[i];
+               if (!strcasecmp(param->name, name)) {
+                       talloc_free(param->value);
+                       param->value = talloc_strdup(event, value);
+                       return;
+               }
+       }
+
+       /* not found - create a new param */
+       event->params = talloc_realloc(event, event->params,
+                               struct param, ++event->n_params);
+       param = &event->params[event->n_params - 1];
+
+       param->name = talloc_strdup(event, name);
+       param->value = talloc_strdup(event, value);
+}