* TODO, NEWS: Update.
* mailbox/msrv.c: New file. * mailbox/Makefile.am: Add msrv.c. * include/mailutils/server.h (mu_tcp_server_conn_fp): Take sockaddr as argument (mu_tcp_server_create,mu_tcp_server_get_sockaddr): Likewise. (mu_m_server_*): New prototypes. * include/mailutils/types.hin (mu_m_server_t): New type. * mailbox/acl.c: Fix debugging output. (mu_sockaddr_to_str, mu_sockaddr_to_astr): New functions. * mailbox/tcpsrv.c: Handle AF_INET and AF_UNIX sockets. * examples/echosrv.c: Update mu_tcp_server_* calls. * examples/config/Makefile.am: Remove comsat.conf and mailutils.rc. * imap4d/imap4d.c, imap4d/imap4d.h, imap4d/signal.c, maidag/lmtp.c, maidag/maidag.c, maidag/maidag.h, pop3d/extra.c, pop3d/pop3d.c, pop3d/pop3d.h, pop3d/signal.c: Rewrite using m-server. * include/mailutils/cfg.h (mu_offsetof): Bug fix. * mailbox/cfg_driver.c (dup_container): Bugfix. Offset was not copied. (mu_cfg_section_add_params): If identifier starts with a dot, it is hidden, i.e. its substatements are copied directly into the parent structure. * mailbox/cfg_lexer.c (isword): Take care of opening braces. (default_lexer): Several fixes. * mailbox/cfg_parser.y (mu_cfg_parse): Initialize debugging level from global settings. (_scan_tree_helper): Ensure debugging object has correct locus information before calling the section parser. (mu_cfg_scan_tree): If no debugging object is supplied, use the one from diag.c * mailbox/daemon.c (mu_daemon_create_pidfile): Return a meaningful error code. * mailbox/debug.c (mu_debug_create): Initialize printer to NULL. (mu_debug_vprintf): If printer is NULL, use mu_debug_default_printer. (mu_debug_check_level): Bugfix. * mailbox/server.c: Minor indentation fix. * mailbox/syslog.c (mu_diag_syslog_printer): Chop off \r as well. * mailbox/folder.c (mu_folder_create_from_record): Bugfixes. * include/mailutils/debug.hm4 (mu_sockaddr_to_str) (mu_sockaddr_to_astr): New functions. * include/mailutils/.cvsignore: Add debug.h * po/POTFILES.in: Update.
Showing
4 changed files
with
174 additions
and
303 deletions
1 | /* GNU Mailutils -- a suite of utilities for electronic mail | 1 | /* GNU Mailutils -- a suite of utilities for electronic mail |
2 | Copyright (C) 1999, 2001, 2002, 2003, 2005, | 2 | Copyright (C) 1999, 2001, 2002, 2003, 2005, |
3 | 2007 Free Software Foundation, Inc. | 3 | 2007, 2008 Free Software Foundation, Inc. |
4 | 4 | ||
5 | GNU Mailutils is free software; you can redistribute it and/or modify | 5 | GNU Mailutils is free software; you can redistribute it and/or modify |
6 | it under the terms of the GNU General Public License as published by | 6 | it under the terms of the GNU General Public License as published by |
... | @@ -202,6 +202,22 @@ pop3d_is_master () | ... | @@ -202,6 +202,22 @@ pop3d_is_master () |
202 | return ostream == NULL; | 202 | return ostream == NULL; |
203 | } | 203 | } |
204 | 204 | ||
205 | static void | ||
206 | transcript (const char *pfx, const char *buf) | ||
207 | { | ||
208 | if (pop3d_transcript) | ||
209 | { | ||
210 | int len = strlen (buf); | ||
211 | if (len > 0 && buf[len-1] == '\n') | ||
212 | { | ||
213 | len--; | ||
214 | if (len > 0 && buf[len-1] == '\r') | ||
215 | len--; | ||
216 | } | ||
217 | mu_diag_output (MU_DIAG_DEBUG, "%s: %-.*s", pfx, len, buf); | ||
218 | } | ||
219 | } | ||
220 | |||
205 | void | 221 | void |
206 | pop3d_outf (const char *fmt, ...) | 222 | pop3d_outf (const char *fmt, ...) |
207 | { | 223 | { |
... | @@ -216,8 +232,7 @@ pop3d_outf (const char *fmt, ...) | ... | @@ -216,8 +232,7 @@ pop3d_outf (const char *fmt, ...) |
216 | if (!buf) | 232 | if (!buf) |
217 | pop3d_abquit (ERR_NO_MEM); | 233 | pop3d_abquit (ERR_NO_MEM); |
218 | 234 | ||
219 | if (mu_gocs_daemon.transcript) | 235 | transcript ("sent", buf); |
220 | mu_diag_output (MU_DIAG_DEBUG, "sent: %s", buf); | ||
221 | 236 | ||
222 | rc = mu_stream_sequential_write (ostream, buf, strlen (buf)); | 237 | rc = mu_stream_sequential_write (ostream, buf, strlen (buf)); |
223 | free (buf); | 238 | free (buf); |
... | @@ -232,7 +247,6 @@ pop3d_outf (const char *fmt, ...) | ... | @@ -232,7 +247,6 @@ pop3d_outf (const char *fmt, ...) |
232 | } | 247 | } |
233 | } | 248 | } |
234 | 249 | ||
235 | |||
236 | /* Gets a line of input from the client, caller should free() */ | 250 | /* Gets a line of input from the client, caller should free() */ |
237 | char * | 251 | char * |
238 | pop3d_readline (char *buffer, size_t size) | 252 | pop3d_readline (char *buffer, size_t size) |
... | @@ -240,7 +254,7 @@ pop3d_readline (char *buffer, size_t size) | ... | @@ -240,7 +254,7 @@ pop3d_readline (char *buffer, size_t size) |
240 | int rc; | 254 | int rc; |
241 | size_t nbytes; | 255 | size_t nbytes; |
242 | 256 | ||
243 | alarm (mu_gocs_daemon.timeout); | 257 | alarm (idle_timeout); |
244 | rc = mu_stream_sequential_readline (istream, buffer, size, &nbytes); | 258 | rc = mu_stream_sequential_readline (istream, buffer, size, &nbytes); |
245 | alarm (0); | 259 | alarm (0); |
246 | 260 | ||
... | @@ -259,8 +273,7 @@ pop3d_readline (char *buffer, size_t size) | ... | @@ -259,8 +273,7 @@ pop3d_readline (char *buffer, size_t size) |
259 | pop3d_abquit (ERR_NO_OFILE); | 273 | pop3d_abquit (ERR_NO_OFILE); |
260 | } | 274 | } |
261 | 275 | ||
262 | if (mu_gocs_daemon.transcript) | 276 | transcript ("recv", buffer); |
263 | mu_diag_output (MU_DIAG_DEBUG, "recv: %s", buffer); | ||
264 | 277 | ||
265 | /* Caller should not free () this ... should we strdup() then? */ | 278 | /* Caller should not free () this ... should we strdup() then? */ |
266 | return buffer; | 279 | return buffer; | ... | ... |
1 | /* GNU Mailutils -- a suite of utilities for electronic mail | 1 | /* GNU Mailutils -- a suite of utilities for electronic mail |
2 | Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, | 2 | Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, |
3 | 2005, 2007 Free Software Foundation, Inc. | 3 | 2005, 2007, 2008 Free Software Foundation, Inc. |
4 | 4 | ||
5 | GNU Mailutils is free software; you can redistribute it and/or modify | 5 | GNU Mailutils is free software; you can redistribute it and/or modify |
6 | it under the terms of the GNU General Public License as published by | 6 | it under the terms of the GNU General Public License as published by |
... | @@ -27,15 +27,9 @@ int state; | ... | @@ -27,15 +27,9 @@ int state; |
27 | char *username; | 27 | char *username; |
28 | char *md5shared; | 28 | char *md5shared; |
29 | 29 | ||
30 | struct mu_gocs_daemon default_gocs_daemon = { | 30 | mu_m_server_t server; |
31 | MODE_INTERACTIVE, /* Start in interactive (inetd) mode */ | 31 | unsigned int idle_timeout; |
32 | 20, /* Default maximum number of children */ | 32 | int pop3d_transcript; |
33 | 110, /* Standard POP3 port */ | ||
34 | 600, /* Idle timeout */ | ||
35 | 0, /* No transcript by default */ | ||
36 | NULL /* No PID file by default */ | ||
37 | }; | ||
38 | |||
39 | int debug_mode; | 33 | int debug_mode; |
40 | 34 | ||
41 | #ifdef WITH_TLS | 35 | #ifdef WITH_TLS |
... | @@ -45,8 +39,6 @@ int tls_done; | ... | @@ -45,8 +39,6 @@ int tls_done; |
45 | 39 | ||
46 | int initial_state = AUTHORIZATION; | 40 | int initial_state = AUTHORIZATION; |
47 | 41 | ||
48 | /* Number of child processes. */ | ||
49 | size_t children; | ||
50 | /* Should all the messages be undeleted on startup */ | 42 | /* Should all the messages be undeleted on startup */ |
51 | int undelete_on_startup; | 43 | int undelete_on_startup; |
52 | #ifdef ENABLE_LOGIN_DELAY | 44 | #ifdef ENABLE_LOGIN_DELAY |
... | @@ -58,11 +50,6 @@ char *login_stat_file = LOGIN_STAT_FILE; | ... | @@ -58,11 +50,6 @@ char *login_stat_file = LOGIN_STAT_FILE; |
58 | unsigned expire = EXPIRE_NEVER; /* Expire messages after this number of days */ | 50 | unsigned expire = EXPIRE_NEVER; /* Expire messages after this number of days */ |
59 | int expire_on_exit = 0; /* Delete expired messages on exit */ | 51 | int expire_on_exit = 0; /* Delete expired messages on exit */ |
60 | 52 | ||
61 | mu_acl_t pop3d_acl; | ||
62 | |||
63 | static int pop3d_mainloop (int fd, FILE *, FILE *); | ||
64 | static void pop3d_daemon_init (void); | ||
65 | static void pop3d_daemon (unsigned int, unsigned int); | ||
66 | static error_t pop3d_parse_opt (int key, char *arg, struct argp_state *astate); | 53 | static error_t pop3d_parse_opt (int key, char *arg, struct argp_state *astate); |
67 | 54 | ||
68 | const char *program_version = "pop3d (" PACKAGE_STRING ")"; | 55 | const char *program_version = "pop3d (" PACKAGE_STRING ")"; |
... | @@ -75,9 +62,17 @@ static char doc[] = N_("GNU pop3d -- the POP3 daemon"); | ... | @@ -75,9 +62,17 @@ static char doc[] = N_("GNU pop3d -- the POP3 daemon"); |
75 | #define OPT_TLS_REQUIRED 261 | 62 | #define OPT_TLS_REQUIRED 261 |
76 | #define OPT_BULLETIN_SOURCE 262 | 63 | #define OPT_BULLETIN_SOURCE 262 |
77 | #define OPT_BULLETIN_DB 263 | 64 | #define OPT_BULLETIN_DB 263 |
65 | #define OPT_FOREGROUND 264 | ||
78 | 66 | ||
79 | static struct argp_option options[] = { | 67 | static struct argp_option options[] = { |
80 | #define GRP 0 | 68 | #define GRP 0 |
69 | { "foreground", OPT_FOREGROUND, 0, 0, N_("Remain in foreground."), GRP+1}, | ||
70 | { "inetd", 'i', 0, 0, N_("Run in inetd mode"), GRP+1}, | ||
71 | { "daemon", 'd', N_("NUMBER"), OPTION_ARG_OPTIONAL, | ||
72 | N_("Runs in daemon mode with a maximum of NUMBER children"), GRP+1 }, | ||
73 | #undef GRP | ||
74 | |||
75 | #define GRP 5 | ||
81 | {"undelete", 'u', NULL, OPTION_HIDDEN, | 76 | {"undelete", 'u', NULL, OPTION_HIDDEN, |
82 | N_("Undelete all messages on startup"), GRP+1}, | 77 | N_("Undelete all messages on startup"), GRP+1}, |
83 | {"expire", OPT_EXPIRE, N_("DAYS"), OPTION_HIDDEN, | 78 | {"expire", OPT_EXPIRE, N_("DAYS"), OPTION_HIDDEN, |
... | @@ -161,7 +156,8 @@ static struct mu_cfg_param pop3d_cfg_param[] = { | ... | @@ -161,7 +156,8 @@ static struct mu_cfg_param pop3d_cfg_param[] = { |
161 | N_("Set the bulletin database file name."), | 156 | N_("Set the bulletin database file name."), |
162 | N_("file") }, | 157 | N_("file") }, |
163 | #endif | 158 | #endif |
164 | { "acl", mu_cfg_section, }, | 159 | { ".server", mu_cfg_section, NULL, 0, NULL, |
160 | N_("Server configuration.") }, | ||
165 | TCP_WRAPPERS_CONFIG | 161 | TCP_WRAPPERS_CONFIG |
166 | { NULL } | 162 | { NULL } |
167 | }; | 163 | }; |
... | @@ -176,7 +172,6 @@ static struct argp argp = { | ... | @@ -176,7 +172,6 @@ static struct argp argp = { |
176 | }; | 172 | }; |
177 | 173 | ||
178 | static const char *pop3d_argp_capa[] = { | 174 | static const char *pop3d_argp_capa[] = { |
179 | "daemon", | ||
180 | "auth", | 175 | "auth", |
181 | "common", | 176 | "common", |
182 | "debug", | 177 | "debug", |
... | @@ -194,6 +189,20 @@ pop3d_parse_opt (int key, char *arg, struct argp_state *astate) | ... | @@ -194,6 +189,20 @@ pop3d_parse_opt (int key, char *arg, struct argp_state *astate) |
194 | 189 | ||
195 | switch (key) | 190 | switch (key) |
196 | { | 191 | { |
192 | case 'd': | ||
193 | mu_argp_node_list_new (&lst, "mode", "daemon"); | ||
194 | if (arg) | ||
195 | mu_argp_node_list_new (&lst, "max-children", arg); | ||
196 | break; | ||
197 | |||
198 | case 'i': | ||
199 | mu_argp_node_list_new (&lst, "mode", "inetd"); | ||
200 | break; | ||
201 | |||
202 | case OPT_FOREGROUND: | ||
203 | mu_argp_node_list_new (&lst, "foreground", "yes"); | ||
204 | break; | ||
205 | |||
197 | case 'u': | 206 | case 'u': |
198 | mu_argp_node_list_new (&lst, "undelete", "yes"); | 207 | mu_argp_node_list_new (&lst, "undelete", "yes"); |
199 | break; | 208 | break; |
... | @@ -246,153 +255,6 @@ pop3d_parse_opt (int key, char *arg, struct argp_state *astate) | ... | @@ -246,153 +255,6 @@ pop3d_parse_opt (int key, char *arg, struct argp_state *astate) |
246 | return 0; | 255 | return 0; |
247 | } | 256 | } |
248 | 257 | ||
249 | |||
250 | int | ||
251 | main (int argc, char **argv) | ||
252 | { | ||
253 | struct group *gr; | ||
254 | int status = OK; | ||
255 | |||
256 | /* Native Language Support */ | ||
257 | mu_init_nls (); | ||
258 | |||
259 | MU_AUTH_REGISTER_ALL_MODULES(); | ||
260 | /* Register the desired formats. */ | ||
261 | mu_register_local_mbox_formats (); | ||
262 | |||
263 | #ifdef WITH_TLS | ||
264 | mu_gocs_register ("tls", mu_tls_module_init); | ||
265 | #endif /* WITH_TLS */ | ||
266 | mu_tcpwrapper_cfg_init (); | ||
267 | mu_acl_cfg_init (); | ||
268 | |||
269 | mu_gocs_daemon = default_gocs_daemon; | ||
270 | mu_argp_init (program_version, NULL); | ||
271 | if (mu_app_init (&argp, pop3d_argp_capa, pop3d_cfg_param, | ||
272 | argc, argv, 0, NULL, &pop3d_acl)) | ||
273 | exit (1); | ||
274 | |||
275 | if (expire == 0) | ||
276 | expire_on_exit = 1; | ||
277 | |||
278 | #ifdef USE_LIBPAM | ||
279 | if (!mu_pam_service) | ||
280 | mu_pam_service = "gnu-pop3d"; | ||
281 | #endif | ||
282 | |||
283 | if (mu_gocs_daemon.mode == MODE_INTERACTIVE && isatty (0)) | ||
284 | { | ||
285 | /* If input is a tty, switch to debug mode */ | ||
286 | debug_mode = 1; | ||
287 | } | ||
288 | else | ||
289 | { | ||
290 | gr = getgrnam ("mail"); | ||
291 | if (gr == NULL) | ||
292 | { | ||
293 | perror (_("Error getting mail group")); | ||
294 | exit (EXIT_FAILURE); | ||
295 | } | ||
296 | |||
297 | if (setgid (gr->gr_gid) == -1) | ||
298 | { | ||
299 | perror (_("Error setting mail group")); | ||
300 | exit (EXIT_FAILURE); | ||
301 | } | ||
302 | } | ||
303 | |||
304 | /* Set the signal handlers. */ | ||
305 | signal (SIGINT, pop3d_signal); | ||
306 | signal (SIGQUIT, pop3d_signal); | ||
307 | signal (SIGILL, pop3d_signal); | ||
308 | signal (SIGBUS, pop3d_signal); | ||
309 | signal (SIGFPE, pop3d_signal); | ||
310 | signal (SIGSEGV, pop3d_signal); | ||
311 | signal (SIGTERM, pop3d_signal); | ||
312 | signal (SIGSTOP, pop3d_signal); | ||
313 | signal (SIGPIPE, pop3d_signal); | ||
314 | signal (SIGABRT, pop3d_signal); | ||
315 | |||
316 | if (mu_gocs_daemon.mode == MODE_DAEMON) | ||
317 | pop3d_daemon_init (); | ||
318 | else | ||
319 | { | ||
320 | /* Make sure we are in the root directory. */ | ||
321 | chdir ("/"); | ||
322 | } | ||
323 | |||
324 | /* Set up for syslog. */ | ||
325 | openlog ("gnu-pop3d", LOG_PID, log_facility); | ||
326 | /* Redirect any stdout error from the library to syslog, they | ||
327 | should not go to the client. */ | ||
328 | { | ||
329 | mu_debug_t debug; | ||
330 | |||
331 | mu_diag_get_debug (&debug); | ||
332 | mu_debug_set_print (debug, mu_diag_syslog_printer, NULL); | ||
333 | |||
334 | /* FIXME: this should be done automatically by cfg */ | ||
335 | if (pop3d_acl) | ||
336 | { | ||
337 | mu_acl_get_debug (pop3d_acl, &debug); | ||
338 | mu_debug_set_print (debug, mu_debug_syslog_printer, NULL); | ||
339 | } | ||
340 | } | ||
341 | |||
342 | umask (S_IROTH | S_IWOTH | S_IXOTH); /* 007 */ | ||
343 | |||
344 | if (mu_gocs_daemon.pidfile) | ||
345 | { | ||
346 | mu_daemon_create_pidfile (mu_gocs_daemon.pidfile); | ||
347 | } | ||
348 | |||
349 | /* Check TLS environment, i.e. cert and key files */ | ||
350 | #ifdef WITH_TLS | ||
351 | tls_available = mu_check_tls_environment (); | ||
352 | if (tls_available) | ||
353 | tls_available = mu_init_tls_libs (); | ||
354 | #endif /* WITH_TLS */ | ||
355 | |||
356 | /* Actually run the daemon. */ | ||
357 | if (mu_gocs_daemon.mode == MODE_DAEMON) | ||
358 | pop3d_daemon (mu_gocs_daemon.maxchildren, mu_gocs_daemon.port); | ||
359 | /* exit (EXIT_SUCCESS) -- no way out of daemon except a signal. */ | ||
360 | else | ||
361 | status = pop3d_mainloop (fileno (stdin), stdin, stdout); | ||
362 | |||
363 | /* Close the syslog connection and exit. */ | ||
364 | closelog (); | ||
365 | return (OK != status); | ||
366 | } | ||
367 | |||
368 | /* Sets things up for daemon mode. */ | ||
369 | static void | ||
370 | pop3d_daemon_init (void) | ||
371 | { | ||
372 | extern int daemon (int, int); | ||
373 | |||
374 | /* Become a daemon. Take care to close inherited fds and to hold | ||
375 | first three one, in, out, err */ | ||
376 | if (daemon (0, 0) < 0) | ||
377 | { | ||
378 | perror (_("Failed to become a daemon:")); | ||
379 | exit (EXIT_FAILURE); | ||
380 | } | ||
381 | |||
382 | /* SIGCHLD is not ignore but rather use to do some simple load balancing. */ | ||
383 | #ifdef HAVE_SIGACTION | ||
384 | { | ||
385 | struct sigaction act; | ||
386 | act.sa_handler = pop3d_sigchld; | ||
387 | sigemptyset (&act.sa_mask); | ||
388 | act.sa_flags = 0; | ||
389 | sigaction (SIGCHLD, &act, NULL); | ||
390 | } | ||
391 | #else | ||
392 | signal (SIGCHLD, pop3d_sigchld); | ||
393 | #endif | ||
394 | } | ||
395 | |||
396 | int | 258 | int |
397 | pop3d_get_client_address (int fd, struct sockaddr_in *pcs) | 259 | pop3d_get_client_address (int fd, struct sockaddr_in *pcs) |
398 | { | 260 | { |
... | @@ -424,7 +286,7 @@ pop3d_get_client_address (int fd, struct sockaddr_in *pcs) | ... | @@ -424,7 +286,7 @@ pop3d_get_client_address (int fd, struct sockaddr_in *pcs) |
424 | fd -- socket descriptor (for diagnostics) | 286 | fd -- socket descriptor (for diagnostics) |
425 | infile -- input stream | 287 | infile -- input stream |
426 | outfile -- output stream */ | 288 | outfile -- output stream */ |
427 | static int | 289 | int |
428 | pop3d_mainloop (int fd, FILE *infile, FILE *outfile) | 290 | pop3d_mainloop (int fd, FILE *infile, FILE *outfile) |
429 | { | 291 | { |
430 | int status = OK; | 292 | int status = OK; |
... | @@ -433,44 +295,13 @@ pop3d_mainloop (int fd, FILE *infile, FILE *outfile) | ... | @@ -433,44 +295,13 @@ pop3d_mainloop (int fd, FILE *infile, FILE *outfile) |
433 | 295 | ||
434 | if (pop3d_get_client_address (fd, &cs) == 0) | 296 | if (pop3d_get_client_address (fd, &cs) == 0) |
435 | { | 297 | { |
436 | if (pop3d_acl) | ||
437 | { | ||
438 | mu_acl_result_t res; | ||
439 | int rc = mu_acl_check_sockaddr (pop3d_acl, | ||
440 | (struct sockaddr*) &cs, | ||
441 | sizeof (cs), | ||
442 | &res); | ||
443 | if (rc) | ||
444 | { | ||
445 | mu_error (_("Access from %s blocked: cannot check ACLs: %s"), | ||
446 | inet_ntoa (cs.sin_addr), mu_strerror (rc)); | ||
447 | return 1; | ||
448 | } | ||
449 | switch (res) | ||
450 | { | ||
451 | case mu_acl_result_undefined: | ||
452 | mu_diag_output (MU_DIAG_INFO, | ||
453 | _("%s: undefined ACL result; access allowed"), | ||
454 | inet_ntoa (cs.sin_addr)); | ||
455 | break; | ||
456 | |||
457 | case mu_acl_result_accept: | ||
458 | break; | ||
459 | |||
460 | case mu_acl_result_deny: | ||
461 | mu_error (_("Access from %s blocked."), | ||
462 | inet_ntoa (cs.sin_addr)); | ||
463 | return 1; | ||
464 | } | ||
465 | } | ||
466 | |||
467 | if (!mu_tcpwrapper_access (fd)) | 298 | if (!mu_tcpwrapper_access (fd)) |
468 | { | 299 | { |
469 | mu_error (_("Access from %s blocked."), inet_ntoa (cs.sin_addr)); | 300 | mu_error (_("Access from %s blocked."), inet_ntoa (cs.sin_addr)); |
470 | return 1; | 301 | return 1; |
471 | } | 302 | } |
472 | } | 303 | } |
473 | else if (!debug_mode && (mu_tcp_wrapper_enable || pop3d_acl)) | 304 | else if (!debug_mode && mu_tcp_wrapper_enable) |
474 | { | 305 | { |
475 | mu_error (_("Rejecting connection from unknown address")); | 306 | mu_error (_("Rejecting connection from unknown address")); |
476 | return 1; | 307 | return 1; |
... | @@ -630,85 +461,131 @@ pop3d_mainloop (int fd, FILE *infile, FILE *outfile) | ... | @@ -630,85 +461,131 @@ pop3d_mainloop (int fd, FILE *infile, FILE *outfile) |
630 | return (status != OK); | 461 | return (status != OK); |
631 | } | 462 | } |
632 | 463 | ||
633 | /* Runs GNU POP3 in standalone daemon mode. This opens and binds to a port | 464 | int |
634 | (default 110) then executes a pop3d_mainloop() upon accepting a connection. | 465 | pop3d_connection (int fd, void *data, time_t timeout, int transcript) |
635 | It starts maxchildren child processes to listen to and accept socket | 466 | { |
636 | connections. */ | 467 | idle_timeout = timeout; |
637 | static void | 468 | pop3d_transcript = transcript; |
638 | pop3d_daemon (unsigned int maxchildren, unsigned int port) | 469 | pop3d_mainloop (fd, fdopen (fd, "r"), fdopen (fd, "w")); |
470 | return 0; | ||
471 | } | ||
472 | |||
473 | int | ||
474 | main (int argc, char **argv) | ||
639 | { | 475 | { |
640 | struct sockaddr_in server, client; | 476 | struct group *gr; |
641 | pid_t pid; | 477 | int status = OK; |
642 | int listenfd, connfd; | ||
643 | size_t size; | ||
644 | 478 | ||
645 | listenfd = socket (PF_INET, SOCK_STREAM, 0); | 479 | /* Native Language Support */ |
646 | if (listenfd == -1) | 480 | mu_init_nls (); |
481 | |||
482 | MU_AUTH_REGISTER_ALL_MODULES(); | ||
483 | /* Register the desired formats. */ | ||
484 | mu_register_local_mbox_formats (); | ||
485 | |||
486 | #ifdef WITH_TLS | ||
487 | mu_gocs_register ("tls", mu_tls_module_init); | ||
488 | #endif /* WITH_TLS */ | ||
489 | mu_tcpwrapper_cfg_init (); | ||
490 | mu_acl_cfg_init (); | ||
491 | mu_m_server_cfg_init (); | ||
492 | |||
493 | mu_argp_init (program_version, NULL); | ||
494 | |||
495 | mu_m_server_create (&server, "GNU pop3d"); | ||
496 | mu_m_server_set_conn (server, pop3d_connection); | ||
497 | mu_m_server_set_mode (server, MODE_INTERACTIVE); | ||
498 | mu_m_server_set_max_children (server, 20); | ||
499 | /* FIXME mu_m_server_set_pidfile (); */ | ||
500 | mu_m_server_set_default_port (server, 110); | ||
501 | mu_m_server_set_timeout (server, 600); | ||
502 | |||
503 | if (mu_app_init (&argp, pop3d_argp_capa, pop3d_cfg_param, | ||
504 | argc, argv, 0, NULL, server)) | ||
505 | exit (1); | ||
506 | |||
507 | if (expire == 0) | ||
508 | expire_on_exit = 1; | ||
509 | |||
510 | #ifdef USE_LIBPAM | ||
511 | if (!mu_pam_service) | ||
512 | mu_pam_service = "gnu-pop3d"; | ||
513 | #endif | ||
514 | |||
515 | if (mu_m_server_mode (server) == MODE_INTERACTIVE && isatty (0)) | ||
647 | { | 516 | { |
648 | mu_diag_output (MU_DIAG_ERROR, "socket: %s", strerror(errno)); | 517 | /* If input is a tty, switch to debug mode */ |
649 | exit (EXIT_FAILURE); | 518 | debug_mode = 1; |
650 | } | 519 | } |
651 | size = 1; /* Use size here to avoid making a new variable. */ | 520 | else |
652 | setsockopt (listenfd, SOL_SOCKET, SO_REUSEADDR, &size, sizeof(size)); | ||
653 | size = sizeof (server); | ||
654 | memset (&server, 0, size); | ||
655 | server.sin_family = AF_INET; | ||
656 | server.sin_addr.s_addr = htonl (INADDR_ANY); | ||
657 | server.sin_port = htons (port); | ||
658 | |||
659 | if (bind (listenfd, (struct sockaddr *)&server, size) == -1) | ||
660 | { | 521 | { |
661 | mu_diag_output (MU_DIAG_ERROR, "bind: %s", strerror (errno)); | 522 | gr = getgrnam ("mail"); |
662 | exit (EXIT_FAILURE); | 523 | if (gr == NULL) |
663 | } | 524 | { |
525 | perror (_("Error getting mail group")); | ||
526 | exit (EXIT_FAILURE); | ||
527 | } | ||
664 | 528 | ||
665 | if (listen (listenfd, 128) == -1) | 529 | if (setgid (gr->gr_gid) == -1) |
666 | { | 530 | { |
667 | mu_diag_output (MU_DIAG_ERROR, "listen: %s", strerror (errno)); | 531 | perror (_("Error setting mail group")); |
668 | exit (EXIT_FAILURE); | 532 | exit (EXIT_FAILURE); |
533 | } | ||
669 | } | 534 | } |
670 | 535 | ||
671 | mu_diag_output (MU_DIAG_INFO, _("GNU pop3d started")); | 536 | /* Set the signal handlers. */ |
537 | signal (SIGINT, pop3d_signal); | ||
538 | signal (SIGQUIT, pop3d_signal); | ||
539 | signal (SIGILL, pop3d_signal); | ||
540 | signal (SIGBUS, pop3d_signal); | ||
541 | signal (SIGFPE, pop3d_signal); | ||
542 | signal (SIGSEGV, pop3d_signal); | ||
543 | signal (SIGTERM, pop3d_signal); | ||
544 | signal (SIGSTOP, pop3d_signal); | ||
545 | signal (SIGPIPE, pop3d_signal); | ||
546 | signal (SIGABRT, pop3d_signal); | ||
672 | 547 | ||
673 | for (;;) | 548 | /* Set up for syslog. */ |
549 | openlog ("gnu-pop3d", LOG_PID, log_facility); | ||
550 | /* Redirect any stdout error from the library to syslog, they | ||
551 | should not go to the client. */ | ||
552 | { | ||
553 | mu_debug_t debug; | ||
554 | |||
555 | mu_diag_get_debug (&debug); | ||
556 | mu_debug_set_print (debug, mu_diag_syslog_printer, NULL); | ||
557 | |||
558 | mu_debug_default_printer = mu_debug_syslog_printer; | ||
559 | } | ||
560 | |||
561 | umask (S_IROTH | S_IWOTH | S_IXOTH); /* 007 */ | ||
562 | |||
563 | /* Check TLS environment, i.e. cert and key files */ | ||
564 | #ifdef WITH_TLS | ||
565 | tls_available = mu_check_tls_environment (); | ||
566 | if (tls_available) | ||
567 | tls_available = mu_init_tls_libs (); | ||
568 | #endif /* WITH_TLS */ | ||
569 | |||
570 | /* Actually run the daemon. */ | ||
571 | if (mu_m_server_mode (server) == MODE_DAEMON) | ||
674 | { | 572 | { |
675 | process_cleanup (); | 573 | mu_m_server_begin (server); |
676 | if (children > maxchildren) | 574 | status = mu_m_server_run (server); |
677 | { | 575 | mu_m_server_end (server); |
678 | mu_diag_output (MU_DIAG_ERROR, _("too many children (%s)"), | 576 | mu_m_server_destroy (&server); |
679 | mu_umaxtostr (0, children)); | 577 | } |
680 | pause (); | 578 | else |
681 | continue; | 579 | { |
682 | } | 580 | /* Make sure we are in the root directory. */ |
683 | connfd = accept (listenfd, (struct sockaddr *)&client, | 581 | chdir ("/"); |
684 | (socklen_t *) &size); | 582 | status = pop3d_mainloop (fileno (stdin), stdin, stdout); |
685 | if (connfd == -1) | ||
686 | { | ||
687 | if (errno == EINTR) | ||
688 | continue; | ||
689 | mu_diag_output (MU_DIAG_ERROR, "accept: %s", strerror (errno)); | ||
690 | continue; | ||
691 | /*exit (EXIT_FAILURE);*/ | ||
692 | } | ||
693 | |||
694 | pid = fork (); | ||
695 | if (pid == -1) | ||
696 | mu_diag_output (MU_DIAG_ERROR, "fork: %s", strerror (errno)); | ||
697 | else if (pid == 0) /* Child. */ | ||
698 | { | ||
699 | int status; | ||
700 | |||
701 | close (listenfd); | ||
702 | status = pop3d_mainloop (connfd, | ||
703 | fdopen (connfd, "r"), fdopen (connfd, "w")); | ||
704 | closelog (); | ||
705 | exit (status); | ||
706 | } | ||
707 | else | ||
708 | { | ||
709 | ++children; | ||
710 | } | ||
711 | close (connfd); | ||
712 | } | 583 | } |
584 | |||
585 | if (status) | ||
586 | mu_error (_("Main loop status: %s"), mu_strerror (status)); | ||
587 | /* Close the syslog connection and exit. */ | ||
588 | closelog (); | ||
589 | return (OK != status); | ||
713 | } | 590 | } |
714 | 591 | ... | ... |
1 | /* GNU Mailutils -- a suite of utilities for electronic mail | 1 | /* GNU Mailutils -- a suite of utilities for electronic mail |
2 | Copyright (C) 1999, 2000, 2001, 2002, 2003, | 2 | Copyright (C) 1999, 2000, 2001, 2002, 2003, |
3 | 2004, 2005, 2007 Free Software Foundation, Inc. | 3 | 2004, 2005, 2007, 2008 Free Software Foundation, Inc. |
4 | 4 | ||
5 | GNU Mailutils is free software; you can redistribute it and/or modify | 5 | GNU Mailutils is free software; you can redistribute it and/or modify |
6 | it under the terms of the GNU General Public License as published by | 6 | it under the terms of the GNU General Public License as published by |
... | @@ -156,6 +156,7 @@ extern int expire_on_exit; | ... | @@ -156,6 +156,7 @@ extern int expire_on_exit; |
156 | #include <mailutils/url.h> | 156 | #include <mailutils/url.h> |
157 | #include <mailutils/md5.h> | 157 | #include <mailutils/md5.h> |
158 | #include <mailutils/acl.h> | 158 | #include <mailutils/acl.h> |
159 | #include <mailutils/server.h> | ||
159 | 160 | ||
160 | /* For Berkley DB2 APOP password file */ | 161 | /* For Berkley DB2 APOP password file */ |
161 | #ifdef HAVE_DB_H | 162 | #ifdef HAVE_DB_H |
... | @@ -205,6 +206,9 @@ extern int expire_on_exit; | ... | @@ -205,6 +206,9 @@ extern int expire_on_exit; |
205 | #define ERR_TLS_IO 18 | 206 | #define ERR_TLS_IO 18 |
206 | #define ERR_LOGIN_DELAY 19 | 207 | #define ERR_LOGIN_DELAY 19 |
207 | 208 | ||
209 | typedef struct mu_pop_server *mu_pop_server_t; | ||
210 | |||
211 | extern mu_pop_server_t pop3srv; | ||
208 | extern mu_mailbox_t mbox; | 212 | extern mu_mailbox_t mbox; |
209 | extern int state; | 213 | extern int state; |
210 | extern int initial_state; | 214 | extern int initial_state; |
... | @@ -220,6 +224,8 @@ extern int tls_done; | ... | @@ -220,6 +224,8 @@ extern int tls_done; |
220 | #endif /* WITH_TLS */ | 224 | #endif /* WITH_TLS */ |
221 | extern int undelete_on_startup; | 225 | extern int undelete_on_startup; |
222 | extern struct mu_auth_data *auth_data; | 226 | extern struct mu_auth_data *auth_data; |
227 | extern unsigned int idle_timeout; | ||
228 | extern int pop3d_transcript; | ||
223 | 229 | ||
224 | extern void pop3d_bye (void); | 230 | extern void pop3d_bye (void); |
225 | extern int pop3d_abquit (int); | 231 | extern int pop3d_abquit (int); |
... | @@ -238,7 +244,6 @@ extern int pop3d_retr (const char *); | ... | @@ -238,7 +244,6 @@ extern int pop3d_retr (const char *); |
238 | extern int pop3d_rset (const char *); | 244 | extern int pop3d_rset (const char *); |
239 | extern void process_cleanup (void); | 245 | extern void process_cleanup (void); |
240 | 246 | ||
241 | extern RETSIGTYPE pop3d_sigchld (int); | ||
242 | extern RETSIGTYPE pop3d_signal (int); | 247 | extern RETSIGTYPE pop3d_signal (int); |
243 | extern int pop3d_stat (const char *); | 248 | extern int pop3d_stat (const char *); |
244 | #ifdef WITH_TLS | 249 | #ifdef WITH_TLS | ... | ... |
1 | |||
2 | /* GNU Mailutils -- a suite of utilities for electronic mail | 1 | /* GNU Mailutils -- a suite of utilities for electronic mail |
3 | Copyright (C) 1999, 2000, 2001, 2002, 2007 Free Software Foundation, Inc. | 2 | Copyright (C) 1999, 2000, 2001, 2002, 2007, 2008 |
3 | Free Software Foundation, Inc. | ||
4 | 4 | ||
5 | GNU Mailutils is free software; you can redistribute it and/or modify | 5 | GNU Mailutils is free software; you can redistribute it and/or modify |
6 | it under the terms of the GNU General Public License as published by | 6 | it under the terms of the GNU General Public License as published by |
... | @@ -19,30 +19,6 @@ | ... | @@ -19,30 +19,6 @@ |
19 | 19 | ||
20 | #include "pop3d.h" | 20 | #include "pop3d.h" |
21 | 21 | ||
22 | static int need_cleanup = 0; | ||
23 | |||
24 | void | ||
25 | process_cleanup () | ||
26 | { | ||
27 | pid_t pid; | ||
28 | int status; | ||
29 | |||
30 | if (need_cleanup) | ||
31 | { | ||
32 | need_cleanup = 0; | ||
33 | while ( (pid = waitpid (-1, &status, WNOHANG)) > 0) | ||
34 | --children; | ||
35 | } | ||
36 | } | ||
37 | |||
38 | RETSIGTYPE | ||
39 | pop3d_sigchld (int signo MU_ARG_UNUSED) | ||
40 | { | ||
41 | need_cleanup = 1; | ||
42 | #ifndef HAVE_SIGACTION | ||
43 | signal (signo, pop3d_sigchld); | ||
44 | #endif | ||
45 | } | ||
46 | 22 | ||
47 | /* Default signal handler to call the pop3d_abquit() function */ | 23 | /* Default signal handler to call the pop3d_abquit() function */ |
48 | 24 | ... | ... |
-
Please register or sign in to post a comment