summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/OS/os.h-Linux3
-rw-r--r--src/src/dk.c66
-rw-r--r--src/src/transport.c41
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);