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