Software /
code /
prosody
Comparison
plugins/mod_admin_telnet.lua @ 4989:573123ff2ab0
mod_admin_telnet: Always handle commands terminated by line feeds - ensures consistency even when packets are joined or split on the network
author | Matthew Wild <mwild1@gmail.com> |
---|---|
date | Mon, 23 Jul 2012 14:03:00 +0100 |
parent | 4979:5614bbc163e0 |
child | 5005:ab950c9ff074 |
comparison
equal
deleted
inserted
replaced
4988:29bdf68ad142 | 4989:573123ff2ab0 |
---|---|
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 | 15 |
16 local console_listener = { default_port = 5582; default_mode = "*l"; interface = "127.0.0.1" }; | 16 local console_listener = { default_port = 5582; default_mode = "*a"; interface = "127.0.0.1" }; |
17 | 17 |
18 local iterators = require "util.iterators"; | 18 local iterators = require "util.iterators"; |
19 local keys, values = iterators.keys, iterators.values; | 19 local keys, values = iterators.keys, iterators.values; |
20 local jid = require "util.jid"; | 20 local jid = require "util.jid"; |
21 local jid_bare, jid_split = jid.bare, jid.split; | 21 local jid_bare, jid_split = jid.bare, jid.split; |
74 end | 74 end |
75 | 75 |
76 function console_listener.onincoming(conn, data) | 76 function console_listener.onincoming(conn, data) |
77 local session = sessions[conn]; | 77 local session = sessions[conn]; |
78 | 78 |
79 -- Handle data (loop allows us to break to add \0 after response) | 79 local partial = session.partial_data; |
80 repeat | 80 if partial then |
81 local useglobalenv; | 81 data = partial..data; |
82 | 82 end |
83 if data:match("^>") then | 83 |
84 data = data:gsub("^>", ""); | 84 for line in data:gmatch("[^\n]*[\n\004]") do |
85 useglobalenv = true; | 85 -- Handle data (loop allows us to break to add \0 after response) |
86 elseif data == "\004" then | 86 repeat |
87 commands["bye"](session, data); | 87 local useglobalenv; |
88 break; | 88 |
89 else | 89 if line:match("^>") then |
90 local command = data:lower(); | 90 line = line:gsub("^>", ""); |
91 command = data:match("^%w+") or data:match("%p"); | 91 useglobalenv = true; |
92 if commands[command] then | 92 elseif line == "\004" then |
93 commands[command](session, data); | 93 commands["bye"](session, line); |
94 break; | 94 break; |
95 end | 95 else |
96 end | 96 local command = line:lower(); |
97 | 97 command = line:match("^%w+") or line:match("%p"); |
98 session.env._ = data; | 98 if commands[command] then |
99 commands[command](session, line); | |
100 break; | |
101 end | |
102 end | |
103 | |
104 session.env._ = line; | |
105 | |
106 local chunkname = "=console"; | |
107 local chunk, err = loadstring("return "..line, chunkname); | |
108 if not chunk then | |
109 chunk, err = loadstring(line, chunkname); | |
110 if not chunk then | |
111 err = err:gsub("^%[string .-%]:%d+: ", ""); | |
112 err = err:gsub("^:%d+: ", ""); | |
113 err = err:gsub("'<eof>'", "the end of the line"); | |
114 session.print("Sorry, I couldn't understand that... "..err); | |
115 break; | |
116 end | |
117 end | |
118 | |
119 setfenv(chunk, (useglobalenv and redirect_output(_G, session)) or session.env or nil); | |
120 | |
121 local ranok, taskok, message = pcall(chunk); | |
122 | |
123 if not (ranok or message or useglobalenv) and commands[line:lower()] then | |
124 commands[line:lower()](session, line); | |
125 break; | |
126 end | |
127 | |
128 if not ranok then | |
129 session.print("Fatal error while running command, it did not complete"); | |
130 session.print("Error: "..taskok); | |
131 break; | |
132 end | |
133 | |
134 if not message then | |
135 session.print("Result: "..tostring(taskok)); | |
136 break; | |
137 elseif (not taskok) and message then | |
138 session.print("Command completed with a problem"); | |
139 session.print("Message: "..tostring(message)); | |
140 break; | |
141 end | |
142 | |
143 session.print("OK: "..tostring(message)); | |
144 until true | |
99 | 145 |
100 local chunkname = "=console"; | 146 session.send(string.char(0)); |
101 local chunk, err = loadstring("return "..data, chunkname); | 147 end |
102 if not chunk then | 148 session.partial_data = data:match("[^\n]+$"); |
103 chunk, err = loadstring(data, chunkname); | |
104 if not chunk then | |
105 err = err:gsub("^%[string .-%]:%d+: ", ""); | |
106 err = err:gsub("^:%d+: ", ""); | |
107 err = err:gsub("'<eof>'", "the end of the line"); | |
108 session.print("Sorry, I couldn't understand that... "..err); | |
109 break; | |
110 end | |
111 end | |
112 | |
113 setfenv(chunk, (useglobalenv and redirect_output(_G, session)) or session.env or nil); | |
114 | |
115 local ranok, taskok, message = pcall(chunk); | |
116 | |
117 if not (ranok or message or useglobalenv) and commands[data:lower()] then | |
118 commands[data:lower()](session, data); | |
119 break; | |
120 end | |
121 | |
122 if not ranok then | |
123 session.print("Fatal error while running command, it did not complete"); | |
124 session.print("Error: "..taskok); | |
125 break; | |
126 end | |
127 | |
128 if not message then | |
129 session.print("Result: "..tostring(taskok)); | |
130 break; | |
131 elseif (not taskok) and message then | |
132 session.print("Command completed with a problem"); | |
133 session.print("Message: "..tostring(message)); | |
134 break; | |
135 end | |
136 | |
137 session.print("OK: "..tostring(message)); | |
138 until true | |
139 | |
140 session.send(string.char(0)); | |
141 end | 149 end |
142 | 150 |
143 function console_listener.ondisconnect(conn, err) | 151 function console_listener.ondisconnect(conn, err) |
144 local session = sessions[conn]; | 152 local session = sessions[conn]; |
145 if session then | 153 if session then |