util/prosodyctl.lua
changeset 10875 e5dee71d0ebb
parent 10726 3ddc7c9f35dc
child 11136 287d0d80aa57
equal deleted inserted replaced
10874:3f1889608f3e 10875:e5dee71d0ebb
    13 local storagemanager = require "core.storagemanager";
    13 local storagemanager = require "core.storagemanager";
    14 local usermanager = require "core.usermanager";
    14 local usermanager = require "core.usermanager";
    15 local signal = require "util.signal";
    15 local signal = require "util.signal";
    16 local set = require "util.set";
    16 local set = require "util.set";
    17 local lfs = require "lfs";
    17 local lfs = require "lfs";
    18 local pcall = pcall;
       
    19 local type = type;
    18 local type = type;
    20 
    19 
    21 local nodeprep, nameprep = stringprep.nodeprep, stringprep.nameprep;
    20 local nodeprep, nameprep = stringprep.nodeprep, stringprep.nameprep;
    22 
    21 
    23 local io, os = io, os;
    22 local io, os = io, os;
    25 local tonumber = tonumber;
    24 local tonumber = tonumber;
    26 
    25 
    27 local _G = _G;
    26 local _G = _G;
    28 local prosody = prosody;
    27 local prosody = prosody;
    29 
    28 
       
    29 local error_messages = setmetatable({
       
    30 		["invalid-username"] = "The given username is invalid in a Jabber ID";
       
    31 		["invalid-hostname"] = "The given hostname is invalid";
       
    32 		["no-password"] = "No password was supplied";
       
    33 		["no-such-user"] = "The given user does not exist on the server";
       
    34 		["no-such-host"] = "The given hostname does not exist in the config";
       
    35 		["unable-to-save-data"] = "Unable to store, perhaps you don't have permission?";
       
    36 		["no-pidfile"] = "There is no 'pidfile' option in the configuration file, see https://prosody.im/doc/prosodyctl#pidfile for help";
       
    37 		["invalid-pidfile"] = "The 'pidfile' option in the configuration file is not a string, see https://prosody.im/doc/prosodyctl#pidfile for help";
       
    38 		["no-posix"] = "The mod_posix module is not enabled in the Prosody config file, see https://prosody.im/doc/prosodyctl for more info";
       
    39 		["no-such-method"] = "This module has no commands";
       
    40 		["not-running"] = "Prosody is not running";
       
    41 		}, { __index = function (_,k) return "Error: "..(tostring(k):gsub("%-", " "):gsub("^.", string.upper)); end });
       
    42 
    30 -- UI helpers
    43 -- UI helpers
    31 local function show_message(msg, ...)
    44 local show_message = require "util.human.io".printf;
    32 	print(msg:format(...));
       
    33 end
       
    34 
    45 
    35 local function show_usage(usage, desc)
    46 local function show_usage(usage, desc)
    36 	print("Usage: ".._G.arg[0].." "..usage);
    47 	print("Usage: ".._G.arg[0].." "..usage);
    37 	if desc then
    48 	if desc then
    38 		print(" "..desc);
    49 		print(" "..desc);
    47 	print("More info about: ")
    58 	print("More info about: ")
    48 	print("	modules_enabled: https://prosody.im/doc/modules_enabled")
    59 	print("	modules_enabled: https://prosody.im/doc/modules_enabled")
    49 	print("	"..mod_name..": https://modules.prosody.im/"..mod_name..".html")
    60 	print("	"..mod_name..": https://modules.prosody.im/"..mod_name..".html")
    50 end
    61 end
    51 
    62 
    52 local function getchar(n)
       
    53 	local stty_ret = os.execute("stty raw -echo 2>/dev/null");
       
    54 	local ok, char;
       
    55 	if stty_ret == true or stty_ret == 0 then
       
    56 		ok, char = pcall(io.read, n or 1);
       
    57 		os.execute("stty sane");
       
    58 	else
       
    59 		ok, char = pcall(io.read, "*l");
       
    60 		if ok then
       
    61 			char = char:sub(1, n or 1);
       
    62 		end
       
    63 	end
       
    64 	if ok then
       
    65 		return char;
       
    66 	end
       
    67 end
       
    68 
       
    69 local function getline()
       
    70 	local ok, line = pcall(io.read, "*l");
       
    71 	if ok then
       
    72 		return line;
       
    73 	end
       
    74 end
       
    75 
       
    76 local function getpass()
       
    77 	local stty_ret, _, status_code = os.execute("stty -echo 2>/dev/null");
       
    78 	if status_code then -- COMPAT w/ Lua 5.1
       
    79 		stty_ret = status_code;
       
    80 	end
       
    81 	if stty_ret ~= 0 then
       
    82 		io.write("\027[08m"); -- ANSI 'hidden' text attribute
       
    83 	end
       
    84 	local ok, pass = pcall(io.read, "*l");
       
    85 	if stty_ret == 0 then
       
    86 		os.execute("stty sane");
       
    87 	else
       
    88 		io.write("\027[00m");
       
    89 	end
       
    90 	io.write("\n");
       
    91 	if ok then
       
    92 		return pass;
       
    93 	end
       
    94 end
       
    95 
       
    96 local function show_yesno(prompt)
       
    97 	io.write(prompt, " ");
       
    98 	local choice = getchar():lower();
       
    99 	io.write("\n");
       
   100 	if not choice:match("%a") then
       
   101 		choice = prompt:match("%[.-(%U).-%]$");
       
   102 		if not choice then return nil; end
       
   103 	end
       
   104 	return (choice == "y");
       
   105 end
       
   106 
       
   107 local function read_password()
       
   108 	local password;
       
   109 	while true do
       
   110 		io.write("Enter new password: ");
       
   111 		password = getpass();
       
   112 		if not password then
       
   113 			show_message("No password - cancelled");
       
   114 			return;
       
   115 		end
       
   116 		io.write("Retype new password: ");
       
   117 		if getpass() ~= password then
       
   118 			if not show_yesno [=[Passwords did not match, try again? [Y/n]]=] then
       
   119 				return;
       
   120 			end
       
   121 		else
       
   122 			break;
       
   123 		end
       
   124 	end
       
   125 	return password;
       
   126 end
       
   127 
       
   128 local function show_prompt(prompt)
       
   129 	io.write(prompt, " ");
       
   130 	local line = getline();
       
   131 	line = line and line:gsub("\n$","");
       
   132 	return (line and #line > 0) and line or nil;
       
   133 end
       
   134 
       
   135 -- Server control
    63 -- Server control
   136 local function adduser(params)
    64 local function adduser(params)
   137 	local user, host, password = nodeprep(params.user, true), nameprep(params.host), params.password;
    65 	local user, host, password = nodeprep(params.user, true), nameprep(params.host), params.password;
   138 	if not user then
    66 	if not user then
   139 		return false, "invalid-username";
    67 		return false, "invalid-username";
   316 return {
   244 return {
   317 	show_message = show_message;
   245 	show_message = show_message;
   318 	show_warning = show_message;
   246 	show_warning = show_message;
   319 	show_usage = show_usage;
   247 	show_usage = show_usage;
   320 	show_module_configuration_help = show_module_configuration_help;
   248 	show_module_configuration_help = show_module_configuration_help;
   321 	getchar = getchar;
       
   322 	getline = getline;
       
   323 	getpass = getpass;
       
   324 	show_yesno = show_yesno;
       
   325 	read_password = read_password;
       
   326 	show_prompt = show_prompt;
       
   327 	adduser = adduser;
   249 	adduser = adduser;
   328 	user_exists = user_exists;
   250 	user_exists = user_exists;
   329 	passwd = passwd;
   251 	passwd = passwd;
   330 	deluser = deluser;
   252 	deluser = deluser;
   331 	getpid = getpid;
   253 	getpid = getpid;
   333 	start = start;
   255 	start = start;
   334 	stop = stop;
   256 	stop = stop;
   335 	reload = reload;
   257 	reload = reload;
   336 	get_path_custom_plugins = get_path_custom_plugins;
   258 	get_path_custom_plugins = get_path_custom_plugins;
   337 	call_luarocks = call_luarocks;
   259 	call_luarocks = call_luarocks;
       
   260 	error_messages = error_messages;
   338 };
   261 };