Kil va_copy(). It isn't present on some ancient systems.
authorDavid Woodhouse <David.Woodhouse@intel.com>
Wed, 15 Dec 2010 13:24:00 +0000 (13:24 +0000)
committerDavid Woodhouse <David.Woodhouse@intel.com>
Wed, 15 Dec 2010 13:24:00 +0000 (13:24 +0000)
doc/doc-txt/ChangeLog
src/src/macros.h
src/src/smtp_in.c

index 162d6c5f6aeef09f0b67e56d6e8ab652e1b17295..201d9616de66294110f79efb5a1cfb4a3d096c3e 100644 (file)
@@ -98,6 +98,9 @@ PP/27 Bugzilla 1047: change the default for system_filter_user to be the Exim
 PP/28 Add WHITELIST_D_MACROS option to let some macros be overriden by the
       Exim run-time user without dropping privileges.
 
+DW/29 Remove use of va_copy() which breaks pre-C99 systems. Duplicate the
+      result string, instead of calling string_vformat() twice with the same
+      arguments.
 
 
 Exim version 4.72
index ed90b25357fb55ea35dc1249e0eaafcfe1e94e75..09bc601b9adbd29249b32c7b15a6c18d96157f3a 100644 (file)
@@ -844,19 +844,4 @@ explicit port number. */
 
 enum { FILTER_UNSET, FILTER_FORWARD, FILTER_EXIM, FILTER_SIEVE };
 
-/* C99 defines va_copy() for copying a varargs ap so that it can be reused,
-since on some platforms multiple iterations of va_start()/va_end() are not
-supported.  But va_copy() is itself not so portable.  Hack around it.
-See portability notes at: http://unixpapa.com/incnote/variadic.html */
-
-#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
-/* va_copy exists for us or the system is broken and we need OS hacks */
-#elif defined(va_copy)
-/* trust it; hope that va_copy is always a macro when defined */
-#elif !defined(va_copy) && defined(__va_copy)
-#define va_copy(dest, src)  __va_copy(dest, src)
-#else
-#define va_copy(dest, src) do { memcpy(dest, src, sizeof(va_list) } while (0)
-#endif
-
 /* End of macros.h */
index 9d10961c51a7cdbfe44e22ccaaebb031d0f08160..0fcedc8216cb68719cdb5f416c3276f4330ca22a 100644 (file)
@@ -387,29 +387,28 @@ va_end(ap);
 
 /* This is split off so that verify.c:respond_printf() can, in effect, call
 smtp_printf(), bearing in mind that in C a vararg function can't directly
-call another vararg function, only a function which accepts a va_list.
-
-Note also that repeated calls to va_start()/va_end() pairs is claimed to be
-non-portable; meanwhile, va_copy() is also non-portable in that it's C99, so
-we end up needing OS support to define it for us. */
+call another vararg function, only a function which accepts a va_list. */
 
 void
 smtp_vprintf(char *format, va_list ap)
 {
-va_list ap_d;
+BOOL yield;
+
+yield = string_vformat(big_buffer, big_buffer_size, format, ap);
 
 DEBUG(D_receive)
   {
-  uschar *cr, *end;
-  va_copy(ap_d, ap);
-  (void) string_vformat(big_buffer, big_buffer_size, format, ap_d);
-  end = big_buffer + Ustrlen(big_buffer);
-  while ((cr = Ustrchr(big_buffer, '\r')) != NULL)   /* lose CRs */
-    memmove(cr, cr + 1, (end--) - cr);
-  debug_printf("SMTP>> %s", big_buffer);
+  void *reset_point = store_get(0);
+  uschar *msg_copy, *cr, *end;
+  msg_copy = string_copy(big_buffer);
+  end = msg_copy + Ustrlen(msg_copy);
+  while ((cr = Ustrchr(msg_copy, '\r')) != NULL)   /* lose CRs */
+  memmove(cr, cr + 1, (end--) - cr);
+  debug_printf("SMTP>> %s", msg_copy);
+  store_reset(reset_point);
   }
 
-if (!string_vformat(big_buffer, big_buffer_size, format, ap))
+if (!yield)
   {
   log_write(0, LOG_MAIN|LOG_PANIC, "string too large in smtp_printf()");
   smtp_closedown(US"Unexpected error");