1 /* $OpenBSD: b_print.c,v 1.26 2019/06/28 05:47:57 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 (ret == -1) 53 return (ret); 54 BIO_write(bio, buf, ret); 55 free(buf); 56 return (ret); 57 } 58 59 #endif /* HAVE_FUNOPEN */ 60 61 /* 62 * BIO_snprintf and BIO_vsnprintf return -1 for overflow, 63 * due to the history of this API. Justification: 64 * 65 * Traditional snprintf surfaced in 4.4BSD, and returned 66 * "number of bytes wanted". Solaris and Windows opted to 67 * return -1. A draft standard was written which returned -1. 68 * Due to the large volume of code already using the first 69 * semantics, the draft was repaired before standardization to 70 * specify "number of bytes wanted" plus "-1 for character conversion 71 * style errors". Solaris adapted to this rule, but Windows stuck 72 * with -1. 73 * 74 * Original OpenSSL comment which is full of lies: 75 * 76 * "In case of truncation, return -1 like traditional snprintf. 77 * (Current drafts for ISO/IEC 9899 say snprintf should return 78 * the number of characters that would have been written, 79 * had the buffer been large enough.)" 80 */ 81 int 82 BIO_snprintf(char *buf, size_t n, const char *format, ...) 83 { 84 va_list args; 85 int ret; 86 87 va_start(args, format); 88 ret = vsnprintf(buf, n, format, args); 89 va_end(args); 90 91 if (ret >= n || ret == -1) 92 return (-1); 93 return (ret); 94 } 95 96 int 97 BIO_vsnprintf(char *buf, size_t n, const char *format, va_list args) 98 { 99 int ret; 100 101 ret = vsnprintf(buf, n, format, args); 102 103 if (ret >= n || ret == -1) 104 return (-1); 105 return (ret); 106 } 107