diff options
author | Christian Pointner <equinox@helsinki.at> | 2011-04-02 17:04:52 (GMT) |
---|---|---|
committer | Christian Pointner <equinox@helsinki.at> | 2011-04-02 17:04:52 (GMT) |
commit | d3a42c5c7f60d78e49d766318c98ed0efa1b7496 (patch) | |
tree | 114cfecc8431d93f696c31724c8de82225beca48 | |
parent | f84cc90e072816544ed7f18760358cf450c80fc0 (diff) |
added mode-tcplistener
-rw-r--r-- | mode-tcplistener.lua | 160 | ||||
-rw-r--r-- | openwrt/rhctl/files/rhctl.config | 7 |
2 files changed, 167 insertions, 0 deletions
diff --git a/mode-tcplistener.lua b/mode-tcplistener.lua new file mode 100644 index 0000000..f1f3e92 --- /dev/null +++ b/mode-tcplistener.lua @@ -0,0 +1,160 @@ +-- +-- rhctl +-- +-- Copyright (C) 2009 Christian Pointner <equinox@spreadspace.org> +-- +-- This file is part of rhctl. +-- +-- rhctl is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- any later version. +-- +-- rhctl 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. +-- +-- You should have received a copy of the GNU General Public License +-- along with rhctl. If not, see <http://www.gnu.org/licenses/>. +-- + +socket = require("socket") + +current_mode = nil + +function init_server(host, port) + local server = assert(socket.tcp()) + + assert(server:setoption('reuseaddr', true)) + assert(server:bind(host, port)) + assert(server:listen(5)) + + return server +end + +local clients = {} + +function add_client(hdl) + -- print("new client(" .. hdl:getfd() .. ") from " .. hdl:getpeername()) + local client = {} + if current_mode then + client.buffer = current_mode .. "\n" + else + client.buffer = "" + end + client.hdl = hdl + client.getfd = function() return hdl:getfd() end + client.dirty = function() return hdl:dirty() end + table.insert(clients, client) +end + +function remove_client(c) + local idx = 0 + for idx, client in ipairs(clients) do + if client == c then + break + end + end + + -- print("removing client(" .. c.hdl:getfd() .. ")") + c.hdl:close() + table.remove(clients, idx) +end + +function cleanup_clients() + for _, client in ipairs(clients) do + client:close() + end +end + +function clients_get_writeables() + local fds = {} + + for _, client in ipairs(clients) do + if client.buffer ~= "" then + table.insert(fds, client) + end + end + + return fds +end + +function clients_senddata(data) + for _, client in ipairs(clients) do + client.buffer = client.buffer .. data .. "\n" + end +end + +function process_cmd(message) + log.printf(log.DEBUG, "received message: '%s'", message) + + local new_mode = nil + local exps = { "Current Mode: (%a+)", "new Mode: (%a+)" } + for _, exp in ipairs(exps) do + new_mode = string.match(message, exp) + if(new_mode) then + new_mode = string.lower(new_mode) + break + end + end + + if(new_mode and new_mode ~= current_mode) then + clients_senddata(new_mode) + current_mode = new_mode + end + + return 0 +end + +function main_loop(opt) + log.printf(log.NOTICE, "main_loop started") + local sig = signal.init() + local cmdfd = cmd.init() + + local server = init_server("*", "2345") + + cmd.send_string("listen mode"); + cmd.send_string("status"); + + local return_value = 0 + while return_value == 0 do + local readable, _, err = socket.select({ sig , cmdfd , server , unpack(clients) }, clients_get_writeables()) + if(err) then + log.printf(log.ERROR, "select returned with error: %s", err) + return_value = -1 + else + for _, input in ipairs(readable) do + if input == sig then + return_value = signal.handle() + if(return_value == 1) then break end + elseif input == cmdfd then + return_value = cmd.recv_data(process_cmd) + if(return_value ~= 0) then break end + elseif input == server then + local client = server:accept() + if(client == nil) then + return_value =-3 + break + else + add_client(client) + end + else + if input.hdl then + -- receive is insanely stupid, therefore we must always read one byte only + local _, err = input.hdl:receive(1) + if err then + remove_client(input) + end + end + end + end + end + end + + server:close() + cleanup_clients() + + signal.stop() + return return_value +end diff --git a/openwrt/rhctl/files/rhctl.config b/openwrt/rhctl/files/rhctl.config index cf25990..6dbb9c0 100644 --- a/openwrt/rhctl/files/rhctl.config +++ b/openwrt/rhctl/files/rhctl.config @@ -46,3 +46,10 @@ config 'luaclient' option log 'syslog:3,luaclient-silence-watch,daemon' option command_sock '/var/run/rhctl/switchctl.sock' option lua_file '/usr/share/rhctl/silence-watch.lua' + +config 'luaclient' +# option disabled 1 + option name 'tcpserver' + option log 'syslog:3,luaclient-mode-tcpserver,daemon' + option command_sock '/var/run/rhctl/switchctl.sock' + option lua_file '/usr/share/rhctl/mode-tcpserver.lua' |