prosodyctl, util.prosodyctl: Show error when mod_posix is not enabled and an attempt...
[prosody.git] / util / prosodyctl.lua
1 -- Prosody IM
2 -- Copyright (C) 2008-2010 Matthew Wild
3 -- Copyright (C) 2008-2010 Waqas Hussain
4 -- 
5 -- This project is MIT/X11 licensed. Please see the
6 -- COPYING file in the source package for more information.
7 --
8
9
10 local config = require "core.configmanager";
11 local encodings = require "util.encodings";
12 local stringprep = encodings.stringprep;
13 local usermanager = require "core.usermanager";
14 local signal = require "util.signal";
15 local set = require "util.set";
16 local lfs = require "lfs";
17
18 local nodeprep, nameprep = stringprep.nodeprep, stringprep.nameprep;
19
20 local io, os = io, os;
21 local tostring, tonumber = tostring, tonumber;
22
23 local CFG_SOURCEDIR = _G.CFG_SOURCEDIR;
24
25 local prosody = prosody;
26
27 module "prosodyctl"
28
29 function adduser(params)
30         local user, host, password = nodeprep(params.user), nameprep(params.host), params.password;
31         if not user then
32                 return false, "invalid-username";
33         elseif not host then
34                 return false, "invalid-hostname";
35         end
36
37         local provider = prosody.hosts[host].users;
38         if not(provider) or provider.name == "null" then
39                 usermanager.initialize_host(host);
40         end
41         
42         local ok = usermanager.create_user(user, password, host);
43         if not ok then
44                 return false, "unable-to-save-data";
45         end
46         return true;
47 end
48
49 function user_exists(params)
50         local provider = prosody.hosts[params.host].users;
51         if not(provider) or provider.name == "null" then
52                 usermanager.initialize_host(params.host);
53         end
54         
55         return usermanager.user_exists(params.user, params.host);
56 end
57
58 function passwd(params)
59         if not _M.user_exists(params) then
60                 return false, "no-such-user";
61         end
62         
63         return _M.adduser(params);
64 end
65
66 function deluser(params)
67         if not _M.user_exists(params) then
68                 return false, "no-such-user";
69         end
70         params.password = nil;
71         
72         return _M.adduser(params);
73 end
74
75 function getpid()
76         local pidfile = config.get("*", "core", "pidfile");
77         if not pidfile then
78                 return false, "no-pidfile";
79         end
80         
81         local modules_enabled = set.new(config.get("*", "core", "modules_enabled"));
82         if not modules_enabled:contains("posix") then
83                 return false, "no-posix";
84         end
85         
86         local file, err = io.open(pidfile, "r+");
87         if not file then
88                 return false, "pidfile-read-failed", err;
89         end
90         
91         local locked, err = lfs.lock(file, "w");
92         if locked then
93                 file:close();
94                 return false, "pidfile-not-locked";
95         end
96         
97         local pid = tonumber(file:read("*a"));
98         file:close();
99         
100         if not pid then
101                 return false, "invalid-pid";
102         end
103         
104         return true, pid;
105 end
106
107 function isrunning()
108         local ok, pid, err = _M.getpid();
109         if not ok then
110                 if pid == "pidfile-read-failed" or pid == "pidfile-not-locked" then
111                         -- Report as not running, since we can't open the pidfile
112                         -- (it probably doesn't exist)
113                         return true, false;
114                 end
115                 return ok, pid;
116         end
117         return true, signal.kill(pid, 0) == 0;
118 end
119
120 function start()
121         local ok, ret = _M.isrunning();
122         if not ok then
123                 return ok, ret;
124         end
125         if ret then
126                 return false, "already-running";
127         end
128         if not CFG_SOURCEDIR then
129                 os.execute("./prosody");
130         else
131                 os.execute(CFG_SOURCEDIR.."/../../bin/prosody");
132         end
133         return true;
134 end
135
136 function stop()
137         local ok, ret = _M.isrunning();
138         if not ok then
139                 return ok, ret;
140         end
141         if not ret then
142                 return false, "not-running";
143         end
144         
145         local ok, pid = _M.getpid()
146         if not ok then return false, pid; end
147         
148         signal.kill(pid, signal.SIGTERM);
149         return true;
150 end