2 -- Copyright (C) 2008-2010 Matthew Wild
3 -- Copyright (C) 2008-2010 Waqas Hussain
5 -- This project is MIT/X11 licensed. Please see the
6 -- COPYING file in the source package for more information.
10 local config = require "core.configmanager";
11 local encodings = require "util.encodings";
12 local stringprep = encodings.stringprep;
13 local storagemanager = require "core.storagemanager";
14 local usermanager = require "core.usermanager";
15 local signal = require "util.signal";
16 local set = require "util.set";
17 local lfs = require "lfs";
21 local nodeprep, nameprep = stringprep.nodeprep, stringprep.nameprep;
23 local io, os = io, os;
25 local tostring, tonumber = tostring, tonumber;
27 local CFG_SOURCEDIR = _G.CFG_SOURCEDIR;
30 local prosody = prosody;
35 function show_message(msg, ...)
36 print(msg:format(...));
39 function show_warning(msg, ...)
40 print(msg:format(...));
43 function show_usage(usage, desc)
44 print("Usage: ".._G.arg[0].." "..usage);
51 local stty_ret = os.execute("stty raw -echo 2>/dev/null");
54 ok, char = pcall(io.read, n or 1);
55 os.execute("stty sane");
57 ok, char = pcall(io.read, "*l");
59 char = char:sub(1, n or 1);
68 local ok, line = pcall(io.read, "*l");
75 local stty_ret = os.execute("stty -echo 2>/dev/null");
77 io.write("\027[08m"); -- ANSI 'hidden' text attribute
79 local ok, pass = pcall(io.read, "*l");
81 os.execute("stty sane");
91 function show_yesno(prompt)
92 io.write(prompt, " ");
93 local choice = getchar():lower();
95 if not choice:match("%a") then
96 choice = prompt:match("%[.-(%U).-%]$");
97 if not choice then return nil; end
99 return (choice == "y");
102 function read_password()
105 io.write("Enter new password: ");
106 password = getpass();
108 show_message("No password - cancelled");
111 io.write("Retype new password: ");
112 if getpass() ~= password then
113 if not show_yesno [=[Passwords did not match, try again? [Y/n]]=] then
123 function show_prompt(prompt)
124 io.write(prompt, " ");
125 local line = getline();
126 line = line and line:gsub("\n$","");
127 return (line and #line > 0) and line or nil;
131 function adduser(params)
132 local user, host, password = nodeprep(params.user), nameprep(params.host), params.password;
134 return false, "invalid-username";
136 return false, "invalid-hostname";
139 local host_session = prosody.hosts[host];
140 if not host_session then
141 return false, "no-such-host";
143 local provider = host_session.users;
144 if not(provider) or provider.name == "null" then
145 usermanager.initialize_host(host);
147 storagemanager.initialize_host(host);
149 local ok, errmsg = usermanager.create_user(user, password, host);
151 return false, errmsg;
156 function user_exists(params)
157 local user, host, password = nodeprep(params.user), nameprep(params.host), params.password;
158 local provider = prosody.hosts[host].users;
159 if not(provider) or provider.name == "null" then
160 usermanager.initialize_host(host);
162 storagemanager.initialize_host(host);
164 return usermanager.user_exists(user, host);
167 function passwd(params)
168 if not _M.user_exists(params) then
169 return false, "no-such-user";
172 return _M.adduser(params);
175 function deluser(params)
176 if not _M.user_exists(params) then
177 return false, "no-such-user";
179 params.password = nil;
181 return _M.adduser(params);
185 local pidfile = config.get("*", "core", "pidfile");
187 return false, "no-pidfile";
190 local modules_enabled = set.new(config.get("*", "core", "modules_enabled"));
191 if not modules_enabled:contains("posix") then
192 return false, "no-posix";
195 local file, err = io.open(pidfile, "r+");
197 return false, "pidfile-read-failed", err;
200 local locked, err = lfs.lock(file, "w");
203 return false, "pidfile-not-locked";
206 local pid = tonumber(file:read("*a"));
210 return false, "invalid-pid";
217 local ok, pid, err = _M.getpid();
219 if pid == "pidfile-read-failed" or pid == "pidfile-not-locked" then
220 -- Report as not running, since we can't open the pidfile
221 -- (it probably doesn't exist)
226 return true, signal.kill(pid, 0) == 0;
230 local ok, ret = _M.isrunning();
235 return false, "already-running";
237 if not CFG_SOURCEDIR then
238 os.execute("./prosody");
240 os.execute(CFG_SOURCEDIR.."/../../bin/prosody");
246 local ok, ret = _M.isrunning();
251 return false, "not-running";
254 local ok, pid = _M.getpid()
255 if not ok then return false, pid; end
257 signal.kill(pid, signal.SIGTERM);
262 local ok, ret = _M.isrunning();
267 return false, "not-running";
270 local ok, pid = _M.getpid()
271 if not ok then return false, pid; end
273 signal.kill(pid, signal.SIGHUP);