Software / code / prosody
Comparison
plugins/mod_admin_shell.lua @ 10859:8de0057b4279
mod_admin_shell, mod_admin_telnet, util.prosodyctl.shell: Separate output from final result
Fixes the client pausing for input after output from commands.
| author | Matthew Wild <mwild1@gmail.com> |
|---|---|
| date | Mon, 01 Jun 2020 16:14:06 +0100 |
| parent | 10856:c99711eda0d1 |
| child | 10860:934dca972f2c |
comparison
equal
deleted
inserted
replaced
| 10858:efa49d484560 | 10859:8de0057b4279 |
|---|---|
| 59 | 59 |
| 60 self.data.print("Fatal error while running command, it did not complete"); | 60 self.data.print("Fatal error while running command, it did not complete"); |
| 61 self.data.print("Error: "..tostring(err)); | 61 self.data.print("Error: "..tostring(err)); |
| 62 end | 62 end |
| 63 | 63 |
| 64 local function send_repl_result(session, line) | 64 local function send_repl_output(session, line) |
| 65 return session.send(st.stanza("repl-result"):text(tostring(line))); | 65 return session.send(st.stanza("repl-output"):text(tostring(line))); |
| 66 end | 66 end |
| 67 | 67 |
| 68 function console:new_session(admin_session) | 68 function console:new_session(admin_session) |
| 69 local session = { | 69 local session = { |
| 70 send = function (t) | 70 send = function (t) |
| 71 return send_repl_result(admin_session, t); | 71 return send_repl_output(admin_session, t); |
| 72 end; | 72 end; |
| 73 print = function (...) | 73 print = function (...) |
| 74 local t = {}; | 74 local t = {}; |
| 75 for i=1,select("#", ...) do | 75 for i=1,select("#", ...) do |
| 76 t[i] = tostring(select(i, ...)); | 76 t[i] = tostring(select(i, ...)); |
| 77 end | 77 end |
| 78 return send_repl_result(admin_session, table.concat(t, "\t")); | 78 return send_repl_output(admin_session, table.concat(t, "\t")); |
| 79 end; | 79 end; |
| 80 serialize = tostring; | 80 serialize = tostring; |
| 81 disconnect = function () admin_session:close(); end; | 81 disconnect = function () admin_session:close(); end; |
| 82 }; | 82 }; |
| 83 session.env = setmetatable({}, default_env_mt); | 83 session.env = setmetatable({}, default_env_mt); |
| 105 event.origin.shell_session = session; | 105 event.origin.shell_session = session; |
| 106 end | 106 end |
| 107 local line = event.stanza:get_text(); | 107 local line = event.stanza:get_text(); |
| 108 local useglobalenv; | 108 local useglobalenv; |
| 109 | 109 |
| 110 | 110 local result = st.stanza("repl-result"); |
| 111 module:log("debug", "HELLO: %s", line) | 111 |
| 112 if line:match("^>") then | 112 if line:match("^>") then |
| 113 line = line:gsub("^>", ""); | 113 line = line:gsub("^>", ""); |
| 114 useglobalenv = true; | 114 useglobalenv = true; |
| 115 else | 115 else |
| 116 local command = line:match("^%w+") or line:match("%p"); | 116 local command = line:match("^%w+") or line:match("%p"); |
| 117 if commands[command] then | 117 if commands[command] then |
| 118 commands[command](session, line); | 118 commands[command](session, line); |
| 119 event.origin.send(result); | |
| 119 return; | 120 return; |
| 120 end | 121 end |
| 121 end | 122 end |
| 122 | 123 |
| 123 session.env._ = line; | 124 session.env._ = line; |
| 124 | 125 |
| 125 if not useglobalenv and commands[line:lower()] then | 126 if not useglobalenv and commands[line:lower()] then |
| 126 commands[line:lower()](session, line); | 127 commands[line:lower()](session, line); |
| 128 event.origin.send(result); | |
| 127 return; | 129 return; |
| 128 end | 130 end |
| 129 | 131 |
| 130 local chunkname = "=console"; | 132 local chunkname = "=console"; |
| 131 local env = (useglobalenv and redirect_output(_G, session)) or session.env or nil | 133 local env = (useglobalenv and redirect_output(_G, session)) or session.env or nil |
| 135 chunk, err = envload(line, chunkname, env); | 137 chunk, err = envload(line, chunkname, env); |
| 136 if not chunk then | 138 if not chunk then |
| 137 err = err:gsub("^%[string .-%]:%d+: ", ""); | 139 err = err:gsub("^%[string .-%]:%d+: ", ""); |
| 138 err = err:gsub("^:%d+: ", ""); | 140 err = err:gsub("^:%d+: ", ""); |
| 139 err = err:gsub("'<eof>'", "the end of the line"); | 141 err = err:gsub("'<eof>'", "the end of the line"); |
| 140 session.print("Sorry, I couldn't understand that... "..err); | 142 result.attr.type = "error"; |
| 143 result:text("Sorry, I couldn't understand that... "..err); | |
| 144 event.origin.send(result); | |
| 141 return; | 145 return; |
| 142 end | 146 end |
| 143 end | 147 end |
| 144 | 148 |
| 145 local taskok, message = chunk(); | 149 local taskok, message = chunk(); |
| 150 | |
| 151 local result = st.stanza("repl-result"); | |
| 146 | 152 |
| 147 if not message then | 153 if not message then |
| 148 if type(taskok) ~= "string" and useglobalenv then | 154 if type(taskok) ~= "string" and useglobalenv then |
| 149 taskok = session.serialize(taskok); | 155 taskok = session.serialize(taskok); |
| 150 end | 156 end |
| 151 session.print("Result: "..tostring(taskok)); | 157 result:text("Result: "..tostring(taskok)); |
| 152 return; | |
| 153 elseif (not taskok) and message then | 158 elseif (not taskok) and message then |
| 154 session.print("Command completed with a problem"); | 159 result.attr.type = "error"; |
| 155 session.print("Message: "..tostring(message)); | 160 result:text("Error: "..tostring(message)); |
| 156 return; | 161 else |
| 157 end | 162 result:text("OK: "..tostring(message)); |
| 158 | 163 end |
| 159 session.print("OK: "..tostring(message)); | 164 |
| 160 end | 165 event.origin.send(result); |
| 161 | 166 end |
| 162 module:hook("admin/repl-line", function (event) | 167 |
| 168 module:hook("admin/repl-input", function (event) | |
| 163 local ok, err = pcall(handle_line, event); | 169 local ok, err = pcall(handle_line, event); |
| 164 if not ok then | 170 if not ok then |
| 165 event.origin.send(st.stanza("repl-result", { type = "error" }):text(err)); | 171 event.origin.send(st.stanza("repl-result", { type = "error" }):text(err)); |
| 166 end | 172 end |
| 167 end); | 173 end); |