On Wed, 2010-12-15 at 12:42 +0000, Paul Civati wrote:
> W B Hacker <wbh@???> wrote:
>
> > Time to move on. Really.
>
> Accepted. But, no time to upgrade right now.
>
> However I will make do without debug mode for now.
It actually looks like our use of va_copy was fairly gratuitous. We're
using the va_list twice for *exactly* the same call to string_vformat().
Instead of repeating the string_vformat() call, let's just strdup the
results and then we don't have to worry about va_copy.
Please test...
diff --git a/src/src/macros.h b/src/src/macros.h
index ed90b25..09bc601 100644
--- a/src/src/macros.h
+++ b/src/src/macros.h
@@ -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 */
diff --git a/src/src/smtp_in.c b/src/src/smtp_in.c
index 9d10961..0fcedc8 100644
--- a/src/src/smtp_in.c
+++ b/src/src/smtp_in.c
@@ -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");
--
David Woodhouse Open Source Technology Centre
David.Woodhouse@??? Intel Corporation