diff options
Diffstat (limited to 'service')
-rw-r--r-- | service/instance.c | 226 | ||||
-rw-r--r-- | service/instance.h | 6 | ||||
-rw-r--r-- | service/service.c | 40 | ||||
-rw-r--r-- | service/trigger.c | 352 | ||||
-rw-r--r-- | service/watch.c | 120 |
5 files changed, 1 insertions, 743 deletions
diff --git a/service/instance.c b/service/instance.c index 3c98ff7..7c902f9 100644 --- a/service/instance.c +++ b/service/instance.c @@ -41,18 +41,13 @@ enum { INSTANCE_ATTR_DATA, INSTANCE_ATTR_NETDEV, INSTANCE_ATTR_FILE, - INSTANCE_ATTR_TRIGGER, INSTANCE_ATTR_RESPAWN, INSTANCE_ATTR_NICE, INSTANCE_ATTR_LIMITS, - INSTANCE_ATTR_WATCH, INSTANCE_ATTR_ERROR, INSTANCE_ATTR_USER, INSTANCE_ATTR_STDOUT, INSTANCE_ATTR_STDERR, - INSTANCE_ATTR_JAIL, - INSTANCE_ATTR_TRACE, - INSTANCE_ATTR_SECCOMP, __INSTANCE_ATTR_MAX }; @@ -62,39 +57,13 @@ static const struct blobmsg_policy instance_attr[__INSTANCE_ATTR_MAX] = { [INSTANCE_ATTR_DATA] = { "data", BLOBMSG_TYPE_TABLE }, [INSTANCE_ATTR_NETDEV] = { "netdev", BLOBMSG_TYPE_ARRAY }, [INSTANCE_ATTR_FILE] = { "file", BLOBMSG_TYPE_ARRAY }, - [INSTANCE_ATTR_TRIGGER] = { "triggers", BLOBMSG_TYPE_ARRAY }, [INSTANCE_ATTR_RESPAWN] = { "respawn", BLOBMSG_TYPE_ARRAY }, [INSTANCE_ATTR_NICE] = { "nice", BLOBMSG_TYPE_INT32 }, [INSTANCE_ATTR_LIMITS] = { "limits", BLOBMSG_TYPE_TABLE }, - [INSTANCE_ATTR_WATCH] = { "watch", BLOBMSG_TYPE_ARRAY }, [INSTANCE_ATTR_ERROR] = { "error", BLOBMSG_TYPE_ARRAY }, [INSTANCE_ATTR_USER] = { "user", BLOBMSG_TYPE_STRING }, [INSTANCE_ATTR_STDOUT] = { "stdout", BLOBMSG_TYPE_BOOL }, [INSTANCE_ATTR_STDERR] = { "stderr", BLOBMSG_TYPE_BOOL }, - [INSTANCE_ATTR_JAIL] = { "jail", BLOBMSG_TYPE_TABLE }, - [INSTANCE_ATTR_TRACE] = { "trace", BLOBMSG_TYPE_BOOL }, - [INSTANCE_ATTR_SECCOMP] = { "seccomp", BLOBMSG_TYPE_STRING }, -}; - -enum { - JAIL_ATTR_NAME, - JAIL_ATTR_ROOT, - JAIL_ATTR_PROCFS, - JAIL_ATTR_SYSFS, - JAIL_ATTR_UBUS, - JAIL_ATTR_LOG, - JAIL_ATTR_MOUNT, - __JAIL_ATTR_MAX, -}; - -static const struct blobmsg_policy jail_attr[__JAIL_ATTR_MAX] = { - [JAIL_ATTR_NAME] = { "name", BLOBMSG_TYPE_STRING }, - [JAIL_ATTR_ROOT] = { "root", BLOBMSG_TYPE_STRING }, - [JAIL_ATTR_PROCFS] = { "procfs", BLOBMSG_TYPE_BOOL }, - [JAIL_ATTR_SYSFS] = { "sysfs", BLOBMSG_TYPE_BOOL }, - [JAIL_ATTR_UBUS] = { "ubus", BLOBMSG_TYPE_BOOL }, - [JAIL_ATTR_LOG] = { "log", BLOBMSG_TYPE_BOOL }, - [JAIL_ATTR_MOUNT] = { "mount", BLOBMSG_TYPE_TABLE }, }; struct instance_netdev { @@ -130,8 +99,6 @@ static const struct rlimit_name rlimit_names[] = { { NULL, 0 } }; -static char trace[] = "/sbin/utrace"; - static void closefd(int fd) { if (fd > STDERR_FILENO) @@ -170,68 +137,14 @@ instance_limits(const char *limit, const char *value) } } -static inline int -jail_run(struct service_instance *in, char **argv) -{ - struct blobmsg_list_node *var; - struct jail *jail = &in->jail; - int argc = 0; - - argv[argc++] = "/sbin/ujail"; - - if (jail->name) { - argv[argc++] = "-n"; - argv[argc++] = jail->name; - } - - if (jail->root) { - argv[argc++] = "-P"; - argv[argc++] = jail->root; - } - - if (in->seccomp) { - argv[argc++] = "-S"; - argv[argc++] = in->seccomp; - } - - if (jail->procfs) - argv[argc++] = "-p"; - - if (jail->sysfs) - argv[argc++] = "-s"; - - if (jail->ubus) - argv[argc++] = "-u"; - - if (jail->log) - argv[argc++] = "-l"; - - blobmsg_list_for_each(&jail->mount, var) { - const char *type = blobmsg_data(var->data); - - if (*type == '1') - argv[argc++] = "-w"; - else - argv[argc++] = "-r"; - argv[argc++] = (char *) blobmsg_name(var->data); - } - - argv[argc++] = "--"; - - return argc; -} - static void instance_run(struct service_instance *in, int _stdout, int _stderr) { struct blobmsg_list_node *var; struct blob_attr *cur; char **argv; - char *ld_preload; int argc = 1; /* NULL terminated */ int rem, _stdin; - bool seccomp = !in->trace && !in->has_jail && in->seccomp; - bool setlbf = _stdout >= 0; if (in->nice) setpriority(PRIO_PROCESS, 0, in->nice); @@ -242,30 +155,12 @@ instance_run(struct service_instance *in, int _stdout, int _stderr) blobmsg_list_for_each(&in->env, var) setenv(blobmsg_name(var->data), blobmsg_data(var->data), 1); - if (seccomp) - setenv("SECCOMP_FILE", in->seccomp, 1); - - if ((seccomp || setlbf) && asprintf(&ld_preload, "LD_PRELOAD=%s%s%s", - seccomp ? "/lib/libpreload-seccomp.so" : "", - seccomp && setlbf ? ":" : "", - setlbf ? "/lib/libsetlbf.so" : "") > 0) - putenv(ld_preload); - blobmsg_list_for_each(&in->limits, var) instance_limits(blobmsg_name(var->data), blobmsg_data(var->data)); - if (in->trace) - argc += 1; - - argv = alloca(sizeof(char *) * (argc + in->jail.argc)); + argv = alloca(sizeof(char *) * argc); argc = 0; - if (in->trace) - argv[argc++] = trace; - - if (in->has_jail) - argc = jail_run(in, argv); - blobmsg_for_each_attr(cur, in->command, rem) argv[argc++] = blobmsg_data(cur); @@ -532,9 +427,6 @@ instance_config_changed(struct service_instance *in, struct service_instance *in if (!blobmsg_list_equal(&in->limits, &in_new->limits)) return true; - if (!blobmsg_list_equal(&in->jail.mount, &in_new->jail.mount)) - return true; - if (!blobmsg_list_equal(&in->errors, &in_new->errors)) return true; @@ -628,59 +520,6 @@ instance_fill_array(struct blobmsg_list *l, struct blob_attr *cur, blobmsg_updat return true; } -static int -instance_jail_parse(struct service_instance *in, struct blob_attr *attr) -{ - struct blob_attr *tb[__JAIL_ATTR_MAX]; - struct jail *jail = &in->jail; - struct stat s; - - if (stat("/sbin/ujail", &s)) - return 0; - - blobmsg_parse(jail_attr, __JAIL_ATTR_MAX, tb, - blobmsg_data(attr), blobmsg_data_len(attr)); - - jail->argc = 2; - - if (tb[JAIL_ATTR_NAME]) { - jail->name = blobmsg_get_string(tb[JAIL_ATTR_NAME]); - jail->argc += 2; - } - if (tb[JAIL_ATTR_ROOT]) { - jail->root = blobmsg_get_string(tb[JAIL_ATTR_ROOT]); - jail->argc += 2; - } - if (tb[JAIL_ATTR_PROCFS]) { - jail->procfs = blobmsg_get_bool(tb[JAIL_ATTR_PROCFS]); - jail->argc++; - } - if (tb[JAIL_ATTR_SYSFS]) { - jail->sysfs = blobmsg_get_bool(tb[JAIL_ATTR_SYSFS]); - jail->argc++; - } - if (tb[JAIL_ATTR_UBUS]) { - jail->ubus = blobmsg_get_bool(tb[JAIL_ATTR_UBUS]); - jail->argc++; - } - if (tb[JAIL_ATTR_LOG]) { - jail->log = blobmsg_get_bool(tb[JAIL_ATTR_LOG]); - jail->argc++; - } - if (tb[JAIL_ATTR_MOUNT]) { - struct blob_attr *cur; - int rem; - - blobmsg_for_each_attr(cur, tb[JAIL_ATTR_MOUNT], rem) - jail->argc += 2; - instance_fill_array(&jail->mount, tb[JAIL_ATTR_MOUNT], NULL, false); - } - if (in->seccomp) - jail->argc += 2; - - return 1; -} - static bool instance_config_parse(struct service_instance *in) { @@ -724,19 +563,6 @@ instance_config_parse(struct service_instance *in) in->respawn_timeout = vals[1]; in->respawn_retry = vals[2]; } - if (tb[INSTANCE_ATTR_TRIGGER]) { - in->trigger = tb[INSTANCE_ATTR_TRIGGER]; - trigger_add(in->trigger, in); - } - - if (tb[INSTANCE_ATTR_WATCH]) { - blobmsg_for_each_attr(cur2, tb[INSTANCE_ATTR_WATCH], rem) { - if (blobmsg_type(cur2) != BLOBMSG_TYPE_STRING) - continue; - DEBUG(3, "watch for %s\n", blobmsg_get_string(cur2)); - watch_add(blobmsg_get_string(cur2), in); - } - } if ((cur = tb[INSTANCE_ATTR_NICE])) { in->nice = (int8_t) blobmsg_get_u32(cur); @@ -752,21 +578,6 @@ instance_config_parse(struct service_instance *in) } } - if (tb[INSTANCE_ATTR_TRACE]) - in->trace = blobmsg_get_bool(tb[INSTANCE_ATTR_TRACE]); - - if (!in->trace && tb[INSTANCE_ATTR_SECCOMP]) { - char *seccomp = blobmsg_get_string(tb[INSTANCE_ATTR_SECCOMP]); - struct stat s; - - if (stat(seccomp, &s)) - ERROR("%s: not starting seccomp as %s is missing\n", in->name, seccomp); - else - in->seccomp = seccomp; - } - if (!in->trace && tb[INSTANCE_ATTR_JAIL]) - in->has_jail = instance_jail_parse(in, tb[INSTANCE_ATTR_JAIL]); - if (tb[INSTANCE_ATTR_STDOUT] && blobmsg_get_bool(tb[INSTANCE_ATTR_STDOUT])) in->_stdout.fd.fd = -1; @@ -802,7 +613,6 @@ instance_config_cleanup(struct service_instance *in) blobmsg_list_free(&in->file); blobmsg_list_free(&in->limits); blobmsg_list_free(&in->errors); - blobmsg_list_free(&in->jail.mount); } static void @@ -815,8 +625,6 @@ instance_config_move(struct service_instance *in, struct service_instance *in_sr blobmsg_list_move(&in->file, &in_src->file); blobmsg_list_move(&in->limits, &in_src->limits); blobmsg_list_move(&in->errors, &in_src->errors); - blobmsg_list_move(&in->jail.mount, &in_src->jail.mount); - in->trigger = in_src->trigger; in->command = in_src->command; in->name = in_src->name; in->node.avl.key = in_src->node.avl.key; @@ -853,8 +661,6 @@ instance_free(struct service_instance *in) instance_free_stdio(in); uloop_process_delete(&in->proc); uloop_timeout_cancel(&in->timeout); - trigger_del(in); - watch_del(in); instance_config_cleanup(in); free(in->config); free(in); @@ -884,7 +690,6 @@ instance_init(struct service_instance *in, struct service *s, struct blob_attr * blobmsg_list_simple_init(&in->data); blobmsg_list_simple_init(&in->limits); blobmsg_list_simple_init(&in->errors); - blobmsg_list_simple_init(&in->jail.mount); in->valid = instance_config_parse(in); } @@ -941,34 +746,5 @@ void instance_dump(struct blob_buf *b, struct service_instance *in, int verbose) blobmsg_close_table(b, r); } - if (in->trace) - blobmsg_add_u8(b, "trace", true); - - if (in->seccomp) - blobmsg_add_string(b, "seccomp", in->seccomp); - - if (in->has_jail) { - void *r = blobmsg_open_table(b, "jail"); - if (in->jail.name) - blobmsg_add_string(b, "name", in->jail.name); - if (in->jail.root) - blobmsg_add_string(b, "root", in->jail.root); - blobmsg_add_u8(b, "procfs", in->jail.procfs); - blobmsg_add_u8(b, "sysfs", in->jail.sysfs); - blobmsg_add_u8(b, "ubus", in->jail.ubus); - blobmsg_add_u8(b, "log", in->jail.log); - blobmsg_close_table(b, r); - if (!avl_is_empty(&in->jail.mount.avl)) { - struct blobmsg_list_node *var; - void *e = blobmsg_open_table(b, "mount"); - blobmsg_list_for_each(&in->jail.mount, var) - blobmsg_add_string(b, blobmsg_name(var->data), blobmsg_data(var->data)); - blobmsg_close_table(b, e); - } - } - - if (verbose && in->trigger) - blobmsg_add_blob(b, in->trigger); - blobmsg_close_table(b, i); } diff --git a/service/instance.h b/service/instance.h index cdf0bf7..4970dca 100644 --- a/service/instance.h +++ b/service/instance.h @@ -51,11 +51,6 @@ struct service_instance { int respawn_count; struct timespec start; - bool trace; - bool has_jail; - struct jail jail; - char *seccomp; - uint32_t respawn_timeout; uint32_t respawn_threshold; uint32_t respawn_retry; @@ -67,7 +62,6 @@ struct service_instance { struct ustream_fd _stderr; struct blob_attr *command; - struct blob_attr *trigger; struct blobmsg_list env; struct blobmsg_list data; struct blobmsg_list netdev; diff --git a/service/service.c b/service/service.c index a983cee..8d5dd95 100644 --- a/service/service.c +++ b/service/service.c @@ -66,7 +66,6 @@ service_instance_update(struct vlist_tree *tree, struct vlist_node *node_new, instance_start(in_n); } blob_buf_init(&b, 0); - trigger_event("instance.update", b.head); } static struct service * @@ -90,7 +89,6 @@ enum { SERVICE_SET_NAME, SERVICE_SET_SCRIPT, SERVICE_SET_INSTANCES, - SERVICE_SET_TRIGGER, __SERVICE_SET_MAX }; @@ -98,7 +96,6 @@ static const struct blobmsg_policy service_set_attrs[__SERVICE_SET_MAX] = { [SERVICE_SET_NAME] = { "name", BLOBMSG_TYPE_STRING }, [SERVICE_SET_SCRIPT] = { "script", BLOBMSG_TYPE_STRING }, [SERVICE_SET_INSTANCES] = { "instances", BLOBMSG_TYPE_TABLE }, - [SERVICE_SET_TRIGGER] = { "triggers", BLOBMSG_TYPE_ARRAY }, }; static int @@ -107,19 +104,6 @@ service_update(struct service *s, struct blob_attr **tb, bool add) struct blob_attr *cur; int rem; - if (s->trigger) { - trigger_del(s); - free(s->trigger); - s->trigger = NULL; - } - - if (tb[SERVICE_SET_TRIGGER] && blobmsg_data_len(tb[SERVICE_SET_TRIGGER])) { - s->trigger = blob_memdup(tb[SERVICE_SET_TRIGGER]); - if (!s->trigger) - return -1; - trigger_add(s->trigger, s); - } - if (tb[SERVICE_SET_INSTANCES]) { if (!add) vlist_update(&s->instances); @@ -139,8 +123,6 @@ service_delete(struct service *s) service_event("service.stop", s->name, NULL); vlist_flush_all(&s->instances); avl_delete(&services, &s->avl); - trigger_del(s); - free(s->trigger); free(s); } @@ -253,8 +235,6 @@ service_dump(struct service *s, bool verbose) instance_dump(&b, in, verbose); blobmsg_close_table(&b, i); } - if (verbose && s->trigger) - blobmsg_add_blob(&b, s->trigger); blobmsg_close_table(&b, c); } @@ -351,25 +331,6 @@ service_handle_update(struct ubus_context *ctx, struct ubus_object *obj, } static int -service_handle_event(struct ubus_context *ctx, struct ubus_object *obj, - struct ubus_request_data *req, const char *method, - struct blob_attr *msg) -{ - struct blob_attr *tb[__EVENT_MAX]; - - if (!msg) - return UBUS_STATUS_INVALID_ARGUMENT; - - blobmsg_parse(event_policy, __EVENT_MAX, tb, blob_data(msg), blob_len(msg)); - if (!tb[EVENT_TYPE] || !tb[EVENT_DATA]) - return UBUS_STATUS_INVALID_ARGUMENT; - - trigger_event(blobmsg_get_string(tb[EVENT_TYPE]), tb[EVENT_DATA]); - - return 0; -} - -static int service_get_data(struct ubus_context *ctx, struct ubus_object *obj, struct ubus_request_data *req, const char *method, struct blob_attr *msg) @@ -435,7 +396,6 @@ static struct ubus_method main_object_methods[] = { UBUS_METHOD("delete", service_handle_delete, service_del_attrs), UBUS_METHOD("update_start", service_handle_update, service_attrs), UBUS_METHOD("update_complete", service_handle_update, service_attrs), - UBUS_METHOD("event", service_handle_event, event_policy), UBUS_METHOD("get_data", service_get_data, get_data_policy), }; diff --git a/service/trigger.c b/service/trigger.c deleted file mode 100644 index 9c7115c..0000000 --- a/service/trigger.c +++ /dev/null @@ -1,352 +0,0 @@ -/* - * Copyright (C) 2013 Felix Fietkau <nbd@openwrt.org> - * Copyright (C) 2013 John Crispin <blogic@openwrt.org> - * Copyright (C) 2015 Matthias Schiffer <mschiffer@universe-factory.net> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 2.1 - * as published by the Free Software Foundation - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include <sys/stat.h> -#include <sys/socket.h> -#include <sys/types.h> - -#include <linux/types.h> -#include <linux/netlink.h> - -#include <libubox/blobmsg_json.h> -#include <libubox/json_script.h> -#include <libubox/runqueue.h> -#include <libubox/ustream.h> -#include <libubox/uloop.h> - -#include <fcntl.h> -#include <unistd.h> -#include <stdlib.h> -#include <libgen.h> - -#include "../procd.h" - -struct trigger { - struct list_head list; - - char *type; - - int pending; - int remove; - int timeout; - - void *id; - - struct blob_attr *rule; - struct blob_attr *data; - struct uloop_timeout delay; - - struct json_script_ctx jctx; -}; - -struct job; -struct cmd { - char *name; - void (*handler)(struct job *job, struct blob_attr *exec, struct blob_attr *env); -}; - -struct job { - struct runqueue_process proc; - struct cmd *cmd; - struct trigger *trigger; - struct blob_attr *exec; - struct blob_attr *env; -}; - -static LIST_HEAD(triggers); -static struct runqueue q; - -static const char* rule_handle_var(struct json_script_ctx *ctx, const char *name, struct blob_attr *vars) -{ - return NULL; -} - -static struct json_script_file * -rule_load_script(struct json_script_ctx *ctx, const char *name) -{ - struct trigger *t = container_of(ctx, struct trigger, jctx); - - return json_script_file_from_blobmsg(t->type, t->rule, blob_pad_len(t->rule)); -} - -static void q_job_run(struct runqueue *q, struct runqueue_task *t) -{ - struct job *j = container_of(t, struct job, proc.task); - - DEBUG(4, "handle event %s\n", j->cmd->name); - j->cmd->handler(j, j->exec, j->env); -} - -static void trigger_free(struct trigger *t) -{ - json_script_free(&t->jctx); - uloop_timeout_cancel(&t->delay); - free(t->data); - list_del(&t->list); - free(t); -} - -static void q_job_complete(struct runqueue *q, struct runqueue_task *p) -{ - struct job *j = container_of(p, struct job, proc.task); - - if (j->trigger->remove) { - trigger_free(j->trigger); - } else { - j->trigger->pending = 0; - } - free(j); -} - -static void add_job(struct trigger *t, struct cmd *cmd, struct blob_attr *exec, struct blob_attr *data) -{ - static const struct runqueue_task_type job_type = { - .run = q_job_run, - .cancel = runqueue_process_cancel_cb, - .kill = runqueue_process_kill_cb, - }; - struct blob_attr *d, *e; - struct job *j = calloc_a(sizeof(*j), &e, blob_pad_len(exec), &d, blob_pad_len(data)); - - j->env = d; - j->exec = e; - j->cmd = cmd; - j->trigger = t; - j->proc.task.type = &job_type; - j->proc.task.complete = q_job_complete; - t->pending = 1; - - memcpy(j->exec, exec, blob_pad_len(exec)); - memcpy(j->env, data, blob_pad_len(data)); - - runqueue_task_add(&q, &j->proc.task, false); -} - -static void _setenv(const char *key, const char *val) -{ - char _key[32]; - - snprintf(_key, sizeof(_key), "PARAM_%s", key); - setenv(_key, val, 1); -} - -static void handle_run_script(struct job *j, struct blob_attr *exec, struct blob_attr *env) -{ - char *argv[8]; - struct blob_attr *cur; - int rem; - int i = 0; - pid_t pid; - - pid = fork(); - if (pid < 0) - return; - - if (pid) { - runqueue_process_add(&q, &j->proc, pid); - return; - } - - if (debug < 3) { - close(STDIN_FILENO); - close(STDOUT_FILENO); - close(STDERR_FILENO); - } - - _setenv("type", j->trigger->type); - blobmsg_for_each_attr(cur, j->env, rem) - _setenv(blobmsg_name(cur), blobmsg_data(cur)); - - blobmsg_for_each_attr(cur, j->exec, rem) { - argv[i] = blobmsg_data(cur); - i++; - if (i == 7) - break; - } - - if (i > 0) { - argv[i] = NULL; - execvp(argv[0], &argv[0]); - } - - exit(1); -} - -static struct cmd handlers[] = { - { - .name = "run_script", - .handler = handle_run_script, - }, -}; - -static void rule_handle_command(struct json_script_ctx *ctx, const char *name, - struct blob_attr *exec, struct blob_attr *vars) -{ - struct trigger *t = container_of(ctx, struct trigger, jctx); - int i; - - if (t->pending) - return; - - for (i = 0; i < ARRAY_SIZE(handlers); i++) { - if (!strcmp(handlers[i].name, name)) { - add_job(t, &handlers[i], exec, vars); - break; - } - } -} - -static void rule_handle_error(struct json_script_ctx *ctx, const char *msg, - struct blob_attr *context) -{ - char *s; - - s = blobmsg_format_json(context, false); - ERROR("ERROR: %s in block: %s\n", msg, s); - free(s); -} - -static void q_empty(struct runqueue *q) -{ -} - -static void trigger_delay_cb(struct uloop_timeout *tout) -{ - struct trigger *t = container_of(tout, struct trigger, delay); - - json_script_run(&t->jctx, "foo", t->data); - free(t->data); - t->data = NULL; -} - -static struct trigger* _trigger_add(char *type, struct blob_attr *rule, int timeout, void *id) -{ - char *_t; - struct blob_attr *_r; - struct trigger *t = calloc_a(sizeof(*t), &_t, strlen(type) + 1, &_r, blob_pad_len(rule)); - - t->type = _t; - t->rule = _r; - t->delay.cb = trigger_delay_cb; - t->timeout = timeout; - t->pending = 0; - t->remove = 0; - t->id = id; - t->jctx.handle_var = rule_handle_var, - t->jctx.handle_error = rule_handle_error, - t->jctx.handle_command = rule_handle_command, - t->jctx.handle_file = rule_load_script, - - strcpy(t->type, type); - memcpy(t->rule, rule, blob_pad_len(rule)); - - list_add(&t->list, &triggers); - json_script_init(&t->jctx); - - return t; -} - -void trigger_add(struct blob_attr *rule, void *id) -{ - struct blob_attr *cur; - int rem; - - blobmsg_for_each_attr(cur, rule, rem) { - struct blob_attr *_cur, *type = NULL, *script = NULL, *timeout = NULL; - int _rem; - int i = 0; - - if (blobmsg_type(cur) != BLOBMSG_TYPE_ARRAY) - continue; - - blobmsg_for_each_attr(_cur, cur, _rem) { - switch (i++) { - case 0: - if (blobmsg_type(_cur) == BLOBMSG_TYPE_STRING) - type = _cur; - break; - - case 1: - if (blobmsg_type(_cur) == BLOBMSG_TYPE_ARRAY) - script = _cur; - break; - - case 2: - if (blobmsg_type(_cur) == BLOBMSG_TYPE_INT32) - timeout = _cur; - break; - } - } - - if (type && script) { - int t = 0; - - if (timeout) - t = blobmsg_get_u32(timeout); - _trigger_add(blobmsg_get_string(type), script, t, id); - } - } -} - -void trigger_del(void *id) -{ - struct trigger *t, *n; - - list_for_each_entry_safe(t, n, &triggers, list) { - if (t->id != id) - continue; - - if (t->pending) { - t->remove = 1; - continue; - } - - trigger_free(t); - } -} - -void trigger_init(void) -{ - runqueue_init(&q); - q.empty_cb = q_empty; - q.max_running_tasks = 1; -} - -static bool trigger_match(const char *event, const char *match) -{ - char *wildcard = strstr(match, ".*"); - if (wildcard) - return !strncmp(event, match, wildcard - match); - return !strcmp(event, match); -} - -void trigger_event(const char *type, struct blob_attr *data) -{ - struct trigger *t; - - list_for_each_entry(t, &triggers, list) { - if (t->remove) - continue; - if (trigger_match(type, t->type)) { - if (t->timeout) { - free(t->data); - t->data = blob_memdup(data); - uloop_timeout_set(&t->delay, t->timeout); - } else { - json_script_run(&t->jctx, "foo", data); - } - } - } -} diff --git a/service/watch.c b/service/watch.c deleted file mode 100644 index cc0b2ee..0000000 --- a/service/watch.c +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright (C) 2013 Felix Fietkau <nbd@openwrt.org> - * Copyright (C) 2013 John Crispin <blogic@openwrt.org> - * Copyright (C) 2015 Matthias Schiffer <mschiffer@universe-factory.net> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 2.1 - * as published by the Free Software Foundation - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include <stdlib.h> -#include <unistd.h> - -#include <libubox/blobmsg_json.h> - -#include "../procd.h" - -struct watch_object { - struct list_head list; - - void *id; - char *name; -}; - -static struct ubus_event_handler watch_event; -static struct ubus_subscriber watch_subscribe; -static LIST_HEAD(watch_objects); - -static void watch_subscribe_cb(struct ubus_context *ctx, struct ubus_event_handler *ev, - const char *type, struct blob_attr *msg) -{ - static const struct blobmsg_policy policy = { - "path", BLOBMSG_TYPE_STRING - }; - struct watch_object *o; - struct blob_attr *attr; - const char *path; - - DEBUG(3, "ubus event %s\n", type); - if (strcmp(type, "ubus.object.add") != 0) - return; - - blobmsg_parse(&policy, 1, &attr, blob_data(msg), blob_len(msg)); - if (!attr) - return; - - path = blobmsg_data(attr); - DEBUG(3, "ubus path %s\n", path); - - list_for_each_entry(o, &watch_objects, list) { - unsigned int id; - - if (strcmp(o->name, path)) - continue; - if (ubus_lookup_id(ctx, path, &id)) - continue; - if (!ubus_subscribe(ctx, &watch_subscribe, id)) - return; - ERROR("failed to subscribe %d\n", id); - } -} - -void -watch_add(const char *_name, void *id) -{ - int len = strlen(_name); - char *name; - struct watch_object *o = calloc_a(sizeof(*o), &name, len + 1); - - o->name = name; - strcpy(name, _name); - o->id = id; - list_add(&o->list, &watch_objects); -} - -void -watch_del(void *id) -{ - struct watch_object *t, *n; - - list_for_each_entry_safe(t, n, &watch_objects, list) { - if (t->id != id) - continue; - list_del(&t->list); - free(t); - } -} - -static int -watch_notify_cb(struct ubus_context *ctx, struct ubus_object *obj, - struct ubus_request_data *req, const char *method, - struct blob_attr *msg) -{ - if (debug >= 3) { - char *str; - - str = blobmsg_format_json(msg, true); - DEBUG(3, "Received ubus notify '%s': %s\n", method, str); - free(str); - } - - trigger_event(method, msg); - return 0; -} - -void -watch_ubus(struct ubus_context *ctx) -{ - watch_event.cb = watch_subscribe_cb; - watch_subscribe.cb = watch_notify_cb; - if (ubus_register_subscriber(ctx, &watch_subscribe)) - ERROR("failed to register ubus subscriber\n"); - if (ubus_register_event_handler(ctx, &watch_event, "ubus.object.add")) - ERROR("failed to add ubus event handler\n"); -} |