382
|
1
|
|
2 local connlisteners_register = require "net.connlisteners".register;
|
|
3
|
|
4 local console_listener = { default_port = 5582; default_mode = "*l"; };
|
|
5
|
|
6 local commands = {};
|
411
|
7 local def_env = {};
|
|
8 local default_env_mt = { __index = def_env };
|
382
|
9
|
|
10 console = {};
|
|
11
|
|
12 function console:new_session(conn)
|
|
13 local w = conn.write;
|
411
|
14 local session = { conn = conn;
|
382
|
15 send = function (t) w(tostring(t)); end;
|
|
16 print = function (t) w("| "..tostring(t).."\n"); end;
|
|
17 disconnect = function () conn.close(); end;
|
|
18 };
|
411
|
19 session.env = setmetatable({}, default_env_mt);
|
|
20
|
|
21 -- Load up environment with helper objects
|
|
22 for name, t in pairs(def_env) do
|
|
23 if type(t) == "table" then
|
|
24 session.env[name] = setmetatable({ session = session }, { __index = t });
|
|
25 end
|
|
26 end
|
|
27
|
|
28 return session;
|
382
|
29 end
|
|
30
|
|
31 local sessions = {};
|
|
32
|
|
33 function console_listener.listener(conn, data)
|
|
34 local session = sessions[conn];
|
|
35
|
|
36 if not session then
|
|
37 -- Handle new connection
|
|
38 session = console:new_session(conn);
|
|
39 sessions[conn] = session;
|
440
|
40 printbanner(session);
|
382
|
41 end
|
|
42 if data then
|
|
43 -- Handle data
|
|
44
|
|
45 if data:match("[!.]$") then
|
|
46 local command = data:lower();
|
|
47 command = data:match("^%w+") or data:match("%p");
|
|
48 if commands[command] then
|
|
49 commands[command](session, data);
|
|
50 return;
|
|
51 end
|
|
52 end
|
|
53
|
|
54 session.env._ = data;
|
|
55
|
|
56 local chunk, err = loadstring("return "..data);
|
|
57 if not chunk then
|
|
58 chunk, err = loadstring(data);
|
|
59 if not chunk then
|
|
60 err = err:gsub("^%[string .-%]:%d+: ", "");
|
|
61 err = err:gsub("^:%d+: ", "");
|
|
62 err = err:gsub("'<eof>'", "the end of the line");
|
|
63 session.print("Sorry, I couldn't understand that... "..err);
|
|
64 return;
|
|
65 end
|
|
66 end
|
|
67
|
|
68 setfenv(chunk, session.env);
|
|
69 local ranok, taskok, message = pcall(chunk);
|
|
70
|
|
71 if not ranok then
|
|
72 session.print("Fatal error while running command, it did not complete");
|
|
73 session.print("Error: "..taskok);
|
|
74 return;
|
|
75 end
|
|
76
|
|
77 if not message then
|
|
78 session.print("Result: "..tostring(taskok));
|
|
79 return;
|
|
80 elseif (not taskok) and message then
|
|
81 session.print("Command completed with a problem");
|
|
82 session.print("Message: "..tostring(message));
|
|
83 return;
|
|
84 end
|
|
85
|
|
86 session.print("OK: "..tostring(message));
|
|
87 end
|
|
88 end
|
|
89
|
|
90 function console_listener.disconnect(conn, err)
|
|
91
|
|
92 end
|
|
93
|
|
94 connlisteners_register('console', console_listener);
|
|
95
|
|
96 -- Console commands --
|
|
97 -- These are simple commands, not valid standalone in Lua
|
|
98
|
|
99 function commands.bye(session)
|
|
100 session.print("See you! :)");
|
|
101 session.disconnect();
|
|
102 end
|
|
103
|
|
104 commands["!"] = function (session, data)
|
|
105 if data:match("^!!") then
|
|
106 session.print("!> "..session.env._);
|
|
107 return console_listener.listener(session.conn, session.env._);
|
|
108 end
|
|
109 local old, new = data:match("^!(.-[^\\])!(.-)!$");
|
|
110 if old and new then
|
|
111 local ok, res = pcall(string.gsub, session.env._, old, new);
|
|
112 if not ok then
|
|
113 session.print(res)
|
|
114 return;
|
|
115 end
|
|
116 session.print("!> "..res);
|
|
117 return console_listener.listener(session.conn, res);
|
|
118 end
|
|
119 session.print("Sorry, not sure what you want");
|
|
120 end
|
|
121
|
|
122 -- Session environment --
|
411
|
123 -- Anything in def_env will be accessible within the session as a global variable
|
382
|
124
|
411
|
125 def_env.server = {};
|
|
126 function def_env.server:reload()
|
382
|
127 dofile "main.lua"
|
|
128 return true, "Server reloaded";
|
|
129 end
|
|
130
|
411
|
131 def_env.module = {};
|
440
|
132 function def_env.module:load(name, host)
|
382
|
133 local mm = require "modulemanager";
|
440
|
134 local ok, err = mm.load(host or self.env.host, name);
|
382
|
135 if not ok then
|
|
136 return false, err or "Unknown error loading module";
|
|
137 end
|
|
138 return true, "Module loaded";
|
|
139 end
|
|
140
|
411
|
141 def_env.config = {};
|
|
142 function def_env.config:load(filename, format)
|
|
143 local config_load = require "core.configmanager".load;
|
|
144 local ok, err = config_load(filename, format);
|
382
|
145 if not ok then
|
|
146 return false, err or "Unknown error loading config";
|
|
147 end
|
|
148 return true, "Config loaded";
|
|
149 end
|
411
|
150
|
|
151 function def_env.config:get(host, section, key)
|
|
152 local config_get = require "core.configmanager".get
|
|
153 return true, tostring(config_get(host, section, key));
|
|
154 end
|
|
155
|
|
156 def_env.hosts = {};
|
|
157 function def_env.hosts:list()
|
|
158 for host, host_session in pairs(hosts) do
|
|
159 self.session.print(host);
|
|
160 end
|
|
161 return true, "Done";
|
|
162 end
|
|
163
|
|
164 function def_env.hosts:add(name)
|
|
165 end
|
440
|
166
|
|
167 -------------
|
|
168
|
|
169 function printbanner(session)
|
|
170 session.print [[
|
|
171 ____ \ / _
|
|
172 | _ \ _ __ ___ ___ _-_ __| |_ _
|
|
173 | |_) | '__/ _ \/ __|/ _ \ / _` | | | |
|
|
174 | __/| | | (_) \__ \ |_| | (_| | |_| |
|
|
175 |_| |_| \___/|___/\___/ \__,_|\__, |
|
|
176 A study in simplicity |___/
|
|
177
|
|
178 ]]
|
|
179 session.print("Welcome to the Prosody administration console. For a list of commands, type: help");
|
|
180 session.print("You may find more help on using this console in our online documentation at ");
|
|
181 session.print("http://prosody.im/doc/console\n");
|
|
182 end
|