1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
|
local have_unix, unix = pcall(require, "socket.unix");
if not have_unix or type(unix) ~= "table" then
print("** LuaSocket unix socket support not available or incompatible, ensure your");
print("** version is up to date.");
os.exit(1);
end
local config = require "core.configmanager";
local server = require "net.server";
local st = require "util.stanza";
local path = require "util.paths";
local have_readline, readline = pcall(require, "readline");
local adminstream = require "util.adminstream";
if have_readline then
readline.set_readline_name("prosody");
end
local function read_line()
if have_readline then
return readline.readline("prosody> ");
else
io.write("prosody> ");
return io.read("*line");
end
end
local function send_line(client, line)
client.send(st.stanza("repl-input"):text(line));
end
local function repl(client)
local line = read_line();
if not line or line == "quit" or line == "exit" or line == "bye" then
if not line then
print("");
end
os.exit();
end
send_line(client, line);
end
local function connection(socket_path, listeners)
local conn, sock;
return {
connect = function ()
if sock or conn then
return nil, "already connected";
end
sock = unix.stream();
sock:settimeout(0);
local ok, err = sock:connect(socket_path);
if not ok then
return nil, err;
end
conn = server.wrapclient(sock, nil, nil, listeners, "*a");
return true;
end;
disconnect = function ()
if conn then
conn:close();
conn = nil;
end
if sock then
sock:close();
sock = nil;
end
return true;
end;
};
end
local function printbanner()
print([[
____ \ / _
| _ \ _ __ ___ ___ _-_ __| |_ _
| |_) | '__/ _ \/ __|/ _ \ / _` | | | |
| __/| | | (_) \__ \ |_| | (_| | |_| |
|_| |_| \___/|___/\___/ \__,_|\__, |
A study in simplicity |___/
]]);
print("Welcome to the Prosody administration console. For a list of commands, type: help");
print("You may find more help on using this console in our online documentation at ");
print("https://prosody.im/doc/console\n");
end
local function start(arg) --luacheck: ignore 212/arg
local client = adminstream.client();
client.events.add_handler("connected", function ()
if not arg.quiet then
printbanner();
end
repl(client);
end);
client.events.add_handler("disconnected", function ()
print("--- session closed ---");
os.exit();
end);
client.events.add_handler("received", function (stanza)
if stanza.name == "repl-output" or stanza.name == "repl-result" then
local result_prefix = stanza.attr.type == "error" and "!" or "|";
print(result_prefix.." "..stanza:get_text());
end
if stanza.name == "repl-result" then
repl(client);
end
end);
local socket_path = path.resolve_relative_path(prosody.paths.data, arg.socket or config.get("*", "admin_socket") or "prosody.sock");
local conn = connection(socket_path, client.listeners);
local ok, err = conn:connect();
if not ok then
print("** Unable to connect to server - is it running? Is mod_admin_shell enabled?");
print("** Connection error: "..err);
os.exit(1);
end
server.loop();
end
return {
start = start;
};
|