1 /* $OpenBSD: b_print.c,v 1.25 2014/06/12 15:49:28 deraadt Exp $ */ 2 3 /* Theo de Raadt places this file in the public domain. */ 4 5 #include <openssl/bio.h> 6 7 int 8 BIO_printf(BIO *bio, const char *format, ...) 9 { 10 va_list args; 11 int ret; 12 13 va_start(args, format); 14 ret = BIO_vprintf(bio, format, args); 15 va_end(args); 16 return (ret); 17 } 18 19 #ifdef HAVE_FUNOPEN 20 static int 21 _BIO_write(void *cookie, const char *buf, int nbytes) 22 { 23 return BIO_write(cookie, buf, nbytes); 24 } 25 26 int 27 BIO_vprintf(BIO *bio, const char *format, va_list args) 28 { 29 int ret; 30 FILE *fp; 31 32 fp = funopen(bio, NULL, &_BIO_write, NULL, NULL); 33 if (fp == NULL) { 34 ret = -1; 35 goto fail; 36 } 37 ret = vfprintf(fp, format, args); 38 fclose(fp); 39 fail: 40 return (ret); 41 } 42 43 #else /* !HAVE_FUNOPEN */ 44 45 int 46 BIO_vprintf(BIO *bio, const char *format, va_list args) 47 { 48 int ret; 49 char *buf = NULL; 50 51 ret = vasprintf(&buf, format, args); 52 if (buf == NULL) { 53 ret = -1; 54 goto fail; 55 } 56 BIO_write(bio, buf, ret); 57 free(buf); 58 fail: 59 return (ret); 60 } 61 62 #endif /* HAVE_FUNOPEN */ 63 64 /* 65 * BIO_snprintf and BIO_vsnprintf return -1 for overflow, 66 * due to the history of this API. Justification: 67 * 68 * Traditional snprintf surfaced in 4.4BSD, and returned 69 * "number of bytes wanted". Solaris and Windows opted to 70 * return -1. A draft standard was written which returned -1. 71 * Due to the large volume of code already using the first 72 * semantics, the draft was repaired before standardization to 73 * specify "number of bytes wanted" plus "-1 for character conversion 74 * style errors". Solaris adapted to this rule, but Windows stuck 75 * with -1. 76 * 77 * Original OpenSSL comment which is full of lies: 78 * 79 * "In case of truncation, return -1 like traditional snprintf. 80 * (Current drafts for ISO/IEC 9899 say snprintf should return 81 * the number of characters that would have been written, 82 * had the buffer been large enough.)" 83 */ 84 int 85 BIO_snprintf(char *buf, size_t n, const char *format, ...) 86 { 87 va_list args; 88 int ret; 89 90 va_start(args, format); 91 ret = vsnprintf(buf, n, format, args); 92 va_end(args); 93 94 if (ret >= n || ret == -1) 95 return (-1); 96 return (ret); 97 } 98 99 int 100 BIO_vsnprintf(char *buf, size_t n, const char *format, va_list args) 101 { 102 int ret; 103 104 ret = vsnprintf(buf, n, format, args); 105 106 if (ret >= n || ret == -1) 107 return (-1); 108 return (ret); 109 } 110