jcs's openbsd hax
openbsd
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 */
6
7#undef _GNU_SOURCE /* XSI strerror_r() */
8
9#include <stdarg.h>
10#include <stdio.h>
11
12#include "fido.h"
13
14#ifndef FIDO_NO_DIAGNOSTIC
15
16#define XXDLEN 32
17#define XXDROW 128
18#define LINELEN 256
19
20#ifndef TLS
21#define TLS
22#endif
23
24static TLS int logging;
25static TLS fido_log_handler_t *log_handler;
26
27static void
28log_on_stderr(const char *str)
29{
30 fprintf(stderr, "%s", str);
31}
32
33static void
34do_log(const char *suffix, const char *fmt, va_list args)
35{
36 char line[LINELEN], body[LINELEN];
37
38 vsnprintf(body, sizeof(body), fmt, args);
39
40 if (suffix != NULL)
41 snprintf(line, sizeof(line), "%.180s: %.70s\n", body, suffix);
42 else
43 snprintf(line, sizeof(line), "%.180s\n", body);
44
45 log_handler(line);
46}
47
48void
49fido_log_init(void)
50{
51 logging = 1;
52 log_handler = log_on_stderr;
53}
54
55void
56fido_log_debug(const char *fmt, ...)
57{
58 va_list args;
59
60 if (!logging || log_handler == NULL)
61 return;
62
63 va_start(args, fmt);
64 do_log(NULL, fmt, args);
65 va_end(args);
66}
67
68void
69fido_log_xxd(const void *buf, size_t count, const char *fmt, ...)
70{
71 const uint8_t *ptr = buf;
72 char row[XXDROW], xxd[XXDLEN];
73 va_list args;
74
75 if (!logging || log_handler == NULL)
76 return;
77
78 snprintf(row, sizeof(row), "buf=%p, len=%zu", buf, count);
79 va_start(args, fmt);
80 do_log(row, fmt, args);
81 va_end(args);
82 *row = '\0';
83
84 for (size_t i = 0; i < count; i++) {
85 *xxd = '\0';
86 if (i % 16 == 0)
87 snprintf(xxd, sizeof(xxd), "%04zu: %02x", i, *ptr++);
88 else
89 snprintf(xxd, sizeof(xxd), " %02x", *ptr++);
90 strlcat(row, xxd, sizeof(row));
91 if (i % 16 == 15 || i == count - 1) {
92 fido_log_debug("%s", row);
93 *row = '\0';
94 }
95 }
96}
97
98void
99fido_log_error(int errnum, const char *fmt, ...)
100{
101 char errstr[LINELEN];
102 va_list args;
103
104 if (!logging || log_handler == NULL)
105 return;
106 if (strerror_r(errnum, errstr, sizeof(errstr)) != 0)
107 snprintf(errstr, sizeof(errstr), "error %d", errnum);
108
109 va_start(args, fmt);
110 do_log(errstr, fmt, args);
111 va_end(args);
112}
113
114void
115fido_set_log_handler(fido_log_handler_t *handler)
116{
117 if (handler != NULL)
118 log_handler = handler;
119}
120
121#endif /* !FIDO_NO_DIAGNOSTIC */