#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. */
-
-struct aci {
- struct aci *next;
- address_item *ptr;
- };
-
-
-/* Static data for write_chunk() */
-
-static uschar *chunk_ptr; /* chunk pointer */
-static uschar *nl_check; /* string to look for at line start */
-static int nl_check_length; /* length of same */
-static uschar *nl_escape; /* string to insert */
-static int nl_escape_length; /* length of same */
-static int nl_partial_match; /* length matched at chunk end */
-
-
/* Generic options for transports, all of which live inside transport_instance
data blocks and which therefore have the opt_public flag set. Note that there
are other options living inside this structure which can be set only from
int optionlist_transports_size = nelem(optionlist_transports);
+#ifdef MACRO_PREDEF
+
+# include "macro_predef.h"
void
-readconf_options_transports(void)
+options_transports(void)
{
struct transport_info * ti;
+uschar buf[64];
-readconf_options_from_list(optionlist_transports, nelem(optionlist_transports), US"TRANSPORTS", NULL);
+options_from_list(optionlist_transports, nelem(optionlist_transports), US"TRANSPORTS", NULL);
for (ti = transports_available; ti->driver_name[0]; ti++)
{
- macro_create(string_sprintf("_DRIVER_TRANSPORT_%T", ti->driver_name), US"y", FALSE, TRUE);
- readconf_options_from_list(ti->options, (unsigned)*ti->options_count, US"TRANSPORT", ti->driver_name);
+ spf(buf, sizeof(buf), "_DRIVER_TRANSPORT_%T", ti->driver_name);
+ builtin_macro_create(buf);
+ options_from_list(ti->options, (unsigned)*ti->options_count, US"TRANSPORT", ti->driver_name);
}
}
+#else /*!MACRO_PREDEF*/
+
+/* Structure for keeping list of addresses that have been added to
+Envelope-To:, in order to avoid duplication. */
+
+struct aci {
+ struct aci *next;
+ address_item *ptr;
+ };
+
+
+/* Static data for write_chunk() */
+
+static uschar *chunk_ptr; /* chunk pointer */
+static uschar *nl_check; /* string to look for at line start */
+static int nl_check_length; /* length of same */
+static uschar *nl_escape; /* string to insert */
+static int nl_escape_length; /* length of same */
+static int nl_partial_match; /* length matched at chunk end */
+
+
/*************************************************
* Initialize transport list *
*************************************************/
tctx transport context: file descriptor or string to write to
block block of bytes to write
len number of bytes to write
+ more further data expected soon
Returns: TRUE on success, FALSE on failure (with errno preserved);
transport_count is incremented by the number of bytes written
{
rc =
#ifdef SUPPORT_TLS
- (tls_out.active == fd) ? tls_write(FALSE, block, len) :
+ tls_out.active == fd ? tls_write(FALSE, block, len, more) :
#endif
#ifdef MSG_MORE
more ? send(fd, block, len, MSG_MORE) :
rc =
#ifdef SUPPORT_TLS
- (tls_out.active == fd) ? tls_write(FALSE, block, len) :
+ tls_out.active == fd ? tls_write(FALSE, block, len, more) :
#endif
#ifdef MSG_MORE
more ? send(fd, block, len, MSG_MORE) :
/* If CHUNKING, prefix with BDAT (size) NON-LAST. Also, reap responses
from previous SMTP commands. */
- if (tctx && tctx->options & topt_use_bdat && tctx->chunk_cb)
+ if (tctx->options & topt_use_bdat && tctx->chunk_cb)
{
if ( tctx->chunk_cb(tctx, (unsigned)len, 0) != OK
|| !transport_write_block(tctx, deliver_out_buffer, len, FALSE)
/* Remove CR before NL if required */
if ( *ptr == '\r' && ptr[1] == '\n'
- && (!tctx || !(tctx->options & topt_use_crlf))
+ && !(tctx->options & topt_use_crlf)
&& spool_file_wireformat
)
ptr++;
/* Insert CR before NL if required */
- if (tctx && tctx->options & topt_use_crlf && !spool_file_wireformat)
+ if (tctx->options & topt_use_crlf && !spool_file_wireformat)
*chunk_ptr++ = '\r';
*chunk_ptr++ = '\n';
transport_newlines++;
is incremented by the number of bytes written.
*/
-BOOL
+static BOOL
internal_transport_write_message(transport_ctx * tctx, int size_limit)
{
int len, size = 0;
if (tctx->options & topt_add_delivery_date)
{
- uschar buffer[100];
- int n = sprintf(CS buffer, "Delivery-date: %s\n", tod_stamp(tod_full));
- if (!write_chunk(tctx, buffer, n)) goto bad;
+ uschar * s = tod_stamp(tod_full);
+
+ if ( !write_chunk(tctx, US"Delivery-date: ", 15)
+ || !write_chunk(tctx, s, Ustrlen(s))
+ || !write_chunk(tctx, US"\n", 1)) goto bad;
}
/* Then the message's headers. Don't write any that are flagged as "old";
This should get used for CHUNKING output and also for writing the -K file for
dkim signing, when we had CHUNKING input. */
-#ifdef HAVE_LINUX_SENDFILE
+#ifdef OS_SENDFILE
if ( spool_file_wireformat
&& !(tctx->options & (topt_no_body | topt_end_dot))
&& !nl_check_length
while(size > 0)
{
- if ((copied = sendfile(tctx->u.fd, deliver_datafile, &offset, size)) <= 0) break;
+ if ((copied = os_sendfile(tctx->u.fd, deliver_datafile, &offset, size)) <= 0) break;
size -= copied;
}
return copied >= 0;
argv = CUSS child_exec_exim(CEE_RETURN_ARGV, TRUE, &i, FALSE, 0);
if (smtp_authenticated) argv[i++] = US"-MCA";
-if (smtp_peer_options & PEER_OFFERED_CHUNKING) argv[i++] = US"-MCK";
-if (smtp_peer_options & PEER_OFFERED_DSN) argv[i++] = US"-MCD";
-if (smtp_peer_options & PEER_OFFERED_PIPE) argv[i++] = US"-MCP";
-if (smtp_peer_options & PEER_OFFERED_SIZE) argv[i++] = US"-MCS";
+if (smtp_peer_options & OPTION_CHUNKING) argv[i++] = US"-MCK";
+if (smtp_peer_options & OPTION_DSN) argv[i++] = US"-MCD";
+if (smtp_peer_options & OPTION_PIPE) argv[i++] = US"-MCP";
+if (smtp_peer_options & OPTION_SIZE) argv[i++] = US"-MCS";
#ifdef SUPPORT_TLS
-if (smtp_peer_options & PEER_OFFERED_TLS)
+if (smtp_peer_options & OPTION_TLS)
if (tls_out.active >= 0 || continue_proxy_cipher)
{
argv[i++] = US"-MCt";
write the log, etc., so that the output is always in the same order for
automatic comparison. */
- if ((pid = fork()) != 0) _exit(EXIT_SUCCESS);
+ if ((pid = fork()) != 0)
+ {
+ DEBUG(D_transport) debug_printf("transport_pass_socket succeeded (final-pid %d)\n", pid);
+ _exit(EXIT_SUCCESS);
+ }
if (running_in_test_harness) sleep(1);
transport_do_pass_socket(transport_name, hostname, hostaddress,
{
int rc;
while ((rc = wait(&status)) != pid && (rc >= 0 || errno != ECHILD));
- DEBUG(D_transport) debug_printf("transport_pass_socket succeeded\n");
+ DEBUG(D_transport) debug_printf("transport_pass_socket succeeded (inter-pid %d)\n", pid);
return TRUE;
}
else
return TRUE;
}
+#endif /*!MACRO_PREDEF*/
/* vi: aw ai sw=2
*/
/* End of transport.c */