X-Git-Url: https://git.exim.org/exim.git/blobdiff_plain/d315eda12f25ca2f72ca56b777a427c9ee7188e1..d5b80e59458182b2d557a929a18cb8c70cd56b68:/src/src/transport.c diff --git a/src/src/transport.c b/src/src/transport.c index 71fd9dac2..5d4102ef8 100644 --- a/src/src/transport.c +++ b/src/src/transport.c @@ -11,35 +11,13 @@ transports. */ #include "exim.h" -#ifdef HAVE_LINUX_SENDFILE -# include -#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 certain transports. */ optionlist optionlist_transports[] = { + /* name type value */ { "*expand_group", opt_stringptr|opt_hidden|opt_public, (void *)offsetof(transport_instance, expand_gid) }, { "*expand_user", opt_stringptr|opt_hidden|opt_public, @@ -110,21 +88,47 @@ optionlist optionlist_transports[] = { 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), US"_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 * *************************************************/ @@ -207,6 +211,7 @@ Arguments: 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 @@ -237,7 +242,7 @@ for (i = 0; i < 100; i++) { 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) : @@ -254,7 +259,7 @@ for (i = 0; i < 100; i++) 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) : @@ -370,7 +375,7 @@ Returns: the yield of transport_write_block() BOOL transport_write_string(int fd, const char *format, ...) { -transport_ctx tctx = {0}; +transport_ctx tctx = {{0}}; va_list ap; va_start(ap, format); if (!string_vformat(big_buffer, big_buffer_size, format, ap)) @@ -972,9 +977,11 @@ if (!(tctx->options & topt_no_headers)) 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"; @@ -1065,7 +1072,7 @@ then we can just dump it using sendfile. 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 @@ -1088,7 +1095,7 @@ if ( spool_file_wireformat 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; @@ -1169,7 +1176,6 @@ BOOL save_spool_file_wireformat = spool_file_wireformat; int rc, len, yield, fd_read, fd_write, save_errno; int pfd[2] = {-1, -1}; pid_t filter_pid, write_pid; -static transport_ctx dummy_tctx = {0}; transport_filter_timed_out = FALSE; @@ -1247,6 +1253,8 @@ if ((write_pid = fork()) == 0) != sizeof(int) || write(pfd[pipe_write], (void *)&tctx->addr->more_errno, sizeof(int)) != sizeof(int) + || write(pfd[pipe_write], (void *)&tctx->addr->delivery_usec, sizeof(int)) + != sizeof(int) ) rc = FALSE; /* compiler quietening */ _exit(0); @@ -1371,7 +1379,9 @@ if (write_pid > 0) else if (!ok) { int dummy = read(pfd[pipe_read], (void *)&save_errno, sizeof(int)); - dummy = read(pfd[pipe_read], (void *)&(tctx->addr->more_errno), sizeof(int)); + dummy = read(pfd[pipe_read], (void *)&tctx->addr->more_errno, sizeof(int)); + dummy = read(pfd[pipe_read], (void *)&tctx->addr->delivery_usec, sizeof(int)); + dummy = dummy; /* compiler quietening */ yield = FALSE; } } @@ -1860,12 +1870,12 @@ but we have a number of extras that may be added. */ 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"; @@ -1940,7 +1950,11 @@ if ((pid = fork()) == 0) 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, @@ -1955,7 +1969,7 @@ if (pid > 0) { 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 @@ -2037,7 +2051,7 @@ while (*s != 0 && argcount < max_args) while (isspace(*s)) s++; } -argv[argcount] = (uschar *)0; +argv[argcount] = US 0; /* If *s != 0 we have run out of argument slots. */ @@ -2073,7 +2087,7 @@ $recipients. */ DEBUG(D_transport) { debug_printf("direct command:\n"); - for (i = 0; argv[i] != (uschar *)0; i++) + for (i = 0; argv[i] != US 0; i++) debug_printf(" argv[%d] = %s\n", i, string_printing(argv[i])); } @@ -2083,7 +2097,7 @@ if (expand_arguments) addr->parent != NULL && Ustrcmp(addr->parent->address, "system-filter") == 0; - for (i = 0; argv[i] != (uschar *)0; i++) + for (i = 0; argv[i] != US 0; i++) { /* Handle special fudge for passing an address list */ @@ -2167,7 +2181,7 @@ if (expand_arguments) while (isspace(*s)) s++; /* strip space after arg */ } - address_pipe_argv[address_pipe_argcount] = (uschar *)0; + address_pipe_argv[address_pipe_argcount] = US 0; /* If *s != 0 we have run out of argument slots. */ if (*s != 0) @@ -2215,7 +2229,7 @@ if (expand_arguments) * [argv 0][argv 1][argv 2=pipeargv[0]][argv 3=pipeargv[1]][old argv 3][0] */ for (address_pipe_i = 0; - address_pipe_argv[address_pipe_i] != (uschar *)0; + address_pipe_argv[address_pipe_i] != US 0; address_pipe_i++) { argv[i++] = address_pipe_argv[address_pipe_i]; @@ -2256,7 +2270,7 @@ if (expand_arguments) DEBUG(D_transport) { debug_printf("direct command after expansion:\n"); - for (i = 0; argv[i] != (uschar *)0; i++) + for (i = 0; argv[i] != US 0; i++) debug_printf(" argv[%d] = %s\n", i, string_printing(argv[i])); } } @@ -2264,6 +2278,7 @@ if (expand_arguments) return TRUE; } +#endif /*!MACRO_PREDEF*/ /* vi: aw ai sw=2 */ /* End of transport.c */