diff -urNp vpopmail-5.0.1.orig/Makefile.am vpopmail-5.0.1/Makefile.am --- vpopmail-5.0.1.orig/Makefile.am Wed Nov 21 22:06:17 2001 +++ vpopmail-5.0.1/Makefile.am Thu Jan 3 19:41:38 2002 @@ -4,7 +4,7 @@ SUBDIRS=cdb noinst_LIBRARIES=libvpopmail.a -COMMONSOURCES=vpopmail.c md5.c bigdir.c vauth.c file_lock.c vpalias.c +COMMONSOURCES=vpopmail.c md5.c bigdir.c vauth.c file_lock.c vpalias.c seek.c CONFIG_CLEAN_FILES=vauth.c libvpopmail_a_SOURCES=$(COMMONSOURCES) diff -urNp vpopmail-5.0.1.orig/Makefile.in vpopmail-5.0.1/Makefile.in --- vpopmail-5.0.1.orig/Makefile.in Mon Dec 3 23:01:56 2001 +++ vpopmail-5.0.1/Makefile.in Thu Jan 3 19:41:58 2002 @@ -75,7 +75,7 @@ SUBDIRS = cdb noinst_LIBRARIES = libvpopmail.a -COMMONSOURCES = vpopmail.c md5.c bigdir.c vauth.c file_lock.c vpalias.c +COMMONSOURCES = vpopmail.c md5.c bigdir.c vauth.c file_lock.c vpalias.c seek.c CONFIG_CLEAN_FILES = vauth.c libvpopmail_a_SOURCES = $(COMMONSOURCES) @@ -158,7 +158,7 @@ LDFLAGS = @LDFLAGS@ LIBS = @LIBS@ libvpopmail_a_DEPENDENCIES = cdb/*.o libvpopmail_a_OBJECTS = vpopmail.o md5.o bigdir.o vauth.o file_lock.o \ -vpalias.o +vpalias.o seek.o AR = ar PROGRAMS = $(vpopmailbin_PROGRAMS) diff -urNp vpopmail-5.0.1.orig/seek.c vpopmail-5.0.1/seek.c --- vpopmail-5.0.1.orig/seek.c Thu Jan 1 01:00:00 1970 +++ vpopmail-5.0.1/seek.c Thu Jan 3 20:14:42 2002 @@ -0,0 +1,87 @@ +/* + * Copyright (c) 1987 University of Maryland Computer Science Department. + * All rights reserved. + * Permission to copy for any purpose is hereby granted so long as this + * copyright notice remains intact. + * + * Changed MakeSeekable to use tmpfile() - marcus@quintic.co.uk + */ + +/* + * Seekable is a predicate which returns true iff a Unix fd is seekable. + * + * MakeSeekable forces an input stdio file to be seekable, by copying to + * a temporary file if necessary. + */ + +#include +#include +#include +#include +#include +#include + +long lseek(); +char *getenv(); + +int +Seekable(fd) + int fd; +{ + + return (lseek(fd, 0L, 1) >= 0 && !isatty(fd)); +} + +int +MakeSeekable(f) + register FILE *f; +{ + register int tf, n; + FILE *tmpf; + int blksize; +#ifdef MAXBSIZE + char buf[MAXBSIZE]; + struct stat st; +#else + char buf[BUFSIZ]; +#endif + + if (Seekable(fileno(f))) + return (0); + + tmpf = tmpfile(); /* tmpfile() is not safe on all systems */ + tf = fileno(tmpf); + + /* copy from input file to temp file */ +#ifdef MAXBSIZE + if (fstat(tf, &st)) /* how can this ever fail? */ + blksize = MAXBSIZE; + else + blksize = MIN(MAXBSIZE, st.st_blksize); +#else + blksize = BUFSIZ; +#endif + while ((n = fread(buf, 1, blksize, f)) > 0) { + if (write(tf, buf, n) != n) { + (void) close(tf); + return (-1); + } + } + /* ferror() is broken in Ultrix 1.2; hence the && */ + if (ferror(f) && !feof(f)) { + (void) close(tf); + return (-1); + } + + /* + * Now switch f to point at the temp file. Since we hit EOF, there + * is nothing in f's stdio buffers, so we can play a dirty trick: + */ + clearerr(f); + if (dup2(tf, fileno(f))) { + (void) close(tf); + return (-1); + } + (void) close(tf); + return (0); +} diff -urNp vpopmail-5.0.1.orig/seek.h vpopmail-5.0.1/seek.h --- vpopmail-5.0.1.orig/seek.h Thu Jan 1 01:00:00 1970 +++ vpopmail-5.0.1/seek.h Thu Jan 3 20:43:21 2002 @@ -0,0 +1,16 @@ +/* + * Copyright (c) 1987 University of Maryland Computer Science Department. + * All rights reserved. + * Permission to copy for any purpose is hereby granted so long as this + * copyright notice remains intact. + */ + +/* + * Seekable is a predicate which returns true iff a Unix fd is seekable. + * + * MakeSeekable forces an input stdio file to be seekable, by copying to + * a temporary file if necessary. + */ + +int Seekable(int fd); +int MakeSeekable(register FILE *f); diff -urNp vpopmail-5.0.1.orig/vdelivermail.c vpopmail-5.0.1/vdelivermail.c --- vpopmail-5.0.1.orig/vdelivermail.c Mon Dec 3 23:01:02 2001 +++ vpopmail-5.0.1/vdelivermail.c Fri Jan 4 15:04:52 2002 @@ -35,6 +35,7 @@ #include "config.h" #include "vpopmail.h" #include "vauth.h" +#include "seek.h" /* Globals */ #define AUTH_SIZE 300 @@ -408,6 +409,10 @@ int deliver_mail(char *address, char *qu return(-3); } + /* at this point we know the message size - if its 0 drop out silently */ + if (message_size==0) + return(0); + /* This is a directory/Maildir location */ if ( *address == '/' ) { @@ -494,6 +499,9 @@ int deliver_mail(char *address, char *qu "%sDelivered-To: %s\n", getenv("RPLINE"), dtline); } + if (!Seekable(0)) + MakeSeekable(stdin); + if ( lseek(0, 0L, SEEK_SET) < 0 ) { printf("lseek errno=%d\n", errno); return(errno); @@ -670,6 +678,9 @@ void run_command(char *prog) while (*prog==' ') ++prog; while (*prog=='|') ++prog; + if (!Seekable(0)) + MakeSeekable(stdin); + if ( lseek(0, 0L, SEEK_SET) < 0 ) { printf("lseek errno=%d\n", errno); return; @@ -720,6 +731,9 @@ int is_looping( char *address ) return(1); } + if (!Seekable(0)) + MakeSeekable(stdin); + lseek(0,0L,SEEK_SET); while(fgets(loop_buf,sizeof(loop_buf),stdin)!=NULL){ @@ -786,6 +800,9 @@ off_t get_message_size() { ssize_t message_size; ssize_t bytes; + + if (!Seekable(0)) + MakeSeekable(stdin); if ( lseek(0, 0L,SEEK_SET) < 0 ) { printf("lseek error %d\n", errno);