diff -X mailutils.nebu/.cvsignore -Nru mailutils.cvs/configure.ac mailutils.nebu/configure.ac --- mailutils.cvs/configure.ac 2004-04-10 16:17:16.000000000 +0200 +++ mailutils.nebu/configure.ac 2004-05-02 16:24:55.000000000 +0200 @@ -83,6 +83,27 @@ *) AC_MSG_ERROR(bad value ${enableval} for --disable-pthread) ;; esac],[usepthread=yes]) +AC_ARG_ENABLE([ipv4], + AC_HELP_STRING([--disable-ipv4], + [disable ipv4]), + [ +case "${enableval}" in + yes) useipv4=yes ;; + no) useipv4=no ;; + *) AC_MSG_ERROR([bad value ${enableval} for --disable-ipv4]) ;; +esac],[useipv4=yes]) + +AC_ARG_ENABLE([ipv6], + AC_HELP_STRING([--disable-ipv6], + [disable ipv6]), + [ +case "${enableval}" in + yes) useipv6=yes ;; + no) useipv6=no ;; + *) AC_MSG_ERROR([bad value ${enableval} for --disable-ipv6]) ;; +esac],[useipv6=yes]) + + AC_ARG_WITH([readline], AC_HELP_STRING([--without-readline], [do not use readline]), @@ -565,6 +586,29 @@ AC_CHECK_FUNC(socket, [true], AC_CHECK_LIB(socket, socket, LIBS="-lsocket $LIBS")) +dnl FIXME: may need more test for ipv6 +dnl FIXME: need replacement if test failed + +dnl Check for getaddrinfo +AC_CHECK_FUNC(getaddrinfo, [true], + AC_MSG_ERROR([cannot find getaddrinfo function])) + +dnl Check for inet_ntop +AC_CHECK_FUNC(inet_ntop, [true], + AC_MSG_ERROR([cannot find inet_ntop function])) + +dnl Check for ipv4 +dnl FIXME: need to test for PF_INET4 +if test x"$useipv4" = x"yes"; then + AC_DEFINE(WITH_IPV4,1,[Defined if mailutils use ipv4]) +fi + +dnl Check for ipv6 +dnl FIXME: need to test for PF_INET6 +if test x"$useipv6" = x"yes"; then + AC_DEFINE(WITH_IPV6,1,[Defined if mailutils use ipv6]) +fi + dnl Check for Curses libs. for lib in ncurses curses termcap do diff -X mailutils.nebu/.cvsignore -Nru mailutils.cvs/imap4d/imap4d.c mailutils.nebu/imap4d/imap4d.c --- mailutils.cvs/imap4d/imap4d.c 2004-04-28 17:58:08.000000000 +0200 +++ mailutils.nebu/imap4d/imap4d.c 2004-04-28 18:13:22.000000000 +0200 @@ -225,6 +225,7 @@ imap4d_mainloop (int fd, FILE *infile, FILE *outfile) { char *text; + char *peer; /* Reset hup to exit. */ signal (SIGHUP, imap4d_signal); @@ -236,15 +237,10 @@ /* log information on the connecting client */ if (!debug_mode) { - struct sockaddr_in cs; - int len = sizeof cs; - syslog (LOG_INFO, _("Incoming connection opened")); - if (getpeername (fd, (struct sockaddr *) &cs, &len) < 0) - syslog (LOG_ERR, _("can't obtain IP address of client: %s"), - strerror (errno)); - else - syslog (LOG_INFO, _("connect from %s"), inet_ntoa (cs.sin_addr)); + if (mu_getpeername (fd, &peer)) { + syslog (LOG_INFO, _("connect from %s"), peer); + } text = "IMAP4rev1"; } else @@ -289,92 +285,59 @@ #ifdef HAVE_SIGACTION { struct sigaction act; - act.sa_handler = imap4d_sigchld; + act.sa_handler = mu_sigchld_hanlder; sigemptyset (&act.sa_mask); act.sa_flags = 0; sigaction (SIGCHLD, &act, NULL); } #else - signal (SIGCHLD, imap4d_sigchld); + signal (SIGCHLD, mu_sigchld_hanlder); #endif } /* Runs GNU imap4d in standalone daemon mode. This opens and binds to a port - (default 143) then executes a imap4d_mainloop() upon accepting a connection. + (default 143) then executes imap4d_mainloop() upon accepting a connection. It starts maxchildren child processes to listen to and accept socket connections. */ static void imap4d_daemon (unsigned int maxchildren, unsigned int port) { - struct sockaddr_in server, client; - pid_t pid; - int listenfd, connfd; - size_t size; + int ret; - listenfd = socket (PF_INET, SOCK_STREAM, 0); - if (listenfd == -1) - { - syslog (LOG_ERR, "socket: %s", strerror (errno)); - exit (1); - } - size = 1; /* Use size here to avoid making a new variable. */ - setsockopt (listenfd, SOL_SOCKET, SO_REUSEADDR, &size, sizeof (size)); - size = sizeof (server); - memset (&server, 0, size); - server.sin_family = AF_INET; - server.sin_addr.s_addr = htonl (INADDR_ANY); - server.sin_port = htons (port); + list_t sockets; - if (bind (listenfd, (struct sockaddr *) &server, size) == -1) - { - syslog (LOG_ERR, "bind: %s", strerror (errno)); - exit (1); - } + list_create(&sockets); - if (listen (listenfd, 128) == -1) + /* FIXME: need to handle a liste of interfaces to listen on + * for each interface, create the corresponding sockets + * need to change imap4d_daemon prototype + */ + +/* iterator_t itr; */ +/* char *interface; */ +/* char *addr, port; */ +/* iterator_create (&itr, addr_to_listen); */ + +/* for (iterator_first (itr); !iterator_is_done(itr); iterator_next(itr)) */ +/* { */ + +/* } */ + + ret = mu_getsockets(0, NULL, port, 0, sockets); + if (ret) { - syslog (LOG_ERR, "listen: %s", strerror (errno)); - exit (1); - } + syslog (LOG_ERR, "imap4d_daemon: unable to create sockets"); + exit(1); + } syslog (LOG_INFO, _("GNU imap4d started")); - for (;;) - { - if (children > maxchildren) - { - syslog (LOG_ERR, _("too many children (%lu)"), - (unsigned long) children); - pause (); - continue; - } - connfd = accept (listenfd, (struct sockaddr *) &client, - (socklen_t *) & size); - if (connfd == -1) - { - if (errno == EINTR) - continue; - syslog (LOG_ERR, "accept: %s", strerror (errno)); - exit (1); - } - - pid = fork (); - if (pid == -1) - syslog (LOG_ERR, "fork: %s", strerror (errno)); - else if (pid == 0) /* Child. */ - { - int status; - close (listenfd); - status = imap4d_mainloop (connfd, - fdopen (connfd, "r"), - fdopen (connfd, "w")); - closelog (); - exit (status); - } - else - { - ++children; - } - close (connfd); - } + ret = daemon_select (sockets, maxchildren, &imap4d_mainloop); + if (ret) { + syslog (LOG_ERR, "imap4d_daemon: unbale to listen for connections"); + exit(1); + } + + exit(0); + } diff -X mailutils.nebu/.cvsignore -Nru mailutils.cvs/imap4d/imap4d.h mailutils.nebu/imap4d/imap4d.h --- mailutils.cvs/imap4d/imap4d.h 2004-04-28 17:58:08.000000000 +0200 +++ mailutils.nebu/imap4d/imap4d.h 2004-04-28 20:03:40.000000000 +0200 @@ -148,7 +148,6 @@ extern char *homedir; extern char *rootdir; extern int state; -extern volatile size_t children; extern int is_virtual; extern struct daemon_param daemon_param; extern struct mu_auth_data *auth_data; @@ -209,7 +208,6 @@ extern size_t uid_to_msgno __P ((size_t)); /* Signal handling. */ -extern RETSIGTYPE imap4d_sigchld __P ((int)); extern RETSIGTYPE imap4d_signal __P ((int)); extern int imap4d_bye __P ((int)); extern int imap4d_bye0 __P ((int reason, struct imap4d_command *command)); diff -X mailutils.nebu/.cvsignore -Nru mailutils.cvs/imap4d/signal.c mailutils.nebu/imap4d/signal.c --- mailutils.cvs/imap4d/signal.c 2003-08-29 21:08:41.000000000 +0200 +++ mailutils.nebu/imap4d/signal.c 2004-04-05 18:57:20.000000000 +0200 @@ -18,21 +18,6 @@ #define __USE_MISC #include "imap4d.h" -RETSIGTYPE -imap4d_sigchld (int signo) -{ - pid_t pid; - int status; - - while ((pid = waitpid (-1, &status, WNOHANG)) > 0) - --children; -#ifndef HAVE_SIGACTION - /* On some system, signal implements the unreliable semantic and - has to be rearm. */ - signal (signo, imap4d_sigchld); -#endif -} - /* Default signal handler to call the imap4d_bye() function */ RETSIGTYPE diff -X mailutils.nebu/.cvsignore -Nru mailutils.cvs/include/mailutils/daemon.h mailutils.nebu/include/mailutils/daemon.h --- mailutils.cvs/include/mailutils/daemon.h 2004-04-26 22:57:24.000000000 +0200 +++ mailutils.nebu/include/mailutils/daemon.h 2004-04-28 18:24:09.000000000 +0200 @@ -22,8 +22,16 @@ extern "C" { #endif +#include +#include + extern int daemon_create_pidfile __P ((const char *)); extern void daemon_remove_pidfile __P ((void)); + +/* Make all the necesary work to listen on incomming sockets */ +extern int daemon_select __P ((list_t sockets, int maxchildren, + int (*handler) (int fd, FILE *infile, FILE *outfile))); + #ifdef __cplusplus } diff -X mailutils.nebu/.cvsignore -Nru mailutils.cvs/include/mailutils/mutil.h mailutils.nebu/include/mailutils/mutil.h --- mailutils.cvs/include/mailutils/mutil.h 2004-01-13 16:08:24.000000000 +0100 +++ mailutils.nebu/include/mailutils/mutil.h 2004-04-28 18:21:50.000000000 +0200 @@ -28,6 +28,11 @@ #include #include +#if HAVE_CONFIG_H +# include +#endif + + #ifdef __cplusplus extern "C" { #endif @@ -64,7 +69,7 @@ * * It is the caller's responsibility to free host. */ -extern int mu_get_host_name __P((char **host)); +extern int mu_get_host_name __P ((char **host)); /* Set the default user email address. * @@ -129,6 +134,23 @@ extern int mu_true_answer_p __P((const char *p)); extern int mu_scheme_autodetect_p __P((const char *scheme, const char **path)); +/* Handler for SIGCHLD, on some system, signal implements the unreliable + * semantic and has to be rearm. */ +extern RETSIGTYPE mu_sigchld_hanlder __P ((int signo)); + +/* Wait for dead children and decrement children counter */ +extern void mu_process_cleanup __P ((unsigned int* children)); + +/* Get the peername using getaddrinfo */ +extern int mu_getpeername __P ((int fd, char** peer)); + +/* Get sockets for a host and store them in a list. + * if family = 0 we use PF_UNSPEC + * if node is NULL we use AI_PASSIVE + * if sock_type = 0 we use SOCK_STREAM + */ +extern int mu_getsockets __P ((int family, char *node, int port, int sock_type, list_t sockets)); + #ifdef __cplusplus } #endif diff -X mailutils.nebu/.cvsignore -Nru mailutils.cvs/mailbox/daemon.c mailutils.nebu/mailbox/daemon.c --- mailutils.cvs/mailbox/daemon.c 2004-04-26 22:56:24.000000000 +0200 +++ mailutils.nebu/mailbox/daemon.c 2004-04-28 18:38:07.000000000 +0200 @@ -23,11 +23,22 @@ #include #include #include +#include + +#include +#include + #include #include +#include +#include #include +#include +#include +#include + static char *pidfile; static pid_t current_pid; @@ -55,7 +66,8 @@ return 2; /* failure */ } - snprintf (pid_string, sizeof (pid_string) - 1, "%lu\n", current_pid); + snprintf (pid_string, sizeof (pid_string) - 1, "%lu\n", + (long unsigned int) current_pid); write (fd, pid_string, strlen (pid_string)); close (fd); @@ -73,3 +85,104 @@ } } +/* Make all the necesary work to listen on incomming sockets */ +int +daemon_select (list_t sockets, int maxchildren, + int (*handler) (int fd, FILE *infile, FILE *outfile)) +{ + pid_t pid; + fd_set fdset; + int *fd, connfd; + int ret, children = 0; + + struct sockaddr_storage client; + socklen_t size = sizeof (client); + + iterator_t itr; + + ret = iterator_create (&itr, sockets); + if (ret) { + syslog (LOG_ERR, "iterator_create : error number %d", ret); + return 1; + } + + for (;;) + { + mu_process_cleanup (&children); + if (children > maxchildren) + { + syslog (LOG_ERR, "too many children (%lu)", (unsigned long) children); + pause (); + continue; + } + + FD_ZERO (&fdset); + + for (iterator_first(itr); !iterator_is_done(itr); iterator_next(itr)) + { + iterator_current (itr, (void**) &fd); + + /* Do not listen on fd if unwanted or file descriptor to big for slect + * (paranoiac attitude) + */ + if (listen (*fd, 128) == -1) + { + syslog (LOG_ERR, "listen: %s", strerror (errno)); + exit (1); + } + + if (*fd && (*fd < FD_SETSIZE)) + FD_SET (*fd, &fdset); + + } + + if (select (FD_SETSIZE, &fdset, NULL, NULL, NULL) < 0) + { + if (errno == EINTR) + continue; + syslog (LOG_ERR, "select: %s", strerror (errno)); + iterator_destroy (&itr); + return 1; + } + + /* We have something interesting somewhere*/ + for (iterator_first(itr); !iterator_is_done(itr); iterator_next(itr)) + { + iterator_current (itr, (void**) &fd); + + if (*fd && FD_ISSET (*fd, &fdset)) + { + connfd = accept (*fd, (struct sockaddr *) &client, &size); + if (connfd == -1) + { + if (errno == EINTR) + continue; + syslog (LOG_ERR, "accept: %s", strerror (errno)); + iterator_destroy (&itr); + return 1; + } + + pid = fork (); + if (pid == -1) + syslog (LOG_ERR, "fork: %s", strerror (errno)); + else if (pid == 0) /* Child. */ + { + int status; + close (*fd); + + status = handler (connfd, + fdopen (connfd, "r"), + fdopen (connfd, "w")); + exit (status); + } + else + { + ++children; + } + close (connfd); + } + } + } + iterator_destroy (&itr); + return 0; +} diff -X mailutils.nebu/.cvsignore -Nru mailutils.cvs/mailbox/mutil.c mailutils.nebu/mailbox/mutil.c --- mailutils.cvs/mailbox/mutil.c 2004-04-25 19:20:42.000000000 +0200 +++ mailutils.nebu/mailbox/mutil.c 2004-05-02 15:03:18.000000000 +0200 @@ -34,6 +34,8 @@ #include #include #include +#include +#include #ifdef HAVE_STRINGS_H #include @@ -303,6 +305,7 @@ return 0; } + /* * Functions used to convert unix mailbox/user names into RFC822 addr-specs. */ @@ -1176,4 +1179,187 @@ return 1; return 0; } - + +/* Handler for SIGCHLD, on some system, signal implements the unreliable + * semantic and has to be rearm. */ +RETSIGTYPE +mu_sigchld_hanlder (int signo) +{ +#ifndef HAVE_SIGACTION + signal (signo, mu_deadchld_hanlder); +#endif +} + +/* Wait for dead children and decrement children counter */ +void +mu_process_cleanup (unsigned int* children) +{ + pid_t pid; + int status; + + while ( (pid = waitpid (-1, &status, WNOHANG)) > 0) + --*children; +} + +/* IPv6 capable functions */ + +/* get peername of a connected socket + * FIXME: useless comment ;-) + */ +int +mu_getpeername (int fd, char** peer) +{ + struct sockaddr_storage cs; + int len = sizeof cs; + + if (getpeername (fd, (struct sockaddr *) &cs, &len) < 0) + mu_error ("can't obtain IP address: %s", strerror (errno)); + else { + switch (cs.ss_family) { +#ifdef WITH_IPV4 + case AF_INET: { + *peer = malloc (INET_ADDRSTRLEN); + struct in_addr src = ((struct sockaddr_in *) &cs)->sin_addr; + + if (!inet_ntop (AF_INET, (const void*) &src, *peer, INET_ADDRSTRLEN)) { + mu_error ("inet_ntop error: %s", strerror (errno)); + break; + } + return 0; + } +#endif +#ifdef WITH_IPV6 + case AF_INET6: { + *peer = malloc (INET6_ADDRSTRLEN); + struct in6_addr src = ((struct sockaddr_in6 *) &cs)->sin6_addr; + + if (!inet_ntop (AF_INET6, (const void*) &src, *peer, INET6_ADDRSTRLEN)) { + mu_error ("inet_ntop error: %s", strerror (errno)); + break; + } + return 0; + } +#endif + default: + mu_error ("mu_getpeername: %s", strerror(EAFNOSUPPORT)); + } + } + return -1; +} + +/* Create sockets an append them in the sockets list ready for listen + we do not take care of the protocol, 0 by default */ +int +mu_getsockets (int family, char *node, int port, int sock_type, list_t sockets) +{ + int ret, on; + int *fd; + + struct addrinfo *srv, *ptr; + struct addrinfo hints = { + AI_PASSIVE, + PF_UNSPEC, + SOCK_STREAM, + 0, + 0, + NULL, + NULL, + NULL + }; + + /* port in null terminated string format for getaddrinfo 5+1 char (port is a + short)*/ + char service[6]; + + /* if sockets are for a client get canonname of target node */ + hints.ai_flags = (node != NULL ? AI_CANONNAME : AI_PASSIVE) ; + + /* get the good family from PF_UNSPEC, PF_INET, PF_INET6 + if 0 default is PF_UNSPEC*/ + hints.ai_family = (family != 0 ? family : PF_UNSPEC) ; + + /* set sock_type of the socket default is SOCK_STREAM */ + hints.ai_socktype = (sock_type != 0 ? sock_type : SOCK_STREAM); + + snprintf (service, sizeof (service), "%d", port); + service[5] = 0; + + ret = getaddrinfo (node, service, &hints, &srv); + if (ret) + { + mu_error ("getaddrinfo: %s", gai_strerror (ret)); + return -1; + } + + for (ptr = srv; ptr; ptr = ptr->ai_next) + { + switch (ptr->ai_family) + { +#ifdef WITH_IPV4 + case AF_INET: + { + /* FIXME add an --ipv4 | -4 option to break here if ipv4 is unwanted */ + fd = malloc (sizeof(int)); + + *fd = socket (PF_INET, SOCK_STREAM, 0); + if (*fd == -1) + { + mu_error ("socket: %s", strerror (errno)); + break; + } + + on = 1; + setsockopt (*fd, SOL_SOCKET, SO_REUSEADDR, (const void *)&on, sizeof (on)); + + if (bind (*fd, ptr->ai_addr, ptr->ai_addrlen) == -1) + { + mu_error ("bind: %s", strerror (errno)); + exit (1); + } + list_append (sockets, (void*) fd); + break; + } +#endif +#ifdef WITH_IPV6 + case AF_INET6: + { + /* FIXME add an --ipv6 | -6 option to break here if ipv6 is unwanted */ + fd = malloc (sizeof(int)); + + + *fd = socket (PF_INET6, SOCK_STREAM, 0); + if (*fd == -1) + { + mu_error ("socket: %s", strerror (errno)); + exit (1); + } + + ((struct sockaddr_in6 *) ptr->ai_addr)->sin6_flowinfo = 0; + + on = 1; + if (setsockopt(*fd, IPPROTO_IPV6, IPV6_V6ONLY, + (const void *)&on, sizeof(on)) == -1) + mu_error ("setsockopt: %s\n", strerror (errno)); + + on = 1; + setsockopt (*fd, SOL_SOCKET, SO_REUSEADDR, (const void *)&on, sizeof (on)); + + if (bind (*fd, ptr->ai_addr, ptr->ai_addrlen) == -1) + { + mu_error ("bind: %s", strerror (errno)); + exit (1); + } + + list_append (sockets, (void*) fd); + break; + } +#endif + default: + mu_error ("mu_getsockets: %s", strerror(EAFNOSUPPORT)); + } + } + freeaddrinfo (srv); + + return 0; +} + diff -X mailutils.nebu/.cvsignore -Nru mailutils.cvs/pop3d/pop3d.c mailutils.nebu/pop3d/pop3d.c --- mailutils.cvs/pop3d/pop3d.c 2004-04-28 17:58:45.000000000 +0200 +++ mailutils.nebu/pop3d/pop3d.c 2004-04-28 18:13:43.000000000 +0200 @@ -262,19 +262,21 @@ #ifdef HAVE_SIGACTION { struct sigaction act; - act.sa_handler = pop3d_sigchld; + act.sa_handler = mu_sigchld_hanlder; sigemptyset (&act.sa_mask); act.sa_flags = 0; sigaction (SIGCHLD, &act, NULL); } #else - signal (SIGCHLD, pop3d_sigchld); + signal (SIGCHLD, mu_sigchld_hanlder); #endif } void pop3d_log_connection (int fd) { + char *peer; + syslog (LOG_INFO, _("Incoming connection opened")); /* log information on the connecting client */ @@ -284,13 +286,11 @@ } else { - struct sockaddr_in cs; - int len = sizeof cs; - if (getpeername (fd, (struct sockaddr*)&cs, &len) < 0) - syslog (LOG_ERR, _("can't obtain IP address of client: %s"), - strerror (errno)); - else - syslog (LOG_INFO, _("connect from %s"), inet_ntoa (cs.sin_addr)); + if (mu_getpeername (fd, &peer)) + { + syslog (LOG_INFO, _("connect from %s"), peer); + } + } } @@ -326,13 +326,35 @@ /* Get our canonical hostname. */ { - struct hostent *htbuf; + struct addrinfo *htbuf; + struct addrinfo hints = { + AI_CANONNAME, + PF_UNSPEC, + SOCK_STREAM, + 0, + 0, + NULL, + NULL, + NULL + }; + int ret; + +/* struct hostent *htbuf; */ gethostname (local_hostname, MAXHOSTNAMELEN); - htbuf = gethostbyname (local_hostname); - if (htbuf) + + ret = getaddrinfo (local_hostname, NULL, &hints, &htbuf); + if (ret) { + syslog (LOG_ERR, "getaddrinfo: %s", gai_strerror (ret)); + freeaddrinfo (htbuf); free (local_hostname); - local_hostname = strdup (htbuf->h_name); + exit (1); + } + else + { + free (local_hostname); + local_hostname = strdup (htbuf->ai_canonname); + freeaddrinfo (htbuf); } } @@ -469,78 +491,39 @@ static void pop3d_daemon (unsigned int maxchildren, unsigned int port) { - struct sockaddr_in server, client; - pid_t pid; - int listenfd, connfd; - size_t size; + int ret; - listenfd = socket (PF_INET, SOCK_STREAM, 0); - if (listenfd == -1) - { - syslog (LOG_ERR, "socket: %s", strerror(errno)); - exit (EXIT_FAILURE); - } - size = 1; /* Use size here to avoid making a new variable. */ - setsockopt (listenfd, SOL_SOCKET, SO_REUSEADDR, &size, sizeof(size)); - size = sizeof (server); - memset (&server, 0, size); - server.sin_family = AF_INET; - server.sin_addr.s_addr = htonl (INADDR_ANY); - server.sin_port = htons (port); + list_t sockets; - if (bind (listenfd, (struct sockaddr *)&server, size) == -1) - { - syslog (LOG_ERR, "bind: %s", strerror (errno)); - exit (EXIT_FAILURE); - } + list_create(&sockets); + + /* FIXME: need to handle a liste of interfaces to listen on + * for each interface, create the corresponding sockets*/ - if (listen (listenfd, 128) == -1) +/* iterator_t itr; */ +/* char *interface; */ +/* char *addr, port; */ +/* iterator_create (&itr, addr_to_listen); */ + +/* for (iterator_first (itr); !iterator_is_done(itr); iterator_next(itr)) */ +/* { */ + +/* } */ + + ret = mu_getsockets(0, NULL, port, 0, sockets); + if (ret) { - syslog (LOG_ERR, "listen: %s", strerror (errno)); - exit (EXIT_FAILURE); - } + syslog (LOG_ERR, "pop3d_daemon: unable to create sockets"); + exit(1); + } syslog (LOG_INFO, _("GNU pop3d started")); - for (;;) - { - process_cleanup (); - if (children > maxchildren) - { - syslog (LOG_ERR, _("too many children (%lu)"), - (unsigned long) children); - pause (); - continue; - } - connfd = accept (listenfd, (struct sockaddr *)&client, - (socklen_t *) &size); - if (connfd == -1) - { - if (errno == EINTR) - continue; - syslog (LOG_ERR, "accept: %s", strerror (errno)); - continue; - /*exit (EXIT_FAILURE);*/ - } - - pid = fork (); - if (pid == -1) - syslog(LOG_ERR, "fork: %s", strerror (errno)); - else if (pid == 0) /* Child. */ - { - int status; - - close (listenfd); - status = pop3d_mainloop (connfd, - fdopen (connfd, "r"), fdopen (connfd, "w")); - closelog (); - exit (status); - } - else - { - ++children; - } - close (connfd); - } -} + ret = daemon_select (sockets, maxchildren, &pop3d_mainloop); + if (ret) { + syslog (LOG_ERR, "pop3d_daemon: unbale to listen for connections"); + exit(1); + } + exit(0); +} diff -X mailutils.nebu/.cvsignore -Nru mailutils.cvs/pop3d/pop3d.h mailutils.nebu/pop3d/pop3d.h --- mailutils.cvs/pop3d/pop3d.h 2004-04-28 17:58:45.000000000 +0200 +++ mailutils.nebu/pop3d/pop3d.h 2004-04-28 18:02:17.000000000 +0200 @@ -203,7 +203,6 @@ extern char *username; extern char *maildir; extern char *md5shared; -extern volatile size_t children; extern struct daemon_param daemon_param; extern int debug_mode; #ifdef WITH_TLS @@ -227,9 +226,7 @@ extern int pop3d_quit __P ((const char *)); extern int pop3d_retr __P ((const char *)); extern int pop3d_rset __P ((const char *)); -extern void process_cleanup __P ((void)); -extern RETSIGTYPE pop3d_sigchld __P ((int)); extern RETSIGTYPE pop3d_signal __P ((int)); extern int pop3d_stat __P ((const char *)); #ifdef WITH_TLS diff -X mailutils.nebu/.cvsignore -Nru mailutils.cvs/pop3d/signal.c mailutils.nebu/pop3d/signal.c --- mailutils.cvs/pop3d/signal.c 2003-09-18 12:06:36.000000000 +0200 +++ mailutils.nebu/pop3d/signal.c 2004-04-10 20:47:42.000000000 +0200 @@ -17,31 +17,6 @@ #include "pop3d.h" -static int need_cleanup = 0; - -void -process_cleanup () -{ - pid_t pid; - int status; - - if (need_cleanup) - { - need_cleanup = 0; - while ( (pid = waitpid (-1, &status, WNOHANG)) > 0) - --children; - } -} - -RETSIGTYPE -pop3d_sigchld (int signo ARG_UNUSED) -{ - need_cleanup = 1; -#ifndef HAVE_SIGACTION - signal (signo, pop3d_sigchld); -#endif -} - /* Default signal handler to call the pop3d_abquit() function */ RETSIGTYPE