X-Git-Url: http://git.claws-mail.org/?p=claws.git;a=blobdiff_plain;f=src%2Fplugins%2Fspamassassin%2Futils.c;h=62d9c688dd301c1ce0656e51b21ba9c1fc807dd6;hp=e21280832ebcc46f6898dff96070a5d90b809ac3;hb=6f3002f0bad92101b004ef76090d3add7cf24be2;hpb=f5603666f278373a531b677845a9a34e8abb94a9 diff --git a/src/plugins/spamassassin/utils.c b/src/plugins/spamassassin/utils.c index e21280832..62d9c688d 100644 --- a/src/plugins/spamassassin/utils.c +++ b/src/plugins/spamassassin/utils.c @@ -1,13 +1,18 @@ /* * This code is copyright 2001 by Craig Hughes * Portions copyright 2002 by Brad Jorsch - * It is licensed for use with SpamAssassin according to the terms of the Perl Artistic License - * The text of this license is included in the SpamAssassin distribution in the file named "License" + * It is licensed under the same license as Perl itself. The text of this + * license is included in the SpamAssassin distribution in the file named + * "License". */ #include #include - +#include +#include +#include +#include +#include #include "utils.h" /* Dec 13 2001 jm: added safe full-read and full-write functions. These @@ -16,17 +21,62 @@ */ /* Aug 14, 2002 bj: EINTR and EAGAIN aren't fatal, are they? */ /* Aug 14, 2002 bj: moved these to utils.c */ +/* Jan 13, 2003 ym: added timeout functionality */ + +typedef void sigfunc(int); /* for signal handlers */ + +sigfunc* sig_catch(int sig, void (*f)(int)) +{ + struct sigaction act, oact; + act.sa_handler = f; + act.sa_flags = 0; + sigemptyset(&act.sa_mask); + sigaction(sig, &act, &oact); + return oact.sa_handler; +} + +static void catch_alrm(int x) { + /* dummy */ +} + +ssize_t timeout_read(ssize_t (*reader)(int d, void *buf, size_t nbytes), + int fd, void *buf, size_t nbytes) { + ssize_t nred; + sigfunc* sig; + + sig = sig_catch(SIGALRM, catch_alrm); + if (libspamc_timeout > 0) { + alarm(libspamc_timeout); + } + + do { + nred = reader(fd, buf, nbytes); + } while(nred < 0 && errno == EAGAIN); + + if(nred < 0 && errno == EINTR) + errno = ETIMEDOUT; + + if (libspamc_timeout > 0) { + alarm(0); + } + + /* restore old signal handler */ + sig_catch(SIGALRM, sig); + + return nred; +} + int full_read (int fd, unsigned char *buf, int min, int len) { int total; int thistime; + for (total = 0; total < min; ) { - thistime = read (fd, buf+total, len-total); + thistime = timeout_read (read, fd, buf+total, len-total); if (thistime < 0) { - if(EINTR == errno || EAGAIN == errno) continue; return -1; } else if (thistime == 0) { /* EOF, but we didn't read the minimum. return what we've read