diff options
-rw-r--r-- | NEWS | 8 | ||||
-rw-r--r-- | daemon.c | 79 | ||||
-rw-r--r-- | driver.c | 27 | ||||
-rw-r--r-- | fetchmail.c | 31 | ||||
-rw-r--r-- | fetchmail.h | 3 | ||||
-rw-r--r-- | getpass.c | 6 | ||||
-rw-r--r-- | idle.c | 17 | ||||
-rw-r--r-- | sink.c | 12 | ||||
-rw-r--r-- | smtp.c | 13 |
9 files changed, 91 insertions, 105 deletions
@@ -2,6 +2,14 @@ (The `lines' figures total .c, .h, .l, and .y files under version control.) +fetchmail-6.2.0 (Fri Dec 13 00:10:07 EST 2002), 22235 lines: + +* Applied Steffen Esser's fix for a buffer-overflow bug in rfc822.c +* Updated Danish, German, and Turkish translation files. +* Sunil Sheye's SMTP timeout patch. + +There are 538 people on fetchmail-friends and 701 on fetchmail-announce. + fetchmail-6.1.3 (Thu Nov 28 05:35:15 EST 2002), 22203 lines: * Updated Turkish, Danish, German, Spanish, Catalan po files. @@ -82,36 +82,54 @@ sigchld_handler (int sig) lastsig = SIGCHLD; } +RETSIGTYPE null_signal_handler(int sig) { } + +SIGHANDLERTYPE set_signal_handler(int sig, SIGHANDLERTYPE handler) /* * This function is called by other parts of the program to - * setup the sigchld handler after a change to the signal context. + * setup the signal handler after a change to the signal context. * This is done to improve robustness of the signal handling code. + * It has the same prototype as signal(2). */ -void deal_with_sigchld(void) { - RETSIGTYPE sigchld_handler(int); + SIGHANDLERTYPE rethandler; #ifdef HAVE_SIGACTION - struct sigaction sa_new; + struct sigaction sa_new, sa_old; memset (&sa_new, 0, sizeof sa_new); sigemptyset (&sa_new.sa_mask); - /* sa_new.sa_handler = SIG_IGN; pointless */ - - /* set up to catch child process termination signals */ - sa_new.sa_handler = sigchld_handler; + sa_new.sa_handler = handler; + sa_new.sa_flags = 0; #ifdef SA_RESTART /* SunOS 4.1 portability hack */ - sa_new.sa_flags = SA_RESTART | SA_NOCLDSTOP; + /* system call should restart on all signals except SIGALRM */ + if (sig != SIGALRM) + sa_new.sa_flags |= SA_RESTART; #endif - sigaction (SIGCHLD, &sa_new, NULL); +#ifdef SA_NOCLDSTOP /* SunOS 4.1 portability hack */ + if (sig == SIGCHLD) + sa_new.sa_flags |= SA_NOCLDSTOP; +#endif + sigaction(sig, &sa_new, &sa_old); + rethandler = sa_old.sa_handler; #if defined(SIGPWR) - sigaction (SIGPWR, &sa_new, NULL); + if (sig == SIGCHLD) + sigaction(SIGPWR, &sa_new, NULL); #endif #else /* HAVE_SIGACTION */ - signal(SIGCHLD, sigchld_handler); + rethandler = signal(sig, handler); #if defined(SIGPWR) - signal(SIGPWR, sigchld_handler); + if (sig == SIGCHLD) + signal(SIGPWR, handler); #endif + /* system call should restart on all signals except SIGALRM */ + siginterrupt(sig, sig == SIGALRM); #endif /* HAVE_SIGACTION */ + return rethandler; +} + +void deal_with_sigchld(void) +{ + set_signal_handler(SIGCHLD, sigchld_handler); } int @@ -120,9 +138,6 @@ daemonize (const char *logfile, void (*termhook)(int)) { int fd; pid_t childpid; -#ifdef HAVE_SIGACTION - struct sigaction sa_new; -#endif /* HAVE_SIGACTION */ /* if we are started by init (process 1) via /etc/inittab we needn't bother to detach from our process group context */ @@ -131,34 +146,14 @@ daemonize (const char *logfile, void (*termhook)(int)) goto nottyDetach; /* Ignore BSD terminal stop signals */ -#ifdef HAVE_SIGACTION - memset (&sa_new, 0, sizeof sa_new); - sigemptyset (&sa_new.sa_mask); - sa_new.sa_handler = SIG_IGN; -#ifdef SA_RESTART /* SunOS 4.1 portability hack */ - sa_new.sa_flags = SA_RESTART; -#endif -#endif /* HAVE_SIGACTION */ #ifdef SIGTTOU -#ifndef HAVE_SIGACTION - signal(SIGTTOU, SIG_IGN); -#else - sigaction (SIGTTOU, &sa_new, NULL); -#endif /* HAVE_SIGACTION */ + set_signal_handler(SIGTTOU, SIG_IGN); #endif #ifdef SIGTTIN -#ifndef HAVE_SIGACTION - signal(SIGTTIN, SIG_IGN); -#else - sigaction (SIGTTIN, &sa_new, NULL); -#endif /* HAVE_SIGACTION */ + set_signal_handler(SIGTTIN, SIG_IGN); #endif #ifdef SIGTSTP -#ifndef HAVE_SIGACTION - signal(SIGTSTP, SIG_IGN); -#else - sigaction (SIGTSTP, &sa_new, NULL); -#endif /* HAVE_SIGACTION */ + set_signal_handler(SIGTSTP, SIG_IGN); #endif /* In case we were not started in the background, fork and let @@ -199,11 +194,7 @@ daemonize (const char *logfile, void (*termhook)(int)) #endif /* lose controlling tty */ -#ifndef HAVE_SIGACTION - signal(SIGHUP, SIG_IGN); -#else - sigaction (SIGHUP, &sa_new, NULL); -#endif /* HAVE_SIGACTION */ + set_signal_handler(SIGHUP, SIG_IGN); if ((childpid = fork()) < 0) { report(stderr, "fork (%s)\n", strerror(errno)); return(PS_IOERR); @@ -89,34 +89,31 @@ void set_timeout(int timeleft) #endif } -static void timeout_handler (int signal) +static RETSIGTYPE timeout_handler (int signal) /* handle SIGALRM signal indicating a server timeout */ { timeoutcount++; longjmp(restart, THROW_TIMEOUT); } -static void sigpipe_handler (int signal) +static RETSIGTYPE sigpipe_handler (int signal) /* handle SIGPIPE signal indicating a broken stream socket */ { longjmp(restart, THROW_SIGPIPE); } -/* ignore SIGALRM signal indicating a timeout during cleanup */ -static void cleanup_timeout_handler (int signal) { } - #define CLEANUP_TIMEOUT 60 /* maximum timeout during cleanup */ static int cleanupSockClose (int fd) /* close sockets in maximum CLEANUP_TIMEOUT seconds during cleanup */ { int scerror; - void (*alrmsave)(int); - alrmsave = signal(SIGALRM, cleanup_timeout_handler); + SIGHANDLERTYPE alrmsave; + alrmsave = set_signal_handler(SIGALRM, null_signal_handler); set_timeout(CLEANUP_TIMEOUT); scerror = SockClose(fd); set_timeout(0); - signal(SIGALRM, alrmsave); + set_signal_handler(SIGALRM, alrmsave); return (scerror); } @@ -734,8 +731,8 @@ const int maxfetch; /* maximum number of messages to fetch */ int err, mailserver_socket = -1; #endif /* HAVE_VOLATILE */ const char *msg; - void (*pipesave)(int); - void (*alrmsave)(int); + SIGHANDLERTYPE pipesave; + SIGHANDLERTYPE alrmsave; ctl->server.base_protocol = proto; @@ -744,11 +741,11 @@ const int maxfetch; /* maximum number of messages to fetch */ init_transact(proto); /* set up the server-nonresponse timeout */ - alrmsave = signal(SIGALRM, timeout_handler); + alrmsave = set_signal_handler(SIGALRM, timeout_handler); mytimeout = ctl->server.timeout; /* set up the broken-pipe timeout */ - pipesave = signal(SIGPIPE, sigpipe_handler); + pipesave = set_signal_handler(SIGPIPE, sigpipe_handler); if ((js = setjmp(restart))) { @@ -770,7 +767,7 @@ const int maxfetch; /* maximum number of messages to fetch */ if (js == THROW_SIGPIPE) { - signal(SIGPIPE, SIG_IGN); + set_signal_handler(SIGPIPE, SIG_IGN); report(stdout, GT_("SIGPIPE thrown from an MDA or a stream socket error\n")); wait(0); @@ -1510,8 +1507,8 @@ closeUp: } set_timeout(0); /* cancel any pending alarm */ - signal(SIGALRM, alrmsave); - signal(SIGPIPE, pipesave); + set_signal_handler(SIGALRM, alrmsave); + set_signal_handler(SIGPIPE, pipesave); return(err); } diff --git a/fetchmail.c b/fetchmail.c index debb8853..e541aa57 100644 --- a/fetchmail.c +++ b/fetchmail.c @@ -74,8 +74,8 @@ static int activecount; /* count number of active entries */ static struct runctl cmd_run; /* global options set from command line */ static time_t parsetime; /* time of last parse */ -static void terminate_run(int); -static void terminate_poll(int); +static RETSIGTYPE terminate_run(int); +static RETSIGTYPE terminate_poll(int); #if defined(__FreeBSD__) && defined(__FreeBSD_USE_KVM) /* drop SGID kmem privileage until we need it */ @@ -119,7 +119,8 @@ static char *timestamp (void) static RETSIGTYPE donothing(int sig) { extern volatile int lastsig; /* declared in idle.c */ - signal(sig, donothing); lastsig = sig; + set_signal_handler(sig, donothing); + lastsig = sig; } int main(int argc, char **argv) @@ -490,9 +491,9 @@ int main(int argc, char **argv) * We'll set up a handler for these when we're sleeping, * but ignore them otherwise so as not to interrupt a poll. */ - signal(SIGUSR1, SIG_IGN); + set_signal_handler(SIGUSR1, SIG_IGN); if (run.poll_interval && getuid() == ROOT_UID) - signal(SIGHUP, SIG_IGN); + set_signal_handler(SIGHUP, SIG_IGN); } else { @@ -511,12 +512,12 @@ int main(int argc, char **argv) /* beyond here we don't want more than one fetchmail running per user */ umask(0077); - signal(SIGABRT, terminate_run); - signal(SIGINT, terminate_run); - signal(SIGTERM, terminate_run); - signal(SIGALRM, terminate_run); - signal(SIGPIPE, terminate_run); - signal(SIGQUIT, terminate_run); + set_signal_handler(SIGABRT, terminate_run); + set_signal_handler(SIGINT, terminate_run); + set_signal_handler(SIGTERM, terminate_run); + set_signal_handler(SIGALRM, terminate_run); + set_signal_handler(SIGPIPE, terminate_run); + set_signal_handler(SIGQUIT, terminate_run); /* here's the exclusion lock */ lock_or_die(); @@ -737,9 +738,9 @@ int main(int argc, char **argv) * forcing fetchmail to re-poll its hosts. The second line is * for people who think all system daemons wake up on SIGHUP. */ - signal(SIGUSR1, donothing); + set_signal_handler(SIGUSR1, donothing); if (getuid() != ROOT_UID) - signal(SIGHUP, donothing); + set_signal_handler(SIGHUP, donothing); /* * OK, now pause until it's time for the next poll cycle. @@ -1207,7 +1208,7 @@ static int load_params(int argc, char **argv, int optind) return(implicitmode); } -static void terminate_poll(int sig) +static RETSIGTYPE terminate_poll(int sig) /* to be executed at the end of a poll cycle */ { /* @@ -1254,7 +1255,7 @@ static void terminate_poll(int sig) #endif /* POP3_ENABLE */ } -static void terminate_run(int sig) +static RETSIGTYPE terminate_run(int sig) /* to be executed on normal or signal-induced termination */ { struct query *ctl; diff --git a/fetchmail.h b/fetchmail.h index 8bdfbc57..4367d845 100644 --- a/fetchmail.h +++ b/fetchmail.h @@ -598,7 +598,10 @@ char *prependdir (const char *, const char *); char *MD5Digest (unsigned char *); void hmac_md5 (unsigned char *, size_t, unsigned char *, size_t, unsigned char *, size_t); int POP3_auth_rpa(unsigned char *, unsigned char *, int socket); +typedef RETSIGTYPE (*SIGHANDLERTYPE) (int); void deal_with_sigchld(void); +RETSIGTYPE null_signal_handler(int sig); +SIGHANDLERTYPE set_signal_handler(int sig, SIGHANDLERTYPE handler); int daemonize(const char *, void (*)(int)); char *fm_getpassword(char *); void escapes(const char *, char *); @@ -77,7 +77,7 @@ char *prompt; register int c; FILE *fi; static char pbuf[INPUT_BUF_SIZE]; - RETSIGTYPE (*sig)(int) = 0; /* initialization pacifies -Wall */ + SIGHANDLERTYPE sig = 0; /* initialization pacifies -Wall */ RETSIGTYPE sigint_handler(int); int istty = isatty(0); @@ -103,7 +103,7 @@ char *prompt; /* now that we have the current tty state, we can catch SIGINT and exit gracefully */ - sig = signal(SIGINT, sigint_handler); + sig = set_signal_handler(SIGINT, sigint_handler); /* turn off echo on the tty */ disable_tty_echo(); @@ -129,7 +129,7 @@ char *prompt; restore_tty_state(); /* restore previous state of SIGINT */ - signal(SIGINT, sig); + set_signal_handler(SIGINT, sig); } if (fi != stdin) fclose(fi); /* not checking should be safe, file mode was "r" */ @@ -43,9 +43,9 @@ volatile int lastsig; /* last signal received */ */ static sig_atomic_t alarm_latch = FALSE; -void gotsigalrm(int sig) +RETSIGTYPE gotsigalrm(int sig) { - signal(sig, gotsigalrm); + set_signal_handler(sig, gotsigalrm); lastsig = sig; alarm_latch = TRUE; } @@ -109,9 +109,8 @@ int interruptible_idle(int seconds) ntimeout.it_value.tv_sec = seconds; ntimeout.it_value.tv_usec = 0; - siginterrupt(SIGALRM, 1); alarm_latch = FALSE; - signal(SIGALRM, gotsigalrm); /* first trap signals */ + set_signal_handler(SIGALRM, gotsigalrm); /* first trap signals */ setitimer(ITIMER_REAL,&ntimeout,NULL); /* then start timer */ /* there is a very small window between the next two lines */ /* which could result in a deadlock. But this will now be */ @@ -122,7 +121,7 @@ int interruptible_idle(int seconds) ntimeout.it_interval.tv_sec = ntimeout.it_interval.tv_usec = 0; ntimeout.it_value.tv_sec = ntimeout.it_value.tv_usec = 0; setitimer(ITIMER_REAL,&ntimeout,NULL); /* now stop timer */ - signal(SIGALRM, SIG_IGN); + set_signal_handler(SIGALRM, SIG_IGN); } #else /* @@ -148,21 +147,21 @@ int interruptible_idle(int seconds) #endif #else /* EMX */ alarm_latch = FALSE; - signal(SIGALRM, gotsigalrm); + set_signal_handler(SIGALRM, gotsigalrm); _beginthread(itimerthread, NULL, 32768, NULL); /* see similar code above */ if (!alarm_latch) pause(); - signal(SIGALRM, SIG_IGN); + set_signal_handler(SIGALRM, SIG_IGN); #endif /* ! EMX */ if (lastsig == SIGUSR1 || ((seconds && getuid() == ROOT_UID) && lastsig == SIGHUP)) awoken = TRUE; /* now lock out interrupts again */ - signal(SIGUSR1, SIG_IGN); + set_signal_handler(SIGUSR1, SIG_IGN); if (getuid() == ROOT_UID) - signal(SIGHUP, SIG_IGN); + set_signal_handler(SIGHUP, SIG_IGN); return(awoken ? lastsig : 0); } @@ -1011,9 +1011,6 @@ static int open_mda_sink(struct query *ctl, struct msgblk *msg, int *good_addresses, int *bad_addresses) /* open a stream to a local MDA */ { -#ifdef HAVE_SIGACTION - struct sigaction sa_new; -#endif /* HAVE_SIGACTION */ #ifdef HAVE_SETEUID uid_t orig_uid; #endif /* HAVE_SETEUID */ @@ -1166,14 +1163,7 @@ static int open_mda_sink(struct query *ctl, struct msgblk *msg, * sigchld_handler() would reap away the error status, returning * error status instead of 0 for successful completion. */ -#ifndef HAVE_SIGACTION - signal(SIGCHLD, SIG_DFL); -#else - memset (&sa_new, 0, sizeof sa_new); - sigemptyset (&sa_new.sa_mask); - sa_new.sa_handler = SIG_DFL; - sigaction (SIGCHLD, &sa_new, NULL); -#endif /* HAVE_SIGACTION */ + set_signal_handler(SIGCHLD, SIG_DFL); return(PS_SUCCESS); } @@ -323,16 +323,13 @@ int SMTP_eom(int sock) return ok; } -/* ignore SIGALRM signal indicating a timeout during smtp ok */ -static void smtp_timeout_handler (int signal) { } - int SMTP_ok(int sock) /* returns status of SMTP connection */ { - void (*alrmsave)(int); + SIGHANDLERTYPE alrmsave; /* set an alarm for smtp ok */ - alrmsave = signal(SIGALRM, smtp_timeout_handler); + alrmsave = set_signal_handler(SIGALRM, null_signal_handler); set_timeout(mytimeout); while ((SockRead(sock, smtp_response, sizeof(smtp_response)-1)) != -1) @@ -341,7 +338,7 @@ int SMTP_ok(int sock) /* restore alarm */ set_timeout(0); - signal(SIGALRM, alrmsave); + set_signal_handler(SIGALRM, alrmsave); n = strlen(smtp_response); if (n > 0 && smtp_response[n-1] == '\n') @@ -366,14 +363,14 @@ int SMTP_ok(int sock) return SM_ERROR; /* set an alarm for smtp ok */ - signal(SIGALRM, smtp_timeout_handler); + set_signal_handler(SIGALRM, null_signal_handler); set_timeout(mytimeout); } /* restore alarm */ set_timeout(0); - signal(SIGALRM, alrmsave); + set_signal_handler(SIGALRM, alrmsave); if (outlevel >= O_MONITOR) report(stderr, GT_("smtp listener protocol error\n")); |