build: use pkg-config for i18n
[exim.git] / src / src / smtp_out.c
index 90a0eb23e9b9340559f248d750b8ca35d5a3bd44..2ea29a7e442e6d0e0f386188b35e57e74776b4f8 100644 (file)
@@ -2,7 +2,7 @@
 *     Exim - an Internet mail transport agent    *
 *************************************************/
 
 *     Exim - an Internet mail transport agent    *
 *************************************************/
 
-/* Copyright (c) The Exim Maintainers 2020 - 2023 */
+/* Copyright (c) The Exim Maintainers 2020 - 2024 */
 /* Copyright (c) University of Cambridge 1995 - 2018 */
 /* See the file NOTICE for conditions of use and distribution. */
 /* SPDX-License-Identifier: GPL-2.0-or-later */
 /* Copyright (c) University of Cambridge 1995 - 2018 */
 /* See the file NOTICE for conditions of use and distribution. */
 /* SPDX-License-Identifier: GPL-2.0-or-later */
@@ -261,8 +261,7 @@ int
 smtp_boundsock(smtp_connect_args * sc)
 {
 transport_instance * tb = sc->tblock;
 smtp_boundsock(smtp_connect_args * sc)
 {
 transport_instance * tb = sc->tblock;
-smtp_transport_options_block * ob =
-  (smtp_transport_options_block *)tb->options_block;
+smtp_transport_options_block * ob = tb->drinst.options_block;
 const uschar * dscp = ob->dscp;
 int sock, dscp_value, dscp_level, dscp_option;
 
 const uschar * dscp = ob->dscp;
 int sock, dscp_value, dscp_level, dscp_option;
 
@@ -278,6 +277,7 @@ if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, US &on, sizeof(on)))
 /* 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. */
 
 /* 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. */
 
+GET_OPTION("dscp");
 if (dscp && dscp_lookup(dscp, sc->host_af, &dscp_level, &dscp_option, &dscp_value))
   {
   HDEBUG(D_transport|D_acl|D_v)
 if (dscp && dscp_lookup(dscp, sc->host_af, &dscp_level, &dscp_option, &dscp_value))
   {
   HDEBUG(D_transport|D_acl|D_v)
@@ -337,8 +337,7 @@ Returns:      connected socket number, or -1 with errno set
 int
 smtp_sock_connect(smtp_connect_args * sc, int timeout, const blob * early_data)
 {
 int
 smtp_sock_connect(smtp_connect_args * sc, int timeout, const blob * early_data)
 {
-smtp_transport_options_block * ob =
-  (smtp_transport_options_block *)sc->tblock->options_block;
+smtp_transport_options_block * ob = sc->tblock->drinst.options_block;
 int sock;
 int save_errno = 0;
 const blob * fastopen_blob = NULL;
 int sock;
 int save_errno = 0;
 const blob * fastopen_blob = NULL;
@@ -364,6 +363,7 @@ if (!save_errno)
   {
 #ifdef TCP_FASTOPEN
   /* See if TCP Fast Open usable.  Default is a traditional 3WHS connect */
   {
 #ifdef TCP_FASTOPEN
   /* See if TCP Fast Open usable.  Default is a traditional 3WHS connect */
+  expand_level++;
   if (verify_check_given_host(CUSS &ob->hosts_try_fastopen, sc->host) == OK)
     {
     if (!early_data)
   if (verify_check_given_host(CUSS &ob->hosts_try_fastopen, sc->host) == OK)
     {
     if (!early_data)
@@ -379,6 +379,7 @@ if (!save_errno)
       }
 # endif
     }
       }
 # endif
     }
+  expand_level--;
 #endif
 
   if (ip_connect(sock, sc->host_af, sc->host->address, sc->host->port, timeout, fastopen_blob) < 0)
 #endif
 
   if (ip_connect(sock, sc->host_af, sc->host->address, sc->host->port, timeout, fastopen_blob) < 0)
@@ -411,7 +412,7 @@ if (!save_errno)
 
   /* Both bind() and connect() succeeded, and any early-data */
 
 
   /* Both bind() and connect() succeeded, and any early-data */
 
-  HDEBUG(D_transport|D_acl|D_v) debug_printf_indent(" connected\n");
+  HDEBUG(D_transport|D_acl|D_v) debug_printf_indent("connected\n");
   if (getsockname(sock, (struct sockaddr *)(&interface_sock), &size) == 0)
     sending_ip_address = host_ntoa(-1, &interface_sock, NULL, &sending_port);
   else
   if (getsockname(sock, (struct sockaddr *)(&interface_sock), &size) == 0)
     sending_ip_address = host_ntoa(-1, &interface_sock, NULL, &sending_port);
   else
@@ -495,7 +496,7 @@ HDEBUG(D_transport|D_acl|D_v)
 #ifdef SUPPORT_SOCKS
   if (ob->socks_proxy) s = string_sprintf("%svia proxy ", s);
 #endif
 #ifdef SUPPORT_SOCKS
   if (ob->socks_proxy) s = string_sprintf("%svia proxy ", s);
 #endif
-  debug_printf_indent("Connecting to %s %s%s... ", sc->host->name, callout_address, s);
+  debug_printf_indent("Connecting to %s %s%s...\n", sc->host->name, callout_address, s);
   }
 
 /* Create and connect the socket */
   }
 
 /* Create and connect the socket */
@@ -550,10 +551,10 @@ Returns:     TRUE if OK, FALSE on error, with errno set
 static BOOL
 flush_buffer(smtp_outblock * outblock, int mode)
 {
 static BOOL
 flush_buffer(smtp_outblock * outblock, int mode)
 {
-int rc;
-int n = outblock->ptr - outblock->buffer;
+int n = outblock->ptr - outblock->buffer, rc;
 BOOL more = mode == SCMD_MORE;
 client_conn_ctx * cctx;
 BOOL more = mode == SCMD_MORE;
 client_conn_ctx * cctx;
+const uschar * where;
 
 HDEBUG(D_transport|D_acl) debug_printf_indent("cmd buf flush %d bytes%s\n", n,
   more ? " (more expected)" : "");
 
 HDEBUG(D_transport|D_acl) debug_printf_indent("cmd buf flush %d bytes%s\n", n,
   more ? " (more expected)" : "");
@@ -566,6 +567,7 @@ if (!(cctx = outblock->cctx))
   }
 
 #ifndef DISABLE_TLS
   }
 
 #ifndef DISABLE_TLS
+where = US"tls_write";
 if (cctx->tls_ctx)             /*XXX have seen a null cctx here, rvfy sending QUIT, hence check above */
   rc = tls_write(cctx->tls_ctx, outblock->buffer, n, more);
 else
 if (cctx->tls_ctx)             /*XXX have seen a null cctx here, rvfy sending QUIT, hence check above */
   rc = tls_write(cctx->tls_ctx, outblock->buffer, n, more);
 else
@@ -581,6 +583,7 @@ else
     requirement: TFO with data can, in rare cases, replay the data to the
     receiver. */
 
     requirement: TFO with data can, in rare cases, replay the data to the
     receiver. */
 
+    where = US"smtp_connect";
     if (  (cctx->sock = smtp_connect(outblock->conn_args, &early_data))
        < 0)
       return FALSE;
     if (  (cctx->sock = smtp_connect(outblock->conn_args, &early_data))
        < 0)
       return FALSE;
@@ -589,6 +592,7 @@ else
     }
   else
     {
     }
   else
     {
+    where = US"send";
     rc = send(cctx->sock, outblock->buffer, n,
 #ifdef MSG_MORE
              more ? MSG_MORE : 0
     rc = send(cctx->sock, outblock->buffer, n,
 #ifdef MSG_MORE
              more ? MSG_MORE : 0
@@ -603,6 +607,7 @@ else
     This is despite NODELAY being active.
     https://bugzilla.redhat.com/show_bug.cgi?id=1803806 */
 
     This is despite NODELAY being active.
     https://bugzilla.redhat.com/show_bug.cgi?id=1803806 */
 
+    where = US"cork";
     if (!more)
       setsockopt(cctx->sock, IPPROTO_TCP, TCP_CORK, &off, sizeof(off));
 #endif
     if (!more)
       setsockopt(cctx->sock, IPPROTO_TCP, TCP_CORK, &off, sizeof(off));
 #endif
@@ -611,7 +616,8 @@ else
 
 if (rc <= 0)
   {
 
 if (rc <= 0)
   {
-  HDEBUG(D_transport|D_acl) debug_printf_indent("send failed: %s\n", strerror(errno));
+  HDEBUG(D_transport|D_acl) debug_printf_indent("%s (fd %d) failed: %s\n",
+    where, cctx->sock, strerror(errno));
   return FALSE;
   }
 
   return FALSE;
   }
 
@@ -622,22 +628,6 @@ return TRUE;
 
 
 
 
 
 
-/* This might be called both due to callout and then from delivery.
-Use memory that will not be released between those phases.
-*/
-static void
-smtp_debug_resp(const uschar * buf)
-{
-#ifndef DISABLE_CLIENT_CMD_LOG
-int old_pool = store_pool;
-store_pool = POOL_PERM;
-client_cmd_log = string_append_listele_n(client_cmd_log, ':', buf,
-  buf[3] == ' ' ? 3 : 4);
-store_pool = old_pool;
-#endif
-}
-
-
 /*************************************************
 *             Write SMTP command                 *
 *************************************************/
 /*************************************************
 *             Write SMTP command                 *
 *************************************************/
@@ -649,7 +639,7 @@ Arguments:
   sx        SMTP connection, contains buffer for pipelining, and socket
   mode       buffer, write-with-more-likely, write
   format     a format, starting with one of
   sx        SMTP connection, contains buffer for pipelining, and socket
   mode       buffer, write-with-more-likely, write
   format     a format, starting with one of
-             of HELO, MAIL FROM, RCPT TO, DATA, ".", or QUIT.
+             of HELO, MAIL FROM, RCPT TO, DATA, BDAT, ".", or QUIT.
             If NULL, flush pipeline buffer only.
   ...        data for the format
 
             If NULL, flush pipeline buffer only.
   ...        data for the format
 
@@ -703,13 +693,13 @@ if (format)
 
   if (outblock->authenticating)
     {
 
   if (outblock->authenticating)
     {
-    uschar *p = big_buffer;
+    uschar * p = big_buffer;
     if (Ustrncmp(big_buffer, "AUTH ", 5) == 0)
       {
       p += 5;
     if (Ustrncmp(big_buffer, "AUTH ", 5) == 0)
       {
       p += 5;
-      while (isspace(*p)) p++;
-      while (!isspace(*p)) p++;
-      while (isspace(*p)) p++;
+      Uskip_whitespace(&p);
+      Uskip_nonwhite(&p);
+      Uskip_whitespace(&p);
       }
     while (*p) *p++ = '*';
     }
       }
     while (*p) *p++ = '*';
     }