Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Copyright (c) 2018-2021 Yubico AB. All rights reserved. |
3 | | * Use of this source code is governed by a BSD-style |
4 | | * license that can be found in the LICENSE file. |
5 | | * SPDX-License-Identifier: BSD-2-Clause |
6 | | */ |
7 | | |
8 | | #undef _GNU_SOURCE /* XSI strerror_r() */ |
9 | | |
10 | | #include <stdarg.h> |
11 | | #include <stdio.h> |
12 | | |
13 | | #include "fido.h" |
14 | | |
15 | | #ifndef FIDO_NO_DIAGNOSTIC |
16 | | |
17 | | #define XXDLEN 32 |
18 | | #define XXDROW 128 |
19 | | #define LINELEN 256 |
20 | | |
21 | | #ifndef TLS |
22 | | #define TLS |
23 | | #endif |
24 | | |
25 | | static TLS int logging; |
26 | | static TLS fido_log_handler_t *log_handler; |
27 | | |
28 | | static void |
29 | | log_on_stderr(const char *str) |
30 | 0 | { |
31 | 0 | fprintf(stderr, "%s", str); |
32 | 0 | } |
33 | | |
34 | | static void |
35 | | do_log(const char *suffix, const char *fmt, va_list args) |
36 | 11.0M | { |
37 | 11.0M | char line[LINELEN], body[LINELEN]; |
38 | | |
39 | 11.0M | vsnprintf(body, sizeof(body), fmt, args); |
40 | | |
41 | 11.0M | if (suffix != NULL) |
42 | 1.97M | snprintf(line, sizeof(line), "%.180s: %.70s\n", body, suffix); |
43 | 9.05M | else |
44 | 9.05M | snprintf(line, sizeof(line), "%.180s\n", body); |
45 | | |
46 | 11.0M | log_handler(line); |
47 | 11.0M | } |
48 | | |
49 | | void |
50 | | fido_log_init(void) |
51 | 16.8k | { |
52 | 16.8k | logging = 1; |
53 | 16.8k | log_handler = log_on_stderr; |
54 | 16.8k | } |
55 | | |
56 | | void |
57 | | fido_log_debug(const char *fmt, ...) |
58 | 9.05M | { |
59 | 9.05M | va_list args; |
60 | | |
61 | 9.05M | if (!logging || log_handler == NULL) |
62 | 0 | return; |
63 | | |
64 | 9.05M | va_start(args, fmt); |
65 | 9.05M | do_log(NULL, fmt, args); |
66 | 9.05M | va_end(args); |
67 | 9.05M | } |
68 | | |
69 | | void |
70 | | fido_log_xxd(const void *buf, size_t count, const char *fmt, ...) |
71 | 1.42M | { |
72 | 1.42M | const uint8_t *ptr = buf; |
73 | 1.42M | char row[XXDROW], xxd[XXDLEN]; |
74 | 1.42M | va_list args; |
75 | | |
76 | 1.42M | if (!logging || log_handler == NULL) |
77 | 0 | return; |
78 | | |
79 | 1.42M | snprintf(row, sizeof(row), "buf=%p, len=%zu", buf, count); |
80 | 1.42M | va_start(args, fmt); |
81 | 1.42M | do_log(row, fmt, args); |
82 | 1.42M | va_end(args); |
83 | 1.42M | *row = '\0'; |
84 | | |
85 | 46.1M | for (size_t i = 0; i < count; i++) { |
86 | 44.6M | *xxd = '\0'; |
87 | 44.6M | if (i % 16 == 0) |
88 | 3.34M | snprintf(xxd, sizeof(xxd), "%04zu: %02x", i, *ptr++); |
89 | 41.3M | else |
90 | 41.3M | snprintf(xxd, sizeof(xxd), " %02x", *ptr++); |
91 | 44.6M | strlcat(row, xxd, sizeof(row)); |
92 | 44.6M | if (i % 16 == 15 || i == count - 1) { |
93 | 3.34M | fido_log_debug("%s", row); |
94 | 3.34M | *row = '\0'; |
95 | 3.34M | } |
96 | 44.6M | } |
97 | 1.42M | } |
98 | | |
99 | | void |
100 | | fido_log_error(int errnum, const char *fmt, ...) |
101 | 552k | { |
102 | 552k | char errstr[LINELEN]; |
103 | 552k | va_list args; |
104 | | |
105 | 552k | if (!logging || log_handler == NULL) |
106 | 0 | return; |
107 | 552k | if (strerror_r(errnum, errstr, sizeof(errstr)) != 0) |
108 | 0 | snprintf(errstr, sizeof(errstr), "error %d", errnum); |
109 | | |
110 | 552k | va_start(args, fmt); |
111 | 552k | do_log(errstr, fmt, args); |
112 | 552k | va_end(args); |
113 | 552k | } |
114 | | |
115 | | void |
116 | | fido_set_log_handler(fido_log_handler_t *handler) |
117 | 16.8k | { |
118 | 16.8k | if (handler != NULL) |
119 | 16.8k | log_handler = handler; |
120 | 16.8k | } |
121 | | |
122 | | #endif /* !FIDO_NO_DIAGNOSTIC */ |