mirror of
				git://git.openwrt.org/openwrt/openwrt.git
				synced 2025-11-03 22:44:27 -05:00 
			
		
		
		
	remove ucitrigger, it is unused and will be replaced by something different in the future
SVN-Revision: 26308
This commit is contained in:
		
							parent
							
								
									e8c9ebd052
								
							
						
					
					
						commit
						e4c6bc70aa
					
				@ -41,13 +41,6 @@ define Package/uci
 | 
			
		||||
  TITLE:=Utility for the Unified Configuration Interface (UCI)
 | 
			
		||||
endef
 | 
			
		||||
 | 
			
		||||
define Package/ucitrigger
 | 
			
		||||
  SECTION:=base
 | 
			
		||||
  CATEGORY:=Base system
 | 
			
		||||
  DEPENDS:=+libuci-lua +lua
 | 
			
		||||
  TITLE:=Automatic triggers for applying system config changes
 | 
			
		||||
endef
 | 
			
		||||
 | 
			
		||||
define Package/libuci-lua
 | 
			
		||||
  SECTION=libs
 | 
			
		||||
  CATEGORY=Libraries
 | 
			
		||||
@ -72,14 +65,6 @@ define Package/libuci-lua/install
 | 
			
		||||
	$(CP) $(PKG_BUILD_DIR)/lua/uci.so $(1)/usr/lib/lua/
 | 
			
		||||
endef
 | 
			
		||||
 | 
			
		||||
define Package/ucitrigger/install
 | 
			
		||||
	$(INSTALL_DIR) $(1)/usr/lib/lua/uci $(1)/lib/config/trigger $(1)/usr/sbin
 | 
			
		||||
	$(INSTALL_DATA) ./trigger/lib/trigger.lua $(1)/usr/lib/lua/uci/
 | 
			
		||||
	$(INSTALL_DATA) ./trigger/modules/*.lua $(1)/lib/config/trigger/
 | 
			
		||||
	$(INSTALL_DATA) $(PKG_BUILD_DIR)/trigger/uci_trigger.so $(1)/usr/lib/
 | 
			
		||||
	$(INSTALL_BIN) ./trigger/apply_config $(1)/usr/sbin/
 | 
			
		||||
endef
 | 
			
		||||
 | 
			
		||||
define Package/uci/install
 | 
			
		||||
	$(INSTALL_DIR) $(1)/etc/uci-defaults
 | 
			
		||||
	$(INSTALL_DIR) $(1)/sbin
 | 
			
		||||
@ -98,4 +83,3 @@ endef
 | 
			
		||||
$(eval $(call BuildPackage,uci))
 | 
			
		||||
$(eval $(call BuildPackage,libuci))
 | 
			
		||||
$(eval $(call BuildPackage,libuci-lua))
 | 
			
		||||
$(eval $(call BuildPackage,ucitrigger))
 | 
			
		||||
 | 
			
		||||
@ -1,168 +0,0 @@
 | 
			
		||||
--- /dev/null
 | 
			
		||||
+++ b/trigger/uci_trigger.c
 | 
			
		||||
@@ -0,0 +1,132 @@
 | 
			
		||||
+#include <sys/types.h>
 | 
			
		||||
+#include <sys/time.h>
 | 
			
		||||
+#include <stdbool.h>
 | 
			
		||||
+#include <string.h>
 | 
			
		||||
+#include <stdio.h>
 | 
			
		||||
+#include <lualib.h>
 | 
			
		||||
+#include <lauxlib.h>
 | 
			
		||||
+#include "uci.h"
 | 
			
		||||
+
 | 
			
		||||
+// #define DEBUG
 | 
			
		||||
+
 | 
			
		||||
+static int refcount = 0;
 | 
			
		||||
+static lua_State *gL = NULL;
 | 
			
		||||
+static bool prepared = false;
 | 
			
		||||
+
 | 
			
		||||
+struct trigger_set_op {
 | 
			
		||||
+	struct uci_package *p;
 | 
			
		||||
+	struct uci_delta *h;
 | 
			
		||||
+};
 | 
			
		||||
+
 | 
			
		||||
+static int trigger_set(lua_State *L)
 | 
			
		||||
+{
 | 
			
		||||
+	struct trigger_set_op *so =
 | 
			
		||||
+		(struct trigger_set_op *)lua_touserdata(L, 1);
 | 
			
		||||
+	struct uci_package *p = so->p;
 | 
			
		||||
+	struct uci_delta *h = so->h;
 | 
			
		||||
+	struct uci_context *ctx = p->ctx;
 | 
			
		||||
+
 | 
			
		||||
+	/* ignore non-standard savedirs/configdirs
 | 
			
		||||
+	 * in order to not trigger events on uci state changes */
 | 
			
		||||
+	if (strcmp(ctx->savedir, UCI_SAVEDIR) ||
 | 
			
		||||
+		strcmp(ctx->confdir, UCI_CONFDIR))
 | 
			
		||||
+		return 0;
 | 
			
		||||
+
 | 
			
		||||
+	if (!prepared) {
 | 
			
		||||
+		lua_getglobal(L, "require");
 | 
			
		||||
+		lua_pushstring(L, "uci.trigger");
 | 
			
		||||
+		lua_call(L, 1, 0);
 | 
			
		||||
+
 | 
			
		||||
+		lua_getglobal(L, "uci");
 | 
			
		||||
+		lua_getfield(L, -1, "trigger");
 | 
			
		||||
+		lua_getfield(L, -1, "load_modules");
 | 
			
		||||
+		lua_call(L, 0, 0);
 | 
			
		||||
+		prepared = true;
 | 
			
		||||
+	} else {
 | 
			
		||||
+		lua_getglobal(L, "uci");
 | 
			
		||||
+		lua_getfield(L, -1, "trigger");
 | 
			
		||||
+	}
 | 
			
		||||
+
 | 
			
		||||
+	lua_getfield(L, -1, "set");
 | 
			
		||||
+	lua_createtable(L, 4, 0);
 | 
			
		||||
+
 | 
			
		||||
+	lua_pushstring(L, p->e.name);
 | 
			
		||||
+	lua_rawseti(L, -2, 1);
 | 
			
		||||
+	if (h->section) {
 | 
			
		||||
+		lua_pushstring(L, h->section);
 | 
			
		||||
+		lua_rawseti(L, -2, 2);
 | 
			
		||||
+	}
 | 
			
		||||
+	if (h->e.name) {
 | 
			
		||||
+		lua_pushstring(L, h->e.name);
 | 
			
		||||
+		lua_rawseti(L, -2, 3);
 | 
			
		||||
+	}
 | 
			
		||||
+	if (h->value) {
 | 
			
		||||
+		lua_pushstring(L, h->value);
 | 
			
		||||
+		lua_rawseti(L, -2, 4);
 | 
			
		||||
+	}
 | 
			
		||||
+	lua_call(L, 1, 0);
 | 
			
		||||
+	lua_pop(L, 2);
 | 
			
		||||
+	return 0;
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+#ifdef DEBUG
 | 
			
		||||
+
 | 
			
		||||
+static int report (lua_State *L, int status) {
 | 
			
		||||
+	if (status && !lua_isnil(L, -1)) {
 | 
			
		||||
+		const char *msg = lua_tostring(L, -1);
 | 
			
		||||
+		if (msg == NULL) msg = "(error object is not a string)";
 | 
			
		||||
+		fprintf(stderr, "ERROR: %s\n", msg);
 | 
			
		||||
+		lua_pop(L, 1);
 | 
			
		||||
+	}
 | 
			
		||||
+	return status;
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+#else
 | 
			
		||||
+
 | 
			
		||||
+static inline int report(lua_State *L, int status) {
 | 
			
		||||
+	return status;
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+#endif
 | 
			
		||||
+
 | 
			
		||||
+static void trigger_set_hook(const struct uci_hook_ops *ops, struct uci_package *p, struct uci_delta *h)
 | 
			
		||||
+{
 | 
			
		||||
+	struct trigger_set_op so;
 | 
			
		||||
+
 | 
			
		||||
+	so.p = p;
 | 
			
		||||
+	so.h = h;
 | 
			
		||||
+	report(gL, lua_cpcall(gL, &trigger_set, &so));
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+static struct uci_hook_ops hook = {
 | 
			
		||||
+	.set = trigger_set_hook,
 | 
			
		||||
+};
 | 
			
		||||
+
 | 
			
		||||
+static int trigger_attach(struct uci_context *ctx)
 | 
			
		||||
+{
 | 
			
		||||
+	if (!gL) {
 | 
			
		||||
+		gL = luaL_newstate();
 | 
			
		||||
+		if (!gL)
 | 
			
		||||
+			return -1;
 | 
			
		||||
+		luaL_openlibs(gL);
 | 
			
		||||
+
 | 
			
		||||
+		refcount++;
 | 
			
		||||
+	}
 | 
			
		||||
+	uci_add_hook(ctx, &hook);
 | 
			
		||||
+	return 0;
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+static void trigger_detach(struct uci_context *ctx)
 | 
			
		||||
+{
 | 
			
		||||
+	if (gL && (--refcount <= 0)) {
 | 
			
		||||
+		lua_close(gL);
 | 
			
		||||
+		gL = NULL;
 | 
			
		||||
+		refcount = 0;
 | 
			
		||||
+		prepared = false;
 | 
			
		||||
+	}
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+struct uci_plugin_ops uci_plugin = {
 | 
			
		||||
+	.attach = trigger_attach,
 | 
			
		||||
+	.detach = trigger_detach,
 | 
			
		||||
+};
 | 
			
		||||
--- a/CMakeLists.txt
 | 
			
		||||
+++ b/CMakeLists.txt
 | 
			
		||||
@@ -35,6 +35,7 @@ ADD_EXECUTABLE(ucimap-example ucimap-exa
 | 
			
		||||
 TARGET_LINK_LIBRARIES(ucimap-example uci-static ucimap dl)
 | 
			
		||||
 
 | 
			
		||||
 ADD_SUBDIRECTORY(lua)
 | 
			
		||||
+ADD_SUBDIRECTORY(trigger)
 | 
			
		||||
 
 | 
			
		||||
 INSTALL(FILES uci.h uci_config.h ucimap.h
 | 
			
		||||
 	DESTINATION include/libubox
 | 
			
		||||
--- /dev/null
 | 
			
		||||
+++ b/trigger/CMakeLists.txt
 | 
			
		||||
@@ -0,0 +1,19 @@
 | 
			
		||||
+cmake_minimum_required(VERSION 2.6)
 | 
			
		||||
+
 | 
			
		||||
+PROJECT(uci C)
 | 
			
		||||
+
 | 
			
		||||
+SET(CMAKE_INSTALL_PREFIX /)
 | 
			
		||||
+
 | 
			
		||||
+ADD_DEFINITIONS(-Os -Wall -Werror --std=gnu99 -g3 -I..)
 | 
			
		||||
+
 | 
			
		||||
+IF(APPLE)
 | 
			
		||||
+	SET(CMAKE_SHARED_MODULE_CREATE_C_FLAGS "${CMAKE_SHARED_MODULE_CREATE_C_FLAGS} -undefined dynamic_lookup")
 | 
			
		||||
+ENDIF(APPLE)
 | 
			
		||||
+
 | 
			
		||||
+ADD_LIBRARY(uci_trigger MODULE uci_trigger.c)
 | 
			
		||||
+SET_TARGET_PROPERTIES(uci_trigger PROPERTIES
 | 
			
		||||
+	OUTPUT_NAME uci_trigger
 | 
			
		||||
+	PREFIX ""
 | 
			
		||||
+)
 | 
			
		||||
+TARGET_LINK_LIBRARIES(uci_trigger uci)
 | 
			
		||||
+
 | 
			
		||||
 | 
			
		||||
@ -1,54 +0,0 @@
 | 
			
		||||
#!/usr/bin/lua
 | 
			
		||||
require("uci")
 | 
			
		||||
require("uci.trigger")
 | 
			
		||||
 | 
			
		||||
function usage() 
 | 
			
		||||
	print("Usage: " .. arg[0] .. " [options]")
 | 
			
		||||
	print("Options:")
 | 
			
		||||
	print("    -a: apply the config changes")
 | 
			
		||||
	print("    -t: show matching UCI triggers")
 | 
			
		||||
	print("    -s: show information about tasks to be executed")
 | 
			
		||||
	print("    -r: reset all triggers")
 | 
			
		||||
	print("    -C <trigger> [<section>]: force clear a trigger")
 | 
			
		||||
	print("    -S <trigger> [<section>]: force set a trigger")
 | 
			
		||||
	print("")
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
if arg[1] == "-s" then
 | 
			
		||||
	local triggers = uci.trigger.get_active()
 | 
			
		||||
	if #triggers > 0 then
 | 
			
		||||
		print("Tasks:")
 | 
			
		||||
		for i, a in ipairs(triggers) do
 | 
			
		||||
			local trigger = a[1]
 | 
			
		||||
			local sections = a[2]
 | 
			
		||||
			print(" - " .. uci.trigger.get_description(trigger, sections))
 | 
			
		||||
		end
 | 
			
		||||
	else
 | 
			
		||||
		print "Nothing to do"
 | 
			
		||||
	end
 | 
			
		||||
elseif arg[1] == "-t" then
 | 
			
		||||
	local triggers = uci.trigger.get_active()
 | 
			
		||||
	for i, a in ipairs(triggers) do
 | 
			
		||||
		local trigger = a[1]
 | 
			
		||||
		local sections = a[2]
 | 
			
		||||
		if trigger.section_only then
 | 
			
		||||
			print(trigger.id .. " " .. table.concat(sections, " "))
 | 
			
		||||
		else
 | 
			
		||||
			print(trigger.id)
 | 
			
		||||
		end
 | 
			
		||||
	end
 | 
			
		||||
elseif arg[1] == "-a" then
 | 
			
		||||
	uci.trigger.run()
 | 
			
		||||
elseif arg[1] == "-r" then
 | 
			
		||||
	uci.trigger.reset_state()
 | 
			
		||||
elseif arg[1] == "-S" then
 | 
			
		||||
	local trigger = arg[2]
 | 
			
		||||
	local section = arg[3]
 | 
			
		||||
	uci.trigger.set_active(trigger, section)
 | 
			
		||||
elseif arg[1] == "-C" then
 | 
			
		||||
	local trigger = arg[2]
 | 
			
		||||
	local section = arg[3]
 | 
			
		||||
	uci.trigger.clear_active(trigger, section)
 | 
			
		||||
else
 | 
			
		||||
	usage()
 | 
			
		||||
end
 | 
			
		||||
@ -1,419 +0,0 @@
 | 
			
		||||
module("uci.trigger", package.seeall)
 | 
			
		||||
require("posix")
 | 
			
		||||
require("uci")
 | 
			
		||||
 | 
			
		||||
local path = "/lib/config/trigger"
 | 
			
		||||
local triggers = nil
 | 
			
		||||
local tmp_cursor = nil
 | 
			
		||||
 | 
			
		||||
function load_modules()
 | 
			
		||||
	if triggers ~= nil then
 | 
			
		||||
		return
 | 
			
		||||
	end
 | 
			
		||||
	triggers = {
 | 
			
		||||
		list = {},
 | 
			
		||||
		uci = {},
 | 
			
		||||
		active = {}
 | 
			
		||||
	}
 | 
			
		||||
	local modules = posix.glob(path .. "/*.lua")
 | 
			
		||||
	if modules == nil then
 | 
			
		||||
		return
 | 
			
		||||
	end
 | 
			
		||||
	local oldpath = package.path
 | 
			
		||||
	package.path = path .. "/?.lua"
 | 
			
		||||
	for i, v in ipairs(modules) do
 | 
			
		||||
		pcall(require(string.gsub(v, path .. "/(%w+)%.lua$", "%1")))
 | 
			
		||||
	end
 | 
			
		||||
	package.path = oldpath
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function check_table(table, name)
 | 
			
		||||
	if table[name] == nil then
 | 
			
		||||
		table[name] = {}
 | 
			
		||||
	end
 | 
			
		||||
	return table[name]
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function get_table_val(val, vtype)
 | 
			
		||||
	if type(val) == (vtype or "string") then
 | 
			
		||||
		return { val }
 | 
			
		||||
	elseif type(val) == "table" then
 | 
			
		||||
		return val
 | 
			
		||||
	end
 | 
			
		||||
	return nil
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function get_name_list(name)
 | 
			
		||||
	return get_table_val(name or ".all")
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function add_trigger_option(list, t)
 | 
			
		||||
	local name = get_name_list(t.option)
 | 
			
		||||
	for i, n in ipairs(name) do
 | 
			
		||||
		option = check_table(list, n)
 | 
			
		||||
		table.insert(option, t)
 | 
			
		||||
	end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function add_trigger_section(list, t)
 | 
			
		||||
	local name = get_name_list(t.section)
 | 
			
		||||
	for i, n in ipairs(name) do
 | 
			
		||||
		section = check_table(list, n)
 | 
			
		||||
		add_trigger_option(section, t)
 | 
			
		||||
	end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function check_insert_triggers(dest, list, tuple)
 | 
			
		||||
	if list == nil then
 | 
			
		||||
		return
 | 
			
		||||
	end
 | 
			
		||||
	for i, t in ipairs(list) do
 | 
			
		||||
		local add = true
 | 
			
		||||
		if type(t.check) == "function" then
 | 
			
		||||
			add = t.check(tuple)
 | 
			
		||||
		end
 | 
			
		||||
		if add then
 | 
			
		||||
			dest[t.id] = t
 | 
			
		||||
		end
 | 
			
		||||
	end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function find_section_triggers(tlist, pos, tuple)
 | 
			
		||||
	if pos == nil then
 | 
			
		||||
		return
 | 
			
		||||
	end
 | 
			
		||||
	check_insert_triggers(tlist, pos[".all"], tuple)
 | 
			
		||||
	if tuple.option then
 | 
			
		||||
		check_insert_triggers(tlist, pos[tuple.option], tuple)
 | 
			
		||||
	end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function check_recursion(name, seen)
 | 
			
		||||
	if seen == nil then
 | 
			
		||||
		seen = {}
 | 
			
		||||
	end
 | 
			
		||||
	if seen[name] then
 | 
			
		||||
		return nil
 | 
			
		||||
	end
 | 
			
		||||
	seen[name] = true
 | 
			
		||||
	return seen
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
function find_recursive_depends(list, name, seen)
 | 
			
		||||
	seen = check_recursion(name, seen)
 | 
			
		||||
	if not seen then
 | 
			
		||||
		return
 | 
			
		||||
	end
 | 
			
		||||
	local bt = get_table_val(triggers.list[name].belongs_to) or {}
 | 
			
		||||
	for i, n in ipairs(bt) do
 | 
			
		||||
		table.insert(list, n)
 | 
			
		||||
		find_recursive_depends(list, n, seen)
 | 
			
		||||
	end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function check_trigger_depth(list, name)
 | 
			
		||||
	if name == nil then
 | 
			
		||||
		return
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
	local n = list[name]
 | 
			
		||||
	if n == nil then
 | 
			
		||||
		return
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
	list[name] = nil
 | 
			
		||||
	return check_trigger_depth(list, n)
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function find_triggers(tuple)
 | 
			
		||||
	local pos = triggers.uci[tuple.package]
 | 
			
		||||
	if pos == nil then
 | 
			
		||||
		return {}
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
	local tlist = {}
 | 
			
		||||
	find_section_triggers(tlist, pos[".all"], tuple)
 | 
			
		||||
	find_section_triggers(tlist, pos[tuple.section[".type"]], tuple)
 | 
			
		||||
 | 
			
		||||
	for n, t in pairs(tlist) do
 | 
			
		||||
		local dep = {}
 | 
			
		||||
		find_recursive_depends(dep, t.id)
 | 
			
		||||
		for i, depname in ipairs(dep) do
 | 
			
		||||
			check_trigger_depth(tlist, depname)
 | 
			
		||||
		end
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
	local nlist = {}
 | 
			
		||||
	for n, t in pairs(tlist) do
 | 
			
		||||
		if t then
 | 
			
		||||
			table.insert(nlist, t)
 | 
			
		||||
		end
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
	return nlist
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function reset_state()
 | 
			
		||||
	assert(io.open("/var/run/uci_trigger", "w")):close()
 | 
			
		||||
	if tctx then
 | 
			
		||||
		tctx:unload("uci_trigger")
 | 
			
		||||
	end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function load_state()
 | 
			
		||||
	-- make sure the config file exists before we attempt to load it
 | 
			
		||||
	-- uci doesn't like loading nonexistent config files
 | 
			
		||||
	local f = assert(io.open("/var/run/uci_trigger", "a")):close()
 | 
			
		||||
 | 
			
		||||
	load_modules()
 | 
			
		||||
	triggers.active = {}
 | 
			
		||||
	if tctx then
 | 
			
		||||
		tctx:unload("uci_trigger")
 | 
			
		||||
	else
 | 
			
		||||
		tctx = uci.cursor()
 | 
			
		||||
	end
 | 
			
		||||
	assert(tctx:load("/var/run/uci_trigger"))
 | 
			
		||||
	tctx:foreach("uci_trigger", "trigger",
 | 
			
		||||
		function(section)
 | 
			
		||||
			trigger = triggers.list[section[".name"]]
 | 
			
		||||
			if trigger == nil then
 | 
			
		||||
				return
 | 
			
		||||
			end
 | 
			
		||||
 | 
			
		||||
			active = {}
 | 
			
		||||
			triggers.active[trigger.id] = active
 | 
			
		||||
 | 
			
		||||
			local s = get_table_val(section["sections"]) or {}
 | 
			
		||||
			for i, v in ipairs(s) do
 | 
			
		||||
				active[v] = true
 | 
			
		||||
			end
 | 
			
		||||
		end
 | 
			
		||||
	)
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function get_names(list)
 | 
			
		||||
	local slist = {}
 | 
			
		||||
	for name, val in pairs(list) do
 | 
			
		||||
		if val then
 | 
			
		||||
			table.insert(slist, name)
 | 
			
		||||
		end
 | 
			
		||||
	end
 | 
			
		||||
	return slist
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function check_cancel(name, seen)
 | 
			
		||||
	local t = triggers.list[name]
 | 
			
		||||
	local dep = get_table_val(t.belongs_to)
 | 
			
		||||
	seen = check_recursion(name, seen)
 | 
			
		||||
 | 
			
		||||
	if not t or not dep or not seen then
 | 
			
		||||
		return false
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
	for i, v in ipairs(dep) do
 | 
			
		||||
		-- only cancel triggers for all sections
 | 
			
		||||
		-- if both the current and the parent trigger
 | 
			
		||||
		-- are per-section
 | 
			
		||||
		local section_only = false
 | 
			
		||||
		if t.section_only then
 | 
			
		||||
			local tdep = triggers.list[v]
 | 
			
		||||
			if tdep then
 | 
			
		||||
				section_only = tdep.section_only
 | 
			
		||||
			end
 | 
			
		||||
		end
 | 
			
		||||
 | 
			
		||||
		if check_cancel(v, seen) then
 | 
			
		||||
			return true
 | 
			
		||||
		end
 | 
			
		||||
		if triggers.active[v] then
 | 
			
		||||
			if section_only then
 | 
			
		||||
				for n, active in pairs(triggers.active[v]) do
 | 
			
		||||
					triggers.active[name][n] = false
 | 
			
		||||
				end
 | 
			
		||||
			else
 | 
			
		||||
				return true
 | 
			
		||||
			end
 | 
			
		||||
		end
 | 
			
		||||
	end
 | 
			
		||||
	return false
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
-- trigger api functions
 | 
			
		||||
 | 
			
		||||
function add(ts)
 | 
			
		||||
	for i,t in ipairs(ts) do
 | 
			
		||||
		triggers.list[t.id] = t
 | 
			
		||||
		match = {}
 | 
			
		||||
		if t.package then
 | 
			
		||||
			local package = check_table(triggers.uci, t.package)
 | 
			
		||||
			add_trigger_section(package, t)
 | 
			
		||||
			triggers.list[t.id] = t
 | 
			
		||||
		end
 | 
			
		||||
	end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function save_trigger(name)
 | 
			
		||||
	if triggers.active[name] then
 | 
			
		||||
		local slist = get_names(triggers.active[name])
 | 
			
		||||
		if #slist > 0 then
 | 
			
		||||
			tctx:set("uci_trigger", name, "sections", slist)
 | 
			
		||||
		end
 | 
			
		||||
	else
 | 
			
		||||
		tctx:delete("uci_trigger", name)
 | 
			
		||||
	end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function set(data, cursor)
 | 
			
		||||
	assert(data ~= nil)
 | 
			
		||||
	if cursor == nil then
 | 
			
		||||
		cursor = tmp_cursor or uci.cursor()
 | 
			
		||||
		tmp_cursor = uci.cursor
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
	local tuple = {
 | 
			
		||||
		package = data[1],
 | 
			
		||||
		section = data[2],
 | 
			
		||||
		option = data[3],
 | 
			
		||||
		value = data[4]
 | 
			
		||||
	}
 | 
			
		||||
	assert(cursor:load(tuple.package))
 | 
			
		||||
 | 
			
		||||
	load_state()
 | 
			
		||||
	local section = cursor:get_all(tuple.package, tuple.section)
 | 
			
		||||
	if (section == nil) then
 | 
			
		||||
		if option ~= nil then
 | 
			
		||||
			return
 | 
			
		||||
		end
 | 
			
		||||
		section = {
 | 
			
		||||
			[".type"] = value
 | 
			
		||||
		}
 | 
			
		||||
		if tuple.section == nil then
 | 
			
		||||
			tuple.section = ""
 | 
			
		||||
			section[".anonymous"] = true
 | 
			
		||||
		end
 | 
			
		||||
		section[".name"] = tuple.section
 | 
			
		||||
	end
 | 
			
		||||
	tuple.section = section
 | 
			
		||||
 | 
			
		||||
	local ts = find_triggers(tuple)
 | 
			
		||||
	for i, t in ipairs(ts) do
 | 
			
		||||
		local active = triggers.active[t.id]
 | 
			
		||||
		if not active then
 | 
			
		||||
			active = {}
 | 
			
		||||
			triggers.active[t.id] = active
 | 
			
		||||
			tctx:set("uci_trigger", t.id, "trigger")
 | 
			
		||||
		end
 | 
			
		||||
		if section[".name"] then
 | 
			
		||||
			active[section[".name"]] = true
 | 
			
		||||
		end
 | 
			
		||||
		save_trigger(t.id)
 | 
			
		||||
	end
 | 
			
		||||
	tctx:save("uci_trigger")
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function get_description(trigger, sections)
 | 
			
		||||
	if not trigger.title then
 | 
			
		||||
		return trigger.id
 | 
			
		||||
	end
 | 
			
		||||
	local desc = trigger.title
 | 
			
		||||
	if trigger.section_only and sections and #sections > 0 then
 | 
			
		||||
		desc = desc .. " (" .. table.concat(sections, ", ") .. ")"
 | 
			
		||||
	end
 | 
			
		||||
	return desc
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function get_active()
 | 
			
		||||
	local slist = {}
 | 
			
		||||
 | 
			
		||||
	if triggers == nil then
 | 
			
		||||
		load_state()
 | 
			
		||||
	end
 | 
			
		||||
	for name, val in pairs(triggers.active) do
 | 
			
		||||
		if val and not check_cancel(name) then
 | 
			
		||||
			local sections = {}
 | 
			
		||||
			for name, active in pairs(triggers.active[name]) do
 | 
			
		||||
				if active then
 | 
			
		||||
					table.insert(sections, name)
 | 
			
		||||
				end
 | 
			
		||||
			end
 | 
			
		||||
			table.insert(slist, { triggers.list[name], sections })
 | 
			
		||||
		end
 | 
			
		||||
	end
 | 
			
		||||
	return slist
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function set_active(trigger, sections)
 | 
			
		||||
	if triggers == nil then
 | 
			
		||||
		load_state()
 | 
			
		||||
	end
 | 
			
		||||
	if not triggers.list[trigger] then
 | 
			
		||||
		return
 | 
			
		||||
	end
 | 
			
		||||
	if triggers.active[trigger] == nil then
 | 
			
		||||
		tctx:set("uci_trigger", trigger, "trigger")
 | 
			
		||||
		triggers.active[trigger] = {}
 | 
			
		||||
	end
 | 
			
		||||
	local active = triggers.active[trigger]
 | 
			
		||||
	if triggers.list[trigger].section_only or sections ~= nil then
 | 
			
		||||
		for i, t in ipairs(sections) do
 | 
			
		||||
			triggers.active[trigger][t] = true
 | 
			
		||||
		end
 | 
			
		||||
	end
 | 
			
		||||
	save_trigger(trigger)
 | 
			
		||||
	tctx:save("uci_trigger")
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function clear_active(trigger, sections)
 | 
			
		||||
	if triggers == nil then
 | 
			
		||||
		load_state()
 | 
			
		||||
	end
 | 
			
		||||
	if triggers.list[trigger] == nil or triggers.active[trigger] == nil then
 | 
			
		||||
		return
 | 
			
		||||
	end
 | 
			
		||||
	local active = triggers.active[trigger]
 | 
			
		||||
	if not triggers.list[trigger].section_only or sections == nil then
 | 
			
		||||
		triggers.active[trigger] = nil
 | 
			
		||||
	else
 | 
			
		||||
		for i, t in ipairs(sections) do
 | 
			
		||||
			triggers.active[trigger][t] = false
 | 
			
		||||
		end
 | 
			
		||||
	end
 | 
			
		||||
	save_trigger(trigger)
 | 
			
		||||
	tctx:save("uci_trigger")
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function run(ts)
 | 
			
		||||
	if ts == nil then
 | 
			
		||||
		ts = get_active()
 | 
			
		||||
	end
 | 
			
		||||
	for i, t in ipairs(ts) do
 | 
			
		||||
		local trigger = t[1]
 | 
			
		||||
		local sections = t[2]
 | 
			
		||||
		local actions = get_table_val(trigger.action, "function") or {}
 | 
			
		||||
		for ai, a in ipairs(actions) do
 | 
			
		||||
			if not trigger.section_only then
 | 
			
		||||
				sections = { "" }
 | 
			
		||||
			end
 | 
			
		||||
			for si, s in ipairs(sections) do
 | 
			
		||||
				if a(s) then
 | 
			
		||||
					tctx:delete("uci_trigger", trigger.id)
 | 
			
		||||
					tctx:save("uci_trigger")
 | 
			
		||||
				end
 | 
			
		||||
			end
 | 
			
		||||
		end
 | 
			
		||||
	end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
-- helper functions
 | 
			
		||||
 | 
			
		||||
function system_command(arg)
 | 
			
		||||
	local cmd = arg
 | 
			
		||||
	return function(arg)
 | 
			
		||||
		return os.execute(cmd:format(arg)) == 0
 | 
			
		||||
	end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function service_restart(arg)
 | 
			
		||||
	return system_command("/etc/init.d/" .. arg .. " restart")
 | 
			
		||||
end
 | 
			
		||||
@ -1,63 +0,0 @@
 | 
			
		||||
module("trigger.base", package.seeall)
 | 
			
		||||
require("uci.trigger")
 | 
			
		||||
 | 
			
		||||
uci.trigger.add {
 | 
			
		||||
	{
 | 
			
		||||
		id = "dnsmasq_restart",
 | 
			
		||||
		title = "Restart dnsmasq",
 | 
			
		||||
		package = "dhcp",
 | 
			
		||||
		action = uci.trigger.service_restart("dnsmasq"),
 | 
			
		||||
	},
 | 
			
		||||
	{
 | 
			
		||||
		id = "dropbear_restart",
 | 
			
		||||
		title = "Restart dropbear",
 | 
			
		||||
		package = "dropbear",
 | 
			
		||||
		action = uci.trigger.service_restart("dropbear"),
 | 
			
		||||
	},
 | 
			
		||||
	{
 | 
			
		||||
		id = "fstab_restart",
 | 
			
		||||
		title = "Remount filesystems",
 | 
			
		||||
		package = "fstab",
 | 
			
		||||
		action = uci.trigger.service_restart("fstab"),
 | 
			
		||||
	},
 | 
			
		||||
	{
 | 
			
		||||
		id = "firewall_restart",
 | 
			
		||||
		title = "Reload firewall rules",
 | 
			
		||||
		package = "firewall",
 | 
			
		||||
		action = uci.trigger.service_restart("firewall"),
 | 
			
		||||
	},
 | 
			
		||||
	{
 | 
			
		||||
		id = "httpd_restart",
 | 
			
		||||
		title = "Restart the http server",
 | 
			
		||||
		package = "httpd",
 | 
			
		||||
		action = uci.trigger.service_restart("httpd")
 | 
			
		||||
	},
 | 
			
		||||
	{
 | 
			
		||||
		id = "led_restart",
 | 
			
		||||
		title = "Reload LED settings",
 | 
			
		||||
		package = "system",
 | 
			
		||||
		section = "led",
 | 
			
		||||
		action = uci.trigger.service_restart("led")
 | 
			
		||||
	},
 | 
			
		||||
	{
 | 
			
		||||
		id = "network_restart",
 | 
			
		||||
		title = "Restart networking and wireless",
 | 
			
		||||
		package = "network",
 | 
			
		||||
		action = uci.trigger.service_restart("network")
 | 
			
		||||
	},
 | 
			
		||||
	{
 | 
			
		||||
		id = "qos_restart",
 | 
			
		||||
		title = "Reload Quality of Service rules",
 | 
			
		||||
		package = "qos",
 | 
			
		||||
		action = uci.trigger.service_restart("qos"),
 | 
			
		||||
	},
 | 
			
		||||
	{
 | 
			
		||||
		id = "wireless_restart",
 | 
			
		||||
		title = "Restart all wireless interfaces",
 | 
			
		||||
		package = "wireless",
 | 
			
		||||
		section = { "wifi-device", "wifi-iface" },
 | 
			
		||||
		action = uci.trigger.system_command("wifi"),
 | 
			
		||||
		belongs_to = "network_restart"
 | 
			
		||||
	},
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user