-/* $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 */
#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
-/* $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 *
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];
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. */
-/* $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 *
#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. */
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. */
}
}
- /* 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;
goto CLEANUP;
}
-
CLEANUP:
/* unlink -K file */
(void)close(dk_fd);