Commit c060b5fd c060b5fddd1ae0a06089df418c4cb4393b2de615 by Sergey Poznyakoff

* 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.
1 parent c51fa40b
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
......