Software /
code /
prosody
File
plugins/mod_console.lua @ 1103:b78b1524eb79
Merge with 0.4
author | Matthew Wild <mwild1@gmail.com> |
---|---|
date | Sun, 03 May 2009 17:24:57 +0100 |
parent | 1085:1ac11fb753ca |
child | 1240:397b6e9c1568 |
line wrap: on
line source
-- 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("'<eof>'", "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.s2s = {}; function def_env.s2s:show() 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 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 <stream> 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 for session in pairs(incoming_s2s) do if session.to_host == host 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 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