jcs's openbsd hax
openbsd
at jcs 121 lines 2.2 kB view raw
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 */