Support gring as a first-class conversion specifier in internal string-formatting
authorJeremy Harris <jgh146exb@wizmail.org>
Thu, 6 Jul 2023 23:40:43 +0000 (00:40 +0100)
committerJeremy Harris <jgh146exb@wizmail.org>
Fri, 7 Jul 2023 12:13:58 +0000 (13:13 +0100)
20 files changed:
src/src/auths/heimdal_gssapi.c
src/src/daemon.c
src/src/dcc.c
src/src/debug.c
src/src/deliver.c
src/src/dkim.c
src/src/dmarc.c
src/src/expand.c
src/src/header.c
src/src/log.c
src/src/lookups/pgsql.c
src/src/mime.c
src/src/receive.c
src/src/smtp_in.c
src/src/smtp_out.c
src/src/string.c
src/src/tls-gnu.c
src/src/tls-openssl.c
src/src/transports/lmtp.c
src/src/transports/smtp.c

index 1336d0fab569451ddd21208ddbabd4b605e0ba47..7a74d5be57f07dbe6d254cc732bcc5aab26f3557 100644 (file)
@@ -565,9 +565,8 @@ do {
   if (!auth_defer_msg)
     auth_defer_msg = string_copy(US status_string.value);
 
-  HDEBUG(D_auth) debug_printf("heimdal %s: %.*s\n",
-      string_from_gstring(g), (int)status_string.length,
-      CS status_string.value);
+  HDEBUG(D_auth) debug_printf("heimdal %Y: %.*s\n",
+      g, (int)status_string.length, CS status_string.value);
   gss_release_buffer(&min_stat, &status_string);
 
   } while (msgcontext != 0);
index ea7db0f252617d1cb0ad470f7c2ac9c210dc81cb..f6867b8824ba91ce88b4881b9206232b8f6bc208 100644 (file)
@@ -254,8 +254,6 @@ if (LOGGING(incoming_interface))
   whofrom = string_fmt_append(whofrom, " I=[%s]:%d",
     interface_address, interface_port);
 
-(void) string_from_gstring(whofrom);    /* Terminate the newly-built string */
-
 /* Check maximum number of connections. We do not check for reserved
 connections or unacceptable hosts here. That is done in the subprocess because
 it might take some time. */
@@ -267,8 +265,8 @@ if (smtp_accept_max > 0 && smtp_accept_count >= smtp_accept_max)
   smtp_printf("421 Too many concurrent SMTP connections; "
     "please try again later.\r\n", FALSE);
   log_write(L_connection_reject,
-            LOG_MAIN, "Connection from %s refused: too many connections",
-    whofrom->s);
+            LOG_MAIN, "Connection from %Y refused: too many connections",
+    whofrom);
   goto ERROR_RETURN;
   }
 
@@ -286,8 +284,8 @@ if (smtp_load_reserve >= 0)
       (double)load_average/1000.0);
     smtp_printf("421 Too much load; please try again later.\r\n", FALSE);
     log_write(L_connection_reject,
-              LOG_MAIN, "Connection from %s refused: load average = %.2f",
-      whofrom->s, (double)load_average/1000.0);
+              LOG_MAIN, "Connection from %Y refused: load average = %.2f",
+      whofrom, (double)load_average/1000.0);
     goto ERROR_RETURN;
     }
   }
@@ -307,7 +305,7 @@ if (smtp_accept_max_per_host)
     {
     if (!f.expand_string_forcedfail)
       log_write(0, LOG_MAIN|LOG_PANIC, "expansion of smtp_accept_max_per_host "
-        "failed for %s: %s", whofrom->s, expand_string_message);
+        "failed for %Y: %s", whofrom, expand_string_message);
     }
   /* For speed, interpret a decimal number inline here */
   else
@@ -317,7 +315,7 @@ if (smtp_accept_max_per_host)
       max_for_this_host = max_for_this_host * 10 + *s++ - '0';
     if (*s)
       log_write(0, LOG_MAIN|LOG_PANIC, "expansion of smtp_accept_max_per_host "
-        "for %s contains non-digit: %s", whofrom->s, expanded);
+        "for %Y contains non-digit: %s", whofrom, expanded);
     }
   }
 
@@ -355,8 +353,8 @@ if (max_for_this_host > 0 && smtp_accept_count >= max_for_this_host)
     smtp_printf("421 Too many concurrent SMTP connections "
       "from this IP address; please try again later.\r\n", FALSE);
     log_write(L_connection_reject,
-              LOG_MAIN, "Connection from %s refused: too many connections "
-      "from that IP address", whofrom->s);
+              LOG_MAIN, "Connection from %Y refused: too many connections "
+      "from that IP address", whofrom);
     search_tidyup();
     goto ERROR_RETURN;
     }
@@ -382,8 +380,8 @@ if (LOGGING(smtp_connection))
   if (list && verify_check_host(&list) == OK)
     save_log_selector &= ~L_smtp_connection;
   else
-    log_write(L_smtp_connection, LOG_MAIN, "SMTP connection from %s "
-      "(TCP/IP connection count = %d)", whofrom->s, smtp_accept_count + 1);
+    log_write(L_smtp_connection, LOG_MAIN, "SMTP connection from %Y "
+      "(TCP/IP connection count = %d)", whofrom, smtp_accept_count + 1);
   }
 
 /* Now we can fork the accepting process; do a lookup tidy, just in case any
index 98f978fa902b9bc2ecbd1bb2d8980a4b127fb012..e7a932426cae4df9f3eb10d4d320de37257cefb8 100644 (file)
@@ -237,11 +237,11 @@ for (int i = 0; i < recipients_count; i++)
   }
 /* send a blank line between options and message */
 dcc_headers = string_catn(dcc_headers, US"\n", 1);
+
 /* Now we send the input buffer */
-(void) string_from_gstring(dcc_headers);
 DEBUG(D_acl)
-  debug_printf("DCC: ***********************************\nDCC: Sending options:\n%s"
-              "DCC: ***********************************\n", dcc_headers->s);
+  debug_printf("DCC: ***********************************\nDCC: Sending options:\n%Y"
+              "DCC: ***********************************\n", dcc_headers);
 if (flushbuffer(sockfd, dcc_headers) != 0)
   {
   (void)fclose(data_file);
@@ -259,10 +259,9 @@ while((mail_headers=mail_headers->next))
 
 /* a blank line separates header from body */
 sendbuf = string_catn(sendbuf, US"\r\n", 2);
-(void) string_from_gstring(sendbuf);
 gstring_release_unused(sendbuf);
 DEBUG(D_acl)
-  debug_printf("%sDCC: ***********************************\n", sendbuf->s);
+  debug_printf("%YDCC: ***********************************\n", sendbuf);
 if (flushbuffer(sockfd, sendbuf) != 0)
   {
   (void)fclose(data_file);
@@ -449,23 +448,23 @@ dcc_header_str = string_catn(dcc_header_str, US"\n", 1);
 /* Now let's sum up what we've got. */
 DEBUG(D_acl)
   debug_printf("\nDCC: --------------------------\nDCC: Overall result = %d\n"
-              "DCC: X-DCC header: %sReturn message: %s\nDCC: dcc_result: %s\n",
-                retval, dcc_header_str->s, dcc_return_text, dcc_result);
+              "DCC: X-DCC header: %YReturn message: %s\nDCC: dcc_result: %s\n",
+                retval, dcc_header_str, dcc_return_text, dcc_result);
 
 /* We only add the X-DCC header if it starts with X-DCC */
 if(!(Ustrncmp(dcc_header_str->s, "X-DCC", 5)))
   {
-  dcc_header = dcc_header_str->s;
+  dcc_header = string_from_gstring(dcc_header_str);
   if(dcc_direct_add_header)
     {
-    header_add(' ' , "%s", dcc_header_str->s);
+    header_add(' ' , "%s", dcc_header);
 /* since the MIME ACL already writes the .eml file to disk without DCC Header we've to erase it */
     unspool_mbox();
     }
   }
 else
   DEBUG(D_acl)
-    debug_printf("DCC: Wrong format of the X-DCC header: %.*s\n", dcc_header_str->ptr, dcc_header_str->s);
+    debug_printf("DCC: Wrong format of the X-DCC header: %Y\n", dcc_header_str);
 
 /* check if we should add additional headers passed in acl_m_dcc_add_header */
 if (dcc_direct_add_header)
@@ -477,7 +476,7 @@ if (dcc_direct_add_header)
       dcc_xtra_hdrs = string_catn(dcc_xtra_hdrs, US"\n", 1);
     header_add(' ', "%s", string_from_gstring(dcc_xtra_hdrs));
     DEBUG(D_acl)
-      debug_printf("DCC: adding additional headers in $acl_m_dcc_add_header: %.*s", dcc_xtra_hdrs->ptr, dcc_xtra_hdrs->s);
+      debug_printf("DCC: adding additional headers in $acl_m_dcc_add_header: %Y", dcc_xtra_hdrs);
     }
   }
 
index 44ad763e147b25450b260f024965c2df465ed561..dac7384705497e1c21c1b51517fb2c80a6f2317b 100644 (file)
@@ -439,7 +439,7 @@ if (fstat(fd, &s) == 0 && (s.st_mode & S_IFMT) == S_IFSOCK)
       : string_fmt_append(g, " proto %d", val);
     }
 #endif
-  debug_printf_indent(" socket: %s\n", string_from_gstring(g));
+  debug_printf_indent(" socket: %Y\n", g);
   }
 else
   debug_printf_indent(" fd st_mode 0%o\n", s.st_mode);
index 8f0f350d729e9bda4ccc817d507344b66d886fbf..bea38c5d16facdf301f52df377d3705b234cbbbc 100644 (file)
@@ -723,7 +723,7 @@ child_done(address_item * addr, const uschar * now)
 {
 while (addr->parent)
   {
-  address_item *aa;
+  address_item * aa;
 
   addr = addr->parent;
   if (--addr->child_count > 0) return;   /* Incomplete parent */
@@ -1278,7 +1278,7 @@ if (LOGGING(deliver_time))
 /* string_cat() always leaves room for the terminator. Release the
 store we used to build the line after writing it. */
 
-log_write(0, flags, "%s", string_from_gstring(g));
+log_write(0, flags, "%Y", g);
 
 #ifndef DISABLE_EVENT
 if (!msg) msg_event_raise(US"msg:delivery", addr);
@@ -1337,25 +1337,21 @@ if (LOGGING(deliver_time))
 if (addr->message)
   g = string_append(g, 2, US": ", addr->message);
 
- {
-  const uschar * s = string_from_gstring(g);
+/* Log the deferment in the message log, but don't clutter it
+up with retry-time defers after the first delivery attempt. */
 
-  /* Log the deferment in the message log, but don't clutter it
-  up with retry-time defers after the first delivery attempt. */
+if (f.deliver_firsttime || addr->basic_errno > ERRNO_RETRY_BASE)
+  deliver_msglog("%s %.*s\n", now, g->ptr, g->s);
 
-  if (f.deliver_firsttime || addr->basic_errno > ERRNO_RETRY_BASE)
-    deliver_msglog("%s %s\n", now, s);
+/* Write the main log and reset the store.
+For errors of the type "retry time not reached" (also remotes skipped
+on queue run), logging is controlled by L_retry_defer. Note that this kind
+of error number is negative, and all the retry ones are less than any
+others. */
 
-  /* Write the main log and reset the store.
-  For errors of the type "retry time not reached" (also remotes skipped
-  on queue run), logging is controlled by L_retry_defer. Note that this kind
-  of error number is negative, and all the retry ones are less than any
-  others. */
 
-
-  log_write(addr->basic_errno <= ERRNO_RETRY_BASE ? L_retry_defer : 0, logflags,
-    "== %s", s);
- }
+log_write(addr->basic_errno <= ERRNO_RETRY_BASE ? L_retry_defer : 0, logflags,
+  "== %Y", g);
 
 store_reset(reset_point);
 return;
@@ -1421,16 +1417,12 @@ if (LOGGING(deliver_time))
 /* Do the logging. For the message log, "routing failed" for those cases,
 just to make it clearer. */
 
- {
-  const uschar * s = string_from_gstring(g);
-
-  if (driver_kind)
-    deliver_msglog("%s %s failed for %s\n", now, driver_kind, s);
-  else
-    deliver_msglog("%s %s\n", now, s);
+if (driver_kind)
+  deliver_msglog("%s %s failed for %.*s\n", now, driver_kind, g->ptr, g->s);
+else
+  deliver_msglog("%s %.*s\n", now, g->ptr, g->s);
 
-  log_write(0, LOG_MAIN, "** %s", s);
- }
+log_write(0, LOG_MAIN, "** %Y", g);
 
 store_reset(reset_point);
 return;
@@ -5989,7 +5981,7 @@ wording. */
 
   if (rc != 0)
     {
-    uschar *s = US"";
+    uschar * s = US"";
     if (now - received_time.tv_sec < retry_maximum_timeout && !addr_defer)
       {
       addr_defer = (address_item *)(+1);
index 4c19f752f940120a438faf238ceecfe78815fc80..068b802e002d2e9d957f98f5d28f401fa37970f4 100644 (file)
@@ -289,7 +289,7 @@ else
       break;
     }
 
-log_write(0, LOG_MAIN, "%s", string_from_gstring(logmsg));
+log_write(0, LOG_MAIN, "%Y", logmsg);
 return;
 }
 
index 555e3a72b3dc18b51a1db7db22aae17588cbfd86..409d8a47db65bcd01893e0dca574d08aa4ed4c99 100644 (file)
@@ -306,7 +306,7 @@ DEBUG(D_receive)
 if (host_checking || f.running_in_test_harness)
   {
   DEBUG(D_receive)
-    debug_printf("DMARC history data for debugging:\n%s", string_from_gstring(g));
+    debug_printf("DMARC history data for debugging:\n%Y", g);
   }
 else
   {
index de00c72544c9f8c435a8170dd133ab82d07d8e9e..55c53957ee511bc312a0b4767b0f0456ac733d1a 100644 (file)
@@ -3957,10 +3957,9 @@ if (Ustrlen(key) > 64)
 hash_source = string_catn(NULL, key_num, 1);
 hash_source = string_catn(hash_source, daystamp, 3);
 hash_source = string_cat(hash_source, address);
-(void) string_from_gstring(hash_source);
 
 DEBUG(D_expand)
-  debug_printf_indent("prvs: hash source is '%s'\n", hash_source->s);
+  debug_printf_indent("prvs: hash source is '%Y'\n", hash_source);
 
 memset(innerkey, 0x36, 64);
 memset(outerkey, 0x5c, 64);
@@ -7993,7 +7992,7 @@ NOT_ITEM: ;
            goto EXPAND_FAILED;
            }
          yield = string_cat(yield, s);
-         DEBUG(D_expand) debug_printf_indent("yield: '%s'\n", string_from_gstring(yield));
+         DEBUG(D_expand) debug_printf_indent("yield: '%Y'\n", yield);
          break;
          }
 
index 59a9a13b304d4eba2e800bb0db952ffe284c8b5f..97fa44b4ef41cd9473bf31ab63f572e006346cd3 100644 (file)
@@ -110,7 +110,7 @@ gs.ptr = 0;
 
 if (!string_vformat(&gs, SVFMT_REBUFFER, format, ap))
   log_write(0, LOG_MAIN|LOG_PANIC_DIE, "string too long in header_add: "
-    "%.100s ...", string_from_gstring(&gs));
+    "%.100Y ...", &gs);
 
 if (gs.s != buf) store_release_above(buf);
 gstring_release_unused(&gs);
index 54d2b8027418db56924b31915e172ebbf6979692..fac577d5a6ba57a13839d67e4a280a6088585f10 100644 (file)
@@ -958,8 +958,7 @@ DEBUG(D_any|D_v)
     }
   va_end(ap);
 
-  g = string_catn(g, US"\n", 1);
-  debug_printf("%s", string_from_gstring(g));
+  debug_printf("%Y\n", g);
 
   gs.size = LOG_BUFFER_SIZE-2; /* Having used the buffer for debug output, */
   gs.ptr = 0;                  /* reset it for the real use. */
index 1583378d548eb9ca0f6ebb1e342bb9921f0ea303..5d52f28b1cc59a22ec2a2cebee6fe6ecc9fdc281 100644 (file)
@@ -293,7 +293,7 @@ switch(PQresultStatus(pg_result))
     result = string_cat(result, US PQcmdTuples(pg_result));
     *do_cache = 0;
     DEBUG(D_lookup) debug_printf_indent("PGSQL: command does not return any data "
-      "but was successful. Rows affected: %s\n", string_from_gstring(result));
+      "but was successful. Rows affected: %Y\n", result);
     break;
 
   case PGRES_TUPLES_OK:
index d4c26540a6e5279f4c1ffc7f39c54aec71edc4c9..7d30b546233918e894158ad08b22c214f0c07518 100644 (file)
@@ -489,7 +489,7 @@ while ((c = *fname))
     val = string_catn(val, fname++, 1);
 
 val = string_catn(val, US"?=", 2);
-*len = val->ptr;
+*len = gstring_length(val);
 return string_from_gstring(val);
 }
 
index acb3c40fc1b128afbed56a393449ddfbc89dbd33..0891a4a8c6ca1909c7ac4273a215d80930c52e61 100644 (file)
@@ -3915,8 +3915,8 @@ else
     sender_address[0] == 0 ? US"<>" : sender_address);
   g = add_host_info_for_log(g);
 
-  log_write(0, LOG_MAIN|LOG_REJECT, "%s %srejected by local_scan(): %.256s",
-    string_from_gstring(g), istemp, string_printing(errmsg));
+  log_write(0, LOG_MAIN|LOG_REJECT, "%Y %srejected by local_scan(): %.256s",
+    g, istemp, string_printing(errmsg));
 
   if (smtp_input)
     if (!smtp_batched_input)
@@ -4271,7 +4271,7 @@ if (  smtp_input && sender_host_address && !f.sender_host_notsocket
       gstring_reset(g);
       g = string_cat(g, US"SMTP connection lost after final dot");
       g = add_host_info_for_log(g);
-      log_write(0, LOG_MAIN, "%s", string_from_gstring(g));
+      log_write(0, LOG_MAIN, "%Y", g);
 
       /* Delete the files for this aborted message. */
 
@@ -4337,7 +4337,7 @@ if(!smtp_reply)
   log_write(0, LOG_MAIN |
     (LOGGING(received_recipients) ? LOG_RECIPIENTS : 0) |
     (LOGGING(received_sender) ? LOG_SENDER : 0),
-    "%s", g->s);
+    "%Y", g);
 
   /* Log any control actions taken by an ACL or local_scan(). */
 
index cd759df7b34f5210dc0c999442e908d5eb7530dc..e6f9808ddf5a48199ed8949b7f758f65ba56288b 100644 (file)
@@ -2680,13 +2680,13 @@ if (!check_sync())
 /* Now output the banner */
 /*XXX the ehlo-resp code does its own tls/nontls bit.  Maybe subroutine that? */
 
-smtp_printf("%s",
+smtp_printf("%Y",
 #ifndef DISABLE_PIPE_CONNECT
   fl.pipe_connect_acceptable && pipeline_connect_sends(),
 #else
   FALSE,
 #endif
-  string_from_gstring(ss));
+  ss);
 
 /* Attempt to see if we sent the banner before the last ACK of the 3-way
 handshake arrived.  If so we must have managed a TFO. */
@@ -2735,9 +2735,9 @@ if (++synprot_error_count > smtp_max_synprot_errors)
   {
   yield = 1;
   log_write(0, LOG_MAIN|LOG_REJECT, "SMTP call from %s dropped: too many "
-    "syntax or protocol errors (last command was \"%s\", %s)",
+    "syntax or protocol errors (last command was \"%s\", %Y)",
     host_and_ident(FALSE), string_printing(smtp_cmd_buffer),
-    string_from_gstring(s_connhad_log(NULL))
+    s_connhad_log(NULL)
     );
   }
 
@@ -3195,7 +3195,7 @@ if (code && defaultrespond)
     va_start(ap, defaultrespond);
     g = string_vformat(NULL, SVFMT_EXTEND|SVFMT_REBUFFER, CS defaultrespond, ap);
     va_end(ap);
-    smtp_printf("%s %s\r\n", FALSE, code, string_from_gstring(g));
+    smtp_printf("%s %Y\r\n", FALSE, code, g);
     }
   mac_smtp_fflush();
   }
@@ -3872,9 +3872,9 @@ while (done <= 0)
        if (++synprot_error_count > smtp_max_synprot_errors)
          {
          log_write(0, LOG_MAIN|LOG_REJECT, "SMTP call from %s dropped: too many "
-           "syntax or protocol errors (last command was \"%s\", %s)",
+           "syntax or protocol errors (last command was \"%s\", %Y)",
            host_and_ident(FALSE), string_printing(smtp_cmd_buffer),
-           string_from_gstring(s_connhad_log(NULL))
+           s_connhad_log(NULL)
            );
          done = 1;
          }
index 02f1fa438ff22822f3d1b8311dfa17a1b485b147..7f477ed76504d870234e10f743abc200dd2fe78d 100644 (file)
@@ -680,7 +680,6 @@ if (format)
     log_write(0, LOG_MAIN|LOG_PANIC_DIE, "overlong write_command in outgoing "
       "SMTP");
   va_end(ap);
-  string_from_gstring(&gs);
 
   if (gs.ptr > outblock->buffersize)
     log_write(0, LOG_MAIN|LOG_PANIC_DIE, "overlong write_command in outgoing "
index 0ea98d47d39a59380965cfee1b25cb62b07e81e8..854cf0d34b6e73915ada64173114067dbea601b8 100644 (file)
@@ -1327,6 +1327,11 @@ If the "extend" flag is false, the string passed in may not be NULL,
 will not be grown, and is usable in the original place after return.
 The return value can be NULL to signify overflow.
 
+Field width:           decimal digits, or *
+Precision:             dot, followed by decimal digits or *
+Length modifiers:      h  L  l  ll  z
+Conversion specifiers: n d o u x X p f e E g G % c s S T Y D M
+
 Returns the possibly-new (if copy for growth or taint-handling was needed)
 string, not nul-terminated.
 */
@@ -1571,6 +1576,14 @@ while (*fp)
       slen = string_datestamp_length;
       goto INSERT_STRING;
 
+    case 'Y':                  /* gstring pointer */
+      {
+      gstring * zg = va_arg(ap, gstring *);
+      s = CS zg->s;
+      slen = zg->ptr;
+      goto INSERT_GSTRING;
+      }
+
     case 's':
     case 'S':                   /* Forces *lower* case */
     case 'T':                   /* Forces *upper* case */
@@ -1579,6 +1592,8 @@ while (*fp)
       if (!s) s = null;
       slen = Ustrlen(s);
 
+    INSERT_GSTRING:            /* Coome to from %Y above */
+
       if (!(flags & SVFMT_TAINT_NOCHK) && is_incompatible(g->s, s))
        if (flags & SVFMT_REBUFFER)
          {
index 76176a64e0b4d5428b9bcd4d79458bd5fb2a124f..c3e2d98e8a08d0dcbb86d1181e41cea90cb0df46 100644 (file)
@@ -1135,7 +1135,7 @@ switch (tls_id)
     DEBUG(D_tls) debug_printf("\n");
     if (server_seen_alpn > 1)
       {
-      log_write(0, LOG_MAIN, "TLS ALPN (%s) rejected", string_from_gstring(g));
+      log_write(0, LOG_MAIN, "TLS ALPN (%Y) rejected", g);
       DEBUG(D_tls) debug_printf("TLS: too many ALPNs presented in handshake\n");
       return GNUTLS_E_NO_APPLICATION_PROTOCOL;
       }
index cd715cc184c57be37a2c592dccc94ac05cc40943..22c8ea99ae83bebeddd91ad857ad35e75725474b 100644 (file)
@@ -2404,7 +2404,7 @@ for (int pos = 0, siz; pos < inlen; pos += siz+1)
   if (pos + 1 + siz > inlen) siz = inlen - pos - 1;
   g = string_append_listele_n(g, ':', in + pos + 1, siz);
   }
-log_write(0, LOG_MAIN, "TLS ALPN (%s) rejected", string_from_gstring(g));
+log_write(0, LOG_MAIN, "TLS ALPN (%Y) rejected", g);
 gstring_release_unused(g);
 return SSL_TLSEXT_ERR_ALERT_FATAL;
 }
index e04c991ab703da149bc200adb1d6324c282f9f9f..776c40e05070692406b3c9739bbd9ce853fe02ff 100644 (file)
@@ -241,7 +241,7 @@ if (!string_vformat(&gs, SVFMT_TAINT_NOCHK, CS format, ap))
   return FALSE;
   }
 va_end(ap);
-DEBUG(D_transport|D_v) debug_printf("  LMTP>> %s", string_from_gstring(&gs));
+DEBUG(D_transport|D_v) debug_printf("  LMTP>> %Y", &gs);
 rc = write(fd, gs.s, gs.ptr);
 gs.ptr -= 2; string_from_gstring(&gs); /* remove \r\n for debug and error message */
 if (rc > 0) return TRUE;
index 926e77df4c8169a94d15baa1691a00350d43d8c7..c502d7365d63d32f5de33731f6320987369b2bd8 100644 (file)
@@ -626,8 +626,8 @@ if (suffix)
 else
   message = string_fmt_append(message, " %s", exim_errstr(basic_errno));
 
-log_write(0, LOG_MAIN, "%s", string_from_gstring(message));
-deliver_msglog("%s %s\n", tod_stamp(tod_log), message->s);
+log_write(0, LOG_MAIN, "%Y", message);
+deliver_msglog("%s %.*s\n", tod_stamp(tod_log), message->ptr, message->s);
 }
 
 static void