1 /* 2 * Copyright 2020-2023 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 <openssl/trace.h> 11 #include "apps.h" 12 #include "log.h" 13 14 static int verbosity = LOG_INFO; 15 16 int log_set_verbosity(const char *prog, int level) 17 { 18 if (level < LOG_EMERG || level > LOG_TRACE) { 19 trace_log_message(-1, prog, LOG_ERR, 20 "Invalid verbosity level %d", level); 21 return 0; 22 } 23 verbosity = level; 24 return 1; 25 } 26 27 int log_get_verbosity(void) 28 { 29 return verbosity; 30 } 31 32 #ifdef HTTP_DAEMON 33 static int print_syslog(const char *str, size_t len, void *levPtr) 34 { 35 int level = *(int *)levPtr; 36 int ilen = len > MAXERRLEN ? MAXERRLEN : len; 37 38 syslog(level, "%.*s", ilen, str); 39 40 return ilen; 41 } 42 #endif 43 44 static void log_with_prefix(const char *prog, const char *fmt, va_list ap) 45 { 46 char prefix[80]; 47 BIO *bio, *pre = BIO_new(BIO_f_prefix()); 48 49 (void)BIO_snprintf(prefix, sizeof(prefix), "%s: ", prog); 50 (void)BIO_set_prefix(pre, prefix); 51 bio = BIO_push(pre, bio_err); 52 (void)BIO_vprintf(bio, fmt, ap); 53 (void)BIO_printf(bio, "\n"); 54 (void)BIO_flush(bio); 55 (void)BIO_pop(pre); 56 BIO_free(pre); 57 } 58 59 /* 60 * Unfortunately, C before C99 does not define va_copy, so we must 61 * check if it can be assumed to be present. We do that with an internal 62 * antifeature macro. 63 * C versions since C94 define __STDC_VERSION__, so it's enough to 64 * check its existence and value. 65 */ 66 #undef OSSL_NO_C99 67 #if !defined(__STDC_VERSION__) || __STDC_VERSION__ + 0 < 199900L 68 # define OSSL_NO_C99 69 #endif 70 71 void trace_log_message(int category, 72 const char *prog, int level, const char *fmt, ...) 73 { 74 va_list ap; 75 va_start(ap, fmt); 76 77 #ifdef OSSL_NO_C99 78 if (verbosity >= level) 79 category = -1; /* disabling trace output in addition to logging */ 80 #endif 81 if (category >= 0 && OSSL_trace_enabled(category)) { 82 BIO *out = OSSL_trace_begin(category); 83 #ifndef OSSL_NO_C99 84 va_list ap_copy; 85 86 va_copy(ap_copy, ap); 87 (void)BIO_vprintf(out, fmt, ap_copy); 88 va_end(ap_copy); 89 #else 90 (void)BIO_vprintf(out, fmt, ap); 91 #endif 92 (void)BIO_printf(out, "\n"); 93 OSSL_trace_end(category, out); 94 } 95 if (verbosity < level) { 96 va_end(ap); 97 return; 98 } 99 #ifdef HTTP_DAEMON 100 if (n_responders != 0) { 101 vsyslog(level, fmt, ap); 102 if (level <= LOG_ERR) 103 ERR_print_errors_cb(print_syslog, &level); 104 } else 105 #endif 106 log_with_prefix(prog, fmt, ap); 107 va_end(ap); 108 } 109