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 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";
18
 
19
local nodeprep, nameprep = stringprep.nodeprep, stringprep.nameprep;
20
 
21
local io, os = io, os;
22
local tostring, tonumber = tostring, tonumber;
23
 
24
local CFG_SOURCEDIR = _G.CFG_SOURCEDIR;
25
 
26
local prosody = prosody;
27
 
28
module "prosodyctl"
29
 
30
function adduser(params)
31
	local user, host, password = nodeprep(params.user), nameprep(params.host), params.password;
32
	if not user then
33
		return false, "invalid-username";
34
	elseif not host then
35
		return false, "invalid-hostname";
36
	end
37
 
38
	local provider = prosody.hosts[host].users;
39
	if not(provider) or provider.name == "null" then
40
		usermanager.initialize_host(host);
41
	end
42
	storagemanager.initialize_host(host);
43
	
44
	local ok, errmsg = usermanager.create_user(user, password, host);
45
	if not ok then
46
		return false, errmsg;
47
	end
48
	return true;
49
end
50
 
51
function user_exists(params)
52
	local user, host, password = nodeprep(params.user), nameprep(params.host), params.password;
53
	local provider = prosody.hosts[host].users;
54
	if not(provider) or provider.name == "null" then
55
		usermanager.initialize_host(host);
56
	end
57
	storagemanager.initialize_host(host);
58
	
59
	return usermanager.user_exists(user, host);
60
end
61
 
62
function passwd(params)
63
	if not _M.user_exists(params) then
64
		return false, "no-such-user";
65
	end
66
	
67
	return _M.adduser(params);
68
end
69
 
70
function deluser(params)
71
	if not _M.user_exists(params) then
72
		return false, "no-such-user";
73
	end
74
	params.password = nil;
75
	
76
	return _M.adduser(params);
77
end
78
 
79
function getpid()
80
	local pidfile = config.get("*", "core", "pidfile");
81
	if not pidfile then
82
		return false, "no-pidfile";
83
	end
84
	
85
	local modules_enabled = set.new(config.get("*", "core", "modules_enabled"));
86
	if not modules_enabled:contains("posix") then
87
		return false, "no-posix";
88
	end
89
	
90
	local file, err = io.open(pidfile, "r+");
91
	if not file then
92
		return false, "pidfile-read-failed", err;
93
	end
94
	
95
	local locked, err = lfs.lock(file, "w");
96
	if locked then
97
		file:close();
98
		return false, "pidfile-not-locked";
99
	end
100
	
101
	local pid = tonumber(file:read("*a"));
102
	file:close();
103
	
104
	if not pid then
105
		return false, "invalid-pid";
106
	end
107
	
108
	return true, pid;
109
end
110
 
111
function isrunning()
112
	local ok, pid, err = _M.getpid();
113
	if not ok then
114
		if pid == "pidfile-read-failed" or pid == "pidfile-not-locked" then
115
			-- Report as not running, since we can't open the pidfile
116
			-- (it probably doesn't exist)
117
			return true, false;
118
		end
119
		return ok, pid;
120
	end
121
	return true, signal.kill(pid, 0) == 0;
122
end
123
 
124
function start()
125
	local ok, ret = _M.isrunning();
126
	if not ok then
127
		return ok, ret;
128
	end
129
	if ret then
130
		return false, "already-running";
131
	end
132
	if not CFG_SOURCEDIR then
133
		os.execute("./prosody");
134
	else
135
		os.execute(CFG_SOURCEDIR.."/../../bin/prosody");
136
	end
137
	return true;
138
end
139
 
140
function stop()
141
	local ok, ret = _M.isrunning();
142
	if not ok then
143
		return ok, ret;
144
	end
145
	if not ret then
146
		return false, "not-running";
147
	end
148
	
149
	local ok, pid = _M.getpid()
150
	if not ok then return false, pid; end
151
	
152
	signal.kill(pid, signal.SIGTERM);
153
	return true;
154
end