X-Git-Url: https://vcs.fsf.org/?p=exim.git;a=blobdiff_plain;f=src%2Fsrc%2Ftransport.c;h=869e87f1691e14f3f6947f24896820ab174865a1;hp=fdd97822ae6c1c572374636e93be192bfb7dd690;hb=c193398df07b9917b917b38030c4544271024474;hpb=58fc5fb2eec65bc0b1c7f5e571e3c534cf008b88 diff --git a/src/src/transport.c b/src/src/transport.c index fdd97822a..869e87f16 100644 --- a/src/src/transport.c +++ b/src/src/transport.c @@ -108,10 +108,23 @@ optionlist optionlist_transports[] = { (void *)offsetof(transport_instance, uid) } }; -int optionlist_transports_size = - sizeof(optionlist_transports)/sizeof(optionlist); +int optionlist_transports_size = nelem(optionlist_transports); +void +readconf_options_transports(void) +{ +struct transport_info * ti; + +readconf_options_from_list(optionlist_transports, nelem(optionlist_transports), US"TP"); + +for (ti = transports_available; ti->driver_name[0]; ti++) + { + macro_create(string_sprintf("_DRVR_TPT_%T", ti->driver_name), US"y", FALSE); + readconf_options_from_list(ti->options, (unsigned)*ti->options_count, ti->driver_name); + } +} + /************************************************* * Initialize transport list * *************************************************/ @@ -139,14 +152,11 @@ readconf_driver_init(US"transport", /* Now scan the configured transports and check inconsistencies. A shadow transport is permitted only for local transports. */ -for (t = transports; t != NULL; t = t->next) +for (t = transports; t; t = t->next) { - if (!t->info->local) - { - if (t->shadow != NULL) - log_write(0, LOG_PANIC_DIE|LOG_CONFIG, - "shadow transport not allowed on non-local transport %s", t->name); - } + if (!t->info->local && t->shadow) + log_write(0, LOG_PANIC_DIE|LOG_CONFIG, + "shadow transport not allowed on non-local transport %s", t->name); if (t->body_only && t->headers_only) log_write(0, LOG_PANIC_DIE|LOG_CONFIG, @@ -944,7 +954,7 @@ suboptimal. */ if (tctx->options & topt_use_bdat) { off_t fsize; - int hsize, size; + int hsize, size = 0; if ((hsize = chunk_ptr - deliver_out_buffer) < 0) hsize = 0; @@ -1081,7 +1091,8 @@ if ((dkim_fd = Uopen(dkim_spool_name, O_RDWR|O_CREAT|O_TRUNC, SPOOL_MODE)) < 0) goto CLEANUP; } -/* Call original function to write the -K file; does the CRLF expansion */ +/* Call original function to write the -K file; does the CRLF expansion +(but, in the CHUNKING case, not dot-stuffing and dot-termination). */ options = tctx->options; tctx->options &= ~topt_use_bdat; @@ -1096,14 +1107,9 @@ if (!rc) } /* Rewind file and feed it to the goats^W DKIM lib */ +dkim->dot_stuffed = !!(options & topt_end_dot); lseek(dkim_fd, 0, SEEK_SET); -dkim_signature = dkim_exim_sign(dkim_fd, - dkim->dkim_private_key, - dkim->dkim_domain, - dkim->dkim_selector, - dkim->dkim_canon, - dkim->dkim_sign_headers); -if (dkim_signature) +if ((dkim_signature = dkim_exim_sign(dkim_fd, dkim))) siglen = Ustrlen(dkim_signature); else if (dkim->dkim_strict) { @@ -1179,17 +1185,17 @@ else /* Send file down the original fd */ while((sread = read(dkim_fd, deliver_out_buffer, DELIVER_OUT_BUFFER_SIZE)) >0) { - char *p = deliver_out_buffer; + uschar * p = deliver_out_buffer; /* write the chunk */ while (sread) { #ifdef SUPPORT_TLS wwritten = tls_out.active == out_fd - ? tls_write(FALSE, US p, sread) - : write(out_fd, p, sread); + ? tls_write(FALSE, p, sread) + : write(out_fd, CS p, sread); #else - wwritten = write(out_fd, p, sread); + wwritten = write(out_fd, CS p, sread); #endif if (wwritten == -1) goto err; @@ -1242,7 +1248,6 @@ Returns: TRUE on success; FALSE (with errno) for any failure BOOL transport_write_message(int fd, transport_ctx * tctx, int size_limit) { -unsigned wck_flags; BOOL last_filter_was_NL = TRUE; int rc, len, yield, fd_read, fd_write, save_errno; int pfd[2] = {-1, -1}; @@ -1266,7 +1271,6 @@ if ( !transport_filter_argv before being written to the incoming fd. First set up the special processing to be done during the copying. */ -wck_flags = tctx->options & topt_use_crlf; nl_partial_match = -1; if (tctx->check_string && tctx->escape_string) @@ -1290,10 +1294,13 @@ save_errno = 0; yield = FALSE; write_pid = (pid_t)(-1); -(void)fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC); -filter_pid = child_open(USS transport_filter_argv, NULL, 077, - &fd_write, &fd_read, FALSE); -(void)fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) & ~FD_CLOEXEC); + { + int bits = fcntl(fd, F_GETFD); + (void)fcntl(fd, F_SETFD, bits | FD_CLOEXEC); + filter_pid = child_open(USS transport_filter_argv, NULL, 077, + &fd_write, &fd_read, FALSE); + (void)fcntl(fd, F_SETFD, bits & ~FD_CLOEXEC); + } if (filter_pid < 0) goto TIDY_UP; /* errno set */ DEBUG(D_transport) @@ -1432,14 +1439,19 @@ if (write_pid > 0) { rc = child_close(write_pid, 30); if (yield) - { if (rc == 0) { BOOL ok; - int dummy = read(pfd[pipe_read], (void *)&ok, sizeof(BOOL)); - if (!ok) + if (read(pfd[pipe_read], (void *)&ok, sizeof(BOOL)) != sizeof(BOOL)) + { + DEBUG(D_transport) + debug_printf("pipe read from writing process: %s\n", strerror(errno)); + save_errno = ERRNO_FILTER_FAIL; + yield = FALSE; + } + else if (!ok) { - dummy = read(pfd[pipe_read], (void *)&save_errno, sizeof(int)); + int dummy = read(pfd[pipe_read], (void *)&save_errno, sizeof(int)); dummy = read(pfd[pipe_read], (void *)&(tctx->addr->more_errno), sizeof(int)); yield = FALSE; } @@ -1451,7 +1463,6 @@ if (write_pid > 0) tctx->addr->more_errno = rc; DEBUG(D_transport) debug_printf("writing process returned %d\n", rc); } - } } (void)close(pfd[pipe_read]); @@ -1765,7 +1776,7 @@ while (1) /* create an array to read entire message queue into memory for processing */ - msgq = (msgq_t*) malloc(sizeof(msgq_t) * host_record->count); + msgq = store_malloc(sizeof(msgq_t) * host_record->count); msgq_count = host_record->count; msgq_actual = msgq_count; @@ -1873,7 +1884,7 @@ test but the code should work */ if (bFound) /* Usual exit from main loop */ { - free (msgq); + store_free (msgq); break; } @@ -1899,7 +1910,7 @@ test but the code should work */ return FALSE; } - free(msgq); + store_free(msgq); } /* we need to process a continuation record */ /* Control gets here when an existing message has been encountered; its