summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Pointner <equinox@spreadspace.org>2010-12-29 02:54:55 +0000
committerChristian Pointner <equinox@spreadspace.org>2010-12-29 02:54:55 +0000
commit2c418ff14347f5ae5c4f93c74dcdca9ce8f7e4b0 (patch)
tree875a4628776eeda6cd7ad0e2291bdacce2c8b581
parentadded tcp.client and tcp.connect (diff)
debug shell not using lua sockets any more
updated TODO and README git-svn-id: https://svn.spreadspace.org/gcsd/trunk@86 ac14a137-c7f1-4531-abe0-07747231d213
-rw-r--r--README5
-rw-r--r--TODO2
-rw-r--r--src/modules/debug_shell.lua228
3 files changed, 106 insertions, 129 deletions
diff --git a/README b/README
index 8323847..cc812b3 100644
--- a/README
+++ b/README
@@ -26,7 +26,7 @@ if you want to rebuild the manpage:
asciidoc
modules:
- liblua5.1-socket2
+ <no additional deps yet>
FreeBSD
@@ -37,7 +37,8 @@ core:
lang/lua
modules:
- net/luasocket
+ <no additional deps yet>
+
Windows
-------
diff --git a/TODO b/TODO
index 85bef3e..3c1401e 100644
--- a/TODO
+++ b/TODO
@@ -1,4 +1,4 @@
- * stop daemon when output module is supposed be removed
+ * stop daemon when output module is supposed to be removed
* send response to requestor
* out-of-order responses
* add listener tables (for requests, responses and other messages)
diff --git a/src/modules/debug_shell.lua b/src/modules/debug_shell.lua
index 9632383..a629d3b 100644
--- a/src/modules/debug_shell.lua
+++ b/src/modules/debug_shell.lua
@@ -30,8 +30,6 @@
-- along with gcsd. If not, see <http://www.gnu.org/licenses/>.
--
-local socket = require("socket")
-
-- debug shell module class
local debug_shell = {}
debug_shell.properties = { type=defines.MISC_MODULE, name="debug_shell", max_instances=-1 }
@@ -52,143 +50,121 @@ function debug_shell:new(config, runtype)
if(not config.host) then config.host = self.defaults.host end
if(not config.port) then config.port = self.defaults.port end
- local ip, err = socket.dns.toip(config.host)
- if(ip == nil) then
- log.printf(log.ERROR, inst.name .. ": can't resolve %s: %s", config.host, err)
- return nil
- end
-
- local server_sock_raw, err = socket.tcp()
- if(server_sock_raw == nil) then
- log.printf(log.ERROR, inst.name .. ": can't create tcp socket")
+ local lst, err = tcp.server(config.addr, config.port, config.resolv_type)
+ if(not lst) then
return nil
- end
+ end
- server_sock_raw:setoption('reuseaddr', true);
-
- local ret, err = server_sock_raw:bind(ip, config.port)
- if(ret == nil) then
- log.printf(log.ERROR, inst.name .. ": bind(%s,%s) failed: %s", ip, config.port, err)
- return nil
- end
-
- local ret, err = server_sock_raw:listen()
- if(ret == nil) then
- log.printf(log.ERROR, inst.name .. ": listen() failed: %s", err)
- return nil
- end
-
- server_sock_raw:settimeout(0)
+ inst.listeners = lst
+ for _, l in ipairs(inst.listeners) do
+ log.printf(log.NOTICE, "%s: listening on %s (this is a huge security risk)", inst.name, tcp.endtostring(l.local_end))
- local server_sock = {}
- server_sock.fd = server_sock_raw:getfd()
- server_sock.sock = server_sock_raw
- function server_sock:read()
- local client_sock_raw, err = self.sock:accept()
- if(client_sock_raw == nil) then
- log.printf(log.ERROR, inst.name .. ": accept() failed: %s", err)
- end
- local ip, port = client_sock_raw:getpeername();
- log.printf(log.INFO, inst.name .. ": connection from %s:%s accepted", ip, port)
- client_sock_raw:settimeout(0);
- client_sock_raw:setoption('tcp-nodelay', true);
-
- local client_sock = {}
- client_sock.fd = client_sock_raw:getfd()
- client_sock.sock = client_sock_raw
- client_sock.client_instance = nil
- client_sock.in_buffer = ""
- client_sock.out_buffer = ""
- function client_sock:read()
- local ret = defines.OK
- local data, err, partial = self.sock:receive('*l')
- if(data == nil) then
- if(err == 'closed') then
- log.printf(log.INFO, inst.name .. ": connection closed by peer")
+ function l:read()
+ local new_client, addr = tcp.accept(self.fd)
+ if(not new_client) then
+ log.printf(ERROR, "inst.name: %s", addr)
+ return defines.KILL_MODULE
+ end
+
+ local client_handle = {}
+ client_handle.fd = new_client
+ client_handle.client_instance = nil
+ client_handle.in_buffer = ""
+ client_handle.out_buffer = ""
+ function client_handle:read()
+ -- TODO: which size should we request??
+ local buffer, err = tcp.recv(self.fd, 100)
+ if(buffer == nil) then
+ log.printf(log.ERROR, inst.name .. ": connection error: %s", err)
+ return defines.KILL_CLIENT
+ end
+ if(#buffer == 0) then
+ log.printf(log.INFO, inst.name .. ": connection closed")
+ return defines.KILL_CLIENT
+ end
+ self.in_buffer = self.in_buffer .. buffer
+ return debug_shell:parse_cmd(self)
+ end
+ function client_handle:write()
+ local len, err = tcp.send(self.fd, self.out_buffer)
+ if(len == nil) then
+ log.printf(log.ERROR, inst.name .. ": connection error: %s", err)
ret = defines.KILL_CLIENT
- elseif(err == 'timeout') then
- self.in_buffer = self.in_buffer .. partial
else
- log.printf(log.INFO, inst.name .. ": connection error: %s", err)
- ret = defines.KILL_CLIENT
+ self.out_buffer = string.sub(self.out_buffer, len+1)
end
- else
- self.in_buffer = self.in_buffer .. data
- ret = debug_shell:exec_cmd(self)
- self.in_buffer = ""
+ return defines.OK
end
- return ret
- end
- function client_sock:write()
- local ret = defines.OK
- local len, err, partiallen = self.sock:send(self.out_buffer)
- if(len == nil) then
- if(err == 'closed') then
- log.printf(log.INFO, inst.name .. ": connection closed by peer")
- ret = defines.KILL_CLIENT
- elseif(err == 'timeout') then
- self.out_buffer = string.sub(self.out_buffer, partiallen+1)
+
+ local client = {}
+ client.module_instance = inst
+ client.addr = addr
+ client.name = inst.name .. "#" .. tcp.endtostring(addr)
+ function client:process_response() end
+ function client:process_timeout() end
+ function client:get_read_handles()
+ return { client_handle }
+ end
+ function client:get_write_handles()
+ if(client_handle.out_buffer ~= "") then
+ return { client_handle }
else
- log.printf(log.INFO, inst.name .. ": connection error: %s", err)
- ret = defines.KILL_CLIENT
+ return {}
end
- else
- self.out_buffer = string.sub(self.out_buffer, len+1)
end
- return ret
- end
-
- local client = {}
- client.module_instance = inst
- client.name = inst.name .. "#" .. ip .. ":" .. port
- client.sock = client_sock
- function client:process_response(response)
- self.sock.out_buffer = self.sock.out_buffer .. response
- end
- function client:process_timeout() end
- function client:get_read_handles()
- return { self.sock }
- end
- function client:get_write_handles()
- if(self.sock.out_buffer ~= "") then
- return { self.sock }
- else
- return {}
+ function client:cleanup()
+ rawio.close(client_handle.fd)
end
+ client_handle.client_instance = client
+ client_list:register(client)
+ return defines.OK
end
- function client:cleanup()
- self.sock.sock:close()
- end
- client_sock.client_instance = client
-
- client_list:register(client)
- return defines.OK
+ function l:write() return defines.OK end
end
- function server_sock:write() return defines.OK end
-
- log.printf(log.WARNING, inst.name .. ": listening on %s:%s (this is a huge security risk)", ip, config.port);
function inst:cleanup()
client_list:unregister_by_module(self)
- server_sock.sock:close()
+ for _, l in ipairs(self.listeners) do
+ rawio.close(l.fd);
+ end
end
- function inst:get_read_handles()
- return { server_sock }
+ function inst:get_read_handles()
+ return self.listeners
end
function inst:get_write_handles()
return {}
end
setmetatable(inst, {})
getmetatable(inst).__gc = function() inst:cleanup() end
+
return inst
end
-function debug_shell:exec_cmd(socket)
- local client_name = socket.client_instance.name
- log.printf(log.DEBUG, client_name .. ": received string: '%s'", socket.in_buffer)
+function debug_shell:parse_cmd(handle)
+ local ret = defines.OK
+ local init = 1
+ repeat
+ local had_match = false
+ local cmd, delim = string.match(handle.in_buffer, "([^\n\r]*)(\r?\n)", init)
+ if cmd and delim then
+ ret = self:exec_cmd(handle, cmd)
+ had_match = true
+ init = init + string.len(cmd) + string.len(delim)
+ break
+ end
+ until (not had_match or ret ~= defines.OK)
+
+ handle.in_buffer = string.sub(handle.in_buffer, init + 1)
+
+ return ret
+end
+
+function debug_shell:exec_cmd(handle, buffer)
+ local client_name = handle.client_instance.name
+ log.printf(log.DEBUG, client_name .. ": received string: '%s'", buffer)
local ret = defines.OK
- local luacode = string.match(socket.in_buffer, "^!(.*)$");
+ local luacode = string.match(buffer, "^!(.*)$");
if(luacode and luacode ~= "") then
local chunk = loadstring(luacode)
if(chunk) then
@@ -197,37 +173,37 @@ function debug_shell:exec_cmd(socket)
if(results[1]) then
for i,result in ipairs(results) do
if(i > 1) then
- socket.out_buffer = socket.out_buffer .. string.format("#%d: %s\n", i-1, tostring(result))
+ handle.out_buffer = handle.out_buffer .. string.format("#%d: %s\n", i-1, tostring(result))
end
end
else
- socket.out_buffer = socket.out_buffer .. string.format("lua call failed: %s\n", tostring(results[2]))
+ handle.out_buffer = handle.out_buffer .. string.format("lua call failed: %s\n", tostring(results[2]))
end
else
- socket.out_buffer = socket.out_buffer .. "syntax error\n"
+ handle.out_buffer = handle.out_buffer .. "syntax error\n"
end
else
- local cmd, sep, param = string.match(socket.in_buffer, "^(%w+)(.?)(.*)$");
+ local cmd, sep, param = string.match(buffer, "^(%w+)(.?)(.*)$");
if(cmd == 'quit') then
- if(sep and sep ~= "") then socket.out_buffer = socket.out_buffer .. "unknown command\n" end
+ if(sep and sep ~= "") then handle.out_buffer = handle.out_buffer .. "unknown command\n" end
log.printf(log.INFO, client_name .. ": quitting debug session")
ret = defines.KILL_CLIENT
elseif(cmd == 'disable') then
- if(sep and sep ~= "") then socket.out_buffer = socket.out_buffer .. "unknown command\n" end
+ if(sep and sep ~= "") then handle.out_buffer = handle.out_buffer .. "unknown command\n" end
log.printf(log.NOTICE, client_name .. ": disabling this debug shell instance and close all connections")
ret = defines.KILL_MODULE
elseif(cmd == 'disableall') then
- if(sep and sep ~= "") then socket.out_buffer = socket.out_buffer .. "unknown command\n" end
+ if(sep and sep ~= "") then handle.out_buffer = handle.out_buffer .. "unknown command\n" end
log.printf(log.NOTICE, client_name .. ": disabling all debug shell instances and close all connections")
ret = defines.KILL_MODULE_CLASS
elseif(cmd == 'terminate') then
- if(sep and sep ~= "") then socket.out_buffer = socket.out_buffer .. "unknown command\n" end
+ if(sep and sep ~= "") then handle.out_buffer = handle.out_buffer .. "unknown command\n" end
log.printf(log.NOTICE, client_name .. ": terminate command received")
ret = defines.KILL_DAEMON
elseif(cmd == 'help') then
- if(sep and sep ~= "") then socket.out_buffer = socket.out_buffer .. "unknown command\n" end
- socket.out_buffer = socket.out_buffer .. "!<lua code> execute lua code\n" ..
+ if(sep and sep ~= "") then handle.out_buffer = handle.out_buffer .. "unknown command\n" end
+ handle.out_buffer = handle.out_buffer .. "!<lua code> execute lua code\n" ..
"cmd <cmd> add the command to the command queue\n" ..
"quit quit this debug session\n" ..
"ping[ <data>] echo request (response will be 'pong[ <data>]')\n" ..
@@ -235,16 +211,16 @@ function debug_shell:exec_cmd(socket)
"disableall close all debug shell instances and close all connections\n" ..
"terminate terminate the daemon\n"
elseif(cmd == 'ping') then
- if(sep == ' ') then socket.out_buffer = socket.out_buffer .. "pong " .. (param or "") .. "\n"
- else socket.out_buffer = socket.out_buffer .. "pong\n" end
+ if(sep == ' ') then handle.out_buffer = handle.out_buffer .. "pong " .. (param or "") .. "\n"
+ else handle.out_buffer = handle.out_buffer .. "pong\n" end
elseif(cmd == 'cmd') then
- if(not param or param == '') then socket.out_buffer = socket.out_buffer .. "Error: please specify a command\n"
+ if(not param or param == '') then handle.out_buffer = handle.out_buffer .. "Error: please specify a command\n"
else
- socket.out_buffer = socket.out_buffer .. "enqueing command: " .. param .. "\n"
+ handle.out_buffer = handle.out_buffer .. "enqueing command: " .. param .. "\n"
command_queue:enqueue(param, "ok\n", 2500)
end
else
- socket.out_buffer = socket.out_buffer .. "unknown command\n"
+ handle.out_buffer = handle.out_buffer .. "unknown command\n"
end
end