*BIG* verify code reorganisation.
[oweals/openssl.git] / crypto / bio / b_print.c
index 3db13946628eb3900b6bb3c9d88e57dd91c817dc..a00f0925d242883f7149d8532f11c56527804fc0 100644 (file)
@@ -61,7 +61,6 @@
  */
 
 #include <stdio.h>
-#include <stdarg.h>
 #include <string.h>
 #include <ctype.h>
 #include <assert.h>
 # endif
 #endif
 
-static void dopr (char *buffer, size_t maxlen, size_t *retlen,
-       const char *format, va_list args);
-#ifdef USE_ALLOCATING_PRINT
-static void doapr (char **buffer, size_t *retlen,
-       const char *format, va_list args);
-#endif
-
-int BIO_printf (BIO *bio, ...)
-       {
-       va_list args;
-       char *format;
-       int ret;
-       size_t retlen;
-#ifdef USE_ALLOCATING_PRINT
-       char *hugebuf;
-#else
-       MS_STATIC char hugebuf[1024*2]; /* 10k in one chunk is the limit */
-#endif
-
-       va_start(args, bio);
-       format=va_arg(args, char *);
-
-#ifndef USE_ALLOCATING_PRINT
-       hugebuf[0]='\0';
-       dopr(hugebuf, sizeof(hugebuf), &retlen, format, args);
-#else
-       hugebuf = NULL;
-       CRYPTO_push_info("doapr()");
-       doapr(&hugebuf, &retlen, format, args);
-       if (hugebuf)
-               {
-#endif
-               ret=BIO_write(bio, hugebuf, (int)retlen);
-
-#ifdef USE_ALLOCATING_PRINT
-               Free(hugebuf);
-               }
-       CRYPTO_pop_info();
-#endif
-       va_end(args);
-       return(ret);
-       }
+/***************************************************************************/
 
 /*
  * Copyright Patrick Powell 1995
@@ -140,6 +98,7 @@ int BIO_printf (BIO *bio, ...)
  * o Andrew Tridgell <tridge@samba.org>        (1998, for Samba)
  * o Luke Mewburn <lukem@netbsd.org>           (1999, for LukemFTP)
  * o Ralf S. Engelschall <rse@engelschall.com> (1999, for Pth)
+ * o ...                                       (for OpenSSL)
  */
 
 #if HAVE_LONG_DOUBLE
@@ -171,7 +130,7 @@ static void doapr_outch (char **, size_t *, size_t *, int);
 #endif
 static void _dopr(void (*)(char **, size_t *, size_t *, int),
                  int (*)(size_t, size_t), int (*)(size_t),
-                 char **buffer, size_t *maxlen, size_t *retlen,
+                 char **buffer, size_t *maxlen, size_t *retlen, int *truncated,
                  const char *format, va_list args);
 
 /* format read states */
@@ -203,6 +162,7 @@ static void _dopr(void (*)(char **, size_t *, size_t *, int),
 #define char_to_int(p) (p - '0')
 #define MAX(p,q) ((p >= q) ? p : q)
 
+#ifndef USE_ALLOCATING_PRINT
 static void
 dopr(
     char *buffer,
@@ -211,11 +171,12 @@ dopr(
     const char *format,
     va_list args)
 {
+    int ignored;
     _dopr(dopr_outch, dopr_isbig, dopr_copy,
-         &buffer, &maxlen, retlen, format, args);
+        &buffer, &maxlen, retlen, &ignored, format, args);
 }
 
-#ifdef USE_ALLOCATING_PRINT
+#else
 static void
 doapr(
     char **buffer,
@@ -224,8 +185,9 @@ doapr(
     va_list args)
 {
     size_t dummy_maxlen = 0;
+    int ignored;
     _dopr(doapr_outch, doapr_isbig, doapr_copy,
-         buffer, &dummy_maxlen, retlen, format, args);
+        buffer, &dummy_maxlen, retlen, &ignored, format, args);
 }
 #endif
 
@@ -237,6 +199,7 @@ _dopr(
     char **buffer,
     size_t *maxlen,
     size_t *retlen,
+    int *truncated,
     const char *format,
     va_list args)
 {
@@ -372,7 +335,7 @@ _dopr(
                     break;
                 }
                 fmtint(outch_fn, buffer, &currlen, maxlen,
-                      value, 10, min, max, flags);
+                       value, 10, min, max, flags);
                 break;
             case 'X':
                 flags |= DP_F_UP;
@@ -407,7 +370,7 @@ _dopr(
                 else
                     fvalue = va_arg(args, double);
                 fmtfp(outch_fn, buffer, &currlen, maxlen,
-                     fvalue, min, max, flags);
+                      fvalue, min, max, flags);
                 break;
             case 'E':
                 flags |= DP_F_UP;
@@ -434,7 +397,7 @@ _dopr(
                 if (max < 0)
                     max = (*copy_fn)(*maxlen);
                 fmtstr(outch_fn, buffer, &currlen, maxlen, strvalue,
-                      flags, min, max);
+                       flags, min, max);
                 break;
             case 'p':
                 value = (long)va_arg(args, void *);
@@ -482,7 +445,8 @@ _dopr(
             break;
         }
     }
-    if (currlen >= *maxlen - 1)
+    *truncated = (currlen > *maxlen - 1);
+    if (*truncated)
         currlen = *maxlen - 1;
     (*buffer)[currlen] = '\0';
     *retlen = currlen;
@@ -827,11 +791,11 @@ doapr_outch(
     if (*buffer == NULL) {
        if (*maxlen == 0)
            *maxlen = 1024;
-       *buffer = Malloc(*maxlen);
+       *buffer = OPENSSL_malloc(*maxlen);
     }
     while (*currlen >= *maxlen) {
        *maxlen += 1024;
-       *buffer = Realloc(*buffer, *maxlen);
+       *buffer = OPENSSL_realloc(*buffer, *maxlen);
     }
     /* What to do if *buffer is NULL? */
     assert(*buffer != NULL);
@@ -840,3 +804,82 @@ doapr_outch(
     return;
 }
 #endif
+
+/***************************************************************************/
+
+int BIO_printf (BIO *bio, const char *format, ...)
+       {
+       va_list args;
+       int ret;
+
+       va_start(args, format);
+
+       ret = BIO_vprintf(bio, format, args);
+
+       va_end(args);
+       return(ret);
+       }
+
+int BIO_vprintf (BIO *bio, const char *format, va_list args)
+       {
+       int ret;
+       size_t retlen;
+#ifdef USE_ALLOCATING_PRINT
+       char *hugebuf;
+#else
+       MS_STATIC char hugebuf[1024*10];
+#endif
+
+#ifndef USE_ALLOCATING_PRINT
+       hugebuf[0]='\0';
+       dopr(hugebuf, sizeof(hugebuf), &retlen, format, args);
+#else
+       hugebuf = NULL;
+       CRYPTO_push_info("doapr()");
+       doapr(&hugebuf, &retlen, format, args);
+       if (hugebuf)
+               {
+#endif
+               ret=BIO_write(bio, hugebuf, (int)retlen);
+
+#ifdef USE_ALLOCATING_PRINT
+               OPENSSL_free(hugebuf);
+               }
+       CRYPTO_pop_info();
+#endif
+       return(ret);
+       }
+
+/* As snprintf is not available everywhere, we provide our own implementation.
+ * This function has nothing to do with BIOs, but it's closely related
+ * to BIO_printf, and we need *some* name prefix ...
+ * (XXX  the function should be renamed, but to what?) */
+int BIO_snprintf(char *buf, size_t n, const char *format, ...)
+       {
+       va_list args;
+       int ret;
+
+       va_start(args, format);
+
+       ret = BIO_vsnprintf(buf, n, format, args);
+
+       va_end(args);
+       return(ret);
+       }
+
+int BIO_vsnprintf(char *buf, size_t n, const char *format, va_list args)
+       {
+       size_t retlen;
+       int truncated;
+
+       _dopr(dopr_outch, dopr_isbig, dopr_copy,
+               &buf, &n, &retlen, &truncated, format, args);
+       if (truncated)
+               /* In case of truncation, return -1 like traditional snprintf.
+                * (Current drafts for ISO/IEC 9899 say snprintf should return
+                * the number of characters that would have been written,
+                * had the buffer been large enough.) */
+               return -1;
+       else
+               return (retlen <= INT_MAX) ? retlen : -1;
+       }