+ struct event_source *ev;
+ struct ubus_object *obj;
+ struct blob_attr *attr[EVMSG_LAST];
+ const char *pattern;
+ uint32_t id;
+
+ blobmsg_parse(ev_policy, EVMSG_LAST, attr, blob_data(msg), blob_len(msg));
+ if (!attr[EVMSG_OBJECT])
+ return UBUS_STATUS_INVALID_ARGUMENT;
+
+ id = blobmsg_get_u32(attr[EVMSG_OBJECT]);
+ if (id < UBUS_SYSTEM_OBJECT_MAX)
+ return UBUS_STATUS_PERMISSION_DENIED;
+
+ obj = ubusd_find_object(id);
+ if (!obj)
+ return UBUS_STATUS_NOT_FOUND;
+
+ if (obj->client != cl)
+ return UBUS_STATUS_PERMISSION_DENIED;
+
+ if (!attr[EVMSG_PATTERN])
+ return ubusd_alloc_catchall(obj);
+
+ pattern = blobmsg_data(attr[EVMSG_PATTERN]);
+ ev = ubusd_alloc_event_source(obj, EVS_PATTERN, strlen(pattern) + 1);
+ ev->pattern.avl.key = (void *) (ev + 1);
+ strcpy(ev->pattern.avl.key, pattern);
+ avl_insert(&patterns, &ev->pattern.avl);
+