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 = {};
|
|
7 local default_env = {};
|
|
8 local default_env_mt = { __index = default_env };
|
|
9
|
|
10 console = {};
|
|
11
|
|
12 function console:new_session(conn)
|
|
13 local w = conn.write;
|
|
14 return { conn = conn;
|
|
15 send = function (t) w(tostring(t)); end;
|
|
16 print = function (t) w("| "..tostring(t).."\n"); end;
|
|
17 disconnect = function () conn.close(); end;
|
|
18 env = setmetatable({}, default_env_mt);
|
|
19 };
|
|
20 end
|
|
21
|
|
22 local sessions = {};
|
|
23
|
|
24 function console_listener.listener(conn, data)
|
|
25 local session = sessions[conn];
|
|
26
|
|
27 if not session then
|
|
28 -- Handle new connection
|
|
29 session = console:new_session(conn);
|
|
30 sessions[conn] = session;
|
|
31 session.print("Welcome to the lxmppd admin console!");
|
|
32 end
|
|
33 if data then
|
|
34 -- Handle data
|
|
35
|
|
36 if data:match("[!.]$") then
|
|
37 local command = data:lower();
|
|
38 command = data:match("^%w+") or data:match("%p");
|
|
39 if commands[command] then
|
|
40 commands[command](session, data);
|
|
41 return;
|
|
42 end
|
|
43 end
|
|
44
|
|
45 session.env._ = data;
|
|
46
|
|
47 local chunk, err = loadstring("return "..data);
|
|
48 if not chunk then
|
|
49 chunk, err = loadstring(data);
|
|
50 if not chunk then
|
|
51 err = err:gsub("^%[string .-%]:%d+: ", "");
|
|
52 err = err:gsub("^:%d+: ", "");
|
|
53 err = err:gsub("'<eof>'", "the end of the line");
|
|
54 session.print("Sorry, I couldn't understand that... "..err);
|
|
55 return;
|
|
56 end
|
|
57 end
|
|
58
|
|
59 setfenv(chunk, session.env);
|
|
60 local ranok, taskok, message = pcall(chunk);
|
|
61
|
|
62 if not ranok then
|
|
63 session.print("Fatal error while running command, it did not complete");
|
|
64 session.print("Error: "..taskok);
|
|
65 return;
|
|
66 end
|
|
67
|
|
68 if not message then
|
|
69 session.print("Result: "..tostring(taskok));
|
|
70 return;
|
|
71 elseif (not taskok) and message then
|
|
72 session.print("Command completed with a problem");
|
|
73 session.print("Message: "..tostring(message));
|
|
74 return;
|
|
75 end
|
|
76
|
|
77 session.print("OK: "..tostring(message));
|
|
78 end
|
|
79 end
|
|
80
|
|
81 function console_listener.disconnect(conn, err)
|
|
82
|
|
83 end
|
|
84
|
|
85 connlisteners_register('console', console_listener);
|
|
86
|
|
87 -- Console commands --
|
|
88 -- These are simple commands, not valid standalone in Lua
|
|
89
|
|
90 function commands.bye(session)
|
|
91 session.print("See you! :)");
|
|
92 session.disconnect();
|
|
93 end
|
|
94
|
|
95 commands["!"] = function (session, data)
|
|
96 if data:match("^!!") then
|
|
97 session.print("!> "..session.env._);
|
|
98 return console_listener.listener(session.conn, session.env._);
|
|
99 end
|
|
100 local old, new = data:match("^!(.-[^\\])!(.-)!$");
|
|
101 if old and new then
|
|
102 local ok, res = pcall(string.gsub, session.env._, old, new);
|
|
103 if not ok then
|
|
104 session.print(res)
|
|
105 return;
|
|
106 end
|
|
107 session.print("!> "..res);
|
|
108 return console_listener.listener(session.conn, res);
|
|
109 end
|
|
110 session.print("Sorry, not sure what you want");
|
|
111 end
|
|
112
|
|
113 -- Session environment --
|
|
114 -- Anything in default_env will be accessible within the session as a global variable
|
|
115
|
|
116 default_env.server = {};
|
|
117 function default_env.server.reload()
|
|
118 dofile "main.lua"
|
|
119 return true, "Server reloaded";
|
|
120 end
|
|
121
|
|
122 default_env.module = {};
|
|
123 function default_env.module.load(name)
|
|
124 local mm = require "modulemanager";
|
|
125 local ok, err = mm.load(name);
|
|
126 if not ok then
|
|
127 return false, err or "Unknown error loading module";
|
|
128 end
|
|
129 return true, "Module loaded";
|
|
130 end
|
|
131
|
|
132 default_env.config = {};
|
|
133 function default_env.config.load(filename, format)
|
|
134 local cfgm_load = require "core.configmanager".load;
|
|
135 local ok, err = cfgm_load(filename, format);
|
|
136 if not ok then
|
|
137 return false, err or "Unknown error loading config";
|
|
138 end
|
|
139 return true, "Config loaded";
|
|
140 end
|