log.c 2.7 KB

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