3 local p = require("posix")
9 {"port", "required", 'p'},
14 for opt, optarg, optind, longind in p.getopt(arg, short, long) do
16 print("Unrecognized option")
18 elseif opt == 'h' then
19 print("Usage: ruld [-h|-p PORT]")
21 elseif opt == 'p' then
26 function eval(exp, env)
28 local value = "return " .. exp
30 f = load(value, nil, nil, env)
39 for index = #rules, 1, -1 do
40 local entry = rules[index]
41 if eval(entry[1], env) then
44 delay = entry[3].delay
45 duration = entry[3].duration
46 if delay and delay > 0 then
47 entry[3].delay = delay - 1
49 if ((not delay) or delay == 0) and duration and duration > 0 then
50 entry[3].duration = duration - 1
53 if (((not delay) or delay == 0) and ((not duration) or duration > 0)) then
55 rsp = rsp .. " " .. entry[2]
60 if duration and duration <= 1 then
61 table.remove(rules, index)
68 local fd = p.socket(p.AF_INET, p.SOCK_STREAM, 0)
69 p.setsockopt(fd, p.SOL_SOCKET, p.SO_REUSEADDR, 1)
70 p.bind(fd, {family=p.AF_INET, addr="127.0.0.1", port=port})
71 p.listen(fd, p.SOMAXCONN)
77 local msg = p.recv(ret_fd, p.BUFSIZ)
82 cmd = msg:sub(1, sep - 1)
83 data = msg:sub(sep + 1)
88 local env = eval(data)
93 elseif cmd == "add" then
94 local value = eval(data)
96 table.insert(rules, value)
98 elseif cmd == "remove" then
99 if data == "tail" then
100 table.remove(rules, #rules)
101 elseif data == "head" then
102 table.remove(rules, 1)
104 for index = #rules, 1, -1 do
105 if rules[index][1]:find(data) then
106 table.remove(rules, index)
110 elseif cmd == "quit" then
112 elseif cmd == "list" then
114 for index, entry in pairs(rules) do
115 rsp = rsp .. string.format("%s => %s", entry[1], entry[2])
117 if entry[3].delay then
118 rsp = rsp .. string.format(" @%i", entry[3].delay)
120 if entry[3].duration then
121 rsp = rsp .. string.format(" +%i", entry[3].duration)
124 if index < #rules then