--- /dev/null
+\r
+local connlisteners_register = require "net.connlisteners".register;\r
+\r
+local console_listener = { default_port = 5582; default_mode = "*l"; };\r
+\r
+local commands = {};\r
+local default_env = {};\r
+local default_env_mt = { __index = default_env };\r
+\r
+console = {};\r
+\r
+function console:new_session(conn)\r
+ local w = conn.write;\r
+ return { conn = conn;\r
+ send = function (t) w(tostring(t)); end;\r
+ print = function (t) w("| "..tostring(t).."\n"); end;\r
+ disconnect = function () conn.close(); end;\r
+ env = setmetatable({}, default_env_mt);\r
+ };\r
+end\r
+\r
+local sessions = {};\r
+\r
+function console_listener.listener(conn, data)\r
+ local session = sessions[conn];\r
+ \r
+ if not session then\r
+ -- Handle new connection\r
+ session = console:new_session(conn);\r
+ sessions[conn] = session;\r
+ session.print("Welcome to the lxmppd admin console!");\r
+ end\r
+ if data then\r
+ -- Handle data\r
+ \r
+ if data:match("[!.]$") then\r
+ local command = data:lower();\r
+ command = data:match("^%w+") or data:match("%p");\r
+ if commands[command] then\r
+ commands[command](session, data);\r
+ return;\r
+ end\r
+ end\r
+ \r
+ session.env._ = data;\r
+ \r
+ local chunk, err = loadstring("return "..data);\r
+ if not chunk then\r
+ chunk, err = loadstring(data);\r
+ if not chunk then\r
+ err = err:gsub("^%[string .-%]:%d+: ", "");\r
+ err = err:gsub("^:%d+: ", "");\r
+ err = err:gsub("'<eof>'", "the end of the line");\r
+ session.print("Sorry, I couldn't understand that... "..err);\r
+ return;\r
+ end\r
+ end\r
+ \r
+ setfenv(chunk, session.env);\r
+ local ranok, taskok, message = pcall(chunk);\r
+ \r
+ if not ranok then\r
+ session.print("Fatal error while running command, it did not complete");\r
+ session.print("Error: "..taskok);\r
+ return;\r
+ end\r
+ \r
+ if not message then\r
+ session.print("Result: "..tostring(taskok));\r
+ return;\r
+ elseif (not taskok) and message then\r
+ session.print("Command completed with a problem");\r
+ session.print("Message: "..tostring(message));\r
+ return;\r
+ end\r
+ \r
+ session.print("OK: "..tostring(message));\r
+ end\r
+end\r
+\r
+function console_listener.disconnect(conn, err)\r
+ \r
+end\r
+\r
+connlisteners_register('console', console_listener);\r
+\r
+-- Console commands --\r
+-- These are simple commands, not valid standalone in Lua\r
+\r
+function commands.bye(session)\r
+ session.print("See you! :)");\r
+ session.disconnect();\r
+end\r
+\r
+commands["!"] = function (session, data)\r
+ if data:match("^!!") then\r
+ session.print("!> "..session.env._);\r
+ return console_listener.listener(session.conn, session.env._);\r
+ end\r
+ local old, new = data:match("^!(.-[^\\])!(.-)!$");\r
+ if old and new then\r
+ local ok, res = pcall(string.gsub, session.env._, old, new);\r
+ if not ok then\r
+ session.print(res)\r
+ return;\r
+ end\r
+ session.print("!> "..res);\r
+ return console_listener.listener(session.conn, res);\r
+ end\r
+ session.print("Sorry, not sure what you want");\r
+end\r
+\r
+-- Session environment --\r
+-- Anything in default_env will be accessible within the session as a global variable\r
+\r
+default_env.server = {};\r
+function default_env.server.reload()\r
+ dofile "main.lua"\r
+ return true, "Server reloaded";\r
+end\r
+\r
+default_env.module = {};\r
+function default_env.module.load(name)\r
+ local mm = require "modulemanager";\r
+ local ok, err = mm.load(name);\r
+ if not ok then\r
+ return false, err or "Unknown error loading module";\r
+ end\r
+ return true, "Module loaded";\r
+end\r
+\r
+default_env.config = {};\r
+function default_env.config.load(filename, format)\r
+ local cfgm_load = require "core.configmanager".load;\r
+ local ok, err = cfgm_load(filename, format);\r
+ if not ok then\r
+ return false, err or "Unknown error loading config";\r
+ end\r
+ return true, "Config loaded";\r
+end\r