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
BIO_printf(BIO * bio,const char * format,...)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
_BIO_write(void * cookie,const char * buf,int nbytes)21 _BIO_write(void *cookie, const char *buf, int nbytes)
22 {
23 return BIO_write(cookie, buf, nbytes);
24 }
25
26 int
BIO_vprintf(BIO * bio,const char * format,va_list args)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
BIO_vprintf(BIO * bio,const char * format,va_list args)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
BIO_snprintf(char * buf,size_t n,const char * format,...)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
BIO_vsnprintf(char * buf,size_t n,const char * format,va_list args)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