*message = US string_sprintf("Remote host closed connection "
"in response to %s%s", pl, smtp_command);
}
-else *message = US string_sprintf("%s [%s]", host->name, host->address);
+else
+ *message = US string_sprintf("%s [%s]", host->name, host->address);
return FALSE;
}
while (count-- > 0)
{
- while (addr->transport_return != PENDING_DEFER) addr = addr->next;
+ while (addr->transport_return != PENDING_DEFER)
+ if (!(addr = addr->next))
+ return -2;
/* The address was accepted */
addr->host_used = sx->host;
if (errno == 0 && sx->buffer[0] == '4')
{
errno = ERRNO_DATA4XX; /*XXX does this actually get used? */
- sx->first_addr->more_errno |=
+ sx->addrlist->more_errno |=
((sx->buffer[1] - '0')*10 + sx->buffer[2] - '0') << 8;
}
return ERROR;
dns_answer tlsa_dnsa;
#endif
BOOL pass_message = FALSE;
-
uschar * message = NULL;
-int save_errno;
int yield = OK;
int rc;
if (sx->inblock.sock < 0)
{
uschar * msg = NULL;
- int save_errno = errno;
if (sx->verify)
{
- msg = strerror(errno);
+ msg = US strerror(errno);
HDEBUG(D_verify) debug_printf("connect: %s\n", msg);
}
set_errno_nohost(sx->addrlist,
- save_errno == ETIMEDOUT ? ERRNO_CONNECTTIMEOUT : save_errno,
+ errno == ETIMEDOUT ? ERRNO_CONNECTTIMEOUT : errno,
sx->verify ? string_sprintf("could not connect: %s", msg)
: NULL,
DEFER, FALSE);
if (rsp != sx->buffer && rsp[0] == 0 && (errno == 0 || errno == ECONNRESET))
{
- sx->send_quit = FALSE;
- save_errno = ERRNO_SMTPCLOSED;
- message = string_sprintf("Remote host closed connection "
- "in response to %s (EHLO response was: %s)",
- smtp_command, sx->buffer);
- goto FAILED;
+ errno = ERRNO_SMTPCLOSED;
+ goto EHLOHELO_FAILED;
}
Ustrncpy(sx->buffer, rsp, sizeof(sx->buffer)/2);
goto RESPONSE_FAILED;
sx->host->name, sx->host->address);
# endif
- save_errno = ERRNO_TLSFAILURE;
+ errno = ERRNO_TLSFAILURE;
message = US"failure while setting up TLS session";
sx->send_quit = FALSE;
goto TLS_FAILED;
|| verify_check_given_host(&sx->ob->hosts_require_tls, sx->host) == OK
)
{
- save_errno = ERRNO_TLSREQUIRED;
+ errno = ERRNO_TLSREQUIRED;
message = string_sprintf("a TLS session is required, but %s",
smtp_peer_options & PEER_OFFERED_TLS
? "an attempt to start TLS failed" : "the server did not offer TLS support");
{
int code;
- uschar * set_message;
RESPONSE_FAILED:
- {
- save_errno = errno;
message = NULL;
- sx->send_quit = check_response(sx->host, &save_errno, sx->addrlist->more_errno,
+ sx->send_quit = check_response(sx->host, &errno, sx->addrlist->more_errno,
sx->buffer, &code, &message, &pass_message);
goto FAILED;
- }
SEND_FAILED:
- {
- save_errno = errno;
code = '4';
message = US string_sprintf("send() to %s [%s] failed: %s",
- sx->host->name, sx->host->address, strerror(save_errno));
+ sx->host->name, sx->host->address, strerror(errno));
sx->send_quit = FALSE;
goto FAILED;
- }
/* This label is jumped to directly when a TLS negotiation has failed,
or was not done for a host for which it is required. Values will be set
- in message and save_errno, and setting_up will always be true. Treat as
+ in message and errno, and setting_up will always be true. Treat as
a temporary error. */
+ EHLOHELO_FAILED:
+ code = '4';
+ message = string_sprintf("Remote host closed connection in response to %s"
+ " (EHLO response was: %s)", smtp_command, sx->buffer);
+ sx->send_quit = FALSE;
+ goto FAILED;
+
#ifdef SUPPORT_TLS
TLS_FAILED:
- code = '4';
+ code = '4';
+ goto FAILED;
#endif
/* The failure happened while setting up the call; see if the failure was
whatever), defer all addresses, and yield DEFER, so that the host is not
tried again for a while. */
- FAILED:
+FAILED:
sx->ok = FALSE; /* For when reached by GOTO */
- set_message = message;
yield = code == '5'
#ifdef SUPPORT_I18N
#endif
? FAIL : DEFER;
- set_errno(sx->addrlist, save_errno, set_message, yield, pass_message, sx->host
+ set_errno(sx->addrlist, errno, message, yield, pass_message, sx->host
#ifdef EXPERIMENTAL_DSN_INFO
, sx->smtp_greeting, sx->helo_response
#endif
specified in the transports, and therefore not visible at top level, in which
case continue_more won't get set. */
-HDEBUG(D_transport|D_acl|D_v) debug_printf(" SMTP(close)>>\n");
+HDEBUG(D_transport|D_acl|D_v) debug_printf_indent(" SMTP(close)>>\n");
if (sx->send_quit)
{
shutdown(sx->outblock.sock, SHUT_WR);
? dsn_support_yes : dsn_support_no;
address_count++;
- no_flush = pipelining_active && !sx->verify && (!mua_wrapper || addr->next);
+ no_flush = pipelining_active && !sx->verify
+ && (!mua_wrapper || addr->next && address_count < sx->max_rcpt);
build_rcptcmd_options(sx, addr);
if (mua_wrapper)
{
- address_item *badaddr;
- for (badaddr = sx.first_addr; badaddr; badaddr = badaddr->next)
- if (badaddr->transport_return != PENDING_OK)
+ address_item * a;
+ unsigned cnt;
+
+ for (a = sx.first_addr, cnt = 0; a && cnt < sx.max_rcpt; a = a->next, cnt++)
+ if (a->transport_return != PENDING_OK)
{
/*XXX could we find a better errno than 0 here? */
- set_errno_nohost(addrlist, 0, badaddr->message, FAIL,
- testflag(badaddr, af_pass_message));
+ set_errno_nohost(addrlist, 0, a->message, FAIL,
+ testflag(a, af_pass_message));
sx.ok = FALSE;
break;
}
specified in the transports, and therefore not visible at top level, in which
case continue_more won't get set. */
-HDEBUG(D_transport|D_acl|D_v) debug_printf(" SMTP(close)>>\n");
+HDEBUG(D_transport|D_acl|D_v) debug_printf_indent(" SMTP(close)>>\n");
if (sx.send_quit)
{
shutdown(sx.outblock.sock, SHUT_WR);