X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=src%2Fsrc%2Fsmtp_out.c;h=5ab15cb5f3de4200082526187ae15ef645843e9a;hb=58fc5fb2eec65bc0b1c7f5e571e3c534cf008b88;hp=c704a0b0f2c9d879aed78602a5b1a6cb47a63a57;hpb=0539a19dc27efcfc77713a87aba6b61fef947249;p=user%2Fhenk%2Fcode%2Fexim.git diff --git a/src/src/smtp_out.c b/src/src/smtp_out.c index c704a0b0f..5ab15cb5f 100644 --- a/src/src/smtp_out.c +++ b/src/src/smtp_out.c @@ -2,7 +2,7 @@ * Exim - an Internet mail transport agent * *************************************************/ -/* Copyright (c) University of Cambridge 1995 - 2015 */ +/* Copyright (c) University of Cambridge 1995 - 2016 */ /* See the file NOTICE for conditions of use and distribution. */ /* A number of functions for driving outgoing SMTP calls. */ @@ -26,7 +26,6 @@ Arguments: which case the function does nothing host_af AF_INET or AF_INET6 for the outgoing IP address addr the mail address being handled (for setting errors) - changed if not NULL, set TRUE if expansion actually changed istring interface point this to the interface msg to add to any error message @@ -36,7 +35,7 @@ Returns: TRUE on success, FALSE on failure, with error message BOOL smtp_get_interface(uschar *istring, int host_af, address_item *addr, - BOOL *changed, uschar **interface, uschar *msg) + uschar **interface, uschar *msg) { const uschar * expint; uschar *iface; @@ -54,8 +53,6 @@ if (expint == NULL) return FALSE; } -if (changed != NULL) *changed = expint != istring; - while (isspace(*expint)) expint++; if (*expint == 0) return TRUE; @@ -158,7 +155,7 @@ int sock; int on = 1; int save_errno = 0; -#ifdef EXPERIMENTAL_EVENT +#ifndef DISABLE_EVENT deliver_host_address = host->address; deliver_host_port = port; if (event_raise(tb->event_action, US"tcp:connect", NULL)) return -1; @@ -168,7 +165,9 @@ if ((sock = ip_socket(SOCK_STREAM, host_af)) < 0) return -1; /* Set TCP_NODELAY; Exim does its own buffering. */ -setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (uschar *)(&on), sizeof(on)); +if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, US &on, sizeof(on))) + HDEBUG(D_transport|D_acl|D_v) + debug_printf("failed to set NODELAY: %s ", strerror(errno)); /* Set DSCP value, if we can. For now, if we fail to set the value, we don't bomb out, just log it and continue in default traffic class. */ @@ -270,7 +269,7 @@ int smtp_connect(host_item *host, int host_af, int port, uschar *interface, int timeout, transport_instance * tb) { -#ifdef EXPERIMENTAL_SOCKS +#ifdef SUPPORT_SOCKS smtp_transport_options_block * ob = (smtp_transport_options_block *)tb->options_block; #endif @@ -284,20 +283,21 @@ if (host->port != PORT_NONE) } else host->port = port; /* Set the port actually used */ +callout_address = string_sprintf("[%s]:%d", host->address, port); + HDEBUG(D_transport|D_acl|D_v) { uschar * s = US" "; if (interface) s = string_sprintf(" from %s ", interface); -#ifdef EXPERIMENTAL_SOCKS +#ifdef SUPPORT_SOCKS if (ob->socks_proxy) s = string_sprintf("%svia proxy ", s); #endif - debug_printf("Connecting to %s [%s]:%d%s... ", - host->name, host->address, port, s); + debug_printf("Connecting to %s %s%s... ", host->name, callout_address, s); } /* Create and connect the socket */ -#ifdef EXPERIMENTAL_SOCKS +#ifdef SUPPORT_SOCKS if (ob->socks_proxy) return socks_sock_connect(host, host_af, port, interface, tb, timeout); #endif @@ -324,14 +324,16 @@ static BOOL flush_buffer(smtp_outblock *outblock) { int rc; +int n = outblock->ptr - outblock->buffer; +HDEBUG(D_transport|D_acl) debug_printf("cmd buf flush %d bytes\n", n); #ifdef SUPPORT_TLS if (tls_out.active == outblock->sock) - rc = tls_write(FALSE, outblock->buffer, outblock->ptr - outblock->buffer); + rc = tls_write(FALSE, outblock->buffer, n); else #endif + rc = send(outblock->sock, outblock->buffer, n, 0); -rc = send(outblock->sock, outblock->buffer, outblock->ptr - outblock->buffer, 0); if (rc <= 0) { HDEBUG(D_transport|D_acl) debug_printf("send failed: %s\n", strerror(errno)); @@ -357,6 +359,7 @@ Arguments: noflush if TRUE, save the command in the output buffer, for pipelining format a format, starting with one of of HELO, MAIL FROM, RCPT TO, DATA, ".", or QUIT. + If NULL, flush pipeline buffer only. ... data for the format Returns: 0 if command added to pipelining buffer, with nothing transmitted @@ -371,48 +374,51 @@ int count; int rc = 0; va_list ap; -va_start(ap, format); -if (!string_vformat(big_buffer, big_buffer_size, CS format, ap)) - log_write(0, LOG_MAIN|LOG_PANIC_DIE, "overlong write_command in outgoing " - "SMTP"); -va_end(ap); -count = Ustrlen(big_buffer); - -if (count > outblock->buffersize) - log_write(0, LOG_MAIN|LOG_PANIC_DIE, "overlong write_command in outgoing " - "SMTP"); - -if (count > outblock->buffersize - (outblock->ptr - outblock->buffer)) +if (format) { - rc = outblock->cmd_count; /* flush resets */ - if (!flush_buffer(outblock)) return -1; - } + va_start(ap, format); + if (!string_vformat(big_buffer, big_buffer_size, CS format, ap)) + log_write(0, LOG_MAIN|LOG_PANIC_DIE, "overlong write_command in outgoing " + "SMTP"); + va_end(ap); + count = Ustrlen(big_buffer); + + if (count > outblock->buffersize) + log_write(0, LOG_MAIN|LOG_PANIC_DIE, "overlong write_command in outgoing " + "SMTP"); + + if (count > outblock->buffersize - (outblock->ptr - outblock->buffer)) + { + rc = outblock->cmd_count; /* flush resets */ + if (!flush_buffer(outblock)) return -1; + } -Ustrncpy(CS outblock->ptr, big_buffer, count); -outblock->ptr += count; -outblock->cmd_count++; -count -= 2; -big_buffer[count] = 0; /* remove \r\n for error message */ + Ustrncpy(CS outblock->ptr, big_buffer, count); + outblock->ptr += count; + outblock->cmd_count++; + count -= 2; + big_buffer[count] = 0; /* remove \r\n for error message */ -/* We want to hide the actual data sent in AUTH transactions from reflections -and logs. While authenticating, a flag is set in the outblock to enable this. -The AUTH command itself gets any data flattened. Other lines are flattened -completely. */ + /* We want to hide the actual data sent in AUTH transactions from reflections + and logs. While authenticating, a flag is set in the outblock to enable this. + The AUTH command itself gets any data flattened. Other lines are flattened + completely. */ -if (outblock->authenticating) - { - uschar *p = big_buffer; - if (Ustrncmp(big_buffer, "AUTH ", 5) == 0) + if (outblock->authenticating) { - p += 5; - while (isspace(*p)) p++; - while (!isspace(*p)) p++; - while (isspace(*p)) p++; + uschar *p = big_buffer; + if (Ustrncmp(big_buffer, "AUTH ", 5) == 0) + { + p += 5; + while (isspace(*p)) p++; + while (!isspace(*p)) p++; + while (isspace(*p)) p++; + } + while (*p != 0) *p++ = '*'; } - while (*p != 0) *p++ = '*'; - } -HDEBUG(D_transport|D_acl|D_v) debug_printf(" SMTP>> %s\n", big_buffer); + HDEBUG(D_transport|D_acl|D_v) debug_printf(" SMTP>> %s\n", big_buffer); + } if (!noflush) {