1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
|
-- Prosody IM
-- Copyright (C) 2008-2009 Matthew Wild
-- Copyright (C) 2008-2009 Waqas Hussain
--
-- This project is MIT/X11 licensed. Please see the
-- COPYING file in the source package for more information.
--
local want_pposix_version = "0.3.1";
local pposix = assert(require "util.pposix");
if pposix._VERSION ~= want_pposix_version then module:log("warn", "Unknown version (%s) of binary pposix module, expected %s", tostring(pposix._VERSION), want_pposix_version); end
local signal = select(2, pcall(require, "util.signal"));
if type(signal) == "string" then
module:log("warn", "Couldn't load signal library, won't respond to SIGTERM");
end
local logger_set = require "util.logger".setwriter;
local prosody = _G.prosody;
module.host = "*"; -- we're a global module
-- Allow switching away from root, some people like strange ports.
module:add_event_hook("server-started", function ()
local uid = module:get_option("setuid");
local gid = module:get_option("setgid");
if gid then
local success, msg = pposix.setgid(gid);
if success then
module:log("debug", "Changed group to "..gid.." successfully.");
else
module:log("error", "Failed to change group to "..gid..". Error: "..msg);
prosody.shutdown("Failed to change group to "..gid);
end
end
if uid then
local success, msg = pposix.setuid(uid);
if success then
module:log("debug", "Changed user to "..uid.." successfully.");
else
module:log("error", "Failed to change user to "..uid..". Error: "..msg);
prosody.shutdown("Failed to change user to "..uid);
end
end
end);
-- Don't even think about it!
module:add_event_hook("server-starting", function ()
local suid = module:get_option("setuid");
if not suid or suid == 0 or suid == "root" then
if pposix.getuid() == 0 and not module:get_option("run_as_root") then
module:log("error", "Danger, Will Robinson! Prosody doesn't need to be run as root, so don't do it!");
module:log("error", "For more information on running Prosody as root, see http://prosody.im/doc/root");
prosody.shutdown("Refusing to run as root");
end
end
end);
local pidfile_written;
local function remove_pidfile()
if pidfile_written then
os.remove(pidfile_written);
pidfile_written = nil;
end
end
local function write_pidfile()
if pidfile_written then
remove_pidfile();
end
local pidfile = module:get_option("pidfile");
if pidfile then
local pf, err = io.open(pidfile, "w+");
if not pf then
module:log("error", "Couldn't write pidfile; %s", err);
else
pf:write(tostring(pposix.getpid()));
pf:close();
pidfile_written = pidfile;
end
end
end
local syslog_opened
function syslog_sink_maker(config)
if not syslog_opened then
pposix.syslog_open("prosody");
syslog_opened = true;
end
local syslog, format = pposix.syslog_log, string.format;
return function (name, level, message, ...)
if ... then
syslog(level, format(message, ...));
else
syslog(level, message);
end
end;
end
require "core.loggingmanager".register_sink_type("syslog", syslog_sink_maker);
local daemonize = module:get_option("daemonize");
if daemonize == nil then
daemonize = not module:get_option("no_daemonize"); --COMPAT w/ 0.5
end
if daemonize then
local function daemonize_server()
local ok, ret = pposix.daemonize();
if not ok then
module:log("error", "Failed to daemonize: %s", ret);
elseif ret and ret > 0 then
os.exit(0);
else
module:log("info", "Successfully daemonized to PID %d", pposix.getpid());
write_pidfile();
end
end
module:add_event_hook("server-starting", daemonize_server);
else
-- Not going to daemonize, so write the pid of this process
write_pidfile();
end
module:add_event_hook("server-stopped", remove_pidfile);
-- Set signal handlers
if signal.signal then
signal.signal("SIGTERM", function ()
module:log("warn", "Received SIGTERM");
prosody.unlock_globals();
prosody.shutdown("Received SIGTERM");
prosody.lock_globals();
end);
signal.signal("SIGHUP", function ()
module:log("info", "Received SIGHUP");
prosody.reload_config();
prosody.reopen_logfiles();
end);
end
|