diff options
-rw-r--r-- | src/OS/os.h-Linux | 3 | ||||
-rw-r--r-- | src/src/dk.c | 66 | ||||
-rw-r--r-- | src/src/transport.c | 41 |
3 files changed, 73 insertions, 37 deletions
diff --git a/src/OS/os.h-Linux b/src/OS/os.h-Linux index 285e8d28f..5b731eaa1 100644 --- a/src/OS/os.h-Linux +++ b/src/OS/os.h-Linux @@ -1,4 +1,4 @@ -/* $Cambridge: exim/src/OS/os.h-Linux,v 1.3 2005/02/17 10:04:41 ph10 Exp $ */ +/* $Cambridge: exim/src/OS/os.h-Linux,v 1.4 2006/10/30 22:06:33 tom Exp $ */ /* Exim: OS-specific C header file for Linux */ @@ -7,6 +7,7 @@ #define HAVE_MMAP #define HAVE_BSD_GETLOADAVG #define HAVE_SYS_STATVFS_H +#define HAVE_LINUX_SENDFILE #define NO_IP_VAR_H #define SIG_IGN_WORKS diff --git a/src/src/dk.c b/src/src/dk.c index ddab48b74..9ed82382b 100644 --- a/src/src/dk.c +++ b/src/src/dk.c @@ -1,4 +1,4 @@ -/* $Cambridge: exim/src/src/dk.c,v 1.10 2006/07/06 14:28:04 ph10 Exp $ */ +/* $Cambridge: exim/src/src/dk.c,v 1.11 2006/10/30 22:06:33 tom Exp $ */ /************************************************* * Exim - an Internet mail transport agent * @@ -242,7 +242,7 @@ uschar *dk_exim_sign(int dk_fd, uschar *headers = NULL; int headers_len; int dk_canon_int = DK_CANON_SIMPLE; - char c; + char buf[4096]; int seen_lf = 0; int seen_lfdot = 0; uschar sig[1024]; @@ -271,40 +271,46 @@ uschar *dk_exim_sign(int dk_fd, goto CLEANUP; } - while((sread = read(dk_fd,&c,1)) > 0) { + while((sread = read(dk_fd,&buf,4096)) > 0) { + int pos = 0; + char c; - if ((c == '.') && seen_lfdot) { - /* escaped dot, write "\n.", continue */ - dk_message(dk_context, CUS "\n.", 2); - seen_lf = 0; - seen_lfdot = 0; - continue; - } + while (pos < sread) { + c = buf[pos++]; - if (seen_lfdot) { - /* EOM, write "\n" and break */ - dk_message(dk_context, CUS "\n", 1); - break; - } + if ((c == '.') && seen_lfdot) { + /* escaped dot, write "\n.", continue */ + dk_message(dk_context, CUS "\n.", 2); + seen_lf = 0; + seen_lfdot = 0; + continue; + } - if ((c == '.') && seen_lf) { - seen_lfdot = 1; - continue; - } + if (seen_lfdot) { + /* EOM, write "\n" and break */ + dk_message(dk_context, CUS "\n", 1); + break; + } - if (seen_lf) { - /* normal lf, just send it */ - dk_message(dk_context, CUS "\n", 1); - seen_lf = 0; - } + if ((c == '.') && seen_lf) { + seen_lfdot = 1; + continue; + } - if (c == '\n') { - seen_lf = 1; - continue; - } + if (seen_lf) { + /* normal lf, just send it */ + dk_message(dk_context, CUS "\n", 1); + seen_lf = 0; + } - /* write the char */ - dk_message(dk_context, CUS &c, 1); + if (c == '\n') { + seen_lf = 1; + continue; + } + + /* write the char */ + dk_message(dk_context, CUS &c, 1); + } } /* Handle failed read above. */ diff --git a/src/src/transport.c b/src/src/transport.c index e6ad3c0c4..03d73f9ba 100644 --- a/src/src/transport.c +++ b/src/src/transport.c @@ -1,4 +1,4 @@ -/* $Cambridge: exim/src/src/transport.c,v 1.16 2006/10/30 16:41:04 ph10 Exp $ */ +/* $Cambridge: exim/src/src/transport.c,v 1.17 2006/10/30 22:06:33 tom Exp $ */ /************************************************* * Exim - an Internet mail transport agent * @@ -13,6 +13,9 @@ transports. */ #include "exim.h" +#ifdef HAVE_LINUX_SENDFILE +#include <sys/sendfile.h> +#endif /* Structure for keeping list of addresses that have been added to Envelope-To:, in order to avoid duplication. */ @@ -983,10 +986,11 @@ dk_transport_write_message(address_item *addr, int fd, int options, int sread = 0; int wwritten = 0; uschar *dk_signature = NULL; + off_t size = 0; - (void)string_format(dk_spool_name, 256, "%s/input/%s/%s-K", - spool_directory, message_subdir, message_id); - dk_fd = Uopen(dk_spool_name, O_RDWR|O_CREAT|O_EXCL, SPOOL_MODE); + (void)string_format(dk_spool_name, 256, "%s/input/%s/%s-%d-K", + spool_directory, message_subdir, message_id, (int)getpid()); + dk_fd = Uopen(dk_spool_name, O_RDWR|O_CREAT|O_TRUNC, SPOOL_MODE); if (dk_fd < 0) { /* Can't create spool file. Ugh. */ @@ -1052,9 +1056,35 @@ dk_transport_write_message(address_item *addr, int fd, int options, } } - /* Rewind file and send it down the original fd. */ + /* Fetch file positition (the size) */ + size = lseek(dk_fd,0,SEEK_CUR); + + /* Rewind file */ lseek(dk_fd, 0, SEEK_SET); +#ifdef HAVE_LINUX_SENDFILE + /* We can use sendfile() to shove the file contents + to the socket. However only if we don't use TLS, + in which case theres another layer of indirection + before the data finally hits the socket. */ + if (tls_active != fd) + { + ssize_t copied = 0; + off_t offset = 0; + while((copied >= 0) && (offset<size)) + { + copied = sendfile(fd, dk_fd, &offset, (size - offset)); + } + if (copied < 0) + { + save_errno = errno; + rc = FALSE; + } + goto CLEANUP; + } +#endif + + /* Send file down the original fd */ while((sread = read(dk_fd,sbuf,2048)) > 0) { char *p = sbuf; @@ -1087,7 +1117,6 @@ dk_transport_write_message(address_item *addr, int fd, int options, goto CLEANUP; } - CLEANUP: /* unlink -K file */ (void)close(dk_fd); |