]>
git.ipfire.org Git - thirdparty/openssl.git/blob - test/bio_prefix_text.c
2 * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
4 * Licensed under the Apache License 2.0 (the "License"). You may not use
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
12 #include <openssl/bio.h>
13 #include <openssl/safestack.h>
16 static BIO
*bio_in
= NULL
;
17 static BIO
*bio_out
= NULL
;
18 static BIO
*bio_err
= NULL
;
21 * This program sets up a chain of BIO_f_filter() on top of bio_out, how
22 * many is governed by the user through -n. It allows the user to set the
23 * indentation for each individual filter using -i and -p. Then it reads
24 * text from bio_in and prints it out through the BIO chain.
26 * The filter index is counted from the source/sink, i.e. index 0 is closest
31 * $ echo foo | ./bio_prefix_text -n 2 -i 1:32 -p 1:FOO -i 0:3
33 * ^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
35 * | +------ 32 spaces from filter 1
36 * +-------------------------- 3 spaces from filter 0
39 static size_t amount
= 0;
40 static BIO
**chain
= NULL
;
42 typedef enum OPTION_choice
{
50 static const OPTIONS options
[] = {
51 { "n", OPT_AMOUNT
, 'p', "Amount of BIO_f_prefix() filters" },
53 * idx is the index to the BIO_f_filter chain(), where 0 is closest
54 * to the source/sink BIO. If idx isn't given, 0 is assumed
56 { "i", OPT_INDENT
, 's', "Indentation in form '[idx:]indent'" },
57 { "p", OPT_PREFIX
, 's', "Prefix in form '[idx:]prefix'" },
61 int opt_printf_stderr(const char *fmt
, ...)
67 ret
= BIO_vprintf(bio_err
, fmt
, ap
);
72 static int run_pipe(void)
76 while (!BIO_eof(bio_in
)) {
80 if (!BIO_read_ex(bio_in
, buf
, sizeof(buf
), &bytes_in
))
83 while (bytes_out
< bytes_in
) {
86 if (!BIO_write_ex(chain
[amount
- 1], buf
, bytes_in
, &bytes
))
94 static int setup_bio_chain(const char *progname
)
99 chain
= OPENSSL_zalloc(sizeof(*chain
) * n
);
105 BIO_up_ref(next
); /* Protection against freeing */
107 for (i
= 0; n
> 0; i
++, n
--) {
108 BIO
*curr
= BIO_new(BIO_f_prefix());
112 chain
[i
] = BIO_push(curr
, next
);
113 if (chain
[i
] == NULL
)
118 return chain
!= NULL
;
120 /* Free the chain we built up */
126 static void cleanup(void)
129 BIO_free_all(chain
[amount
- 1]);
133 BIO_free_all(bio_in
);
134 BIO_free_all(bio_out
);
135 BIO_free_all(bio_err
);
138 static int setup(void)
145 const char *progname
= opt_getprog();
147 bio_in
= BIO_new_fp(stdin
, BIO_NOCLOSE
| BIO_FP_TEXT
);
148 bio_out
= BIO_new_fp(stdout
, BIO_NOCLOSE
| BIO_FP_TEXT
);
149 bio_err
= BIO_new_fp(stderr
, BIO_NOCLOSE
| BIO_FP_TEXT
);
151 bio_out
= BIO_push(BIO_new(BIO_f_linebuffer()), bio_out
);
152 bio_err
= BIO_push(BIO_new(BIO_f_linebuffer()), bio_err
);
155 OPENSSL_assert(bio_in
!= NULL
);
156 OPENSSL_assert(bio_out
!= NULL
);
157 OPENSSL_assert(bio_err
!= NULL
);
160 while ((o
= opt_next()) != OPT_EOF
) {
164 amount
= strtoul(arg
, &endptr
, 10);
165 if (endptr
[0] != '\0') {
167 "%s: -n argument isn't a decimal number: %s",
172 BIO_printf(bio_err
, "%s: must set up at least one filter",
176 if (!setup_bio_chain(progname
)) {
177 BIO_printf(bio_err
, "%s: failed setting up filter chain",
184 BIO_printf(bio_err
, "%s: -i given before -n", progname
);
188 colon
= strchr(arg
, ':');
191 idx
= strtoul(arg
, &endptr
, 10);
192 if (endptr
[0] != ':') {
194 "%s: -i index isn't a decimal number: %s",
202 indent
= strtoul(colon
, &endptr
, 10);
203 if (endptr
[0] != '\0') {
205 "%s: -i value isn't a decimal number: %s",
210 BIO_printf(bio_err
, "%s: index (%zu) not within range 0..%zu",
211 progname
, idx
, amount
- 1);
214 if (BIO_set_indent(chain
[idx
], (long)indent
) <= 0) {
215 BIO_printf(bio_err
, "%s: failed setting indentation: %s",
222 BIO_printf(bio_err
, "%s: -p given before -n", progname
);
226 colon
= strchr(arg
, ':');
229 idx
= strtoul(arg
, &endptr
, 10);
230 if (endptr
[0] != ':') {
232 "%s: -p index isn't a decimal number: %s",
241 BIO_printf(bio_err
, "%s: index (%zu) not within range 0..%zu",
242 progname
, idx
, amount
- 1);
245 if (BIO_set_prefix(chain
[idx
], colon
) <= 0) {
246 BIO_printf(bio_err
, "%s: failed setting prefix: %s",
259 int main(int argc
, char **argv
)
261 int rv
= EXIT_SUCCESS
;
263 opt_init(argc
, argv
, options
);
264 rv
= (setup() && run_pipe()) ? EXIT_SUCCESS
: EXIT_FAILURE
;