1 /* $OpenBSD: b_print.c,v 1.27 2023/07/05 21:23:37 beck 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 LCRYPTO_ALIAS(BIO_printf); 19 20 #ifdef HAVE_FUNOPEN 21 static int 22 _BIO_write(void *cookie, const char *buf, int nbytes) 23 { 24 return BIO_write(cookie, buf, nbytes); 25 } 26 27 int 28 BIO_vprintf(BIO *bio, const char *format, va_list args) 29 { 30 int ret; 31 FILE *fp; 32 33 fp = funopen(bio, NULL, &_BIO_write, NULL, NULL); 34 if (fp == NULL) { 35 ret = -1; 36 goto fail; 37 } 38 ret = vfprintf(fp, format, args); 39 fclose(fp); 40 fail: 41 return (ret); 42 } 43 LCRYPTO_ALIAS(BIO_vprintf); 44 45 #else /* !HAVE_FUNOPEN */ 46 47 int 48 BIO_vprintf(BIO *bio, const char *format, va_list args) 49 { 50 int ret; 51 char *buf = NULL; 52 53 ret = vasprintf(&buf, format, args); 54 if (ret == -1) 55 return (ret); 56 BIO_write(bio, buf, ret); 57 free(buf); 58 return (ret); 59 } 60 LCRYPTO_ALIAS(BIO_vprintf); 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 LCRYPTO_ALIAS(BIO_snprintf); 99 100 int 101 BIO_vsnprintf(char *buf, size_t n, const char *format, va_list args) 102 { 103 int ret; 104 105 ret = vsnprintf(buf, n, format, args); 106 107 if (ret >= n || ret == -1) 108 return (-1); 109 return (ret); 110 } 111 LCRYPTO_ALIAS(BIO_vsnprintf); 112