Software / code / prosody
Comparison
plugins/mod_admin_telnet.lua @ 4684:dc70c4ffb66d
Merge timber->trunk - thanks everyone!
| author | Matthew Wild <mwild1@gmail.com> |
|---|---|
| date | Tue, 24 Apr 2012 21:59:20 +0100 |
| parent | 4517:2e274e088ddc |
| parent | 4674:f44726a910a0 |
| child | 4779:9f2639b3d9b1 |
comparison
equal
deleted
inserted
replaced
| 4529:12621337471f | 4684:dc70c4ffb66d |
|---|---|
| 4 -- | 4 -- |
| 5 -- This project is MIT/X11 licensed. Please see the | 5 -- This project is MIT/X11 licensed. Please see the |
| 6 -- COPYING file in the source package for more information. | 6 -- COPYING file in the source package for more information. |
| 7 -- | 7 -- |
| 8 | 8 |
| 9 module.host = "*"; | 9 module:set_global(); |
| 10 | 10 |
| 11 local _G = _G; | 11 local _G = _G; |
| 12 | 12 |
| 13 local prosody = _G.prosody; | 13 local prosody = _G.prosody; |
| 14 local hosts = prosody.hosts; | 14 local hosts = prosody.hosts; |
| 15 local connlisteners_register = require "net.connlisteners".register; | 15 |
| 16 | 16 local console_listener = { default_port = 5582; default_mode = "*l"; interface = "127.0.0.1" }; |
| 17 local console_listener = { default_port = 5582; default_mode = "*l"; default_interface = "127.0.0.1" }; | 17 |
| 18 | 18 local iterators = require "util.iterators"; |
| 19 require "util.iterators"; | 19 local keys, values = iterators.keys, iterators.values; |
| 20 local jid_bare = require "util.jid".bare; | 20 local jid_bare = require "util.jid".bare; |
| 21 local set, array = require "util.set", require "util.array"; | 21 local set, array = require "util.set", require "util.array"; |
| 22 local cert_verify_identity = require "util.x509".verify_identity; | 22 local cert_verify_identity = require "util.x509".verify_identity; |
| 23 | 23 |
| 24 local commands = {}; | 24 local commands = module:shared("commands") |
| 25 local def_env = {}; | 25 local def_env = module:shared("env"); |
| 26 local default_env_mt = { __index = def_env }; | 26 local default_env_mt = { __index = def_env }; |
| 27 | |
| 28 prosody.console = { commands = commands, env = def_env }; | |
| 29 | 27 |
| 30 local function redirect_output(_G, session) | 28 local function redirect_output(_G, session) |
| 31 local env = setmetatable({ print = session.print }, { __index = function (t, k) return rawget(_G, k); end }); | 29 local env = setmetatable({ print = session.print }, { __index = function (t, k) return rawget(_G, k); end }); |
| 32 env.dofile = function(name) | 30 env.dofile = function(name) |
| 33 local f, err = loadfile(name); | 31 local f, err = loadfile(name); |
| 146 if session then | 144 if session then |
| 147 session.disconnect(); | 145 session.disconnect(); |
| 148 sessions[conn] = nil; | 146 sessions[conn] = nil; |
| 149 end | 147 end |
| 150 end | 148 end |
| 151 | |
| 152 connlisteners_register('console', console_listener); | |
| 153 | 149 |
| 154 -- Console commands -- | 150 -- Console commands -- |
| 155 -- These are simple commands, not valid standalone in Lua | 151 -- These are simple commands, not valid standalone in Lua |
| 156 | 152 |
| 157 function commands.bye(session) | 153 function commands.bye(session) |
| 279 end | 275 end |
| 280 elseif type(hosts) == "string" then | 276 elseif type(hosts) == "string" then |
| 281 return set.new { hosts }; | 277 return set.new { hosts }; |
| 282 elseif hosts == nil then | 278 elseif hosts == nil then |
| 283 local mm = require "modulemanager"; | 279 local mm = require "modulemanager"; |
| 284 return set.new(array.collect(keys(prosody.hosts))) | 280 local hosts_set = set.new(array.collect(keys(prosody.hosts))) |
| 285 / function (host) return prosody.hosts[host].type == "local" or module and mm.is_loaded(host, module); end; | 281 / function (host) return prosody.hosts[host].type == "local" or module and mm.is_loaded(host, module); end; |
| 282 if module and mm.get_module("*", module) then | |
| 283 hosts_set:add("*"); | |
| 284 end | |
| 285 return hosts_set; | |
| 286 end | 286 end |
| 287 end | 287 end |
| 288 | 288 |
| 289 function def_env.module:load(name, hosts, config) | 289 function def_env.module:load(name, hosts, config) |
| 290 local mm = require "modulemanager"; | 290 local mm = require "modulemanager"; |
| 291 | 291 |
| 292 hosts = get_hosts_set(hosts); | 292 hosts = get_hosts_set(hosts); |
| 293 | 293 |
| 294 -- Load the module for each host | 294 -- Load the module for each host |
| 295 local ok, err, count = true, nil, 0; | 295 local ok, err, count, mod = true, nil, 0, nil; |
| 296 for host in hosts do | 296 for host in hosts do |
| 297 if (not mm.is_loaded(host, name)) then | 297 if (not mm.is_loaded(host, name)) then |
| 298 ok, err = mm.load(host, name, config); | 298 mod, err = mm.load(host, name, config); |
| 299 if not ok then | 299 if not mod then |
| 300 ok = false; | 300 ok = false; |
| 301 if err == "global-module-already-loaded" then | |
| 302 if count > 0 then | |
| 303 ok, err, count = true, nil, 1; | |
| 304 end | |
| 305 break; | |
| 306 end | |
| 301 self.session.print(err or "Unknown error loading module"); | 307 self.session.print(err or "Unknown error loading module"); |
| 302 else | 308 else |
| 303 count = count + 1; | 309 count = count + 1; |
| 304 self.session.print("Loaded for "..host); | 310 self.session.print("Loaded for "..mod.module.host); |
| 305 end | 311 end |
| 306 end | 312 end |
| 307 end | 313 end |
| 308 | 314 |
| 309 return ok, (ok and "Module loaded onto "..count.." host"..(count ~= 1 and "s" or "")) or ("Last error: "..tostring(err)); | 315 return ok, (ok and "Module loaded onto "..count.." host"..(count ~= 1 and "s" or "")) or ("Last error: "..tostring(err)); |
| 332 end | 338 end |
| 333 | 339 |
| 334 function def_env.module:reload(name, hosts) | 340 function def_env.module:reload(name, hosts) |
| 335 local mm = require "modulemanager"; | 341 local mm = require "modulemanager"; |
| 336 | 342 |
| 337 hosts = get_hosts_set(hosts, name); | 343 hosts = array.collect(get_hosts_set(hosts, name)):sort(function (a, b) |
| 338 | 344 if a == "*" then return true |
| 345 elseif b == "*" then return false | |
| 346 else return a < b; end | |
| 347 end); | |
| 348 | |
| 339 -- Reload the module for each host | 349 -- Reload the module for each host |
| 340 local ok, err, count = true, nil, 0; | 350 local ok, err, count = true, nil, 0; |
| 341 for host in hosts do | 351 for _, host in ipairs(hosts) do |
| 342 if mm.is_loaded(host, name) then | 352 if mm.is_loaded(host, name) then |
| 343 ok, err = mm.reload(host, name); | 353 ok, err = mm.reload(host, name); |
| 344 if not ok then | 354 if not ok then |
| 345 ok = false; | 355 ok = false; |
| 346 self.session.print(err or "Unknown error reloading module"); | 356 self.session.print(err or "Unknown error reloading module"); |
| 357 end | 367 end |
| 358 | 368 |
| 359 function def_env.module:list(hosts) | 369 function def_env.module:list(hosts) |
| 360 if hosts == nil then | 370 if hosts == nil then |
| 361 hosts = array.collect(keys(prosody.hosts)); | 371 hosts = array.collect(keys(prosody.hosts)); |
| 372 table.insert(hosts, 1, "*"); | |
| 362 end | 373 end |
| 363 if type(hosts) == "string" then | 374 if type(hosts) == "string" then |
| 364 hosts = { hosts }; | 375 hosts = { hosts }; |
| 365 end | 376 end |
| 366 if type(hosts) ~= "table" then | 377 if type(hosts) ~= "table" then |
| 367 return false, "Please supply a host or a list of hosts you would like to see"; | 378 return false, "Please supply a host or a list of hosts you would like to see"; |
| 368 end | 379 end |
| 369 | 380 |
| 370 local print = self.session.print; | 381 local print = self.session.print; |
| 371 for _, host in ipairs(hosts) do | 382 for _, host in ipairs(hosts) do |
| 372 print(host..":"); | 383 print((host == "*" and "Global" or host)..":"); |
| 373 local modules = array.collect(keys(prosody.hosts[host] and prosody.hosts[host].modules or {})):sort(); | 384 local modules = array.collect(keys(modulemanager.get_modules(host) or {})):sort(); |
| 374 if #modules == 0 then | 385 if #modules == 0 then |
| 375 if prosody.hosts[host] then | 386 if prosody.hosts[host] then |
| 376 print(" No modules loaded"); | 387 print(" No modules loaded"); |
| 377 else | 388 else |
| 378 print(" Host not found"); | 389 print(" Host not found"); |
| 764 print(host); | 775 print(host); |
| 765 end | 776 end |
| 766 return true, i.." hosts"; | 777 return true, i.." hosts"; |
| 767 end | 778 end |
| 768 | 779 |
| 780 def_env.port = {}; | |
| 781 | |
| 782 function def_env.port:list() | |
| 783 local print = self.session.print; | |
| 784 local services = portmanager.get_active_services().data; | |
| 785 local ordered_services, n_ports = {}, 0; | |
| 786 for service, interfaces in pairs(services) do | |
| 787 table.insert(ordered_services, service); | |
| 788 end | |
| 789 table.sort(ordered_services); | |
| 790 for _, service in ipairs(ordered_services) do | |
| 791 local ports_list = {}; | |
| 792 for interface, ports in pairs(services[service]) do | |
| 793 for port in pairs(ports) do | |
| 794 table.insert(ports_list, "["..interface.."]:"..port); | |
| 795 end | |
| 796 end | |
| 797 n_ports = n_ports + #ports_list; | |
| 798 print(service..": "..table.concat(ports_list, ", ")); | |
| 799 end | |
| 800 return true, #ordered_services.." services listening on "..n_ports.." ports"; | |
| 801 end | |
| 802 | |
| 803 function def_env.port:close(close_port, close_interface) | |
| 804 close_port = assert(tonumber(close_port), "Invalid port number"); | |
| 805 local n_closed = 0; | |
| 806 local services = portmanager.get_active_services().data; | |
| 807 for service, interfaces in pairs(services) do | |
| 808 for interface, ports in pairs(interfaces) do | |
| 809 if not close_interface or close_interface == interface then | |
| 810 if ports[close_port] then | |
| 811 self.session.print("Closing ["..interface.."]:"..close_port.."..."); | |
| 812 local ok, err = portmanager.close(interface, close_port) | |
| 813 if not ok then | |
| 814 self.session.print("Failed to close "..interface.." "..port..": "..err); | |
| 815 else | |
| 816 n_closed = n_closed + 1; | |
| 817 end | |
| 818 end | |
| 819 end | |
| 820 end | |
| 821 end | |
| 822 return true, "Closed "..n_closed.." ports"; | |
| 823 end | |
| 824 | |
| 769 ------------- | 825 ------------- |
| 770 | 826 |
| 771 function printbanner(session) | 827 function printbanner(session) |
| 772 local option = config.get("*", "core", "console_banner"); | 828 local option = config.get("*", "core", "console_banner"); |
| 773 if option == nil or option == "full" or option == "graphic" then | 829 if option == nil or option == "full" or option == "graphic" then |
| 794 pcall(option, session); | 850 pcall(option, session); |
| 795 end | 851 end |
| 796 end | 852 end |
| 797 end | 853 end |
| 798 | 854 |
| 799 prosody.net_activate_ports("console", "console", {5582}, "tcp"); | 855 module:add_item("net-provider", { |
| 856 name = "console"; | |
| 857 listener = console_listener; | |
| 858 default_port = 5582; | |
| 859 private = true; | |
| 860 }); |