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