Mercurial > dovecot > original-hg > dovecot-1.2
annotate src/master/main.c @ 697:7814b29d0862 HEAD
Created env_put() and env_clean() for a bit easier handling of environment
variables.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Tue, 26 Nov 2002 21:49:06 +0200 |
parents | 90a65c017bf0 |
children | 8dd8ebe6bcac |
rev | line source |
---|---|
0 | 1 /* Copyright (C) 2002 Timo Sirainen */ |
2 | |
3 #include "common.h" | |
4 #include "ioloop.h" | |
5 #include "lib-signals.h" | |
6 #include "network.h" | |
697
7814b29d0862
Created env_put() and env_clean() for a bit easier handling of environment
Timo Sirainen <tss@iki.fi>
parents:
635
diff
changeset
|
7 #include "env-util.h" |
0 | 8 |
9 #include "auth-process.h" | |
10 #include "login-process.h" | |
615
0d852af6842e
Master process generates DH/RSA parameters now and stores them into file
Timo Sirainen <tss@iki.fi>
parents:
610
diff
changeset
|
11 #include "ssl-init.h" |
0 | 12 |
279
49f4b0be0d87
Print usage with invalid parameters.
Timo Sirainen <tss@iki.fi>
parents:
50
diff
changeset
|
13 #include <stdio.h> |
0 | 14 #include <stdlib.h> |
15 #include <unistd.h> | |
16 #include <fcntl.h> | |
17 #include <syslog.h> | |
18 #include <sys/stat.h> | |
19 #include <sys/wait.h> | |
20 | |
21 const char *process_names[PROCESS_TYPE_MAX] = { | |
22 "unknown", | |
23 "auth", | |
24 "login", | |
615
0d852af6842e
Master process generates DH/RSA parameters now and stores them into file
Timo Sirainen <tss@iki.fi>
parents:
610
diff
changeset
|
25 "imap", |
0d852af6842e
Master process generates DH/RSA parameters now and stores them into file
Timo Sirainen <tss@iki.fi>
parents:
610
diff
changeset
|
26 "ssl-param" |
0 | 27 }; |
28 | |
635
90a65c017bf0
SIGHUP reloads now settings. Logged in clients are left untouched, but
Timo Sirainen <tss@iki.fi>
parents:
615
diff
changeset
|
29 static const char *configfile = SYSCONFDIR "/" PACKAGE ".conf"; |
0 | 30 static IOLoop ioloop; |
635
90a65c017bf0
SIGHUP reloads now settings. Logged in clients are left untouched, but
Timo Sirainen <tss@iki.fi>
parents:
615
diff
changeset
|
31 static Timeout to; |
0 | 32 |
33 HashTable *pids; | |
34 int null_fd, imap_fd, imaps_fd; | |
35 | |
36 int validate_str(const char *str, int max_len) | |
37 { | |
38 int i; | |
39 | |
40 for (i = 0; i < max_len; i++) { | |
41 if (str[i] == '\0') | |
42 return TRUE; | |
43 } | |
44 | |
45 return FALSE; | |
46 } | |
47 | |
48 void clean_child_process(void) | |
49 { | |
50 /* remove all environment, we don't need them */ | |
697
7814b29d0862
Created env_put() and env_clean() for a bit easier handling of environment
Timo Sirainen <tss@iki.fi>
parents:
635
diff
changeset
|
51 env_clean(); |
0 | 52 |
53 /* set the failure log */ | |
697
7814b29d0862
Created env_put() and env_clean() for a bit easier handling of environment
Timo Sirainen <tss@iki.fi>
parents:
635
diff
changeset
|
54 if (set_log_path != NULL) |
7814b29d0862
Created env_put() and env_clean() for a bit easier handling of environment
Timo Sirainen <tss@iki.fi>
parents:
635
diff
changeset
|
55 env_put(t_strconcat("IMAP_LOGFILE=", set_log_path, NULL)); |
7814b29d0862
Created env_put() and env_clean() for a bit easier handling of environment
Timo Sirainen <tss@iki.fi>
parents:
635
diff
changeset
|
56 if (set_log_timestamp != NULL) |
7814b29d0862
Created env_put() and env_clean() for a bit easier handling of environment
Timo Sirainen <tss@iki.fi>
parents:
635
diff
changeset
|
57 env_put(t_strconcat("IMAP_LOGSTAMP=", set_log_timestamp, NULL)); |
0 | 58 |
59 (void)close(null_fd); | |
60 (void)close(imap_fd); | |
61 (void)close(imaps_fd); | |
62 | |
63 /* close fds for auth/login processes */ | |
64 login_processes_cleanup(); | |
65 auth_processes_cleanup(); | |
66 | |
67 closelog(); | |
68 } | |
69 | |
70 static void sig_quit(int signo __attr_unused__) | |
71 { | |
72 io_loop_stop(ioloop); | |
73 } | |
74 | |
635
90a65c017bf0
SIGHUP reloads now settings. Logged in clients are left untouched, but
Timo Sirainen <tss@iki.fi>
parents:
615
diff
changeset
|
75 static void settings_reload(void) |
90a65c017bf0
SIGHUP reloads now settings. Logged in clients are left untouched, but
Timo Sirainen <tss@iki.fi>
parents:
615
diff
changeset
|
76 { |
90a65c017bf0
SIGHUP reloads now settings. Logged in clients are left untouched, but
Timo Sirainen <tss@iki.fi>
parents:
615
diff
changeset
|
77 i_warning("SIGHUP received - reloading configuration"); |
90a65c017bf0
SIGHUP reloads now settings. Logged in clients are left untouched, but
Timo Sirainen <tss@iki.fi>
parents:
615
diff
changeset
|
78 |
90a65c017bf0
SIGHUP reloads now settings. Logged in clients are left untouched, but
Timo Sirainen <tss@iki.fi>
parents:
615
diff
changeset
|
79 settings_read(configfile); |
90a65c017bf0
SIGHUP reloads now settings. Logged in clients are left untouched, but
Timo Sirainen <tss@iki.fi>
parents:
615
diff
changeset
|
80 |
90a65c017bf0
SIGHUP reloads now settings. Logged in clients are left untouched, but
Timo Sirainen <tss@iki.fi>
parents:
615
diff
changeset
|
81 /* restart auth and login processes */ |
90a65c017bf0
SIGHUP reloads now settings. Logged in clients are left untouched, but
Timo Sirainen <tss@iki.fi>
parents:
615
diff
changeset
|
82 login_processes_destroy_all(); |
90a65c017bf0
SIGHUP reloads now settings. Logged in clients are left untouched, but
Timo Sirainen <tss@iki.fi>
parents:
615
diff
changeset
|
83 auth_processes_destroy_all(); |
90a65c017bf0
SIGHUP reloads now settings. Logged in clients are left untouched, but
Timo Sirainen <tss@iki.fi>
parents:
615
diff
changeset
|
84 } |
90a65c017bf0
SIGHUP reloads now settings. Logged in clients are left untouched, but
Timo Sirainen <tss@iki.fi>
parents:
615
diff
changeset
|
85 |
90a65c017bf0
SIGHUP reloads now settings. Logged in clients are left untouched, but
Timo Sirainen <tss@iki.fi>
parents:
615
diff
changeset
|
86 static void timeout_handler(void *context __attr_unused__, |
90a65c017bf0
SIGHUP reloads now settings. Logged in clients are left untouched, but
Timo Sirainen <tss@iki.fi>
parents:
615
diff
changeset
|
87 Timeout timeout __attr_unused__) |
0 | 88 { |
89 const char *process_type_name; | |
90 pid_t pid; | |
91 int status, process_type; | |
92 | |
635
90a65c017bf0
SIGHUP reloads now settings. Logged in clients are left untouched, but
Timo Sirainen <tss@iki.fi>
parents:
615
diff
changeset
|
93 if (lib_signal_hup != 0) { |
90a65c017bf0
SIGHUP reloads now settings. Logged in clients are left untouched, but
Timo Sirainen <tss@iki.fi>
parents:
615
diff
changeset
|
94 settings_reload(); |
90a65c017bf0
SIGHUP reloads now settings. Logged in clients are left untouched, but
Timo Sirainen <tss@iki.fi>
parents:
615
diff
changeset
|
95 lib_signal_hup = 0; |
90a65c017bf0
SIGHUP reloads now settings. Logged in clients are left untouched, but
Timo Sirainen <tss@iki.fi>
parents:
615
diff
changeset
|
96 } |
90a65c017bf0
SIGHUP reloads now settings. Logged in clients are left untouched, but
Timo Sirainen <tss@iki.fi>
parents:
615
diff
changeset
|
97 |
0 | 98 while ((pid = waitpid(-1, &status, WNOHANG)) > 0) { |
99 /* get the type and remove from hash */ | |
100 process_type = PID_GET_PROCESS_TYPE(pid); | |
101 PID_REMOVE_PROCESS_TYPE(pid); | |
102 | |
103 if (process_type == PROCESS_TYPE_IMAP) | |
104 imap_process_destroyed(pid); | |
615
0d852af6842e
Master process generates DH/RSA parameters now and stores them into file
Timo Sirainen <tss@iki.fi>
parents:
610
diff
changeset
|
105 if (process_type == PROCESS_TYPE_SSL_PARAM) |
0d852af6842e
Master process generates DH/RSA parameters now and stores them into file
Timo Sirainen <tss@iki.fi>
parents:
610
diff
changeset
|
106 ssl_parameter_process_destroyed(pid); |
0 | 107 |
108 /* write errors to syslog */ | |
109 process_type_name = process_names[process_type]; | |
110 if (WIFEXITED(status)) { | |
111 status = WEXITSTATUS(status); | |
112 if (status != 0) { | |
615
0d852af6842e
Master process generates DH/RSA parameters now and stores them into file
Timo Sirainen <tss@iki.fi>
parents:
610
diff
changeset
|
113 login_process_abormal_exit(pid); |
0 | 114 i_error("child %d (%s) returned error %d", |
115 (int)pid, process_type_name, status); | |
116 } | |
117 } else if (WIFSIGNALED(status)) { | |
615
0d852af6842e
Master process generates DH/RSA parameters now and stores them into file
Timo Sirainen <tss@iki.fi>
parents:
610
diff
changeset
|
118 login_process_abormal_exit(pid); |
0 | 119 i_error("child %d (%s) killed with signal %d", |
120 (int)pid, process_type_name, WTERMSIG(status)); | |
121 } | |
122 } | |
123 | |
124 if (pid == -1 && errno != EINTR && errno != ECHILD) | |
125 i_warning("waitpid() failed: %m"); | |
126 } | |
127 | |
128 static IPADDR *resolve_ip(const char *name) | |
129 { | |
130 IPADDR *ip; | |
131 int ret, ips_count; | |
132 | |
36 | 133 if (name == NULL || *name == '\0') |
0 | 134 return NULL; |
135 | |
136 ret = net_gethostbyname(name, &ip, &ips_count); | |
137 if (ret != 0) | |
36 | 138 i_fatal("Can't resolve address: %s", name); |
0 | 139 |
140 if (ips_count < 1) | |
36 | 141 i_fatal("No IPs for address: %s", name); |
0 | 142 |
143 return ip; | |
144 } | |
145 | |
146 static void open_fds(void) | |
147 { | |
148 IPADDR *imap_ip, *imaps_ip; | |
149 | |
150 imap_ip = resolve_ip(set_imap_listen); | |
151 imaps_ip = resolve_ip(set_imaps_listen); | |
152 | |
153 if (imaps_ip == NULL && set_imaps_listen == NULL) | |
154 imaps_ip = imap_ip; | |
155 | |
156 null_fd = open("/dev/null", O_RDONLY); | |
157 if (null_fd == -1) | |
158 i_fatal("Can't open /dev/null: %m"); | |
159 | |
160 imap_fd = set_imap_port == 0 ? dup(null_fd) : | |
161 net_listen(imap_ip, &set_imap_port); | |
635
90a65c017bf0
SIGHUP reloads now settings. Logged in clients are left untouched, but
Timo Sirainen <tss@iki.fi>
parents:
615
diff
changeset
|
162 if (imap_fd == -1) |
468 | 163 i_fatal("listen(%d) failed: %m", set_imap_port); |
0 | 164 |
575
ba6f89be8237
Never open imaps port if we're building with SSL disabled.
Timo Sirainen <tss@iki.fi>
parents:
468
diff
changeset
|
165 #ifdef HAVE_SSL |
37
8b4c5ea7e6da
Some fixes to checking if SSL should be used.
Timo Sirainen <tss@iki.fi>
parents:
36
diff
changeset
|
166 imaps_fd = set_ssl_cert_file == NULL || *set_ssl_cert_file == '\0' || |
8b4c5ea7e6da
Some fixes to checking if SSL should be used.
Timo Sirainen <tss@iki.fi>
parents:
36
diff
changeset
|
167 set_ssl_key_file == NULL || *set_ssl_key_file == '\0' || |
0 | 168 set_imaps_port == 0 ? dup(null_fd) : |
169 net_listen(imaps_ip, &set_imaps_port); | |
575
ba6f89be8237
Never open imaps port if we're building with SSL disabled.
Timo Sirainen <tss@iki.fi>
parents:
468
diff
changeset
|
170 #else |
ba6f89be8237
Never open imaps port if we're building with SSL disabled.
Timo Sirainen <tss@iki.fi>
parents:
468
diff
changeset
|
171 imaps_fd = dup(null_fd); |
ba6f89be8237
Never open imaps port if we're building with SSL disabled.
Timo Sirainen <tss@iki.fi>
parents:
468
diff
changeset
|
172 #endif |
635
90a65c017bf0
SIGHUP reloads now settings. Logged in clients are left untouched, but
Timo Sirainen <tss@iki.fi>
parents:
615
diff
changeset
|
173 if (imaps_fd == -1) |
0 | 174 i_fatal("listen(%d) failed: %m", set_imaps_port); |
175 } | |
176 | |
50
d493b9cc265e
Introduced uoff_t which is the unsigned-equilevant of off_t. This was needed
Timo Sirainen <tss@iki.fi>
parents:
37
diff
changeset
|
177 static void main_init(void) |
0 | 178 { |
179 lib_init_signals(sig_quit); | |
180 | |
181 /* deny file access from everyone else except owner */ | |
182 (void)umask(0077); | |
183 | |
35
b420373f88f6
Added log_path and log_timestamp settings to config file. Removed -l command
Timo Sirainen <tss@iki.fi>
parents:
10
diff
changeset
|
184 if (set_log_path == NULL) { |
0 | 185 openlog("imap-master", LOG_NDELAY, LOG_MAIL); |
186 | |
187 i_set_panic_handler(i_syslog_panic_handler); | |
188 i_set_fatal_handler(i_syslog_fatal_handler); | |
189 i_set_error_handler(i_syslog_error_handler); | |
190 i_set_warning_handler(i_syslog_warning_handler); | |
191 } else { | |
192 /* log failures into specified log file */ | |
35
b420373f88f6
Added log_path and log_timestamp settings to config file. Removed -l command
Timo Sirainen <tss@iki.fi>
parents:
10
diff
changeset
|
193 i_set_failure_file(set_log_path, "imap-master"); |
b420373f88f6
Added log_path and log_timestamp settings to config file. Removed -l command
Timo Sirainen <tss@iki.fi>
parents:
10
diff
changeset
|
194 i_set_failure_timestamp_format(set_log_timestamp); |
0 | 195 } |
196 | |
197 pids = hash_create(default_pool, 128, NULL, NULL); | |
635
90a65c017bf0
SIGHUP reloads now settings. Logged in clients are left untouched, but
Timo Sirainen <tss@iki.fi>
parents:
615
diff
changeset
|
198 to = timeout_add(100, timeout_handler, NULL); |
0 | 199 |
615
0d852af6842e
Master process generates DH/RSA parameters now and stores them into file
Timo Sirainen <tss@iki.fi>
parents:
610
diff
changeset
|
200 ssl_init(); |
0 | 201 auth_processes_init(); |
202 login_processes_init(); | |
203 } | |
204 | |
205 static void main_deinit(void) | |
206 { | |
207 if (lib_signal_kill != 0) | |
208 i_warning("Killed with signal %d", lib_signal_kill); | |
209 | |
210 login_processes_deinit(); | |
211 auth_processes_deinit(); | |
615
0d852af6842e
Master process generates DH/RSA parameters now and stores them into file
Timo Sirainen <tss@iki.fi>
parents:
610
diff
changeset
|
212 ssl_deinit(); |
0 | 213 |
635
90a65c017bf0
SIGHUP reloads now settings. Logged in clients are left untouched, but
Timo Sirainen <tss@iki.fi>
parents:
615
diff
changeset
|
214 timeout_remove(to); |
0 | 215 |
216 (void)close(null_fd); | |
217 (void)close(imap_fd); | |
218 (void)close(imaps_fd); | |
219 | |
220 hash_destroy(pids); | |
221 closelog(); | |
222 } | |
223 | |
224 static void daemonize(void) | |
225 { | |
226 pid_t pid; | |
227 | |
228 pid = fork(); | |
229 if (pid < 0) | |
230 i_fatal("fork() failed: %m"); | |
231 | |
232 if (pid != 0) | |
233 _exit(0); | |
610 | 234 |
235 setsid(); | |
0 | 236 } |
237 | |
279
49f4b0be0d87
Print usage with invalid parameters.
Timo Sirainen <tss@iki.fi>
parents:
50
diff
changeset
|
238 static void print_help(void) |
49f4b0be0d87
Print usage with invalid parameters.
Timo Sirainen <tss@iki.fi>
parents:
50
diff
changeset
|
239 { |
49f4b0be0d87
Print usage with invalid parameters.
Timo Sirainen <tss@iki.fi>
parents:
50
diff
changeset
|
240 printf("Usage: imap-master [-F] [-c <config file>]\n"); |
49f4b0be0d87
Print usage with invalid parameters.
Timo Sirainen <tss@iki.fi>
parents:
50
diff
changeset
|
241 } |
49f4b0be0d87
Print usage with invalid parameters.
Timo Sirainen <tss@iki.fi>
parents:
50
diff
changeset
|
242 |
0 | 243 int main(int argc, char *argv[]) |
244 { | |
245 /* parse arguments */ | |
246 int foreground = FALSE; | |
247 int i; | |
248 | |
249 lib_init(); | |
250 | |
251 for (i = 1; i < argc; i++) { | |
252 if (strcmp(argv[i], "-F") == 0) { | |
253 /* foreground */ | |
254 foreground = TRUE; | |
255 } else if (strcmp(argv[i], "-c") == 0) { | |
256 /* config file */ | |
257 i++; | |
258 if (i == argc) i_fatal("Missing config file argument"); | |
259 configfile = argv[i]; | |
260 } else { | |
279
49f4b0be0d87
Print usage with invalid parameters.
Timo Sirainen <tss@iki.fi>
parents:
50
diff
changeset
|
261 print_help(); |
0 | 262 i_fatal("Unknown argument: %s", argv[1]); |
263 } | |
264 } | |
265 | |
266 /* read and verify settings before forking */ | |
635
90a65c017bf0
SIGHUP reloads now settings. Logged in clients are left untouched, but
Timo Sirainen <tss@iki.fi>
parents:
615
diff
changeset
|
267 settings_init(); |
0 | 268 settings_read(configfile); |
269 open_fds(); | |
270 | |
271 if (!foreground) | |
272 daemonize(); | |
273 | |
389
60040a9d243f
ioloop_create() takes now pool-parameter. io_buffer_create_mmaped() takes
Timo Sirainen <tss@iki.fi>
parents:
279
diff
changeset
|
274 ioloop = io_loop_create(system_pool); |
0 | 275 |
35
b420373f88f6
Added log_path and log_timestamp settings to config file. Removed -l command
Timo Sirainen <tss@iki.fi>
parents:
10
diff
changeset
|
276 main_init(); |
0 | 277 io_loop_run(ioloop); |
278 main_deinit(); | |
279 | |
280 io_loop_destroy(ioloop); | |
281 lib_deinit(); | |
282 | |
283 return 0; | |
284 } |