Fix to EXPN not working under TLS. Fixes bug #744
[exim.git] / src / src / smtp_in.c
index de7663b1a03dfb33910f4cb3ff06638bfbafc8ad..b710c89ced8f2c5e6411d1221882dcfb619eb8e2 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/smtp_in.c,v 1.62 2007/09/28 12:21:57 tom Exp $ */
+/* $Cambridge: exim/src/src/smtp_in.c,v 1.63 2008/09/29 11:41:07 nm4 Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -376,26 +376,41 @@ smtp_printf(char *format, ...)
 {
 va_list ap;
 
+va_start(ap, format);
+smtp_vprintf(format, ap);
+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. */
+
+void
+smtp_vprintf(char *format, va_list ap)
+{
+va_list ap_d;
+
 DEBUG(D_receive)
   {
   uschar *cr, *end;
-  va_start(ap, format);
-  (void) string_vformat(big_buffer, big_buffer_size, format, ap);
-  va_end(ap);
+  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);
   }
 
-va_start(ap, format);
 if (!string_vformat(big_buffer, big_buffer_size, format, ap))
   {
   log_write(0, LOG_MAIN|LOG_PANIC, "string too large in smtp_printf()");
   smtp_closedown(US"Unexpected error");
   exim_exit(EXIT_FAILURE);
   }
-va_end(ap);
 
 /* If this is the first output for a (non-batch) RCPT command, see if all RCPTs
 have had the same. Note: this code is also present in smtp_respond(). It would