4 +include ../Makefile.inc
6 +PREFIX_SEARCH=/usr /usr/local /opt/local
7 +LUA_PLUGINDIR=$(firstword \
8 + $(foreach ldir,$(subst ;, ,$(shell lua -e 'print(package.cpath)')), \
9 + $(if $(findstring lib/lua/,$(ldir)),$(patsubst %/?.so,%,$(ldir))) \
14 +LUA_PREFIX=$(firstword \
15 + $(foreach prefix,$(PREFIX_SEARCH),\
16 + $(if $(wildcard $(prefix)/include/lua.h),$(prefix)) \
20 +libdir=$(prefix)/libs
21 +luadir=$(if $(LUA_PLUGINDIR),$(LUA_PLUGINDIR),$(libdir)/lua/$(LUA_VERSION))
22 +luainc=$(shell pkg-config --silence-errors --cflags lua$(LUA_VERSION))
24 +CPPFLAGS=-I.. $(if $(luainc),$(luainc), -I$(LUA_PREFIX)/include)
25 +LIBS=-L.. -luci $(shell pkg-config --silence-errors --libs lua$(LUA_VERSION))
29 + PLUGIN_LDFLAGS=-bundle
31 + PLUGIN_LDFLAGS=-shared -Wl,-soname,$(SHLIB_FILE)
36 +uci_trigger.so: uci_trigger.o
37 + $(PLUGIN_LD) $(PLUGIN_LDFLAGS) -o $@ $^ $(LIBS)
40 + $(CC) $(CPPFLAGS) $(CFLAGS) $(FPIC) -c -o $@ $<
43 + mkdir -p $(DESTDIR)$(luadir)
44 + $(INSTALL) -m0644 uci_trigger.so $(DESTDIR)$(luadir)/
47 + rm -f *.so *.o uci_trigger.so
49 +++ b/trigger/uci_trigger.c
51 +#include <sys/types.h>
52 +#include <sys/time.h>
62 +static int refcount = 0;
63 +static lua_State *gL = NULL;
64 +static bool prepared = false;
66 +struct trigger_set_op {
67 + struct uci_package *p;
68 + struct uci_delta *h;
71 +static int trigger_set(lua_State *L)
73 + struct trigger_set_op *so =
74 + (struct trigger_set_op *)lua_touserdata(L, 1);
75 + struct uci_package *p = so->p;
76 + struct uci_delta *h = so->h;
77 + struct uci_context *ctx = p->ctx;
79 + /* ignore non-standard savedirs/configdirs
80 + * in order to not trigger events on uci state changes */
81 + if (strcmp(ctx->savedir, UCI_SAVEDIR) ||
82 + strcmp(ctx->confdir, UCI_CONFDIR))
86 + lua_getglobal(L, "require");
87 + lua_pushstring(L, "uci.trigger");
90 + lua_getglobal(L, "uci");
91 + lua_getfield(L, -1, "trigger");
92 + lua_getfield(L, -1, "load_modules");
96 + lua_getglobal(L, "uci");
97 + lua_getfield(L, -1, "trigger");
100 + lua_getfield(L, -1, "set");
101 + lua_createtable(L, 4, 0);
103 + lua_pushstring(L, p->e.name);
104 + lua_rawseti(L, -2, 1);
106 + lua_pushstring(L, h->section);
107 + lua_rawseti(L, -2, 2);
110 + lua_pushstring(L, h->e.name);
111 + lua_rawseti(L, -2, 3);
114 + lua_pushstring(L, h->value);
115 + lua_rawseti(L, -2, 4);
124 +static int report (lua_State *L, int status) {
125 + if (status && !lua_isnil(L, -1)) {
126 + const char *msg = lua_tostring(L, -1);
127 + if (msg == NULL) msg = "(error object is not a string)";
128 + fprintf(stderr, "ERROR: %s\n", msg);
136 +static inline int report(lua_State *L, int status) {
142 +static void trigger_set_hook(const struct uci_hook_ops *ops, struct uci_package *p, struct uci_delta *h)
144 + struct trigger_set_op so;
148 + report(gL, lua_cpcall(gL, &trigger_set, &so));
151 +static struct uci_hook_ops hook = {
152 + .set = trigger_set_hook,
155 +static int trigger_attach(struct uci_context *ctx)
158 + gL = luaL_newstate();
165 + uci_add_hook(ctx, &hook);
169 +static void trigger_detach(struct uci_context *ctx)
171 + if (gL && (--refcount <= 0)) {
179 +struct uci_plugin_ops uci_plugin = {
180 + .attach = trigger_attach,
181 + .detach = trigger_detach,