X-Git-Url: https://git.enpas.org/?a=blobdiff_plain;f=plugins%2Fmod_console.lua;h=a95eb5dcb19c4e07c881723afd5715bf56839d3a;hb=3f9a02bee5e142846bf7da49dd2c6a1be72c86d5;hp=b1dc263cdc69f1df4530f8ddab636a4b1492c3b1;hpb=b461326e77b6cc855618c17b3bb63eaf0f71895c;p=prosody.git diff --git a/plugins/mod_console.lua b/plugins/mod_console.lua index b1dc263c..a95eb5dc 100644 --- a/plugins/mod_console.lua +++ b/plugins/mod_console.lua @@ -1,191 +1,322 @@ - -local connlisteners_register = require "net.connlisteners".register; - -local console_listener = { default_port = 5582; default_mode = "*l"; }; - -local commands = {}; -local def_env = {}; -local default_env_mt = { __index = def_env }; - -console = {}; - -function console:new_session(conn) - local w = conn.write; - local session = { conn = conn; - send = function (t) w(tostring(t)); end; - print = function (t) w("| "..tostring(t).."\n"); end; - disconnect = function () conn.close(); end; - }; - session.env = setmetatable({}, default_env_mt); - - -- Load up environment with helper objects - for name, t in pairs(def_env) do - if type(t) == "table" then - session.env[name] = setmetatable({ session = session }, { __index = t }); - end - end - - return session; -end - -local sessions = {}; - -function console_listener.listener(conn, data) - local session = sessions[conn]; - - if not session then - -- Handle new connection - session = console:new_session(conn); - sessions[conn] = session; - printbanner(session); - end - if data then - -- Handle data - - if data:match("[!.]$") then - local command = data:lower(); - command = data:match("^%w+") or data:match("%p"); - if commands[command] then - commands[command](session, data); - return; - end - end - - session.env._ = data; - - local chunk, err = loadstring("return "..data); - if not chunk then - chunk, err = loadstring(data); - if not chunk then - err = err:gsub("^%[string .-%]:%d+: ", ""); - err = err:gsub("^:%d+: ", ""); - err = err:gsub("''", "the end of the line"); - session.print("Sorry, I couldn't understand that... "..err); - return; - end - end - - setfenv(chunk, session.env); - local ranok, taskok, message = pcall(chunk); - - if not ranok then - session.print("Fatal error while running command, it did not complete"); - session.print("Error: "..taskok); - return; - end - - if not message then - session.print("Result: "..tostring(taskok)); - return; - elseif (not taskok) and message then - session.print("Command completed with a problem"); - session.print("Message: "..tostring(message)); - return; - end - - session.print("OK: "..tostring(message)); - end -end - -function console_listener.disconnect(conn, err) - -end - -connlisteners_register('console', console_listener); - --- Console commands -- --- These are simple commands, not valid standalone in Lua - -function commands.bye(session) - session.print("See you! :)"); - session.disconnect(); -end - -commands["!"] = function (session, data) - if data:match("^!!") then - session.print("!> "..session.env._); - return console_listener.listener(session.conn, session.env._); - end - local old, new = data:match("^!(.-[^\\])!(.-)!$"); - if old and new then - local ok, res = pcall(string.gsub, session.env._, old, new); - if not ok then - session.print(res) - return; - end - session.print("!> "..res); - return console_listener.listener(session.conn, res); - end - session.print("Sorry, not sure what you want"); -end - --- Session environment -- --- Anything in def_env will be accessible within the session as a global variable - -def_env.server = {}; -function def_env.server:reload() - dofile "main.lua" - return true, "Server reloaded"; -end - -def_env.module = {}; -function def_env.module:load(name, host, config) - local mm = require "modulemanager"; - local ok, err = mm.load(host or self.env.host, name, config); - if not ok then - return false, err or "Unknown error loading module"; - end - return true, "Module loaded"; -end - -function def_env.module:unload(name, host) - local mm = require "modulemanager"; - local ok, err = mm.unload(host or self.env.host, name); - if not ok then - return false, err or "Unknown error unloading module"; - end - return true, "Module unloaded"; -end - -def_env.config = {}; -function def_env.config:load(filename, format) - local config_load = require "core.configmanager".load; - local ok, err = config_load(filename, format); - if not ok then - return false, err or "Unknown error loading config"; - end - return true, "Config loaded"; -end - -function def_env.config:get(host, section, key) - local config_get = require "core.configmanager".get - return true, tostring(config_get(host, section, key)); -end - -def_env.hosts = {}; -function def_env.hosts:list() - for host, host_session in pairs(hosts) do - self.session.print(host); - end - return true, "Done"; -end - -function def_env.hosts:add(name) -end - -------------- - -function printbanner(session) -session.print [[ - ____ \ / _ - | _ \ _ __ ___ ___ _-_ __| |_ _ - | |_) | '__/ _ \/ __|/ _ \ / _` | | | | - | __/| | | (_) \__ \ |_| | (_| | |_| | - |_| |_| \___/|___/\___/ \__,_|\__, | - A study in simplicity |___/ - -]] -session.print("Welcome to the Prosody administration console. For a list of commands, type: help"); -session.print("You may find more help on using this console in our online documentation at "); -session.print("http://prosody.im/doc/console\n"); -end +-- Prosody IM v0.4 +-- Copyright (C) 2008-2009 Matthew Wild +-- Copyright (C) 2008-2009 Waqas Hussain +-- +-- This project is MIT/X11 licensed. Please see the +-- COPYING file in the source package for more information. +-- + +module.host = "*"; + +local hosts = _G.hosts; +local connlisteners_register = require "net.connlisteners".register; + +local console_listener = { default_port = 5582; default_mode = "*l"; }; + +local commands = {}; +local def_env = {}; +local default_env_mt = { __index = def_env }; + +console = {}; + +function console:new_session(conn) + local w = function(s) conn.write(s:gsub("\n", "\r\n")); end; + local session = { conn = conn; + send = function (t) w(tostring(t)); end; + print = function (t) w("| "..tostring(t).."\n"); end; + disconnect = function () conn.close(); end; + }; + session.env = setmetatable({}, default_env_mt); + + -- Load up environment with helper objects + for name, t in pairs(def_env) do + if type(t) == "table" then + session.env[name] = setmetatable({ session = session }, { __index = t }); + end + end + + return session; +end + +local sessions = {}; + +function console_listener.listener(conn, data) + local session = sessions[conn]; + + if not session then + -- Handle new connection + session = console:new_session(conn); + sessions[conn] = session; + printbanner(session); + end + if data then + -- Handle data + (function(session, data) + if data:match("[!.]$") then + local command = data:lower(); + command = data:match("^%w+") or data:match("%p"); + if commands[command] then + commands[command](session, data); + return; + end + end + + session.env._ = data; + + local chunk, err = loadstring("return "..data); + if not chunk then + chunk, err = loadstring(data); + if not chunk then + err = err:gsub("^%[string .-%]:%d+: ", ""); + err = err:gsub("^:%d+: ", ""); + err = err:gsub("''", "the end of the line"); + session.print("Sorry, I couldn't understand that... "..err); + return; + end + end + + setfenv(chunk, session.env); + local ranok, taskok, message = pcall(chunk); + + if not ranok then + session.print("Fatal error while running command, it did not complete"); + session.print("Error: "..taskok); + return; + end + + if not message then + session.print("Result: "..tostring(taskok)); + return; + elseif (not taskok) and message then + session.print("Command completed with a problem"); + session.print("Message: "..tostring(message)); + return; + end + + session.print("OK: "..tostring(message)); + end)(session, data); + end + session.send(string.char(0)); +end + +function console_listener.disconnect(conn, err) + +end + +connlisteners_register('console', console_listener); + +-- Console commands -- +-- These are simple commands, not valid standalone in Lua + +function commands.bye(session) + session.print("See you! :)"); + session.disconnect(); +end + +commands["!"] = function (session, data) + if data:match("^!!") then + session.print("!> "..session.env._); + return console_listener.listener(session.conn, session.env._); + end + local old, new = data:match("^!(.-[^\\])!(.-)!$"); + if old and new then + local ok, res = pcall(string.gsub, session.env._, old, new); + if not ok then + session.print(res) + return; + end + session.print("!> "..res); + return console_listener.listener(session.conn, res); + end + session.print("Sorry, not sure what you want"); +end + +-- Session environment -- +-- Anything in def_env will be accessible within the session as a global variable + +def_env.server = {}; +function def_env.server:reload() + dofile "prosody" + return true, "Server reloaded"; +end + +def_env.module = {}; +function def_env.module:load(name, host, config) + local mm = require "modulemanager"; + local ok, err = mm.load(host or self.env.host, name, config); + if not ok then + return false, err or "Unknown error loading module"; + end + return true, "Module loaded"; +end + +function def_env.module:unload(name, host) + local mm = require "modulemanager"; + local ok, err = mm.unload(host or self.env.host, name); + if not ok then + return false, err or "Unknown error unloading module"; + end + return true, "Module unloaded"; +end + +function def_env.module:reload(name, host) + local mm = require "modulemanager"; + local ok, err = mm.reload(host or self.env.host, name); + if not ok then + return false, err or "Unknown error reloading module"; + end + return true, "Module reloaded"; +end + +def_env.config = {}; +function def_env.config:load(filename, format) + local config_load = require "core.configmanager".load; + local ok, err = config_load(filename, format); + if not ok then + return false, err or "Unknown error loading config"; + end + return true, "Config loaded"; +end + +function def_env.config:get(host, section, key) + local config_get = require "core.configmanager".get + return true, tostring(config_get(host, section, key)); +end + +def_env.hosts = {}; +function def_env.hosts:list() + for host, host_session in pairs(hosts) do + self.session.print(host); + end + return true, "Done"; +end + +function def_env.hosts:add(name) +end + +def_env.c2s = {}; + +local function show_c2s(callback) + for hostname, host in pairs(hosts) do + for username, user in pairs(host.sessions or {}) do + for resource, session in pairs(user.sessions or {}) do + local jid = username.."@"..hostname.."/"..resource; + callback(jid, session); + end + end + end +end + +function def_env.c2s:show(match_jid) + local print, count = self.session.print, 0; + show_c2s(function (jid) + if (not match_jid) or jid:match(match_jid) then + count = count + 1; + print(jid); + end + end); + return true, "Total: "..count.." clients"; +end + +function def_env.c2s:show_insecure(match_jid) + local print, count = self.session.print, 0; + show_c2s(function (jid, session) + if ((not match_jid) or jid:match(match_jid)) and not session.secure then + count = count + 1; + print(jid); + end + end); + return true, "Total: "..count.." insecure client connections"; +end + +function def_env.c2s:show_secure(match_jid) + local print, count = self.session.print, 0; + show_c2s(function (jid, session) + if ((not match_jid) or jid:match(match_jid)) and session.secure then + count = count + 1; + print(jid); + end + end); + return true, "Total: "..count.." secure client connections"; +end + + +def_env.s2s = {}; +function def_env.s2s:show(match_jid) + local _print = self.session.print; + local print = self.session.print; + for host, host_session in pairs(hosts) do + print = function (...) _print(host); _print(...); print = _print; end + for remotehost, session in pairs(host_session.s2sout) do + if (not match_jid) or remotehost:match(match_jid) or host:match(match_jid) then + print(" "..host.." -> "..remotehost); + if session.sendq then + print(" There are "..#session.sendq.." queued outgoing stanzas for this connection"); + end + if session.type == "s2sout_unauthed" then + if session.connecting then + print(" Connection not yet established"); + if not session.srv_hosts then + if not session.conn then + print(" We do not yet have a DNS answer for this host's SRV records"); + else + print(" This host has no SRV records, using A record instead"); + end + elseif session.srv_choice then + print(" We are on SRV record "..session.srv_choice.." of "..#session.srv_hosts); + local srv_choice = session.srv_hosts[session.srv_choice]; + print(" Using "..(srv_choice.target or ".")..":"..(srv_choice.port or 5269)); + end + elseif session.notopen then + print(" The has not yet been opened"); + elseif not session.dialback_key then + print(" Dialback has not been initiated yet"); + elseif session.dialback_key then + print(" Dialback has been requested, but no result received"); + end + end + end + end + + for session in pairs(incoming_s2s) do + if session.to_host == host and ((not match_jid) or host:match(match_jid) + or (session.from_host and session.from_host:match(match_jid))) then + print(" "..host.." <- "..(session.from_host or "(unknown)")); + if session.type == "s2sin_unauthed" then + print(" Connection not yet authenticated"); + end + for name in pairs(session.hosts) do + if name ~= session.from_host then + print(" also hosts "..tostring(name)); + end + end + end + end + + print = _print; + end + + for session in pairs(incoming_s2s) do + if not session.to_host and ((not match_jid) or session.from_host and session.from_host:match(match_jid)) then + print("Other incoming s2s connections"); + print(" (unknown) <- "..(session.from_host or "(unknown)")); + end + end +end + +------------- + +function printbanner(session) +session.print [[ + ____ \ / _ + | _ \ _ __ ___ ___ _-_ __| |_ _ + | |_) | '__/ _ \/ __|/ _ \ / _` | | | | + | __/| | | (_) \__ \ |_| | (_| | |_| | + |_| |_| \___/|___/\___/ \__,_|\__, | + A study in simplicity |___/ + +]] +session.print("Welcome to the Prosody administration console. For a list of commands, type: help"); +session.print("You may find more help on using this console in our online documentation at "); +session.print("http://prosody.im/doc/console\n"); +end