9ea3eb3deea0d797cc56a64e0407fe60349b12c2
[openssl.git] / crypto / err / err_prn.c
1 /*
2  * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
3  *
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
8  */
9
10 #include <stdio.h>
11 #include "internal/cryptlib.h"
12 #include <openssl/crypto.h>
13 #include <openssl/buffer.h>
14 #include <openssl/err.h>
15 #include "err_locl.h"
16
17 void ERR_print_errors_cb(int (*cb) (const char *str, size_t len, void *u),
18                          void *u)
19 {
20     CRYPTO_THREAD_ID tid = CRYPTO_THREAD_get_current_id();
21     unsigned long l;
22     char buf[4096], *hex;
23     const char *lib, *reason;
24     const char *file, *data, *func;
25     int line, flags;
26
27     while ((l = ERR_get_error_all(&file, &line, &func, &data, &flags)) != 0) {
28         lib = ERR_lib_error_string(l);
29         reason = ERR_reason_error_string(l);
30         if (func == NULL)
31             func = "unknown function";
32         if ((flags & ERR_TXT_STRING) == 0)
33             data = "";
34         hex = OPENSSL_buf2hexstr((const unsigned char *)&tid, sizeof(tid));
35         BIO_snprintf(buf, sizeof(buf), "%s:error:%s:%s:%s:%s:%d:%s\n",
36                      hex, lib, func, reason, file, line, data);
37         OPENSSL_free(hex);
38         if (cb(buf, strlen(buf), u) <= 0)
39             break;              /* abort outputting the error report */
40     }
41 }
42
43 static int print_bio(const char *str, size_t len, void *bp)
44 {
45     return BIO_write((BIO *)bp, str, len);
46 }
47
48 void ERR_print_errors(BIO *bp)
49 {
50     ERR_print_errors_cb(print_bio, bp);
51 }
52
53 #ifndef OPENSSL_NO_STDIO
54 void ERR_print_errors_fp(FILE *fp)
55 {
56     BIO *bio = BIO_new_fp(fp, BIO_NOCLOSE);
57     if (bio == NULL)
58         return;
59
60     ERR_print_errors_cb(print_bio, bio);
61     BIO_free(bio);
62 }
63 #endif