b_print.c
上传用户:yisoukefu
上传日期:2020-08-09
资源大小:39506k
文件大小:23k
源码类别:

其他游戏

开发平台:

Visual C++

  1. /* crypto/bio/b_print.c */
  2. /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
  3.  * All rights reserved.
  4.  *
  5.  * This package is an SSL implementation written
  6.  * by Eric Young (eay@cryptsoft.com).
  7.  * The implementation was written so as to conform with Netscapes SSL.
  8.  * 
  9.  * This library is free for commercial and non-commercial use as long as
  10.  * the following conditions are aheared to.  The following conditions
  11.  * apply to all code found in this distribution, be it the RC4, RSA,
  12.  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
  13.  * included with this distribution is covered by the same copyright terms
  14.  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
  15.  * 
  16.  * Copyright remains Eric Young's, and as such any Copyright notices in
  17.  * the code are not to be removed.
  18.  * If this package is used in a product, Eric Young should be given attribution
  19.  * as the author of the parts of the library used.
  20.  * This can be in the form of a textual message at program startup or
  21.  * in documentation (online or textual) provided with the package.
  22.  * 
  23.  * Redistribution and use in source and binary forms, with or without
  24.  * modification, are permitted provided that the following conditions
  25.  * are met:
  26.  * 1. Redistributions of source code must retain the copyright
  27.  *    notice, this list of conditions and the following disclaimer.
  28.  * 2. Redistributions in binary form must reproduce the above copyright
  29.  *    notice, this list of conditions and the following disclaimer in the
  30.  *    documentation and/or other materials provided with the distribution.
  31.  * 3. All advertising materials mentioning features or use of this software
  32.  *    must display the following acknowledgement:
  33.  *    "This product includes cryptographic software written by
  34.  *     Eric Young (eay@cryptsoft.com)"
  35.  *    The word 'cryptographic' can be left out if the rouines from the library
  36.  *    being used are not cryptographic related :-).
  37.  * 4. If you include any Windows specific code (or a derivative thereof) from 
  38.  *    the apps directory (application code) you must include an acknowledgement:
  39.  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
  40.  * 
  41.  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
  42.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  43.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  44.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  45.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  46.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  47.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  48.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  49.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  50.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  51.  * SUCH DAMAGE.
  52.  * 
  53.  * The licence and distribution terms for any publically available version or
  54.  * derivative of this code cannot be changed.  i.e. this code cannot simply be
  55.  * copied and put under another distribution licence
  56.  * [including the GNU Public Licence.]
  57.  */
  58. /* disable assert() unless BIO_DEBUG has been defined */
  59. #ifndef BIO_DEBUG
  60. # ifndef NDEBUG
  61. #  define NDEBUG
  62. # endif
  63. #endif
  64. /* 
  65.  * Stolen from tjh's ssl/ssl_trc.c stuff.
  66.  */
  67. #include <stdio.h>
  68. #include <string.h>
  69. #include <ctype.h>
  70. #include <assert.h>
  71. #include <limits.h>
  72. #include "cryptlib.h"
  73. #ifndef NO_SYS_TYPES_H
  74. #include <sys/types.h>
  75. #endif
  76. #include <openssl/bn.h>         /* To get BN_LLONG properly defined */
  77. #include <openssl/bio.h>
  78. #ifdef BN_LLONG
  79. # ifndef HAVE_LONG_LONG
  80. #  define HAVE_LONG_LONG 1
  81. # endif
  82. #endif
  83. /***************************************************************************/
  84. /*
  85.  * Copyright Patrick Powell 1995
  86.  * This code is based on code written by Patrick Powell <papowell@astart.com>
  87.  * It may be used for any purpose as long as this notice remains intact
  88.  * on all source code distributions.
  89.  */
  90. /*
  91.  * This code contains numerious changes and enhancements which were
  92.  * made by lots of contributors over the last years to Patrick Powell's
  93.  * original code:
  94.  *
  95.  * o Patrick Powell <papowell@astart.com>      (1995)
  96.  * o Brandon Long <blong@fiction.net>          (1996, for Mutt)
  97.  * o Thomas Roessler <roessler@guug.de>        (1998, for Mutt)
  98.  * o Michael Elkins <me@cs.hmc.edu>            (1998, for Mutt)
  99.  * o Andrew Tridgell <tridge@samba.org>        (1998, for Samba)
  100.  * o Luke Mewburn <lukem@netbsd.org>           (1999, for LukemFTP)
  101.  * o Ralf S. Engelschall <rse@engelschall.com> (1999, for Pth)
  102.  * o ...                                       (for OpenSSL)
  103.  */
  104. #ifdef HAVE_LONG_DOUBLE
  105. #define LDOUBLE long double
  106. #else
  107. #define LDOUBLE double
  108. #endif
  109. #if HAVE_LONG_LONG
  110. # if defined(OPENSSL_SYS_WIN32) && !defined(__GNUC__)
  111. # define LLONG _int64
  112. # else
  113. # define LLONG long long
  114. # endif
  115. #else
  116. #define LLONG long
  117. #endif
  118. static void fmtstr     (char **, char **, size_t *, size_t *,
  119. const char *, int, int, int);
  120. static void fmtint     (char **, char **, size_t *, size_t *,
  121. LLONG, int, int, int, int);
  122. static void fmtfp      (char **, char **, size_t *, size_t *,
  123. LDOUBLE, int, int, int);
  124. static void doapr_outch (char **, char **, size_t *, size_t *, int);
  125. static void _dopr(char **sbuffer, char **buffer,
  126.   size_t *maxlen, size_t *retlen, int *truncated,
  127.   const char *format, va_list args);
  128. /* format read states */
  129. #define DP_S_DEFAULT    0
  130. #define DP_S_FLAGS      1
  131. #define DP_S_MIN        2
  132. #define DP_S_DOT        3
  133. #define DP_S_MAX        4
  134. #define DP_S_MOD        5
  135. #define DP_S_CONV       6
  136. #define DP_S_DONE       7
  137. /* format flags - Bits */
  138. #define DP_F_MINUS      (1 << 0)
  139. #define DP_F_PLUS       (1 << 1)
  140. #define DP_F_SPACE      (1 << 2)
  141. #define DP_F_NUM        (1 << 3)
  142. #define DP_F_ZERO       (1 << 4)
  143. #define DP_F_UP         (1 << 5)
  144. #define DP_F_UNSIGNED   (1 << 6)
  145. /* conversion flags */
  146. #define DP_C_SHORT      1
  147. #define DP_C_LONG       2
  148. #define DP_C_LDOUBLE    3
  149. #define DP_C_LLONG      4
  150. /* some handy macros */
  151. #define char_to_int(p) (p - '0')
  152. #define OSSL_MAX(p,q) ((p >= q) ? p : q)
  153. static void
  154. _dopr(
  155.     char **sbuffer,
  156.     char **buffer,
  157.     size_t *maxlen,
  158.     size_t *retlen,
  159.     int *truncated,
  160.     const char *format,
  161.     va_list args)
  162. {
  163.     char ch;
  164.     LLONG value;
  165.     LDOUBLE fvalue;
  166.     char *strvalue;
  167.     int min;
  168.     int max;
  169.     int state;
  170.     int flags;
  171.     int cflags;
  172.     size_t currlen;
  173.     state = DP_S_DEFAULT;
  174.     flags = currlen = cflags = min = 0;
  175.     max = -1;
  176.     ch = *format++;
  177.     while (state != DP_S_DONE) {
  178.         if (ch == '' || (buffer == NULL && currlen >= *maxlen))
  179.             state = DP_S_DONE;
  180.         switch (state) {
  181.         case DP_S_DEFAULT:
  182.             if (ch == '%')
  183.                 state = DP_S_FLAGS;
  184.             else
  185.                 doapr_outch(sbuffer,buffer, &currlen, maxlen, ch);
  186.             ch = *format++;
  187.             break;
  188.         case DP_S_FLAGS:
  189.             switch (ch) {
  190.             case '-':
  191.                 flags |= DP_F_MINUS;
  192.                 ch = *format++;
  193.                 break;
  194.             case '+':
  195.                 flags |= DP_F_PLUS;
  196.                 ch = *format++;
  197.                 break;
  198.             case ' ':
  199.                 flags |= DP_F_SPACE;
  200.                 ch = *format++;
  201.                 break;
  202.             case '#':
  203.                 flags |= DP_F_NUM;
  204.                 ch = *format++;
  205.                 break;
  206.             case '0':
  207.                 flags |= DP_F_ZERO;
  208.                 ch = *format++;
  209.                 break;
  210.             default:
  211.                 state = DP_S_MIN;
  212.                 break;
  213.             }
  214.             break;
  215.         case DP_S_MIN:
  216.             if (isdigit((unsigned char)ch)) {
  217.                 min = 10 * min + char_to_int(ch);
  218.                 ch = *format++;
  219.             } else if (ch == '*') {
  220.                 min = va_arg(args, int);
  221.                 ch = *format++;
  222.                 state = DP_S_DOT;
  223.             } else
  224.                 state = DP_S_DOT;
  225.             break;
  226.         case DP_S_DOT:
  227.             if (ch == '.') {
  228.                 state = DP_S_MAX;
  229.                 ch = *format++;
  230.             } else
  231.                 state = DP_S_MOD;
  232.             break;
  233.         case DP_S_MAX:
  234.             if (isdigit((unsigned char)ch)) {
  235.                 if (max < 0)
  236.                     max = 0;
  237.                 max = 10 * max + char_to_int(ch);
  238.                 ch = *format++;
  239.             } else if (ch == '*') {
  240.                 max = va_arg(args, int);
  241.                 ch = *format++;
  242.                 state = DP_S_MOD;
  243.             } else
  244.                 state = DP_S_MOD;
  245.             break;
  246.         case DP_S_MOD:
  247.             switch (ch) {
  248.             case 'h':
  249.                 cflags = DP_C_SHORT;
  250.                 ch = *format++;
  251.                 break;
  252.             case 'l':
  253.                 if (*format == 'l') {
  254.                     cflags = DP_C_LLONG;
  255.                     format++;
  256.                 } else
  257.                     cflags = DP_C_LONG;
  258.                 ch = *format++;
  259.                 break;
  260.             case 'q':
  261.                 cflags = DP_C_LLONG;
  262.                 ch = *format++;
  263.                 break;
  264.             case 'L':
  265.                 cflags = DP_C_LDOUBLE;
  266.                 ch = *format++;
  267.                 break;
  268.             default:
  269.                 break;
  270.             }
  271.             state = DP_S_CONV;
  272.             break;
  273.         case DP_S_CONV:
  274.             switch (ch) {
  275.             case 'd':
  276.             case 'i':
  277.                 switch (cflags) {
  278.                 case DP_C_SHORT:
  279.                     value = (short int)va_arg(args, int);
  280.                     break;
  281.                 case DP_C_LONG:
  282.                     value = va_arg(args, long int);
  283.                     break;
  284.                 case DP_C_LLONG:
  285.                     value = va_arg(args, LLONG);
  286.                     break;
  287.                 default:
  288.                     value = va_arg(args, int);
  289.                     break;
  290.                 }
  291.                 fmtint(sbuffer, buffer, &currlen, maxlen,
  292.                        value, 10, min, max, flags);
  293.                 break;
  294.             case 'X':
  295.                 flags |= DP_F_UP;
  296.                 /* FALLTHROUGH */
  297.             case 'x':
  298.             case 'o':
  299.             case 'u':
  300.                 flags |= DP_F_UNSIGNED;
  301.                 switch (cflags) {
  302.                 case DP_C_SHORT:
  303.                     value = (unsigned short int)va_arg(args, unsigned int);
  304.                     break;
  305.                 case DP_C_LONG:
  306.                     value = (LLONG) va_arg(args,
  307.                         unsigned long int);
  308.                     break;
  309.                 case DP_C_LLONG:
  310.                     value = va_arg(args, unsigned LLONG);
  311.                     break;
  312.                 default:
  313.                     value = (LLONG) va_arg(args,
  314.                         unsigned int);
  315.                     break;
  316.                 }
  317.                 fmtint(sbuffer, buffer, &currlen, maxlen, value,
  318.                        ch == 'o' ? 8 : (ch == 'u' ? 10 : 16),
  319.                        min, max, flags);
  320.                 break;
  321.             case 'f':
  322.                 if (cflags == DP_C_LDOUBLE)
  323.                     fvalue = va_arg(args, LDOUBLE);
  324.                 else
  325.                     fvalue = va_arg(args, double);
  326.                 fmtfp(sbuffer, buffer, &currlen, maxlen,
  327.                       fvalue, min, max, flags);
  328.                 break;
  329.             case 'E':
  330.                 flags |= DP_F_UP;
  331.             case 'e':
  332.                 if (cflags == DP_C_LDOUBLE)
  333.                     fvalue = va_arg(args, LDOUBLE);
  334.                 else
  335.                     fvalue = va_arg(args, double);
  336.                 break;
  337.             case 'G':
  338.                 flags |= DP_F_UP;
  339.             case 'g':
  340.                 if (cflags == DP_C_LDOUBLE)
  341.                     fvalue = va_arg(args, LDOUBLE);
  342.                 else
  343.                     fvalue = va_arg(args, double);
  344.                 break;
  345.             case 'c':
  346.                 doapr_outch(sbuffer, buffer, &currlen, maxlen,
  347.                     va_arg(args, int));
  348.                 break;
  349.             case 's':
  350.                 strvalue = va_arg(args, char *);
  351.                 if (max < 0) {
  352.     if (buffer)
  353. max = INT_MAX;
  354.     else
  355. max = *maxlen;
  356. }
  357.                 fmtstr(sbuffer, buffer, &currlen, maxlen, strvalue,
  358.                        flags, min, max);
  359.                 break;
  360.             case 'p':
  361.                 value = (long)va_arg(args, void *);
  362.                 fmtint(sbuffer, buffer, &currlen, maxlen,
  363.                     value, 16, min, max, flags|DP_F_NUM);
  364.                 break;
  365.             case 'n': /* XXX */
  366.                 if (cflags == DP_C_SHORT) {
  367.                     short int *num;
  368.                     num = va_arg(args, short int *);
  369.                     *num = currlen;
  370.                 } else if (cflags == DP_C_LONG) { /* XXX */
  371.                     long int *num;
  372.                     num = va_arg(args, long int *);
  373.                     *num = (long int) currlen;
  374.                 } else if (cflags == DP_C_LLONG) { /* XXX */
  375.                     LLONG *num;
  376.                     num = va_arg(args, LLONG *);
  377.                     *num = (LLONG) currlen;
  378.                 } else {
  379.                     int    *num;
  380.                     num = va_arg(args, int *);
  381.                     *num = currlen;
  382.                 }
  383.                 break;
  384.             case '%':
  385.                 doapr_outch(sbuffer, buffer, &currlen, maxlen, ch);
  386.                 break;
  387.             case 'w':
  388.                 /* not supported yet, treat as next char */
  389.                 ch = *format++;
  390.                 break;
  391.             default:
  392.                 /* unknown, skip */
  393.                 break;
  394.             }
  395.             ch = *format++;
  396.             state = DP_S_DEFAULT;
  397.             flags = cflags = min = 0;
  398.             max = -1;
  399.             break;
  400.         case DP_S_DONE:
  401.             break;
  402.         default:
  403.             break;
  404.         }
  405.     }
  406.     *truncated = (currlen > *maxlen - 1);
  407.     if (*truncated)
  408.         currlen = *maxlen - 1;
  409.     doapr_outch(sbuffer, buffer, &currlen, maxlen, '');
  410.     *retlen = currlen - 1;
  411.     return;
  412. }
  413. static void
  414. fmtstr(
  415.     char **sbuffer,
  416.     char **buffer,
  417.     size_t *currlen,
  418.     size_t *maxlen,
  419.     const char *value,
  420.     int flags,
  421.     int min,
  422.     int max)
  423. {
  424.     int padlen, strln;
  425.     int cnt = 0;
  426.     if (value == 0)
  427.         value = "<NULL>";
  428.     for (strln = 0; value[strln]; ++strln)
  429.         ;
  430.     padlen = min - strln;
  431.     if (padlen < 0)
  432.         padlen = 0;
  433.     if (flags & DP_F_MINUS)
  434.         padlen = -padlen;
  435.     while ((padlen > 0) && (cnt < max)) {
  436.         doapr_outch(sbuffer, buffer, currlen, maxlen, ' ');
  437.         --padlen;
  438.         ++cnt;
  439.     }
  440.     while (*value && (cnt < max)) {
  441.         doapr_outch(sbuffer, buffer, currlen, maxlen, *value++);
  442.         ++cnt;
  443.     }
  444.     while ((padlen < 0) && (cnt < max)) {
  445.         doapr_outch(sbuffer, buffer, currlen, maxlen, ' ');
  446.         ++padlen;
  447.         ++cnt;
  448.     }
  449. }
  450. static void
  451. fmtint(
  452.     char **sbuffer,
  453.     char **buffer,
  454.     size_t *currlen,
  455.     size_t *maxlen,
  456.     LLONG value,
  457.     int base,
  458.     int min,
  459.     int max,
  460.     int flags)
  461. {
  462.     int signvalue = 0;
  463.     const char *prefix = "";
  464.     unsigned LLONG uvalue;
  465.     char convert[DECIMAL_SIZE(value)+3];
  466.     int place = 0;
  467.     int spadlen = 0;
  468.     int zpadlen = 0;
  469.     int caps = 0;
  470.     if (max < 0)
  471.         max = 0;
  472.     uvalue = value;
  473.     if (!(flags & DP_F_UNSIGNED)) {
  474.         if (value < 0) {
  475.             signvalue = '-';
  476.             uvalue = -value;
  477.         } else if (flags & DP_F_PLUS)
  478.             signvalue = '+';
  479.         else if (flags & DP_F_SPACE)
  480.             signvalue = ' ';
  481.     }
  482.     if (flags & DP_F_NUM) {
  483. if (base == 8) prefix = "0";
  484. if (base == 16) prefix = "0x";
  485.     }
  486.     if (flags & DP_F_UP)
  487.         caps = 1;
  488.     do {
  489.         convert[place++] =
  490.             (caps ? "0123456789ABCDEF" : "0123456789abcdef")
  491.             [uvalue % (unsigned) base];
  492.         uvalue = (uvalue / (unsigned) base);
  493.     } while (uvalue && (place < (int)sizeof(convert)));
  494.     if (place == sizeof(convert))
  495.         place--;
  496.     convert[place] = 0;
  497.     zpadlen = max - place;
  498.     spadlen = min - OSSL_MAX(max, place) - (signvalue ? 1 : 0) - strlen(prefix);
  499.     if (zpadlen < 0)
  500.         zpadlen = 0;
  501.     if (spadlen < 0)
  502.         spadlen = 0;
  503.     if (flags & DP_F_ZERO) {
  504.         zpadlen = OSSL_MAX(zpadlen, spadlen);
  505.         spadlen = 0;
  506.     }
  507.     if (flags & DP_F_MINUS)
  508.         spadlen = -spadlen;
  509.     /* spaces */
  510.     while (spadlen > 0) {
  511.         doapr_outch(sbuffer, buffer, currlen, maxlen, ' ');
  512.         --spadlen;
  513.     }
  514.     /* sign */
  515.     if (signvalue)
  516.         doapr_outch(sbuffer, buffer, currlen, maxlen, signvalue);
  517.     /* prefix */
  518.     while (*prefix) {
  519. doapr_outch(sbuffer, buffer, currlen, maxlen, *prefix);
  520. prefix++;
  521.     }
  522.     /* zeros */
  523.     if (zpadlen > 0) {
  524.         while (zpadlen > 0) {
  525.             doapr_outch(sbuffer, buffer, currlen, maxlen, '0');
  526.             --zpadlen;
  527.         }
  528.     }
  529.     /* digits */
  530.     while (place > 0)
  531.         doapr_outch(sbuffer, buffer, currlen, maxlen, convert[--place]);
  532.     /* left justified spaces */
  533.     while (spadlen < 0) {
  534.         doapr_outch(sbuffer, buffer, currlen, maxlen, ' ');
  535.         ++spadlen;
  536.     }
  537.     return;
  538. }
  539. static LDOUBLE
  540. abs_val(LDOUBLE value)
  541. {
  542.     LDOUBLE result = value;
  543.     if (value < 0)
  544.         result = -value;
  545.     return result;
  546. }
  547. static LDOUBLE
  548. pow_10(int in_exp)
  549. {
  550.     LDOUBLE result = 1;
  551.     while (in_exp) {
  552.         result *= 10;
  553.         in_exp--;
  554.     }
  555.     return result;
  556. }
  557. static long
  558. roundv(LDOUBLE value)
  559. {
  560.     long intpart;
  561.     intpart = (long) value;
  562.     value = value - intpart;
  563.     if (value >= 0.5)
  564.         intpart++;
  565.     return intpart;
  566. }
  567. static void
  568. fmtfp(
  569.     char **sbuffer,
  570.     char **buffer,
  571.     size_t *currlen,
  572.     size_t *maxlen,
  573.     LDOUBLE fvalue,
  574.     int min,
  575.     int max,
  576.     int flags)
  577. {
  578.     int signvalue = 0;
  579.     LDOUBLE ufvalue;
  580.     char iconvert[20];
  581.     char fconvert[20];
  582.     int iplace = 0;
  583.     int fplace = 0;
  584.     int padlen = 0;
  585.     int zpadlen = 0;
  586.     int caps = 0;
  587.     long intpart;
  588.     long fracpart;
  589.     long max10;
  590.     if (max < 0)
  591.         max = 6;
  592.     ufvalue = abs_val(fvalue);
  593.     if (fvalue < 0)
  594.         signvalue = '-';
  595.     else if (flags & DP_F_PLUS)
  596.         signvalue = '+';
  597.     else if (flags & DP_F_SPACE)
  598.         signvalue = ' ';
  599.     intpart = (long)ufvalue;
  600.     /* sorry, we only support 9 digits past the decimal because of our
  601.        conversion method */
  602.     if (max > 9)
  603.         max = 9;
  604.     /* we "cheat" by converting the fractional part to integer by
  605.        multiplying by a factor of 10 */
  606.     max10 = roundv(pow_10(max));
  607.     fracpart = roundv(pow_10(max) * (ufvalue - intpart));
  608.     if (fracpart >= max10) {
  609.         intpart++;
  610.         fracpart -= max10;
  611.     }
  612.     /* convert integer part */
  613.     do {
  614.         iconvert[iplace++] =
  615.             (caps ? "0123456789ABCDEF"
  616.               : "0123456789abcdef")[intpart % 10];
  617.         intpart = (intpart / 10);
  618.     } while (intpart && (iplace < (int)sizeof(iconvert)));
  619.     if (iplace == sizeof iconvert)
  620.         iplace--;
  621.     iconvert[iplace] = 0;
  622.     /* convert fractional part */
  623.     do {
  624.         fconvert[fplace++] =
  625.             (caps ? "0123456789ABCDEF"
  626.               : "0123456789abcdef")[fracpart % 10];
  627.         fracpart = (fracpart / 10);
  628.     } while (fplace < max);
  629.     if (fplace == sizeof fconvert)
  630.         fplace--;
  631.     fconvert[fplace] = 0;
  632.     /* -1 for decimal point, another -1 if we are printing a sign */
  633.     padlen = min - iplace - max - 1 - ((signvalue) ? 1 : 0);
  634.     zpadlen = max - fplace;
  635.     if (zpadlen < 0)
  636.         zpadlen = 0;
  637.     if (padlen < 0)
  638.         padlen = 0;
  639.     if (flags & DP_F_MINUS)
  640.         padlen = -padlen;
  641.     if ((flags & DP_F_ZERO) && (padlen > 0)) {
  642.         if (signvalue) {
  643.             doapr_outch(sbuffer, buffer, currlen, maxlen, signvalue);
  644.             --padlen;
  645.             signvalue = 0;
  646.         }
  647.         while (padlen > 0) {
  648.             doapr_outch(sbuffer, buffer, currlen, maxlen, '0');
  649.             --padlen;
  650.         }
  651.     }
  652.     while (padlen > 0) {
  653.         doapr_outch(sbuffer, buffer, currlen, maxlen, ' ');
  654.         --padlen;
  655.     }
  656.     if (signvalue)
  657.         doapr_outch(sbuffer, buffer, currlen, maxlen, signvalue);
  658.     while (iplace > 0)
  659.         doapr_outch(sbuffer, buffer, currlen, maxlen, iconvert[--iplace]);
  660.     /*
  661.      * Decimal point. This should probably use locale to find the correct
  662.      * char to print out.
  663.      */
  664.     if (max > 0 || (flags & DP_F_NUM)) {
  665.         doapr_outch(sbuffer, buffer, currlen, maxlen, '.');
  666.         while (fplace > 0)
  667.             doapr_outch(sbuffer, buffer, currlen, maxlen, fconvert[--fplace]);
  668.     }
  669.     while (zpadlen > 0) {
  670.         doapr_outch(sbuffer, buffer, currlen, maxlen, '0');
  671.         --zpadlen;
  672.     }
  673.     while (padlen < 0) {
  674.         doapr_outch(sbuffer, buffer, currlen, maxlen, ' ');
  675.         ++padlen;
  676.     }
  677. }
  678. static void
  679. doapr_outch(
  680.     char **sbuffer,
  681.     char **buffer,
  682.     size_t *currlen,
  683.     size_t *maxlen,
  684.     int c)
  685. {
  686.     /* If we haven't at least one buffer, someone has doe a big booboo */
  687.     assert(*sbuffer != NULL || buffer != NULL);
  688.     if (buffer) {
  689. while (*currlen >= *maxlen) {
  690.     if (*buffer == NULL) {
  691. if (*maxlen == 0)
  692.     *maxlen = 1024;
  693. *buffer = OPENSSL_malloc(*maxlen);
  694. if (*currlen > 0) {
  695.     assert(*sbuffer != NULL);
  696.     memcpy(*buffer, *sbuffer, *currlen);
  697. }
  698. *sbuffer = NULL;
  699.     } else {
  700. *maxlen += 1024;
  701. *buffer = OPENSSL_realloc(*buffer, *maxlen);
  702.     }
  703. }
  704. /* What to do if *buffer is NULL? */
  705. assert(*sbuffer != NULL || *buffer != NULL);
  706.     }
  707.     if (*currlen < *maxlen) {
  708. if (*sbuffer)
  709.     (*sbuffer)[(*currlen)++] = (char)c;
  710. else
  711.     (*buffer)[(*currlen)++] = (char)c;
  712.     }
  713.     return;
  714. }
  715. /***************************************************************************/
  716. int BIO_printf (BIO *bio, const char *format, ...)
  717. {
  718. va_list args;
  719. int ret;
  720. va_start(args, format);
  721. ret = BIO_vprintf(bio, format, args);
  722. va_end(args);
  723. return(ret);
  724. }
  725. int BIO_vprintf (BIO *bio, const char *format, va_list args)
  726. {
  727. int ret;
  728. size_t retlen;
  729. char hugebuf[1024*2]; /* Was previously 10k, which is unreasonable
  730.    in small-stack environments, like threads
  731.    or DOS programs. */
  732. char *hugebufp = hugebuf;
  733. size_t hugebufsize = sizeof(hugebuf);
  734. char *dynbuf = NULL;
  735. int ignored;
  736. dynbuf = NULL;
  737. CRYPTO_push_info("doapr()");
  738. _dopr(&hugebufp, &dynbuf, &hugebufsize,
  739. &retlen, &ignored, format, args);
  740. if (dynbuf)
  741. {
  742. ret=BIO_write(bio, dynbuf, (int)retlen);
  743. OPENSSL_free(dynbuf);
  744. }
  745. else
  746. {
  747. ret=BIO_write(bio, hugebuf, (int)retlen);
  748. }
  749. CRYPTO_pop_info();
  750. return(ret);
  751. }
  752. /* As snprintf is not available everywhere, we provide our own implementation.
  753.  * This function has nothing to do with BIOs, but it's closely related
  754.  * to BIO_printf, and we need *some* name prefix ...
  755.  * (XXX  the function should be renamed, but to what?) */
  756. int BIO_snprintf(char *buf, size_t n, const char *format, ...)
  757. {
  758. va_list args;
  759. int ret;
  760. va_start(args, format);
  761. ret = BIO_vsnprintf(buf, n, format, args);
  762. va_end(args);
  763. return(ret);
  764. }
  765. int BIO_vsnprintf(char *buf, size_t n, const char *format, va_list args)
  766. {
  767. size_t retlen;
  768. int truncated;
  769. _dopr(&buf, NULL, &n, &retlen, &truncated, format, args);
  770. if (truncated)
  771. /* In case of truncation, return -1 like traditional snprintf.
  772.  * (Current drafts for ISO/IEC 9899 say snprintf should return
  773.  * the number of characters that would have been written,
  774.  * had the buffer been large enough.) */
  775. return -1;
  776. else
  777. return (retlen <= INT_MAX) ? (int)retlen : -1;
  778. }