From e7f5f48d68553206b95cbb4f610702c887500124 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Tue, 10 Jul 2018 15:20:28 -0400 Subject: Rename torlog.[ch] to log.[ch] Fun fact: these files used to be called log.[ch] until we ran into conflicts with systems having a log.h file. But now that we always include "lib/log/log.h", we should be fine. --- src/lib/compress/compress.c | 2 +- src/lib/compress/compress_lzma.c | 2 +- src/lib/compress/compress_none.c | 2 +- src/lib/compress/compress_zlib.c | 2 +- src/lib/compress/compress_zstd.c | 2 +- src/lib/container/buffers.c | 2 +- src/lib/crypt_ops/aes.c | 2 +- src/lib/crypt_ops/crypto.c | 2 +- src/lib/crypt_ops/crypto_curve25519.c | 2 +- src/lib/crypt_ops/crypto_dh.c | 2 +- src/lib/crypt_ops/crypto_digest.c | 2 +- src/lib/crypt_ops/crypto_ed25519.c | 2 +- src/lib/crypt_ops/crypto_format.c | 2 +- src/lib/crypt_ops/crypto_rand.c | 2 +- src/lib/crypt_ops/crypto_rsa.c | 2 +- src/lib/crypt_ops/crypto_rsa.h | 2 +- src/lib/crypt_ops/crypto_util.c | 2 +- src/lib/encoding/binascii.c | 2 +- src/lib/encoding/confline.c | 2 +- src/lib/encoding/cstring.c | 2 +- src/lib/encoding/keyval.c | 2 +- src/lib/encoding/time_fmt.c | 2 +- src/lib/evloop/compat_libevent.c | 2 +- src/lib/evloop/procmon.c | 2 +- src/lib/evloop/procmon.h | 2 +- src/lib/evloop/timers.c | 2 +- src/lib/evloop/workqueue.c | 2 +- src/lib/fs/conffile.c | 2 +- src/lib/fs/dir.c | 2 +- src/lib/fs/files.c | 2 +- src/lib/fs/lockfile.c | 2 +- src/lib/fs/mmap.c | 2 +- src/lib/fs/path.c | 2 +- src/lib/fs/storagedir.c | 2 +- src/lib/fs/userdb.c | 2 +- src/lib/log/include.am | 4 +- src/lib/log/log.c | 1488 +++++++++++++++++++++++++++++++++ src/lib/log/log.h | 276 ++++++ src/lib/log/torlog.c | 1488 --------------------------------- src/lib/log/torlog.h | 276 ------ src/lib/log/util_bug.c | 2 +- src/lib/log/util_bug.h | 2 +- src/lib/memarea/memarea.c | 2 +- src/lib/meminfo/meminfo.c | 2 +- src/lib/net/address.c | 2 +- src/lib/net/buffers_net.c | 2 +- src/lib/net/socket.c | 2 +- src/lib/process/daemon.c | 2 +- src/lib/process/env.c | 2 +- src/lib/process/pidfile.c | 2 +- src/lib/process/restrict.c | 2 +- src/lib/process/setuid.c | 2 +- src/lib/process/subprocess.c | 2 +- src/lib/process/waitpid.c | 2 +- src/lib/sandbox/sandbox.c | 2 +- src/lib/thread/compat_pthreads.c | 2 +- src/lib/thread/compat_threads.c | 2 +- src/lib/thread/compat_winthreads.c | 2 +- src/lib/thread/numcpus.c | 2 +- src/lib/time/compat_time.c | 2 +- src/lib/time/tvdiff.c | 2 +- src/lib/tls/buffers_tls.c | 2 +- src/lib/tls/tortls.c | 2 +- src/lib/trace/debug.h | 2 +- 64 files changed, 1825 insertions(+), 1825 deletions(-) create mode 100644 src/lib/log/log.c create mode 100644 src/lib/log/log.h delete mode 100644 src/lib/log/torlog.c delete mode 100644 src/lib/log/torlog.h (limited to 'src/lib') diff --git a/src/lib/compress/compress.c b/src/lib/compress/compress.c index ff1aea47a4..2ad9b15b2e 100644 --- a/src/lib/compress/compress.c +++ b/src/lib/compress/compress.c @@ -22,7 +22,7 @@ #include #endif -#include "lib/log/torlog.h" +#include "lib/log/log.h" #include "lib/log/util_bug.h" #include "lib/arch/bytes.h" #include "lib/ctime/di_ops.h" diff --git a/src/lib/compress/compress_lzma.c b/src/lib/compress/compress_lzma.c index 9091832ed3..e6c8368f6a 100644 --- a/src/lib/compress/compress_lzma.c +++ b/src/lib/compress/compress_lzma.c @@ -15,7 +15,7 @@ #include "lib/compress/compress.h" #include "lib/compress/compress_lzma.h" -#include "lib/log/torlog.h" +#include "lib/log/log.h" #include "lib/log/util_bug.h" #include "lib/malloc/malloc.h" #include "lib/thread/threads.h" diff --git a/src/lib/compress/compress_none.c b/src/lib/compress/compress_none.c index 9574c47a7e..a0e82d5a99 100644 --- a/src/lib/compress/compress_none.c +++ b/src/lib/compress/compress_none.c @@ -16,7 +16,7 @@ #include "orconfig.h" -#include "lib/log/torlog.h" +#include "lib/log/log.h" #include "lib/compress/compress.h" #include "lib/compress/compress_none.h" #include "lib/intmath/cmp.h" diff --git a/src/lib/compress/compress_zlib.c b/src/lib/compress/compress_zlib.c index 12e6727dee..64be1d4256 100644 --- a/src/lib/compress/compress_zlib.c +++ b/src/lib/compress/compress_zlib.c @@ -13,7 +13,7 @@ #include "orconfig.h" -#include "lib/log/torlog.h" +#include "lib/log/log.h" #include "lib/log/util_bug.h" #include "lib/compress/compress.h" #include "lib/compress/compress_zlib.h" diff --git a/src/lib/compress/compress_zstd.c b/src/lib/compress/compress_zstd.c index 0a553db55c..0a71fed4b8 100644 --- a/src/lib/compress/compress_zstd.c +++ b/src/lib/compress/compress_zstd.c @@ -13,7 +13,7 @@ #include "orconfig.h" -#include "lib/log/torlog.h" +#include "lib/log/log.h" #include "lib/log/util_bug.h" #include "lib/compress/compress.h" #include "lib/compress/compress_zstd.h" diff --git a/src/lib/container/buffers.c b/src/lib/container/buffers.c index 525747a4c9..87d782d7ef 100644 --- a/src/lib/container/buffers.c +++ b/src/lib/container/buffers.c @@ -27,7 +27,7 @@ #include #include "lib/container/buffers.h" #include "lib/cc/torint.h" -#include "lib/log/torlog.h" +#include "lib/log/log.h" #include "lib/log/util_bug.h" #include "lib/ctime/di_ops.h" #include "lib/malloc/malloc.h" diff --git a/src/lib/crypt_ops/aes.c b/src/lib/crypt_ops/aes.c index a01b1e16b2..ff9d4d855c 100644 --- a/src/lib/crypt_ops/aes.c +++ b/src/lib/crypt_ops/aes.c @@ -38,7 +38,7 @@ DISABLE_GCC_WARNING(redundant-decls) ENABLE_GCC_WARNING(redundant-decls) #include "lib/crypt_ops/aes.h" -#include "lib/log/torlog.h" +#include "lib/log/log.h" #include "lib/ctime/di_ops.h" #ifdef ANDROID diff --git a/src/lib/crypt_ops/crypto.c b/src/lib/crypt_ops/crypto.c index 48574016bf..5bc2da76ab 100644 --- a/src/lib/crypt_ops/crypto.c +++ b/src/lib/crypt_ops/crypto.c @@ -62,7 +62,7 @@ ENABLE_GCC_WARNING(redundant-decls) #include #endif -#include "lib/log/torlog.h" +#include "lib/log/log.h" #include "lib/log/util_bug.h" #include "lib/cc/torint.h" #include "lib/crypt_ops/aes.h" diff --git a/src/lib/crypt_ops/crypto_curve25519.c b/src/lib/crypt_ops/crypto_curve25519.c index 09f492e544..6ad2587f48 100644 --- a/src/lib/crypt_ops/crypto_curve25519.c +++ b/src/lib/crypt_ops/crypto_curve25519.c @@ -26,7 +26,7 @@ #include "lib/crypt_ops/crypto_format.h" #include "lib/crypt_ops/crypto_rand.h" #include "lib/crypt_ops/crypto_util.h" -#include "lib/log/torlog.h" +#include "lib/log/log.h" #include "lib/log/util_bug.h" #include "ed25519/donna/ed25519_donna_tor.h" diff --git a/src/lib/crypt_ops/crypto_dh.c b/src/lib/crypt_ops/crypto_dh.c index c37e286daf..3e82996935 100644 --- a/src/lib/crypt_ops/crypto_dh.c +++ b/src/lib/crypt_ops/crypto_dh.c @@ -14,7 +14,7 @@ #include "lib/crypt_ops/crypto_digest.h" #include "lib/crypt_ops/crypto_hkdf.h" #include "lib/crypt_ops/crypto_util.h" -#include "lib/log/torlog.h" +#include "lib/log/log.h" #include "lib/log/util_bug.h" DISABLE_GCC_WARNING(redundant-decls) diff --git a/src/lib/crypt_ops/crypto_digest.c b/src/lib/crypt_ops/crypto_digest.c index 949e694053..ee5c362e38 100644 --- a/src/lib/crypt_ops/crypto_digest.c +++ b/src/lib/crypt_ops/crypto_digest.c @@ -14,7 +14,7 @@ #include "lib/crypt_ops/crypto_digest.h" #include "lib/crypt_ops/crypto_openssl_mgt.h" #include "lib/crypt_ops/crypto_util.h" -#include "lib/log/torlog.h" +#include "lib/log/log.h" #include "lib/log/util_bug.h" #include "keccak-tiny/keccak-tiny.h" diff --git a/src/lib/crypt_ops/crypto_ed25519.c b/src/lib/crypt_ops/crypto_ed25519.c index 985652ecba..9d2c9e9fab 100644 --- a/src/lib/crypt_ops/crypto_ed25519.c +++ b/src/lib/crypt_ops/crypto_ed25519.c @@ -28,7 +28,7 @@ #include "lib/crypt_ops/crypto_format.h" #include "lib/crypt_ops/crypto_rand.h" #include "lib/crypt_ops/crypto_util.h" -#include "lib/log/torlog.h" +#include "lib/log/log.h" #include "lib/log/util_bug.h" #include "lib/encoding/binascii.h" #include "lib/string/util_string.h" diff --git a/src/lib/crypt_ops/crypto_format.c b/src/lib/crypt_ops/crypto_format.c index 8c71b265bf..50916a8d68 100644 --- a/src/lib/crypt_ops/crypto_format.c +++ b/src/lib/crypt_ops/crypto_format.c @@ -24,7 +24,7 @@ #include "lib/string/util_string.h" #include "lib/string/printf.h" #include "lib/encoding/binascii.h" -#include "lib/log/torlog.h" +#include "lib/log/log.h" #include "lib/log/util_bug.h" #include "lib/fs/files.h" diff --git a/src/lib/crypt_ops/crypto_rand.c b/src/lib/crypt_ops/crypto_rand.c index e2d72a77c0..fb9d0c2c6c 100644 --- a/src/lib/crypt_ops/crypto_rand.c +++ b/src/lib/crypt_ops/crypto_rand.c @@ -26,7 +26,7 @@ #include "lib/crypt_ops/crypto_util.h" #include "lib/encoding/binascii.h" #include "lib/intmath/weakrng.h" -#include "lib/log/torlog.h" +#include "lib/log/log.h" #include "lib/log/util_bug.h" #include "lib/malloc/malloc.h" #include "lib/sandbox/sandbox.h" diff --git a/src/lib/crypt_ops/crypto_rsa.c b/src/lib/crypt_ops/crypto_rsa.c index 9290414de0..5ec69d7319 100644 --- a/src/lib/crypt_ops/crypto_rsa.c +++ b/src/lib/crypt_ops/crypto_rsa.c @@ -36,7 +36,7 @@ DISABLE_GCC_WARNING(redundant-decls) ENABLE_GCC_WARNING(redundant-decls) -#include "lib/log/torlog.h" +#include "lib/log/log.h" #include "lib/encoding/binascii.h" #include diff --git a/src/lib/crypt_ops/crypto_rsa.h b/src/lib/crypt_ops/crypto_rsa.h index 093f2cec6c..51fc974821 100644 --- a/src/lib/crypt_ops/crypto_rsa.h +++ b/src/lib/crypt_ops/crypto_rsa.h @@ -18,7 +18,7 @@ #include "lib/crypt_ops/crypto_digest.h" #include "lib/cc/torint.h" #include "lib/testsupport/testsupport.h" -#include "lib/log/torlog.h" +#include "lib/log/log.h" /** Length of our public keys. */ #define PK_BYTES (1024/8) diff --git a/src/lib/crypt_ops/crypto_util.c b/src/lib/crypt_ops/crypto_util.c index 19b0885256..79988c6a91 100644 --- a/src/lib/crypt_ops/crypto_util.c +++ b/src/lib/crypt_ops/crypto_util.c @@ -31,7 +31,7 @@ DISABLE_GCC_WARNING(redundant-decls) ENABLE_GCC_WARNING(redundant-decls) -#include "lib/log/torlog.h" +#include "lib/log/log.h" #include "lib/log/util_bug.h" /** diff --git a/src/lib/encoding/binascii.c b/src/lib/encoding/binascii.c index 7499d64720..e9140d9432 100644 --- a/src/lib/encoding/binascii.c +++ b/src/lib/encoding/binascii.c @@ -14,7 +14,7 @@ #include "orconfig.h" #include "lib/encoding/binascii.h" -#include "lib/log/torlog.h" +#include "lib/log/log.h" #include "lib/log/util_bug.h" #include "lib/cc/torint.h" #include "lib/string/compat_ctype.h" diff --git a/src/lib/encoding/confline.c b/src/lib/encoding/confline.c index 9b17629537..dd5193d3a7 100644 --- a/src/lib/encoding/confline.c +++ b/src/lib/encoding/confline.c @@ -17,7 +17,7 @@ #include "lib/encoding/confline.h" #include "lib/encoding/cstring.h" -#include "lib/log/torlog.h" +#include "lib/log/log.h" #include "lib/log/util_bug.h" #include "lib/malloc/malloc.h" #include "lib/string/compat_ctype.h" diff --git a/src/lib/encoding/cstring.c b/src/lib/encoding/cstring.c index 3e0db712f9..69aa7f3da5 100644 --- a/src/lib/encoding/cstring.c +++ b/src/lib/encoding/cstring.c @@ -11,7 +11,7 @@ **/ #include "lib/encoding/cstring.h" -#include "lib/log/torlog.h" +#include "lib/log/log.h" #include "lib/log/util_bug.h" #include "lib/malloc/malloc.h" #include "lib/string/compat_ctype.h" diff --git a/src/lib/encoding/keyval.c b/src/lib/encoding/keyval.c index 53ee776fe7..d5e4e4e438 100644 --- a/src/lib/encoding/keyval.c +++ b/src/lib/encoding/keyval.c @@ -12,7 +12,7 @@ #include "orconfig.h" #include "lib/encoding/keyval.h" #include "lib/log/escape.h" -#include "lib/log/torlog.h" +#include "lib/log/log.h" #include "lib/log/util_bug.h" #include diff --git a/src/lib/encoding/time_fmt.c b/src/lib/encoding/time_fmt.c index 8ce15e7477..42b1cc646b 100644 --- a/src/lib/encoding/time_fmt.c +++ b/src/lib/encoding/time_fmt.c @@ -15,7 +15,7 @@ **/ #include "lib/encoding/time_fmt.h" -#include "lib/log/torlog.h" +#include "lib/log/log.h" #include "lib/log/escape.h" #include "lib/log/util_bug.h" #include "lib/malloc/malloc.h" diff --git a/src/lib/evloop/compat_libevent.c b/src/lib/evloop/compat_libevent.c index 5e5faf163c..2ee71c5598 100644 --- a/src/lib/evloop/compat_libevent.c +++ b/src/lib/evloop/compat_libevent.c @@ -11,7 +11,7 @@ #include "lib/evloop/compat_libevent.h" #include "lib/crypt_ops/crypto_rand.h" -#include "lib/log/torlog.h" +#include "lib/log/log.h" #include "lib/log/util_bug.h" #include "lib/string/compat_string.h" diff --git a/src/lib/evloop/procmon.c b/src/lib/evloop/procmon.c index 53c458f159..e0c26caab2 100644 --- a/src/lib/evloop/procmon.c +++ b/src/lib/evloop/procmon.c @@ -8,7 +8,7 @@ #include "lib/evloop/procmon.h" -#include "lib/log/torlog.h" +#include "lib/log/log.h" #include "lib/log/util_bug.h" #include "lib/log/win32err.h" #include "lib/malloc/malloc.h" diff --git a/src/lib/evloop/procmon.h b/src/lib/evloop/procmon.h index b596e5cc6d..42c3788692 100644 --- a/src/lib/evloop/procmon.h +++ b/src/lib/evloop/procmon.h @@ -11,7 +11,7 @@ #include "lib/evloop/compat_libevent.h" -#include "lib/log/torlog.h" +#include "lib/log/log.h" typedef struct tor_process_monitor_t tor_process_monitor_t; diff --git a/src/lib/evloop/timers.c b/src/lib/evloop/timers.c index 4580b89e3c..c4e85c7c93 100644 --- a/src/lib/evloop/timers.c +++ b/src/lib/evloop/timers.c @@ -34,7 +34,7 @@ #include "lib/evloop/compat_libevent.h" #include "lib/evloop/timers.h" #include "lib/intmath/muldiv.h" -#include "lib/log/torlog.h" +#include "lib/log/log.h" #include "lib/log/util_bug.h" #include "lib/malloc/malloc.h" #include "lib/time/compat_time.h" diff --git a/src/lib/evloop/workqueue.c b/src/lib/evloop/workqueue.c index 4d36f352e3..931f65e710 100644 --- a/src/lib/evloop/workqueue.c +++ b/src/lib/evloop/workqueue.c @@ -30,7 +30,7 @@ #include "lib/crypt_ops/crypto_rand.h" #include "lib/intmath/weakrng.h" #include "lib/log/ratelim.h" -#include "lib/log/torlog.h" +#include "lib/log/log.h" #include "lib/log/util_bug.h" #include "lib/net/alertsock.h" #include "lib/net/socket.h" diff --git a/src/lib/fs/conffile.c b/src/lib/fs/conffile.c index 3a4d95f450..d8622bff6b 100644 --- a/src/lib/fs/conffile.c +++ b/src/lib/fs/conffile.c @@ -17,7 +17,7 @@ #include "lib/fs/dir.h" #include "lib/fs/files.h" #include "lib/fs/path.h" -#include "lib/log/torlog.h" +#include "lib/log/log.h" #include "lib/malloc/malloc.h" #include "lib/string/printf.h" diff --git a/src/lib/fs/dir.c b/src/lib/fs/dir.c index 0f2a5e2359..6c24460005 100644 --- a/src/lib/fs/dir.c +++ b/src/lib/fs/dir.c @@ -14,7 +14,7 @@ #include "lib/fs/path.h" #include "lib/fs/userdb.h" -#include "lib/log/torlog.h" +#include "lib/log/log.h" #include "lib/log/util_bug.h" #include "lib/log/win32err.h" #include "lib/container/smartlist.h" diff --git a/src/lib/fs/files.c b/src/lib/fs/files.c index 9012fd64f2..c71e4d2a37 100644 --- a/src/lib/fs/files.c +++ b/src/lib/fs/files.c @@ -16,7 +16,7 @@ #include "lib/fs/files.h" #include "lib/fs/path.h" #include "lib/container/smartlist.h" -#include "lib/log/torlog.h" +#include "lib/log/log.h" #include "lib/log/util_bug.h" #include "lib/log/escape.h" #include "lib/err/torerr.h" diff --git a/src/lib/fs/lockfile.c b/src/lib/fs/lockfile.c index a4e3c427db..ca1711c344 100644 --- a/src/lib/fs/lockfile.c +++ b/src/lib/fs/lockfile.c @@ -13,7 +13,7 @@ #include "orconfig.h" #include "lib/fs/files.h" #include "lib/fs/lockfile.h" -#include "lib/log/torlog.h" +#include "lib/log/log.h" #include "lib/log/util_bug.h" #include "lib/malloc/malloc.h" diff --git a/src/lib/fs/mmap.c b/src/lib/fs/mmap.c index 7d91945bb9..e7da6fc63a 100644 --- a/src/lib/fs/mmap.c +++ b/src/lib/fs/mmap.c @@ -11,7 +11,7 @@ #include "lib/fs/mmap.h" #include "lib/fs/files.h" -#include "lib/log/torlog.h" +#include "lib/log/log.h" #include "lib/log/util_bug.h" #include "lib/log/win32err.h" #include "lib/string/compat_string.h" diff --git a/src/lib/fs/path.c b/src/lib/fs/path.c index 9b32b2ebd3..eb5170920c 100644 --- a/src/lib/fs/path.c +++ b/src/lib/fs/path.c @@ -11,7 +11,7 @@ #include "lib/fs/path.h" #include "lib/malloc/malloc.h" -#include "lib/log/torlog.h" +#include "lib/log/log.h" #include "lib/log/util_bug.h" #include "lib/string/printf.h" #include "lib/string/util_string.h" diff --git a/src/lib/fs/storagedir.c b/src/lib/fs/storagedir.c index 4db56b02f8..014eb4d9eb 100644 --- a/src/lib/fs/storagedir.c +++ b/src/lib/fs/storagedir.c @@ -20,7 +20,7 @@ #include "lib/fs/files.h" #include "lib/fs/mmap.h" #include "lib/log/escape.h" -#include "lib/log/torlog.h" +#include "lib/log/log.h" #include "lib/log/util_bug.h" #include "lib/malloc/malloc.h" #include "lib/memarea/memarea.h" diff --git a/src/lib/fs/userdb.c b/src/lib/fs/userdb.c index 1e772b8fbd..df2935baa8 100644 --- a/src/lib/fs/userdb.c +++ b/src/lib/fs/userdb.c @@ -13,7 +13,7 @@ #ifndef _WIN32 #include "lib/malloc/malloc.h" -#include "lib/log/torlog.h" +#include "lib/log/log.h" #include "lib/log/util_bug.h" #include diff --git a/src/lib/log/include.am b/src/lib/log/include.am index f0491b3863..b5a1c5ca26 100644 --- a/src/lib/log/include.am +++ b/src/lib/log/include.am @@ -8,7 +8,7 @@ endif src_lib_libtor_log_a_SOURCES = \ src/lib/log/escape.c \ src/lib/log/ratelim.c \ - src/lib/log/torlog.c \ + src/lib/log/log.c \ src/lib/log/util_bug.c if WIN32 @@ -26,6 +26,6 @@ src/lib/log/torlog.$(OBJEXT) \ noinst_HEADERS += \ src/lib/log/escape.h \ src/lib/log/ratelim.h \ - src/lib/log/torlog.h \ + src/lib/log/log.h \ src/lib/log/util_bug.h \ src/lib/log/win32err.h diff --git a/src/lib/log/log.c b/src/lib/log/log.c new file mode 100644 index 0000000000..b89747d844 --- /dev/null +++ b/src/lib/log/log.c @@ -0,0 +1,1488 @@ +/* Copyright (c) 2001, Matej Pfajfar. + * Copyright (c) 2001-2004, Roger Dingledine. + * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. + * Copyright (c) 2007-2018, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +/** + * \file log.c + * \brief Functions to send messages to log files or the console. + **/ + +#include "orconfig.h" +#include +#include +#include +#include +#ifdef HAVE_SYS_TIME_H +#include +#endif +#ifdef HAVE_TIME_H +#include +#endif +#ifdef HAVE_UNISTD_H +#include +#endif +#ifdef HAVE_SYS_TYPES_H +#include +#endif +#ifdef HAVE_FCNTL_H +#include +#endif + +#define LOG_PRIVATE +#include "lib/log/log.h" +#include "lib/log/ratelim.h" +#include "lib/lock/compat_mutex.h" +#include "lib/smartlist_core/smartlist_core.h" +#include "lib/smartlist_core/smartlist_foreach.h" +#include "lib/smartlist_core/smartlist_split.h" +#include "lib/err/torerr.h" +#include "lib/intmath/bits.h" +#include "lib/string/compat_string.h" +#include "lib/string/printf.h" +#include "lib/malloc/malloc.h" +#include "lib/string/util_string.h" +#include "lib/wallclock/tor_gettimeofday.h" +#include "lib/wallclock/approx_time.h" +#include "lib/wallclock/tm_cvt.h" +#include "lib/fdio/fdio.h" + +#ifdef HAVE_ANDROID_LOG_H +#include +#endif // HAVE_ANDROID_LOG_H. + +/** Given a severity, yields an index into log_severity_list_t.masks to use + * for that severity. */ +#define SEVERITY_MASK_IDX(sev) ((sev) - LOG_ERR) + +/** @{ */ +/** The string we stick at the end of a log message when it is too long, + * and its length. */ +#define TRUNCATED_STR "[...truncated]" +#define TRUNCATED_STR_LEN 14 +/** @} */ + +/** Defining compile-time constants for Tor log levels (used by the Rust + * log wrapper at src/rust/tor_log) */ +const int LOG_WARN_ = LOG_WARN; +const int LOG_NOTICE_ = LOG_NOTICE; +const log_domain_mask_t LD_GENERAL_ = LD_GENERAL; +const log_domain_mask_t LD_NET_ = LD_NET; + +/** Information for a single logfile; only used in log.c */ +typedef struct logfile_t { + struct logfile_t *next; /**< Next logfile_t in the linked list. */ + char *filename; /**< Filename to open. */ + int fd; /**< fd to receive log messages, or -1 for none. */ + int seems_dead; /**< Boolean: true if the stream seems to be kaput. */ + int needs_close; /**< Boolean: true if the stream gets closed on shutdown. */ + int is_temporary; /**< Boolean: close after initializing logging subsystem.*/ + int is_syslog; /**< Boolean: send messages to syslog. */ + int is_android; /**< Boolean: send messages to Android's log subsystem. */ + char *android_tag; /**< Identity Tag used in Android's log subsystem. */ + log_callback callback; /**< If not NULL, send messages to this function. */ + log_severity_list_t *severities; /**< Which severity of messages should we + * log for each log domain? */ +} logfile_t; + +static void log_free_(logfile_t *victim); +#define log_free(lg) \ + FREE_AND_NULL(logfile_t, log_free_, (lg)) + +/** Helper: map a log severity to descriptive string. */ +static inline const char * +sev_to_string(int severity) +{ + switch (severity) { + case LOG_DEBUG: return "debug"; + case LOG_INFO: return "info"; + case LOG_NOTICE: return "notice"; + case LOG_WARN: return "warn"; + case LOG_ERR: return "err"; + default: /* Call assert, not tor_assert, since tor_assert + * calls log on failure. */ + raw_assert_unreached(); return "UNKNOWN"; // LCOV_EXCL_LINE + } +} + +/** Helper: decide whether to include the function name in the log message. */ +static inline int +should_log_function_name(log_domain_mask_t domain, int severity) +{ + switch (severity) { + case LOG_DEBUG: + case LOG_INFO: + /* All debugging messages occur in interesting places. */ + return (domain & LD_NOFUNCNAME) == 0; + case LOG_NOTICE: + case LOG_WARN: + case LOG_ERR: + /* We care about places where bugs occur. */ + return (domain & (LD_BUG|LD_NOFUNCNAME)) == LD_BUG; + default: + /* Call assert, not tor_assert, since tor_assert calls log on failure. */ + raw_assert(0); return 0; // LCOV_EXCL_LINE + } +} + +#ifdef HAVE_ANDROID_LOG_H +/** Helper function to convert Tor's log severity into the matching + * Android log priority. + */ +static int +severity_to_android_log_priority(int severity) +{ + switch (severity) { + case LOG_DEBUG: + return ANDROID_LOG_VERBOSE; + case LOG_INFO: + return ANDROID_LOG_DEBUG; + case LOG_NOTICE: + return ANDROID_LOG_INFO; + case LOG_WARN: + return ANDROID_LOG_WARN; + case LOG_ERR: + return ANDROID_LOG_ERROR; + default: + // LCOV_EXCL_START + raw_assert(0); + return 0; + // LCOV_EXCL_STOP + } +} +#endif // HAVE_ANDROID_LOG_H. + +/** A mutex to guard changes to logfiles and logging. */ +static tor_mutex_t log_mutex; +/** True iff we have initialized log_mutex */ +static int log_mutex_initialized = 0; + +/** Linked list of logfile_t. */ +static logfile_t *logfiles = NULL; +/** Boolean: do we report logging domains? */ +static int log_domains_are_logged = 0; + +#ifdef HAVE_SYSLOG_H +/** The number of open syslog log handlers that we have. When this reaches 0, + * we can close our connection to the syslog facility. */ +static int syslog_count = 0; +#endif + +/** Represents a log message that we are going to send to callback-driven + * loggers once we can do so in a non-reentrant way. */ +typedef struct pending_log_message_t { + int severity; /**< The severity of the message */ + log_domain_mask_t domain; /**< The domain of the message */ + char *fullmsg; /**< The message, with all decorations */ + char *msg; /**< The content of the message */ +} pending_log_message_t; + +/** Log messages waiting to be replayed onto callback-based logs */ +static smartlist_t *pending_cb_messages = NULL; + +/** Callback to invoke when pending_cb_messages becomes nonempty. */ +static pending_callback_callback pending_cb_cb = NULL; + +/** Log messages waiting to be replayed once the logging system is initialized. + */ +static smartlist_t *pending_startup_messages = NULL; + +/** Number of bytes of messages queued in pending_startup_messages. (This is + * the length of the messages, not the number of bytes used to store + * them.) */ +static size_t pending_startup_messages_len; + +/** True iff we should store messages while waiting for the logs to get + * configured. */ +static int queue_startup_messages = 1; + +/** True iff __PRETTY_FUNCTION__ includes parenthesized arguments. */ +static int pretty_fn_has_parens = 0; + +/** Don't store more than this many bytes of messages while waiting for the + * logs to get configured. */ +#define MAX_STARTUP_MSG_LEN (1<<16) + +/** Lock the log_mutex to prevent others from changing the logfile_t list */ +#define LOCK_LOGS() STMT_BEGIN \ + raw_assert(log_mutex_initialized); \ + tor_mutex_acquire(&log_mutex); \ + STMT_END +/** Unlock the log_mutex */ +#define UNLOCK_LOGS() STMT_BEGIN \ + raw_assert(log_mutex_initialized); \ + tor_mutex_release(&log_mutex); \ + STMT_END + +/** What's the lowest log level anybody cares about? Checking this lets us + * bail out early from log_debug if we aren't debugging. */ +int log_global_min_severity_ = LOG_NOTICE; + +static void delete_log(logfile_t *victim); +static void close_log(logfile_t *victim); + +static char *domain_to_string(log_domain_mask_t domain, + char *buf, size_t buflen); +static inline char *format_msg(char *buf, size_t buf_len, + log_domain_mask_t domain, int severity, const char *funcname, + const char *suffix, + const char *format, va_list ap, size_t *msg_len_out) + CHECK_PRINTF(7,0); + +/** Name of the application: used to generate the message we write at the + * start of each new log. */ +static char *appname = NULL; + +/** Set the "application name" for the logs to name: we'll use this + * name in the message we write when starting up, and at the start of each new + * log. + * + * Tor uses this string to write the version number to the log file. */ +void +log_set_application_name(const char *name) +{ + tor_free(appname); + appname = name ? tor_strdup(name) : NULL; +} + +/** Return true if some of the running logs might be interested in a log + * message of the given severity in the given domains. If this function + * returns true, the log message might be ignored anyway, but if it returns + * false, it is definitely_ safe not to log the message. */ +int +log_message_is_interesting(int severity, log_domain_mask_t domain) +{ + (void) domain; + return (severity <= log_global_min_severity_); +} + +/** + * As tor_log, but takes an optional function name, and does not treat its + * string as a printf format. + * + * For use by Rust integration. + */ +void +tor_log_string(int severity, log_domain_mask_t domain, + const char *function, const char *string) +{ + log_fn_(severity, domain, function, "%s", string); +} + +/** Log time granularity in milliseconds. */ +static int log_time_granularity = 1; + +/** Define log time granularity for all logs to be granularity_msec + * milliseconds. */ +void +set_log_time_granularity(int granularity_msec) +{ + log_time_granularity = granularity_msec; + tor_log_sigsafe_err_set_granularity(granularity_msec); +} + +/** Helper: Write the standard prefix for log lines to a + * buf_len character buffer in buf. + */ +static inline size_t +log_prefix_(char *buf, size_t buf_len, int severity) +{ + time_t t; + struct timeval now; + struct tm tm; + size_t n; + int r, ms; + + tor_gettimeofday(&now); + t = (time_t)now.tv_sec; + ms = (int)now.tv_usec / 1000; + if (log_time_granularity >= 1000) { + t -= t % (log_time_granularity / 1000); + ms = 0; + } else { + ms -= ((int)now.tv_usec / 1000) % log_time_granularity; + } + + n = strftime(buf, buf_len, "%b %d %H:%M:%S", + tor_localtime_r_msg(&t, &tm, NULL)); + r = tor_snprintf(buf+n, buf_len-n, ".%.3i [%s] ", ms, + sev_to_string(severity)); + + if (r<0) + return buf_len-1; + else + return n+r; +} + +/** If lf refers to an actual file that we have just opened, and the file + * contains no data, log an "opening new logfile" message at the top. + * + * Return -1 if the log is broken and needs to be deleted, else return 0. + */ +static int +log_tor_version(logfile_t *lf, int reset) +{ + char buf[256]; + size_t n; + int is_new; + + if (!lf->needs_close) + /* If it doesn't get closed, it isn't really a file. */ + return 0; + if (lf->is_temporary) + /* If it's temporary, it isn't really a file. */ + return 0; + + is_new = lf->fd >= 0 && tor_fd_getpos(lf->fd) == 0; + + if (reset && !is_new) + /* We are resetting, but we aren't at the start of the file; no + * need to log again. */ + return 0; + n = log_prefix_(buf, sizeof(buf), LOG_NOTICE); + if (appname) { + tor_snprintf(buf+n, sizeof(buf)-n, + "%s opening %slog file.\n", appname, is_new?"new ":""); + } else { + tor_snprintf(buf+n, sizeof(buf)-n, + "Tor %s opening %slog file.\n", VERSION, is_new?"new ":""); + } + if (write_all_to_fd_minimal(lf->fd, buf, strlen(buf)) < 0) /* error */ + return -1; /* failed */ + return 0; +} + +static const char bug_suffix[] = " (on Tor " VERSION +#ifndef _MSC_VER + " " +#include "micro-revision.i" +#endif + ")"; + +/** Helper: Format a log message into a fixed-sized buffer. (This is + * factored out of logv so that we never format a message more + * than once.) Return a pointer to the first character of the message + * portion of the formatted string. + */ +static inline char * +format_msg(char *buf, size_t buf_len, + log_domain_mask_t domain, int severity, const char *funcname, + const char *suffix, + const char *format, va_list ap, size_t *msg_len_out) +{ + size_t n; + int r; + char *end_of_prefix; + char *buf_end; + + raw_assert(buf_len >= 16); /* prevent integer underflow and stupidity */ + buf_len -= 2; /* subtract 2 characters so we have room for \n\0 */ + buf_end = buf+buf_len; /* point *after* the last char we can write to */ + + n = log_prefix_(buf, buf_len, severity); + end_of_prefix = buf+n; + + if (log_domains_are_logged) { + char *cp = buf+n; + if (cp == buf_end) goto format_msg_no_room_for_domains; + *cp++ = '{'; + if (cp == buf_end) goto format_msg_no_room_for_domains; + cp = domain_to_string(domain, cp, (buf+buf_len-cp)); + if (cp == buf_end) goto format_msg_no_room_for_domains; + *cp++ = '}'; + if (cp == buf_end) goto format_msg_no_room_for_domains; + *cp++ = ' '; + if (cp == buf_end) goto format_msg_no_room_for_domains; + end_of_prefix = cp; + n = cp-buf; + format_msg_no_room_for_domains: + /* This will leave end_of_prefix and n unchanged, and thus cause + * whatever log domain string we had written to be clobbered. */ + ; + } + + if (funcname && should_log_function_name(domain, severity)) { + r = tor_snprintf(buf+n, buf_len-n, + pretty_fn_has_parens ? "%s: " : "%s(): ", + funcname); + if (r<0) + n = strlen(buf); + else + n += r; + } + + if (domain == LD_BUG && buf_len-n > 6) { + memcpy(buf+n, "Bug: ", 6); + n += 5; + } + + r = tor_vsnprintf(buf+n,buf_len-n,format,ap); + if (r < 0) { + /* The message was too long; overwrite the end of the buffer with + * "[...truncated]" */ + if (buf_len >= TRUNCATED_STR_LEN) { + size_t offset = buf_len-TRUNCATED_STR_LEN; + /* We have an extra 2 characters after buf_len to hold the \n\0, + * so it's safe to add 1 to the size here. */ + strlcpy(buf+offset, TRUNCATED_STR, buf_len-offset+1); + } + /* Set 'n' to the end of the buffer, where we'll be writing \n\0. + * Since we already subtracted 2 from buf_len, this is safe.*/ + n = buf_len; + } else { + n += r; + if (suffix) { + size_t suffix_len = strlen(suffix); + if (buf_len-n >= suffix_len) { + memcpy(buf+n, suffix, suffix_len); + n += suffix_len; + } + } + } + + if (domain == LD_BUG && + buf_len - n > strlen(bug_suffix)+1) { + memcpy(buf+n, bug_suffix, strlen(bug_suffix)); + n += strlen(bug_suffix); + } + + buf[n]='\n'; + buf[n+1]='\0'; + *msg_len_out = n+1; + return end_of_prefix; +} + +/* Create a new pending_log_message_t with appropriate values */ +static pending_log_message_t * +pending_log_message_new(int severity, log_domain_mask_t domain, + const char *fullmsg, const char *shortmsg) +{ + pending_log_message_t *m = tor_malloc(sizeof(pending_log_message_t)); + m->severity = severity; + m->domain = domain; + m->fullmsg = fullmsg ? tor_strdup(fullmsg) : NULL; + m->msg = tor_strdup(shortmsg); + return m; +} + +#define pending_log_message_free(msg) \ + FREE_AND_NULL(pending_log_message_t, pending_log_message_free_, (msg)) + +/** Release all storage held by msg. */ +static void +pending_log_message_free_(pending_log_message_t *msg) +{ + if (!msg) + return; + tor_free(msg->msg); + tor_free(msg->fullmsg); + tor_free(msg); +} + +/** Helper function: returns true iff the log file, given in lf, is + * handled externally via the system log API, the Android logging API, or is an + * external callback function. */ +static inline int +logfile_is_external(const logfile_t *lf) +{ + raw_assert(lf); + return lf->is_syslog || lf->is_android || lf->callback; +} + +/** Return true iff lf would like to receive a message with the + * specified severity in the specified domain. + */ +static inline int +logfile_wants_message(const logfile_t *lf, int severity, + log_domain_mask_t domain) +{ + if (! (lf->severities->masks[SEVERITY_MASK_IDX(severity)] & domain)) { + return 0; + } + if (! (lf->fd >= 0 || logfile_is_external(lf))) { + return 0; + } + if (lf->seems_dead) { + return 0; + } + + return 1; +} + +/** Send a message to lf. The full message, with time prefix and + * severity, is in buf. The message itself is in + * msg_after_prefix. If callbacks_deferred points to true, then + * we already deferred this message for pending callbacks and don't need to do + * it again. Otherwise, if we need to do it, do it, and set + * callbacks_deferred to 1. */ +static inline void +logfile_deliver(logfile_t *lf, const char *buf, size_t msg_len, + const char *msg_after_prefix, log_domain_mask_t domain, + int severity, int *callbacks_deferred) +{ + + if (lf->is_syslog) { +#ifdef HAVE_SYSLOG_H +#ifdef MAXLINE + /* Some syslog implementations have limits on the length of what you can + * pass them, and some very old ones do not detect overflow so well. + * Regrettably, they call their maximum line length MAXLINE. */ +#if MAXLINE < 64 +#warn "MAXLINE is a very low number; it might not be from syslog.h after all" +#endif + char *m = msg_after_prefix; + if (msg_len >= MAXLINE) + m = tor_strndup(msg_after_prefix, MAXLINE-1); + syslog(severity, "%s", m); + if (m != msg_after_prefix) { + tor_free(m); + } +#else /* !(defined(MAXLINE)) */ + /* We have syslog but not MAXLINE. That's promising! */ + syslog(severity, "%s", msg_after_prefix); +#endif /* defined(MAXLINE) */ +#endif /* defined(HAVE_SYSLOG_H) */ + } else if (lf->is_android) { +#ifdef HAVE_ANDROID_LOG_H + int priority = severity_to_android_log_priority(severity); + __android_log_write(priority, lf->android_tag, msg_after_prefix); +#endif // HAVE_ANDROID_LOG_H. + } else if (lf->callback) { + if (domain & LD_NOCB) { + if (!*callbacks_deferred && pending_cb_messages) { + smartlist_add(pending_cb_messages, + pending_log_message_new(severity,domain,NULL,msg_after_prefix)); + *callbacks_deferred = 1; + if (smartlist_len(pending_cb_messages) == 1 && pending_cb_cb) { + pending_cb_cb(); + } + } + } else { + lf->callback(severity, domain, msg_after_prefix); + } + } else { + if (write_all_to_fd_minimal(lf->fd, buf, msg_len) < 0) { /* error */ + /* don't log the error! mark this log entry to be blown away, and + * continue. */ + lf->seems_dead = 1; + } + } +} + +/** Helper: sends a message to the appropriate logfiles, at loglevel + * severity. If provided, funcname is prepended to the + * message. The actual message is derived as from tor_snprintf(format,ap). + */ +MOCK_IMPL(STATIC void, +logv,(int severity, log_domain_mask_t domain, const char *funcname, + const char *suffix, const char *format, va_list ap)) +{ + char buf[10240]; + size_t msg_len = 0; + int formatted = 0; + logfile_t *lf; + char *end_of_prefix=NULL; + int callbacks_deferred = 0; + + /* Call assert, not raw_assert, since raw_assert calls log on failure. */ + raw_assert(format); + /* check that severity is sane. Overrunning the masks array leads to + * interesting and hard to diagnose effects */ + raw_assert(severity >= LOG_ERR && severity <= LOG_DEBUG); + /* check that we've initialised the log mutex before we try to lock it */ + raw_assert(log_mutex_initialized); + LOCK_LOGS(); + + if ((! (domain & LD_NOCB)) && pending_cb_messages + && smartlist_len(pending_cb_messages)) + flush_pending_log_callbacks(); + + if (queue_startup_messages && + pending_startup_messages_len < MAX_STARTUP_MSG_LEN) { + end_of_prefix = + format_msg(buf, sizeof(buf), domain, severity, funcname, suffix, + format, ap, &msg_len); + formatted = 1; + + smartlist_add(pending_startup_messages, + pending_log_message_new(severity,domain,buf,end_of_prefix)); + pending_startup_messages_len += msg_len; + } + + for (lf = logfiles; lf; lf = lf->next) { + if (! logfile_wants_message(lf, severity, domain)) + continue; + + if (!formatted) { + end_of_prefix = + format_msg(buf, sizeof(buf), domain, severity, funcname, suffix, + format, ap, &msg_len); + formatted = 1; + } + + logfile_deliver(lf, buf, msg_len, end_of_prefix, domain, severity, + &callbacks_deferred); + } + UNLOCK_LOGS(); +} + +/** Output a message to the log. It gets logged to all logfiles that + * care about messages with severity in domain. The content + * is formatted printf-style based on format and extra arguments. + * */ +void +tor_log(int severity, log_domain_mask_t domain, const char *format, ...) +{ + va_list ap; + if (severity > log_global_min_severity_) + return; + va_start(ap,format); +#ifdef TOR_UNIT_TESTS + if (domain & LD_NO_MOCK) + logv__real(severity, domain, NULL, NULL, format, ap); + else +#endif + logv(severity, domain, NULL, NULL, format, ap); + va_end(ap); +} + +/** Helper function; return true iff the n-element array array + * contains item. */ +static int +int_array_contains(const int *array, int n, int item) +{ + int j; + for (j = 0; j < n; ++j) { + if (array[j] == item) + return 1; + } + return 0; +} + +/** Function to call whenever the list of logs changes to get ready to log + * from signal handlers. */ +void +tor_log_update_sigsafe_err_fds(void) +{ + const logfile_t *lf; + int found_real_stderr = 0; + + int fds[TOR_SIGSAFE_LOG_MAX_FDS]; + int n_fds; + + LOCK_LOGS(); + /* Reserve the first one for stderr. This is safe because when we daemonize, + * we dup2 /dev/null to stderr, */ + fds[0] = STDERR_FILENO; + n_fds = 1; + + for (lf = logfiles; lf; lf = lf->next) { + /* Don't try callback to the control port, or syslogs: We can't + * do them from a signal handler. Don't try stdout: we always do stderr. + */ + if (lf->is_temporary || logfile_is_external(lf) + || lf->seems_dead || lf->fd < 0) + continue; + if (lf->severities->masks[SEVERITY_MASK_IDX(LOG_ERR)] & + (LD_BUG|LD_GENERAL)) { + if (lf->fd == STDERR_FILENO) + found_real_stderr = 1; + /* Avoid duplicates */ + if (int_array_contains(fds, n_fds, lf->fd)) + continue; + fds[n_fds++] = lf->fd; + if (n_fds == TOR_SIGSAFE_LOG_MAX_FDS) + break; + } + } + + if (!found_real_stderr && + int_array_contains(fds, n_fds, STDOUT_FILENO)) { + /* Don't use a virtual stderr when we're also logging to stdout. */ + raw_assert(n_fds >= 2); /* Don't raw_assert inside log fns */ + fds[0] = fds[--n_fds]; + } + + UNLOCK_LOGS(); + + tor_log_set_sigsafe_err_fds(fds, n_fds); +} + +/** Add to out a copy of every currently configured log file name. Used + * to enable access to these filenames with the sandbox code. */ +void +tor_log_get_logfile_names(smartlist_t *out) +{ + logfile_t *lf; + raw_assert(out); + + LOCK_LOGS(); + + for (lf = logfiles; lf; lf = lf->next) { + if (lf->is_temporary || logfile_is_external(lf)) + continue; + if (lf->filename == NULL) + continue; + smartlist_add_strdup(out, lf->filename); + } + + UNLOCK_LOGS(); +} + +/** Implementation of the log_fn backend, used when we have + * variadic macros. All arguments are as for log_fn, except for + * fn, which is the name of the calling functions. */ +void +log_fn_(int severity, log_domain_mask_t domain, const char *fn, + const char *format, ...) +{ + va_list ap; + if (severity > log_global_min_severity_) + return; + va_start(ap,format); + logv(severity, domain, fn, NULL, format, ap); + va_end(ap); +} +void +log_fn_ratelim_(ratelim_t *ratelim, int severity, log_domain_mask_t domain, + const char *fn, const char *format, ...) +{ + va_list ap; + char *m; + if (severity > log_global_min_severity_) + return; + m = rate_limit_log(ratelim, approx_time()); + if (m == NULL) + return; + va_start(ap, format); + logv(severity, domain, fn, m, format, ap); + va_end(ap); + tor_free(m); +} + +/** Free all storage held by victim. */ +static void +log_free_(logfile_t *victim) +{ + if (!victim) + return; + tor_free(victim->severities); + tor_free(victim->filename); + tor_free(victim->android_tag); + tor_free(victim); +} + +/** Close all open log files, and free other static memory. */ +void +logs_free_all(void) +{ + logfile_t *victim, *next; + smartlist_t *messages, *messages2; + LOCK_LOGS(); + next = logfiles; + logfiles = NULL; + messages = pending_cb_messages; + pending_cb_messages = NULL; + pending_cb_cb = NULL; + messages2 = pending_startup_messages; + pending_startup_messages = NULL; + UNLOCK_LOGS(); + while (next) { + victim = next; + next = next->next; + close_log(victim); + log_free(victim); + } + tor_free(appname); + + SMARTLIST_FOREACH(messages, pending_log_message_t *, msg, { + pending_log_message_free(msg); + }); + smartlist_free(messages); + + if (messages2) { + SMARTLIST_FOREACH(messages2, pending_log_message_t *, msg, { + pending_log_message_free(msg); + }); + smartlist_free(messages2); + } + + /* We _could_ destroy the log mutex here, but that would screw up any logs + * that happened between here and the end of execution. */ +} + +/** Remove and free the log entry victim from the linked-list + * logfiles (it is probably present, but it might not be due to thread + * racing issues). After this function is called, the caller shouldn't + * refer to victim anymore. + * + * Long-term, we need to do something about races in the log subsystem + * in general. See bug 222 for more details. + */ +static void +delete_log(logfile_t *victim) +{ + logfile_t *tmpl; + if (victim == logfiles) + logfiles = victim->next; + else { + for (tmpl = logfiles; tmpl && tmpl->next != victim; tmpl=tmpl->next) ; +// raw_assert(tmpl); +// raw_assert(tmpl->next == victim); + if (!tmpl) + return; + tmpl->next = victim->next; + } + log_free(victim); +} + +/** Helper: release system resources (but not memory) held by a single + * logfile_t. */ +static void +close_log(logfile_t *victim) +{ + if (victim->needs_close && victim->fd >= 0) { + close(victim->fd); + victim->fd = -1; + } else if (victim->is_syslog) { +#ifdef HAVE_SYSLOG_H + if (--syslog_count == 0) { + /* There are no other syslogs; close the logging facility. */ + closelog(); + } +#endif /* defined(HAVE_SYSLOG_H) */ + } +} + +/** Adjust a log severity configuration in severity_out to contain + * every domain between loglevelMin and loglevelMax, inclusive. + */ +void +set_log_severity_config(int loglevelMin, int loglevelMax, + log_severity_list_t *severity_out) +{ + int i; + raw_assert(loglevelMin >= loglevelMax); + raw_assert(loglevelMin >= LOG_ERR && loglevelMin <= LOG_DEBUG); + raw_assert(loglevelMax >= LOG_ERR && loglevelMax <= LOG_DEBUG); + memset(severity_out, 0, sizeof(log_severity_list_t)); + for (i = loglevelMin; i >= loglevelMax; --i) { + severity_out->masks[SEVERITY_MASK_IDX(i)] = ~0u; + } +} + +/** Add a log handler named name to send all messages in severity + * to fd. Copies severity. Helper: does no locking. */ +static void +add_stream_log_impl(const log_severity_list_t *severity, + const char *name, int fd) +{ + logfile_t *lf; + lf = tor_malloc_zero(sizeof(logfile_t)); + lf->fd = fd; + lf->filename = tor_strdup(name); + lf->severities = tor_memdup(severity, sizeof(log_severity_list_t)); + lf->next = logfiles; + + logfiles = lf; + log_global_min_severity_ = get_min_log_level(); +} + +/** Add a log handler named name to send all messages in severity + * to fd. Steals a reference to severity; the caller must + * not use it after calling this function. */ +void +add_stream_log(const log_severity_list_t *severity, const char *name, int fd) +{ + LOCK_LOGS(); + add_stream_log_impl(severity, name, fd); + UNLOCK_LOGS(); +} + +/** Initialize the global logging facility */ +void +init_logging(int disable_startup_queue) +{ + if (!log_mutex_initialized) { + tor_mutex_init(&log_mutex); + log_mutex_initialized = 1; + } +#ifdef __GNUC__ + if (strchr(__PRETTY_FUNCTION__, '(')) { + pretty_fn_has_parens = 1; + } +#endif + if (pending_cb_messages == NULL) + pending_cb_messages = smartlist_new(); + if (disable_startup_queue) + queue_startup_messages = 0; + if (pending_startup_messages == NULL && queue_startup_messages) { + pending_startup_messages = smartlist_new(); + } +} + +/** Set whether we report logging domains as a part of our log messages. + */ +void +logs_set_domain_logging(int enabled) +{ + LOCK_LOGS(); + log_domains_are_logged = enabled; + UNLOCK_LOGS(); +} + +/** Add a log handler to receive messages during startup (before the real + * logs are initialized). + */ +void +add_temp_log(int min_severity) +{ + log_severity_list_t *s = tor_malloc_zero(sizeof(log_severity_list_t)); + set_log_severity_config(min_severity, LOG_ERR, s); + LOCK_LOGS(); + add_stream_log_impl(s, "", fileno(stdout)); + tor_free(s); + logfiles->is_temporary = 1; + UNLOCK_LOGS(); +} + +/** + * Register "cb" as the callback to call when there are new pending log + * callbacks to be flushed with flush_pending_log_callbacks(). + * + * Note that this callback, if present, can be invoked from any thread. + * + * This callback must not log. + * + * It is intentional that this function contains the name "callback" twice: it + * sets a "callback" to be called on the condition that there is a "pending + * callback". + **/ +void +logs_set_pending_callback_callback(pending_callback_callback cb) +{ + pending_cb_cb = cb; +} + +/** + * Add a log handler to send messages in severity + * to the function cb. + */ +int +add_callback_log(const log_severity_list_t *severity, log_callback cb) +{ + logfile_t *lf; + lf = tor_malloc_zero(sizeof(logfile_t)); + lf->fd = -1; + lf->severities = tor_memdup(severity, sizeof(log_severity_list_t)); + lf->filename = tor_strdup(""); + lf->callback = cb; + lf->next = logfiles; + + LOCK_LOGS(); + logfiles = lf; + log_global_min_severity_ = get_min_log_level(); + UNLOCK_LOGS(); + return 0; +} + +/** Adjust the configured severity of any logs whose callback function is + * cb. */ +void +change_callback_log_severity(int loglevelMin, int loglevelMax, + log_callback cb) +{ + logfile_t *lf; + log_severity_list_t severities; + set_log_severity_config(loglevelMin, loglevelMax, &severities); + LOCK_LOGS(); + for (lf = logfiles; lf; lf = lf->next) { + if (lf->callback == cb) { + memcpy(lf->severities, &severities, sizeof(severities)); + } + } + log_global_min_severity_ = get_min_log_level(); + UNLOCK_LOGS(); +} + +/** If there are any log messages that were generated with LD_NOCB waiting to + * be sent to callback-based loggers, send them now. */ +void +flush_pending_log_callbacks(void) +{ + logfile_t *lf; + smartlist_t *messages, *messages_tmp; + + LOCK_LOGS(); + if (!pending_cb_messages || 0 == smartlist_len(pending_cb_messages)) { + UNLOCK_LOGS(); + return; + } + + messages = pending_cb_messages; + pending_cb_messages = smartlist_new(); + do { + SMARTLIST_FOREACH_BEGIN(messages, pending_log_message_t *, msg) { + const int severity = msg->severity; + const int domain = msg->domain; + for (lf = logfiles; lf; lf = lf->next) { + if (! lf->callback || lf->seems_dead || + ! (lf->severities->masks[SEVERITY_MASK_IDX(severity)] & domain)) { + continue; + } + lf->callback(severity, domain, msg->msg); + } + pending_log_message_free(msg); + } SMARTLIST_FOREACH_END(msg); + smartlist_clear(messages); + + messages_tmp = pending_cb_messages; + pending_cb_messages = messages; + messages = messages_tmp; + } while (smartlist_len(messages)); + + smartlist_free(messages); + + UNLOCK_LOGS(); +} + +/** Flush all the messages we stored from startup while waiting for log + * initialization. + */ +void +flush_log_messages_from_startup(void) +{ + logfile_t *lf; + + LOCK_LOGS(); + queue_startup_messages = 0; + pending_startup_messages_len = 0; + if (! pending_startup_messages) + goto out; + + SMARTLIST_FOREACH_BEGIN(pending_startup_messages, pending_log_message_t *, + msg) { + int callbacks_deferred = 0; + for (lf = logfiles; lf; lf = lf->next) { + if (! logfile_wants_message(lf, msg->severity, msg->domain)) + continue; + + /* We configure a temporary startup log that goes to stdout, so we + * shouldn't replay to stdout/stderr*/ + if (lf->fd == STDOUT_FILENO || lf->fd == STDERR_FILENO) { + continue; + } + + logfile_deliver(lf, msg->fullmsg, strlen(msg->fullmsg), msg->msg, + msg->domain, msg->severity, &callbacks_deferred); + } + pending_log_message_free(msg); + } SMARTLIST_FOREACH_END(msg); + smartlist_free(pending_startup_messages); + pending_startup_messages = NULL; + + out: + UNLOCK_LOGS(); +} + +/** Close any log handlers added by add_temp_log() or marked by + * mark_logs_temp(). */ +void +close_temp_logs(void) +{ + logfile_t *lf, **p; + + LOCK_LOGS(); + for (p = &logfiles; *p; ) { + if ((*p)->is_temporary) { + lf = *p; + /* we use *p here to handle the edge case of the head of the list */ + *p = (*p)->next; + close_log(lf); + log_free(lf); + } else { + p = &((*p)->next); + } + } + + log_global_min_severity_ = get_min_log_level(); + UNLOCK_LOGS(); +} + +/** Make all currently temporary logs (set to be closed by close_temp_logs) + * live again, and close all non-temporary logs. */ +void +rollback_log_changes(void) +{ + logfile_t *lf; + LOCK_LOGS(); + for (lf = logfiles; lf; lf = lf->next) + lf->is_temporary = ! lf->is_temporary; + UNLOCK_LOGS(); + close_temp_logs(); +} + +/** Configure all log handles to be closed by close_temp_logs(). */ +void +mark_logs_temp(void) +{ + logfile_t *lf; + LOCK_LOGS(); + for (lf = logfiles; lf; lf = lf->next) + lf->is_temporary = 1; + UNLOCK_LOGS(); +} + +/** + * Add a log handler to send messages to filename via fd. If + * opening the logfile failed, -1 is returned and errno is set appropriately + * (by open(2)). Takes ownership of fd. + */ +int +add_file_log(const log_severity_list_t *severity, + const char *filename, + int fd) +{ + logfile_t *lf; + + if (fd<0) + return -1; + if (tor_fd_seekend(fd)<0) { + close(fd); + return -1; + } + + LOCK_LOGS(); + add_stream_log_impl(severity, filename, fd); + logfiles->needs_close = 1; + lf = logfiles; + log_global_min_severity_ = get_min_log_level(); + + if (log_tor_version(lf, 0) < 0) { + delete_log(lf); + } + UNLOCK_LOGS(); + + return 0; +} + +#ifdef HAVE_SYSLOG_H +/** + * Add a log handler to send messages to they system log facility. + * + * If this is the first log handler, opens syslog with ident Tor or + * Tor- if that is not NULL. + */ +int +add_syslog_log(const log_severity_list_t *severity, + const char* syslog_identity_tag) +{ + logfile_t *lf; + if (syslog_count++ == 0) { + /* This is the first syslog. */ + static char buf[256]; + if (syslog_identity_tag) { + tor_snprintf(buf, sizeof(buf), "Tor-%s", syslog_identity_tag); + } else { + tor_snprintf(buf, sizeof(buf), "Tor"); + } + openlog(buf, LOG_PID | LOG_NDELAY, LOGFACILITY); + } + + lf = tor_malloc_zero(sizeof(logfile_t)); + lf->fd = -1; + lf->severities = tor_memdup(severity, sizeof(log_severity_list_t)); + lf->filename = tor_strdup(""); + lf->is_syslog = 1; + + LOCK_LOGS(); + lf->next = logfiles; + logfiles = lf; + log_global_min_severity_ = get_min_log_level(); + UNLOCK_LOGS(); + return 0; +} +#endif /* defined(HAVE_SYSLOG_H) */ + +#ifdef HAVE_ANDROID_LOG_H +/** + * Add a log handler to send messages to the Android platform log facility. + */ +int +add_android_log(const log_severity_list_t *severity, + const char *android_tag) +{ + logfile_t *lf = NULL; + + lf = tor_malloc_zero(sizeof(logfile_t)); + lf->fd = -1; + lf->severities = tor_memdup(severity, sizeof(log_severity_list_t)); + lf->filename = tor_strdup(""); + lf->is_android = 1; + + if (android_tag == NULL) + lf->android_tag = tor_strdup("Tor"); + else { + char buf[256]; + tor_snprintf(buf, sizeof(buf), "Tor-%s", android_tag); + lf->android_tag = tor_strdup(buf); + } + + LOCK_LOGS(); + lf->next = logfiles; + logfiles = lf; + log_global_min_severity_ = get_min_log_level(); + UNLOCK_LOGS(); + return 0; +} +#endif // HAVE_ANDROID_LOG_H. + +/** If level is a valid log severity, return the corresponding + * numeric value. Otherwise, return -1. */ +int +parse_log_level(const char *level) +{ + if (!strcasecmp(level, "err")) + return LOG_ERR; + if (!strcasecmp(level, "warn")) + return LOG_WARN; + if (!strcasecmp(level, "notice")) + return LOG_NOTICE; + if (!strcasecmp(level, "info")) + return LOG_INFO; + if (!strcasecmp(level, "debug")) + return LOG_DEBUG; + return -1; +} + +/** Return the string equivalent of a given log level. */ +const char * +log_level_to_string(int level) +{ + return sev_to_string(level); +} + +/** NULL-terminated array of names for log domains such that domain_list[dom] + * is a description of dom. + * + * Remember to update doc/tor.1.txt if you modify this list. + * */ +static const char *domain_list[] = { + "GENERAL", "CRYPTO", "NET", "CONFIG", "FS", "PROTOCOL", "MM", + "HTTP", "APP", "CONTROL", "CIRC", "REND", "BUG", "DIR", "DIRSERV", + "OR", "EDGE", "ACCT", "HIST", "HANDSHAKE", "HEARTBEAT", "CHANNEL", + "SCHED", "GUARD", "CONSDIFF", "DOS", NULL +}; + +/** Return a bitmask for the log domain for which domain is the name, + * or 0 if there is no such name. */ +static log_domain_mask_t +parse_log_domain(const char *domain) +{ + int i; + for (i=0; domain_list[i]; ++i) { + if (!strcasecmp(domain, domain_list[i])) + return (1u<= ARRAY_LENGTH(domain_list)-1 || + bit >= N_LOGGING_DOMAINS) { + tor_snprintf(buf, buflen, "", (long)domain); + return buf+strlen(buf); + } + d = domain_list[bit]; + n = strlcpy(cp, d, eos-cp); + if (n >= buflen) { + tor_snprintf(buf, buflen, "", (long)domain); + return buf+strlen(buf); + } + cp += n; + domain &= ~(1<cfg_ptr. Advance cfg_ptr after + * the end of the severityPattern. Set the value of severity_out to + * the parsed pattern. Return 0 on success, -1 on failure. + * + * The syntax for a SeverityPattern is: + *
+ *   SeverityPattern = *(DomainSeverity SP)* DomainSeverity
+ *   DomainSeverity = (DomainList SP)? SeverityRange
+ *   SeverityRange = MinSeverity ("-" MaxSeverity )?
+ *   DomainList = "[" (SP? DomainSpec SP? ",") SP? DomainSpec "]"
+ *   DomainSpec = "*" | Domain | "~" Domain
+ * 
+ * A missing MaxSeverity defaults to ERR. Severities and domains are + * case-insensitive. "~" indicates negation for a domain; negation happens + * last inside a DomainList. Only one SeverityRange without a DomainList is + * allowed per line. + */ +int +parse_log_severity_config(const char **cfg_ptr, + log_severity_list_t *severity_out) +{ + const char *cfg = *cfg_ptr; + int got_anything = 0; + int got_an_unqualified_range = 0; + memset(severity_out, 0, sizeof(*severity_out)); + + cfg = eat_whitespace(cfg); + while (*cfg) { + const char *dash, *space; + char *sev_lo, *sev_hi; + int low, high, i; + log_domain_mask_t domains = ~0u; + + if (*cfg == '[') { + int err = 0; + char *domains_str; + smartlist_t *domains_list; + log_domain_mask_t neg_domains = 0; + const char *closebracket = strchr(cfg, ']'); + if (!closebracket) + return -1; + domains = 0; + domains_str = tor_strndup(cfg+1, closebracket-cfg-1); + domains_list = smartlist_new(); + smartlist_split_string(domains_list, domains_str, ",", SPLIT_SKIP_SPACE, + -1); + tor_free(domains_str); + SMARTLIST_FOREACH_BEGIN(domains_list, const char *, domain) { + if (!strcmp(domain, "*")) { + domains = ~0u; + } else { + int d; + int negate=0; + if (*domain == '~') { + negate = 1; + ++domain; + } + d = parse_log_domain(domain); + if (!d) { + log_warn(LD_CONFIG, "No such logging domain as %s", domain); + err = 1; + } else { + if (negate) + neg_domains |= d; + else + domains |= d; + } + } + } SMARTLIST_FOREACH_END(domain); + SMARTLIST_FOREACH(domains_list, char *, d, tor_free(d)); + smartlist_free(domains_list); + if (err) + return -1; + if (domains == 0 && neg_domains) + domains = ~neg_domains; + else + domains &= ~neg_domains; + cfg = eat_whitespace(closebracket+1); + } else { + ++got_an_unqualified_range; + } + if (!strcasecmpstart(cfg, "file") || + !strcasecmpstart(cfg, "stderr") || + !strcasecmpstart(cfg, "stdout") || + !strcasecmpstart(cfg, "syslog") || + !strcasecmpstart(cfg, "android")) { + goto done; + } + if (got_an_unqualified_range > 1) + return -1; + + space = find_whitespace(cfg); + dash = strchr(cfg, '-'); + if (dash && dash < space) { + sev_lo = tor_strndup(cfg, dash-cfg); + sev_hi = tor_strndup(dash+1, space-(dash+1)); + } else { + sev_lo = tor_strndup(cfg, space-cfg); + sev_hi = tor_strdup("ERR"); + } + low = parse_log_level(sev_lo); + high = parse_log_level(sev_hi); + tor_free(sev_lo); + tor_free(sev_hi); + if (low == -1) + return -1; + if (high == -1) + return -1; + + got_anything = 1; + for (i=low; i >= high; --i) + severity_out->masks[SEVERITY_MASK_IDX(i)] |= domains; + + cfg = eat_whitespace(space); + } + + done: + *cfg_ptr = cfg; + return got_anything ? 0 : -1; +} + +/** Return the least severe log level that any current log is interested in. */ +int +get_min_log_level(void) +{ + logfile_t *lf; + int i; + int min = LOG_ERR; + for (lf = logfiles; lf; lf = lf->next) { + for (i = LOG_DEBUG; i > min; --i) + if (lf->severities->masks[SEVERITY_MASK_IDX(i)]) + min = i; + } + return min; +} + +/** Switch all logs to output at most verbose level. */ +void +switch_logs_debug(void) +{ + logfile_t *lf; + int i; + LOCK_LOGS(); + for (lf = logfiles; lf; lf=lf->next) { + for (i = LOG_DEBUG; i >= LOG_ERR; --i) + lf->severities->masks[SEVERITY_MASK_IDX(i)] = ~0u; + } + log_global_min_severity_ = get_min_log_level(); + UNLOCK_LOGS(); +} + +/** Truncate all the log files. */ +void +truncate_logs(void) +{ + logfile_t *lf; + for (lf = logfiles; lf; lf = lf->next) { + if (lf->fd >= 0) { + tor_ftruncate(lf->fd); + } + } +} diff --git a/src/lib/log/log.h b/src/lib/log/log.h new file mode 100644 index 0000000000..493409756f --- /dev/null +++ b/src/lib/log/log.h @@ -0,0 +1,276 @@ +/* Copyright (c) 2001, Matej Pfajfar. + * Copyright (c) 2001-2004, Roger Dingledine. + * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. + * Copyright (c) 2007-2018, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +/** + * \file log.h + * + * \brief Headers for log.c + **/ + +#ifndef TOR_TORLOG_H + +#include +#include "lib/cc/torint.h" +#include "lib/cc/compat_compiler.h" +#include "lib/testsupport/testsupport.h" + +#ifdef HAVE_SYSLOG_H +#include +#define LOG_WARN LOG_WARNING +#if LOG_DEBUG < LOG_ERR +#error "Your syslog.h thinks high numbers are more important. " \ + "We aren't prepared to deal with that." +#endif +#else /* !(defined(HAVE_SYSLOG_H)) */ +/* Note: Syslog's logging code refers to priorities, with 0 being the most + * important. Thus, all our comparisons needed to be reversed when we added + * syslog support. + * + * The upshot of this is that comments about log levels may be messed up: for + * "maximum severity" read "most severe" and "numerically *lowest* severity". + */ + +/** Debug-level severity: for hyper-verbose messages of no interest to + * anybody but developers. */ +#define LOG_DEBUG 7 +/** Info-level severity: for messages that appear frequently during normal + * operation. */ +#define LOG_INFO 6 +/** Notice-level severity: for messages that appear infrequently + * during normal operation; that the user will probably care about; + * and that are not errors. + */ +#define LOG_NOTICE 5 +/** Warn-level severity: for messages that only appear when something has gone + * wrong. */ +#define LOG_WARN 4 +/** Error-level severity: for messages that only appear when something has gone + * very wrong, and the Tor process can no longer proceed. */ +#define LOG_ERR 3 +#endif /* defined(HAVE_SYSLOG_H) */ + +/* Logging domains */ + +/** Catch-all for miscellaneous events and fatal errors. */ +#define LD_GENERAL (1u<<0) +/** The cryptography subsystem. */ +#define LD_CRYPTO (1u<<1) +/** Networking. */ +#define LD_NET (1u<<2) +/** Parsing and acting on our configuration. */ +#define LD_CONFIG (1u<<3) +/** Reading and writing from the filesystem. */ +#define LD_FS (1u<<4) +/** Other servers' (non)compliance with the Tor protocol. */ +#define LD_PROTOCOL (1u<<5) +/** Memory management. */ +#define LD_MM (1u<<6) +/** HTTP implementation. */ +#define LD_HTTP (1u<<7) +/** Application (socks) requests. */ +#define LD_APP (1u<<8) +/** Communication via the controller protocol. */ +#define LD_CONTROL (1u<<9) +/** Building, using, and managing circuits. */ +#define LD_CIRC (1u<<10) +/** Hidden services. */ +#define LD_REND (1u<<11) +/** Internal errors in this Tor process. */ +#define LD_BUG (1u<<12) +/** Learning and using information about Tor servers. */ +#define LD_DIR (1u<<13) +/** Learning and using information about Tor servers. */ +#define LD_DIRSERV (1u<<14) +/** Onion routing protocol. */ +#define LD_OR (1u<<15) +/** Generic edge-connection functionality. */ +#define LD_EDGE (1u<<16) +#define LD_EXIT LD_EDGE +/** Bandwidth accounting. */ +#define LD_ACCT (1u<<17) +/** Router history */ +#define LD_HIST (1u<<18) +/** OR handshaking */ +#define LD_HANDSHAKE (1u<<19) +/** Heartbeat messages */ +#define LD_HEARTBEAT (1u<<20) +/** Abstract channel_t code */ +#define LD_CHANNEL (1u<<21) +/** Scheduler */ +#define LD_SCHED (1u<<22) +/** Guard nodes */ +#define LD_GUARD (1u<<23) +/** Generation and application of consensus diffs. */ +#define LD_CONSDIFF (1u<<24) +/** Denial of Service mitigation. */ +#define LD_DOS (1u<<25) +/** Number of logging domains in the code. */ +#define N_LOGGING_DOMAINS 26 + +/** This log message is not safe to send to a callback-based logger + * immediately. Used as a flag, not a log domain. */ +#define LD_NOCB (1u<<31) +/** This log message should not include a function name, even if it otherwise + * would. Used as a flag, not a log domain. */ +#define LD_NOFUNCNAME (1u<<30) + +#ifdef TOR_UNIT_TESTS +/** This log message should not be intercepted by mock_saving_logv */ +#define LD_NO_MOCK (1u<<29) +#endif + +/** Mask of zero or more log domains, OR'd together. */ +typedef uint32_t log_domain_mask_t; + +/** Configures which severities are logged for each logging domain for a given + * log target. */ +typedef struct log_severity_list_t { + /** For each log severity, a bitmask of which domains a given logger is + * logging. */ + log_domain_mask_t masks[LOG_DEBUG-LOG_ERR+1]; +} log_severity_list_t; + +/** Callback type used for add_callback_log. */ +typedef void (*log_callback)(int severity, uint32_t domain, const char *msg); + +void init_logging(int disable_startup_queue); +int parse_log_level(const char *level); +const char *log_level_to_string(int level); +int parse_log_severity_config(const char **cfg, + log_severity_list_t *severity_out); +void set_log_severity_config(int minSeverity, int maxSeverity, + log_severity_list_t *severity_out); +void add_stream_log(const log_severity_list_t *severity, const char *name, + int fd); +int add_file_log(const log_severity_list_t *severity, + const char *filename, + int fd); + +#ifdef HAVE_SYSLOG_H +int add_syslog_log(const log_severity_list_t *severity, + const char* syslog_identity_tag); +#endif // HAVE_SYSLOG_H. +#ifdef HAVE_ANDROID_LOG_H +int add_android_log(const log_severity_list_t *severity, + const char *android_identity_tag); +#endif // HAVE_ANDROID_LOG_H. +int add_callback_log(const log_severity_list_t *severity, log_callback cb); +typedef void (*pending_callback_callback)(void); +void logs_set_pending_callback_callback(pending_callback_callback cb); +void logs_set_domain_logging(int enabled); +int get_min_log_level(void); +void switch_logs_debug(void); +void logs_free_all(void); +void add_temp_log(int min_severity); +void close_temp_logs(void); +void rollback_log_changes(void); +void mark_logs_temp(void); +void change_callback_log_severity(int loglevelMin, int loglevelMax, + log_callback cb); +void flush_pending_log_callbacks(void); +void flush_log_messages_from_startup(void); +void log_set_application_name(const char *name); +void set_log_time_granularity(int granularity_msec); +void truncate_logs(void); + +void tor_log(int severity, log_domain_mask_t domain, const char *format, ...) + CHECK_PRINTF(3,4); + +void tor_log_update_sigsafe_err_fds(void); + +struct smartlist_t; +void tor_log_get_logfile_names(struct smartlist_t *out); + +extern int log_global_min_severity_; + +void log_fn_(int severity, log_domain_mask_t domain, + const char *funcname, const char *format, ...) + CHECK_PRINTF(4,5); +struct ratelim_t; +void log_fn_ratelim_(struct ratelim_t *ratelim, int severity, + log_domain_mask_t domain, const char *funcname, + const char *format, ...) + CHECK_PRINTF(5,6); + +int log_message_is_interesting(int severity, log_domain_mask_t domain); +void tor_log_string(int severity, log_domain_mask_t domain, + const char *function, const char *string); + +#if defined(__GNUC__) && __GNUC__ <= 3 + +/* These are the GCC varidaic macros, so that older versions of GCC don't + * break. */ + +/** Log a message at level severity, using a pretty-printed version + * of the current function name. */ +#define log_fn(severity, domain, args...) \ + log_fn_(severity, domain, __FUNCTION__, args) +/** As log_fn, but use ratelim (an instance of ratelim_t) to control + * the frequency at which messages can appear. + */ +#define log_fn_ratelim(ratelim, severity, domain, args...) \ + log_fn_ratelim_(ratelim, severity, domain, __FUNCTION__, args) +#define log_debug(domain, args...) \ + STMT_BEGIN \ + if (PREDICT_UNLIKELY(log_global_min_severity_ == LOG_DEBUG)) \ + log_fn_(LOG_DEBUG, domain, __FUNCTION__, args); \ + STMT_END +#define log_info(domain, args...) \ + log_fn_(LOG_INFO, domain, __FUNCTION__, args) +#define log_notice(domain, args...) \ + log_fn_(LOG_NOTICE, domain, __FUNCTION__, args) +#define log_warn(domain, args...) \ + log_fn_(LOG_WARN, domain, __FUNCTION__, args) +#define log_err(domain, args...) \ + log_fn_(LOG_ERR, domain, __FUNCTION__, args) + +#else /* !(defined(__GNUC__) && __GNUC__ <= 3) */ + +/* Here are the c99 variadic macros, to work with non-GCC compilers */ + +#define log_debug(domain, args, ...) \ + STMT_BEGIN \ + if (PREDICT_UNLIKELY(log_global_min_severity_ == LOG_DEBUG)) \ + log_fn_(LOG_DEBUG, domain, __FUNCTION__, args, ##__VA_ARGS__); \ + STMT_END +#define log_info(domain, args,...) \ + log_fn_(LOG_INFO, domain, __FUNCTION__, args, ##__VA_ARGS__) +#define log_notice(domain, args,...) \ + log_fn_(LOG_NOTICE, domain, __FUNCTION__, args, ##__VA_ARGS__) +#define log_warn(domain, args,...) \ + log_fn_(LOG_WARN, domain, __FUNCTION__, args, ##__VA_ARGS__) +#define log_err(domain, args,...) \ + log_fn_(LOG_ERR, domain, __FUNCTION__, args, ##__VA_ARGS__) +/** Log a message at level severity, using a pretty-printed version + * of the current function name. */ +#define log_fn(severity, domain, args,...) \ + log_fn_(severity, domain, __FUNCTION__, args, ##__VA_ARGS__) +/** As log_fn, but use ratelim (an instance of ratelim_t) to control + * the frequency at which messages can appear. + */ +#define log_fn_ratelim(ratelim, severity, domain, args,...) \ + log_fn_ratelim_(ratelim, severity, domain, __FUNCTION__, \ + args, ##__VA_ARGS__) +#endif /* defined(__GNUC__) && __GNUC__ <= 3 */ + +/** This defines log levels that are linked in the Rust log module, rather + * than re-defining these in both Rust and C. + * + * C_RUST_COUPLED src/rust/tor_log LogSeverity, LogDomain + */ +extern const int LOG_WARN_; +extern const int LOG_NOTICE_; +extern const log_domain_mask_t LD_NET_; +extern const log_domain_mask_t LD_GENERAL_; + +#ifdef LOG_PRIVATE +MOCK_DECL(STATIC void, logv, (int severity, log_domain_mask_t domain, + const char *funcname, const char *suffix, const char *format, + va_list ap) CHECK_PRINTF(5,0)); +#endif + +# define TOR_TORLOG_H +#endif /* !defined(TOR_TORLOG_H) */ diff --git a/src/lib/log/torlog.c b/src/lib/log/torlog.c deleted file mode 100644 index 46d1217554..0000000000 --- a/src/lib/log/torlog.c +++ /dev/null @@ -1,1488 +0,0 @@ -/* Copyright (c) 2001, Matej Pfajfar. - * Copyright (c) 2001-2004, Roger Dingledine. - * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2018, The Tor Project, Inc. */ -/* See LICENSE for licensing information */ - -/** - * \file torlog.c - * \brief Functions to send messages to log files or the console. - **/ - -#include "orconfig.h" -#include -#include -#include -#include -#ifdef HAVE_SYS_TIME_H -#include -#endif -#ifdef HAVE_TIME_H -#include -#endif -#ifdef HAVE_UNISTD_H -#include -#endif -#ifdef HAVE_SYS_TYPES_H -#include -#endif -#ifdef HAVE_FCNTL_H -#include -#endif - -#define LOG_PRIVATE -#include "lib/log/torlog.h" -#include "lib/log/ratelim.h" -#include "lib/lock/compat_mutex.h" -#include "lib/smartlist_core/smartlist_core.h" -#include "lib/smartlist_core/smartlist_foreach.h" -#include "lib/smartlist_core/smartlist_split.h" -#include "lib/err/torerr.h" -#include "lib/intmath/bits.h" -#include "lib/string/compat_string.h" -#include "lib/string/printf.h" -#include "lib/malloc/malloc.h" -#include "lib/string/util_string.h" -#include "lib/wallclock/tor_gettimeofday.h" -#include "lib/wallclock/approx_time.h" -#include "lib/wallclock/tm_cvt.h" -#include "lib/fdio/fdio.h" - -#ifdef HAVE_ANDROID_LOG_H -#include -#endif // HAVE_ANDROID_LOG_H. - -/** Given a severity, yields an index into log_severity_list_t.masks to use - * for that severity. */ -#define SEVERITY_MASK_IDX(sev) ((sev) - LOG_ERR) - -/** @{ */ -/** The string we stick at the end of a log message when it is too long, - * and its length. */ -#define TRUNCATED_STR "[...truncated]" -#define TRUNCATED_STR_LEN 14 -/** @} */ - -/** Defining compile-time constants for Tor log levels (used by the Rust - * log wrapper at src/rust/tor_log) */ -const int LOG_WARN_ = LOG_WARN; -const int LOG_NOTICE_ = LOG_NOTICE; -const log_domain_mask_t LD_GENERAL_ = LD_GENERAL; -const log_domain_mask_t LD_NET_ = LD_NET; - -/** Information for a single logfile; only used in log.c */ -typedef struct logfile_t { - struct logfile_t *next; /**< Next logfile_t in the linked list. */ - char *filename; /**< Filename to open. */ - int fd; /**< fd to receive log messages, or -1 for none. */ - int seems_dead; /**< Boolean: true if the stream seems to be kaput. */ - int needs_close; /**< Boolean: true if the stream gets closed on shutdown. */ - int is_temporary; /**< Boolean: close after initializing logging subsystem.*/ - int is_syslog; /**< Boolean: send messages to syslog. */ - int is_android; /**< Boolean: send messages to Android's log subsystem. */ - char *android_tag; /**< Identity Tag used in Android's log subsystem. */ - log_callback callback; /**< If not NULL, send messages to this function. */ - log_severity_list_t *severities; /**< Which severity of messages should we - * log for each log domain? */ -} logfile_t; - -static void log_free_(logfile_t *victim); -#define log_free(lg) \ - FREE_AND_NULL(logfile_t, log_free_, (lg)) - -/** Helper: map a log severity to descriptive string. */ -static inline const char * -sev_to_string(int severity) -{ - switch (severity) { - case LOG_DEBUG: return "debug"; - case LOG_INFO: return "info"; - case LOG_NOTICE: return "notice"; - case LOG_WARN: return "warn"; - case LOG_ERR: return "err"; - default: /* Call assert, not tor_assert, since tor_assert - * calls log on failure. */ - raw_assert_unreached(); return "UNKNOWN"; // LCOV_EXCL_LINE - } -} - -/** Helper: decide whether to include the function name in the log message. */ -static inline int -should_log_function_name(log_domain_mask_t domain, int severity) -{ - switch (severity) { - case LOG_DEBUG: - case LOG_INFO: - /* All debugging messages occur in interesting places. */ - return (domain & LD_NOFUNCNAME) == 0; - case LOG_NOTICE: - case LOG_WARN: - case LOG_ERR: - /* We care about places where bugs occur. */ - return (domain & (LD_BUG|LD_NOFUNCNAME)) == LD_BUG; - default: - /* Call assert, not tor_assert, since tor_assert calls log on failure. */ - raw_assert(0); return 0; // LCOV_EXCL_LINE - } -} - -#ifdef HAVE_ANDROID_LOG_H -/** Helper function to convert Tor's log severity into the matching - * Android log priority. - */ -static int -severity_to_android_log_priority(int severity) -{ - switch (severity) { - case LOG_DEBUG: - return ANDROID_LOG_VERBOSE; - case LOG_INFO: - return ANDROID_LOG_DEBUG; - case LOG_NOTICE: - return ANDROID_LOG_INFO; - case LOG_WARN: - return ANDROID_LOG_WARN; - case LOG_ERR: - return ANDROID_LOG_ERROR; - default: - // LCOV_EXCL_START - raw_assert(0); - return 0; - // LCOV_EXCL_STOP - } -} -#endif // HAVE_ANDROID_LOG_H. - -/** A mutex to guard changes to logfiles and logging. */ -static tor_mutex_t log_mutex; -/** True iff we have initialized log_mutex */ -static int log_mutex_initialized = 0; - -/** Linked list of logfile_t. */ -static logfile_t *logfiles = NULL; -/** Boolean: do we report logging domains? */ -static int log_domains_are_logged = 0; - -#ifdef HAVE_SYSLOG_H -/** The number of open syslog log handlers that we have. When this reaches 0, - * we can close our connection to the syslog facility. */ -static int syslog_count = 0; -#endif - -/** Represents a log message that we are going to send to callback-driven - * loggers once we can do so in a non-reentrant way. */ -typedef struct pending_log_message_t { - int severity; /**< The severity of the message */ - log_domain_mask_t domain; /**< The domain of the message */ - char *fullmsg; /**< The message, with all decorations */ - char *msg; /**< The content of the message */ -} pending_log_message_t; - -/** Log messages waiting to be replayed onto callback-based logs */ -static smartlist_t *pending_cb_messages = NULL; - -/** Callback to invoke when pending_cb_messages becomes nonempty. */ -static pending_callback_callback pending_cb_cb = NULL; - -/** Log messages waiting to be replayed once the logging system is initialized. - */ -static smartlist_t *pending_startup_messages = NULL; - -/** Number of bytes of messages queued in pending_startup_messages. (This is - * the length of the messages, not the number of bytes used to store - * them.) */ -static size_t pending_startup_messages_len; - -/** True iff we should store messages while waiting for the logs to get - * configured. */ -static int queue_startup_messages = 1; - -/** True iff __PRETTY_FUNCTION__ includes parenthesized arguments. */ -static int pretty_fn_has_parens = 0; - -/** Don't store more than this many bytes of messages while waiting for the - * logs to get configured. */ -#define MAX_STARTUP_MSG_LEN (1<<16) - -/** Lock the log_mutex to prevent others from changing the logfile_t list */ -#define LOCK_LOGS() STMT_BEGIN \ - raw_assert(log_mutex_initialized); \ - tor_mutex_acquire(&log_mutex); \ - STMT_END -/** Unlock the log_mutex */ -#define UNLOCK_LOGS() STMT_BEGIN \ - raw_assert(log_mutex_initialized); \ - tor_mutex_release(&log_mutex); \ - STMT_END - -/** What's the lowest log level anybody cares about? Checking this lets us - * bail out early from log_debug if we aren't debugging. */ -int log_global_min_severity_ = LOG_NOTICE; - -static void delete_log(logfile_t *victim); -static void close_log(logfile_t *victim); - -static char *domain_to_string(log_domain_mask_t domain, - char *buf, size_t buflen); -static inline char *format_msg(char *buf, size_t buf_len, - log_domain_mask_t domain, int severity, const char *funcname, - const char *suffix, - const char *format, va_list ap, size_t *msg_len_out) - CHECK_PRINTF(7,0); - -/** Name of the application: used to generate the message we write at the - * start of each new log. */ -static char *appname = NULL; - -/** Set the "application name" for the logs to name: we'll use this - * name in the message we write when starting up, and at the start of each new - * log. - * - * Tor uses this string to write the version number to the log file. */ -void -log_set_application_name(const char *name) -{ - tor_free(appname); - appname = name ? tor_strdup(name) : NULL; -} - -/** Return true if some of the running logs might be interested in a log - * message of the given severity in the given domains. If this function - * returns true, the log message might be ignored anyway, but if it returns - * false, it is definitely_ safe not to log the message. */ -int -log_message_is_interesting(int severity, log_domain_mask_t domain) -{ - (void) domain; - return (severity <= log_global_min_severity_); -} - -/** - * As tor_log, but takes an optional function name, and does not treat its - * string as a printf format. - * - * For use by Rust integration. - */ -void -tor_log_string(int severity, log_domain_mask_t domain, - const char *function, const char *string) -{ - log_fn_(severity, domain, function, "%s", string); -} - -/** Log time granularity in milliseconds. */ -static int log_time_granularity = 1; - -/** Define log time granularity for all logs to be granularity_msec - * milliseconds. */ -void -set_log_time_granularity(int granularity_msec) -{ - log_time_granularity = granularity_msec; - tor_log_sigsafe_err_set_granularity(granularity_msec); -} - -/** Helper: Write the standard prefix for log lines to a - * buf_len character buffer in buf. - */ -static inline size_t -log_prefix_(char *buf, size_t buf_len, int severity) -{ - time_t t; - struct timeval now; - struct tm tm; - size_t n; - int r, ms; - - tor_gettimeofday(&now); - t = (time_t)now.tv_sec; - ms = (int)now.tv_usec / 1000; - if (log_time_granularity >= 1000) { - t -= t % (log_time_granularity / 1000); - ms = 0; - } else { - ms -= ((int)now.tv_usec / 1000) % log_time_granularity; - } - - n = strftime(buf, buf_len, "%b %d %H:%M:%S", - tor_localtime_r_msg(&t, &tm, NULL)); - r = tor_snprintf(buf+n, buf_len-n, ".%.3i [%s] ", ms, - sev_to_string(severity)); - - if (r<0) - return buf_len-1; - else - return n+r; -} - -/** If lf refers to an actual file that we have just opened, and the file - * contains no data, log an "opening new logfile" message at the top. - * - * Return -1 if the log is broken and needs to be deleted, else return 0. - */ -static int -log_tor_version(logfile_t *lf, int reset) -{ - char buf[256]; - size_t n; - int is_new; - - if (!lf->needs_close) - /* If it doesn't get closed, it isn't really a file. */ - return 0; - if (lf->is_temporary) - /* If it's temporary, it isn't really a file. */ - return 0; - - is_new = lf->fd >= 0 && tor_fd_getpos(lf->fd) == 0; - - if (reset && !is_new) - /* We are resetting, but we aren't at the start of the file; no - * need to log again. */ - return 0; - n = log_prefix_(buf, sizeof(buf), LOG_NOTICE); - if (appname) { - tor_snprintf(buf+n, sizeof(buf)-n, - "%s opening %slog file.\n", appname, is_new?"new ":""); - } else { - tor_snprintf(buf+n, sizeof(buf)-n, - "Tor %s opening %slog file.\n", VERSION, is_new?"new ":""); - } - if (write_all_to_fd_minimal(lf->fd, buf, strlen(buf)) < 0) /* error */ - return -1; /* failed */ - return 0; -} - -static const char bug_suffix[] = " (on Tor " VERSION -#ifndef _MSC_VER - " " -#include "micro-revision.i" -#endif - ")"; - -/** Helper: Format a log message into a fixed-sized buffer. (This is - * factored out of logv so that we never format a message more - * than once.) Return a pointer to the first character of the message - * portion of the formatted string. - */ -static inline char * -format_msg(char *buf, size_t buf_len, - log_domain_mask_t domain, int severity, const char *funcname, - const char *suffix, - const char *format, va_list ap, size_t *msg_len_out) -{ - size_t n; - int r; - char *end_of_prefix; - char *buf_end; - - raw_assert(buf_len >= 16); /* prevent integer underflow and stupidity */ - buf_len -= 2; /* subtract 2 characters so we have room for \n\0 */ - buf_end = buf+buf_len; /* point *after* the last char we can write to */ - - n = log_prefix_(buf, buf_len, severity); - end_of_prefix = buf+n; - - if (log_domains_are_logged) { - char *cp = buf+n; - if (cp == buf_end) goto format_msg_no_room_for_domains; - *cp++ = '{'; - if (cp == buf_end) goto format_msg_no_room_for_domains; - cp = domain_to_string(domain, cp, (buf+buf_len-cp)); - if (cp == buf_end) goto format_msg_no_room_for_domains; - *cp++ = '}'; - if (cp == buf_end) goto format_msg_no_room_for_domains; - *cp++ = ' '; - if (cp == buf_end) goto format_msg_no_room_for_domains; - end_of_prefix = cp; - n = cp-buf; - format_msg_no_room_for_domains: - /* This will leave end_of_prefix and n unchanged, and thus cause - * whatever log domain string we had written to be clobbered. */ - ; - } - - if (funcname && should_log_function_name(domain, severity)) { - r = tor_snprintf(buf+n, buf_len-n, - pretty_fn_has_parens ? "%s: " : "%s(): ", - funcname); - if (r<0) - n = strlen(buf); - else - n += r; - } - - if (domain == LD_BUG && buf_len-n > 6) { - memcpy(buf+n, "Bug: ", 6); - n += 5; - } - - r = tor_vsnprintf(buf+n,buf_len-n,format,ap); - if (r < 0) { - /* The message was too long; overwrite the end of the buffer with - * "[...truncated]" */ - if (buf_len >= TRUNCATED_STR_LEN) { - size_t offset = buf_len-TRUNCATED_STR_LEN; - /* We have an extra 2 characters after buf_len to hold the \n\0, - * so it's safe to add 1 to the size here. */ - strlcpy(buf+offset, TRUNCATED_STR, buf_len-offset+1); - } - /* Set 'n' to the end of the buffer, where we'll be writing \n\0. - * Since we already subtracted 2 from buf_len, this is safe.*/ - n = buf_len; - } else { - n += r; - if (suffix) { - size_t suffix_len = strlen(suffix); - if (buf_len-n >= suffix_len) { - memcpy(buf+n, suffix, suffix_len); - n += suffix_len; - } - } - } - - if (domain == LD_BUG && - buf_len - n > strlen(bug_suffix)+1) { - memcpy(buf+n, bug_suffix, strlen(bug_suffix)); - n += strlen(bug_suffix); - } - - buf[n]='\n'; - buf[n+1]='\0'; - *msg_len_out = n+1; - return end_of_prefix; -} - -/* Create a new pending_log_message_t with appropriate values */ -static pending_log_message_t * -pending_log_message_new(int severity, log_domain_mask_t domain, - const char *fullmsg, const char *shortmsg) -{ - pending_log_message_t *m = tor_malloc(sizeof(pending_log_message_t)); - m->severity = severity; - m->domain = domain; - m->fullmsg = fullmsg ? tor_strdup(fullmsg) : NULL; - m->msg = tor_strdup(shortmsg); - return m; -} - -#define pending_log_message_free(msg) \ - FREE_AND_NULL(pending_log_message_t, pending_log_message_free_, (msg)) - -/** Release all storage held by msg. */ -static void -pending_log_message_free_(pending_log_message_t *msg) -{ - if (!msg) - return; - tor_free(msg->msg); - tor_free(msg->fullmsg); - tor_free(msg); -} - -/** Helper function: returns true iff the log file, given in lf, is - * handled externally via the system log API, the Android logging API, or is an - * external callback function. */ -static inline int -logfile_is_external(const logfile_t *lf) -{ - raw_assert(lf); - return lf->is_syslog || lf->is_android || lf->callback; -} - -/** Return true iff lf would like to receive a message with the - * specified severity in the specified domain. - */ -static inline int -logfile_wants_message(const logfile_t *lf, int severity, - log_domain_mask_t domain) -{ - if (! (lf->severities->masks[SEVERITY_MASK_IDX(severity)] & domain)) { - return 0; - } - if (! (lf->fd >= 0 || logfile_is_external(lf))) { - return 0; - } - if (lf->seems_dead) { - return 0; - } - - return 1; -} - -/** Send a message to lf. The full message, with time prefix and - * severity, is in buf. The message itself is in - * msg_after_prefix. If callbacks_deferred points to true, then - * we already deferred this message for pending callbacks and don't need to do - * it again. Otherwise, if we need to do it, do it, and set - * callbacks_deferred to 1. */ -static inline void -logfile_deliver(logfile_t *lf, const char *buf, size_t msg_len, - const char *msg_after_prefix, log_domain_mask_t domain, - int severity, int *callbacks_deferred) -{ - - if (lf->is_syslog) { -#ifdef HAVE_SYSLOG_H -#ifdef MAXLINE - /* Some syslog implementations have limits on the length of what you can - * pass them, and some very old ones do not detect overflow so well. - * Regrettably, they call their maximum line length MAXLINE. */ -#if MAXLINE < 64 -#warn "MAXLINE is a very low number; it might not be from syslog.h after all" -#endif - char *m = msg_after_prefix; - if (msg_len >= MAXLINE) - m = tor_strndup(msg_after_prefix, MAXLINE-1); - syslog(severity, "%s", m); - if (m != msg_after_prefix) { - tor_free(m); - } -#else /* !(defined(MAXLINE)) */ - /* We have syslog but not MAXLINE. That's promising! */ - syslog(severity, "%s", msg_after_prefix); -#endif /* defined(MAXLINE) */ -#endif /* defined(HAVE_SYSLOG_H) */ - } else if (lf->is_android) { -#ifdef HAVE_ANDROID_LOG_H - int priority = severity_to_android_log_priority(severity); - __android_log_write(priority, lf->android_tag, msg_after_prefix); -#endif // HAVE_ANDROID_LOG_H. - } else if (lf->callback) { - if (domain & LD_NOCB) { - if (!*callbacks_deferred && pending_cb_messages) { - smartlist_add(pending_cb_messages, - pending_log_message_new(severity,domain,NULL,msg_after_prefix)); - *callbacks_deferred = 1; - if (smartlist_len(pending_cb_messages) == 1 && pending_cb_cb) { - pending_cb_cb(); - } - } - } else { - lf->callback(severity, domain, msg_after_prefix); - } - } else { - if (write_all_to_fd_minimal(lf->fd, buf, msg_len) < 0) { /* error */ - /* don't log the error! mark this log entry to be blown away, and - * continue. */ - lf->seems_dead = 1; - } - } -} - -/** Helper: sends a message to the appropriate logfiles, at loglevel - * severity. If provided, funcname is prepended to the - * message. The actual message is derived as from tor_snprintf(format,ap). - */ -MOCK_IMPL(STATIC void, -logv,(int severity, log_domain_mask_t domain, const char *funcname, - const char *suffix, const char *format, va_list ap)) -{ - char buf[10240]; - size_t msg_len = 0; - int formatted = 0; - logfile_t *lf; - char *end_of_prefix=NULL; - int callbacks_deferred = 0; - - /* Call assert, not raw_assert, since raw_assert calls log on failure. */ - raw_assert(format); - /* check that severity is sane. Overrunning the masks array leads to - * interesting and hard to diagnose effects */ - raw_assert(severity >= LOG_ERR && severity <= LOG_DEBUG); - /* check that we've initialised the log mutex before we try to lock it */ - raw_assert(log_mutex_initialized); - LOCK_LOGS(); - - if ((! (domain & LD_NOCB)) && pending_cb_messages - && smartlist_len(pending_cb_messages)) - flush_pending_log_callbacks(); - - if (queue_startup_messages && - pending_startup_messages_len < MAX_STARTUP_MSG_LEN) { - end_of_prefix = - format_msg(buf, sizeof(buf), domain, severity, funcname, suffix, - format, ap, &msg_len); - formatted = 1; - - smartlist_add(pending_startup_messages, - pending_log_message_new(severity,domain,buf,end_of_prefix)); - pending_startup_messages_len += msg_len; - } - - for (lf = logfiles; lf; lf = lf->next) { - if (! logfile_wants_message(lf, severity, domain)) - continue; - - if (!formatted) { - end_of_prefix = - format_msg(buf, sizeof(buf), domain, severity, funcname, suffix, - format, ap, &msg_len); - formatted = 1; - } - - logfile_deliver(lf, buf, msg_len, end_of_prefix, domain, severity, - &callbacks_deferred); - } - UNLOCK_LOGS(); -} - -/** Output a message to the log. It gets logged to all logfiles that - * care about messages with severity in domain. The content - * is formatted printf-style based on format and extra arguments. - * */ -void -tor_log(int severity, log_domain_mask_t domain, const char *format, ...) -{ - va_list ap; - if (severity > log_global_min_severity_) - return; - va_start(ap,format); -#ifdef TOR_UNIT_TESTS - if (domain & LD_NO_MOCK) - logv__real(severity, domain, NULL, NULL, format, ap); - else -#endif - logv(severity, domain, NULL, NULL, format, ap); - va_end(ap); -} - -/** Helper function; return true iff the n-element array array - * contains item. */ -static int -int_array_contains(const int *array, int n, int item) -{ - int j; - for (j = 0; j < n; ++j) { - if (array[j] == item) - return 1; - } - return 0; -} - -/** Function to call whenever the list of logs changes to get ready to log - * from signal handlers. */ -void -tor_log_update_sigsafe_err_fds(void) -{ - const logfile_t *lf; - int found_real_stderr = 0; - - int fds[TOR_SIGSAFE_LOG_MAX_FDS]; - int n_fds; - - LOCK_LOGS(); - /* Reserve the first one for stderr. This is safe because when we daemonize, - * we dup2 /dev/null to stderr, */ - fds[0] = STDERR_FILENO; - n_fds = 1; - - for (lf = logfiles; lf; lf = lf->next) { - /* Don't try callback to the control port, or syslogs: We can't - * do them from a signal handler. Don't try stdout: we always do stderr. - */ - if (lf->is_temporary || logfile_is_external(lf) - || lf->seems_dead || lf->fd < 0) - continue; - if (lf->severities->masks[SEVERITY_MASK_IDX(LOG_ERR)] & - (LD_BUG|LD_GENERAL)) { - if (lf->fd == STDERR_FILENO) - found_real_stderr = 1; - /* Avoid duplicates */ - if (int_array_contains(fds, n_fds, lf->fd)) - continue; - fds[n_fds++] = lf->fd; - if (n_fds == TOR_SIGSAFE_LOG_MAX_FDS) - break; - } - } - - if (!found_real_stderr && - int_array_contains(fds, n_fds, STDOUT_FILENO)) { - /* Don't use a virtual stderr when we're also logging to stdout. */ - raw_assert(n_fds >= 2); /* Don't raw_assert inside log fns */ - fds[0] = fds[--n_fds]; - } - - UNLOCK_LOGS(); - - tor_log_set_sigsafe_err_fds(fds, n_fds); -} - -/** Add to out a copy of every currently configured log file name. Used - * to enable access to these filenames with the sandbox code. */ -void -tor_log_get_logfile_names(smartlist_t *out) -{ - logfile_t *lf; - raw_assert(out); - - LOCK_LOGS(); - - for (lf = logfiles; lf; lf = lf->next) { - if (lf->is_temporary || logfile_is_external(lf)) - continue; - if (lf->filename == NULL) - continue; - smartlist_add_strdup(out, lf->filename); - } - - UNLOCK_LOGS(); -} - -/** Implementation of the log_fn backend, used when we have - * variadic macros. All arguments are as for log_fn, except for - * fn, which is the name of the calling functions. */ -void -log_fn_(int severity, log_domain_mask_t domain, const char *fn, - const char *format, ...) -{ - va_list ap; - if (severity > log_global_min_severity_) - return; - va_start(ap,format); - logv(severity, domain, fn, NULL, format, ap); - va_end(ap); -} -void -log_fn_ratelim_(ratelim_t *ratelim, int severity, log_domain_mask_t domain, - const char *fn, const char *format, ...) -{ - va_list ap; - char *m; - if (severity > log_global_min_severity_) - return; - m = rate_limit_log(ratelim, approx_time()); - if (m == NULL) - return; - va_start(ap, format); - logv(severity, domain, fn, m, format, ap); - va_end(ap); - tor_free(m); -} - -/** Free all storage held by victim. */ -static void -log_free_(logfile_t *victim) -{ - if (!victim) - return; - tor_free(victim->severities); - tor_free(victim->filename); - tor_free(victim->android_tag); - tor_free(victim); -} - -/** Close all open log files, and free other static memory. */ -void -logs_free_all(void) -{ - logfile_t *victim, *next; - smartlist_t *messages, *messages2; - LOCK_LOGS(); - next = logfiles; - logfiles = NULL; - messages = pending_cb_messages; - pending_cb_messages = NULL; - pending_cb_cb = NULL; - messages2 = pending_startup_messages; - pending_startup_messages = NULL; - UNLOCK_LOGS(); - while (next) { - victim = next; - next = next->next; - close_log(victim); - log_free(victim); - } - tor_free(appname); - - SMARTLIST_FOREACH(messages, pending_log_message_t *, msg, { - pending_log_message_free(msg); - }); - smartlist_free(messages); - - if (messages2) { - SMARTLIST_FOREACH(messages2, pending_log_message_t *, msg, { - pending_log_message_free(msg); - }); - smartlist_free(messages2); - } - - /* We _could_ destroy the log mutex here, but that would screw up any logs - * that happened between here and the end of execution. */ -} - -/** Remove and free the log entry victim from the linked-list - * logfiles (it is probably present, but it might not be due to thread - * racing issues). After this function is called, the caller shouldn't - * refer to victim anymore. - * - * Long-term, we need to do something about races in the log subsystem - * in general. See bug 222 for more details. - */ -static void -delete_log(logfile_t *victim) -{ - logfile_t *tmpl; - if (victim == logfiles) - logfiles = victim->next; - else { - for (tmpl = logfiles; tmpl && tmpl->next != victim; tmpl=tmpl->next) ; -// raw_assert(tmpl); -// raw_assert(tmpl->next == victim); - if (!tmpl) - return; - tmpl->next = victim->next; - } - log_free(victim); -} - -/** Helper: release system resources (but not memory) held by a single - * logfile_t. */ -static void -close_log(logfile_t *victim) -{ - if (victim->needs_close && victim->fd >= 0) { - close(victim->fd); - victim->fd = -1; - } else if (victim->is_syslog) { -#ifdef HAVE_SYSLOG_H - if (--syslog_count == 0) { - /* There are no other syslogs; close the logging facility. */ - closelog(); - } -#endif /* defined(HAVE_SYSLOG_H) */ - } -} - -/** Adjust a log severity configuration in severity_out to contain - * every domain between loglevelMin and loglevelMax, inclusive. - */ -void -set_log_severity_config(int loglevelMin, int loglevelMax, - log_severity_list_t *severity_out) -{ - int i; - raw_assert(loglevelMin >= loglevelMax); - raw_assert(loglevelMin >= LOG_ERR && loglevelMin <= LOG_DEBUG); - raw_assert(loglevelMax >= LOG_ERR && loglevelMax <= LOG_DEBUG); - memset(severity_out, 0, sizeof(log_severity_list_t)); - for (i = loglevelMin; i >= loglevelMax; --i) { - severity_out->masks[SEVERITY_MASK_IDX(i)] = ~0u; - } -} - -/** Add a log handler named name to send all messages in severity - * to fd. Copies severity. Helper: does no locking. */ -static void -add_stream_log_impl(const log_severity_list_t *severity, - const char *name, int fd) -{ - logfile_t *lf; - lf = tor_malloc_zero(sizeof(logfile_t)); - lf->fd = fd; - lf->filename = tor_strdup(name); - lf->severities = tor_memdup(severity, sizeof(log_severity_list_t)); - lf->next = logfiles; - - logfiles = lf; - log_global_min_severity_ = get_min_log_level(); -} - -/** Add a log handler named name to send all messages in severity - * to fd. Steals a reference to severity; the caller must - * not use it after calling this function. */ -void -add_stream_log(const log_severity_list_t *severity, const char *name, int fd) -{ - LOCK_LOGS(); - add_stream_log_impl(severity, name, fd); - UNLOCK_LOGS(); -} - -/** Initialize the global logging facility */ -void -init_logging(int disable_startup_queue) -{ - if (!log_mutex_initialized) { - tor_mutex_init(&log_mutex); - log_mutex_initialized = 1; - } -#ifdef __GNUC__ - if (strchr(__PRETTY_FUNCTION__, '(')) { - pretty_fn_has_parens = 1; - } -#endif - if (pending_cb_messages == NULL) - pending_cb_messages = smartlist_new(); - if (disable_startup_queue) - queue_startup_messages = 0; - if (pending_startup_messages == NULL && queue_startup_messages) { - pending_startup_messages = smartlist_new(); - } -} - -/** Set whether we report logging domains as a part of our log messages. - */ -void -logs_set_domain_logging(int enabled) -{ - LOCK_LOGS(); - log_domains_are_logged = enabled; - UNLOCK_LOGS(); -} - -/** Add a log handler to receive messages during startup (before the real - * logs are initialized). - */ -void -add_temp_log(int min_severity) -{ - log_severity_list_t *s = tor_malloc_zero(sizeof(log_severity_list_t)); - set_log_severity_config(min_severity, LOG_ERR, s); - LOCK_LOGS(); - add_stream_log_impl(s, "", fileno(stdout)); - tor_free(s); - logfiles->is_temporary = 1; - UNLOCK_LOGS(); -} - -/** - * Register "cb" as the callback to call when there are new pending log - * callbacks to be flushed with flush_pending_log_callbacks(). - * - * Note that this callback, if present, can be invoked from any thread. - * - * This callback must not log. - * - * It is intentional that this function contains the name "callback" twice: it - * sets a "callback" to be called on the condition that there is a "pending - * callback". - **/ -void -logs_set_pending_callback_callback(pending_callback_callback cb) -{ - pending_cb_cb = cb; -} - -/** - * Add a log handler to send messages in severity - * to the function cb. - */ -int -add_callback_log(const log_severity_list_t *severity, log_callback cb) -{ - logfile_t *lf; - lf = tor_malloc_zero(sizeof(logfile_t)); - lf->fd = -1; - lf->severities = tor_memdup(severity, sizeof(log_severity_list_t)); - lf->filename = tor_strdup(""); - lf->callback = cb; - lf->next = logfiles; - - LOCK_LOGS(); - logfiles = lf; - log_global_min_severity_ = get_min_log_level(); - UNLOCK_LOGS(); - return 0; -} - -/** Adjust the configured severity of any logs whose callback function is - * cb. */ -void -change_callback_log_severity(int loglevelMin, int loglevelMax, - log_callback cb) -{ - logfile_t *lf; - log_severity_list_t severities; - set_log_severity_config(loglevelMin, loglevelMax, &severities); - LOCK_LOGS(); - for (lf = logfiles; lf; lf = lf->next) { - if (lf->callback == cb) { - memcpy(lf->severities, &severities, sizeof(severities)); - } - } - log_global_min_severity_ = get_min_log_level(); - UNLOCK_LOGS(); -} - -/** If there are any log messages that were generated with LD_NOCB waiting to - * be sent to callback-based loggers, send them now. */ -void -flush_pending_log_callbacks(void) -{ - logfile_t *lf; - smartlist_t *messages, *messages_tmp; - - LOCK_LOGS(); - if (!pending_cb_messages || 0 == smartlist_len(pending_cb_messages)) { - UNLOCK_LOGS(); - return; - } - - messages = pending_cb_messages; - pending_cb_messages = smartlist_new(); - do { - SMARTLIST_FOREACH_BEGIN(messages, pending_log_message_t *, msg) { - const int severity = msg->severity; - const int domain = msg->domain; - for (lf = logfiles; lf; lf = lf->next) { - if (! lf->callback || lf->seems_dead || - ! (lf->severities->masks[SEVERITY_MASK_IDX(severity)] & domain)) { - continue; - } - lf->callback(severity, domain, msg->msg); - } - pending_log_message_free(msg); - } SMARTLIST_FOREACH_END(msg); - smartlist_clear(messages); - - messages_tmp = pending_cb_messages; - pending_cb_messages = messages; - messages = messages_tmp; - } while (smartlist_len(messages)); - - smartlist_free(messages); - - UNLOCK_LOGS(); -} - -/** Flush all the messages we stored from startup while waiting for log - * initialization. - */ -void -flush_log_messages_from_startup(void) -{ - logfile_t *lf; - - LOCK_LOGS(); - queue_startup_messages = 0; - pending_startup_messages_len = 0; - if (! pending_startup_messages) - goto out; - - SMARTLIST_FOREACH_BEGIN(pending_startup_messages, pending_log_message_t *, - msg) { - int callbacks_deferred = 0; - for (lf = logfiles; lf; lf = lf->next) { - if (! logfile_wants_message(lf, msg->severity, msg->domain)) - continue; - - /* We configure a temporary startup log that goes to stdout, so we - * shouldn't replay to stdout/stderr*/ - if (lf->fd == STDOUT_FILENO || lf->fd == STDERR_FILENO) { - continue; - } - - logfile_deliver(lf, msg->fullmsg, strlen(msg->fullmsg), msg->msg, - msg->domain, msg->severity, &callbacks_deferred); - } - pending_log_message_free(msg); - } SMARTLIST_FOREACH_END(msg); - smartlist_free(pending_startup_messages); - pending_startup_messages = NULL; - - out: - UNLOCK_LOGS(); -} - -/** Close any log handlers added by add_temp_log() or marked by - * mark_logs_temp(). */ -void -close_temp_logs(void) -{ - logfile_t *lf, **p; - - LOCK_LOGS(); - for (p = &logfiles; *p; ) { - if ((*p)->is_temporary) { - lf = *p; - /* we use *p here to handle the edge case of the head of the list */ - *p = (*p)->next; - close_log(lf); - log_free(lf); - } else { - p = &((*p)->next); - } - } - - log_global_min_severity_ = get_min_log_level(); - UNLOCK_LOGS(); -} - -/** Make all currently temporary logs (set to be closed by close_temp_logs) - * live again, and close all non-temporary logs. */ -void -rollback_log_changes(void) -{ - logfile_t *lf; - LOCK_LOGS(); - for (lf = logfiles; lf; lf = lf->next) - lf->is_temporary = ! lf->is_temporary; - UNLOCK_LOGS(); - close_temp_logs(); -} - -/** Configure all log handles to be closed by close_temp_logs(). */ -void -mark_logs_temp(void) -{ - logfile_t *lf; - LOCK_LOGS(); - for (lf = logfiles; lf; lf = lf->next) - lf->is_temporary = 1; - UNLOCK_LOGS(); -} - -/** - * Add a log handler to send messages to filename via fd. If - * opening the logfile failed, -1 is returned and errno is set appropriately - * (by open(2)). Takes ownership of fd. - */ -int -add_file_log(const log_severity_list_t *severity, - const char *filename, - int fd) -{ - logfile_t *lf; - - if (fd<0) - return -1; - if (tor_fd_seekend(fd)<0) { - close(fd); - return -1; - } - - LOCK_LOGS(); - add_stream_log_impl(severity, filename, fd); - logfiles->needs_close = 1; - lf = logfiles; - log_global_min_severity_ = get_min_log_level(); - - if (log_tor_version(lf, 0) < 0) { - delete_log(lf); - } - UNLOCK_LOGS(); - - return 0; -} - -#ifdef HAVE_SYSLOG_H -/** - * Add a log handler to send messages to they system log facility. - * - * If this is the first log handler, opens syslog with ident Tor or - * Tor- if that is not NULL. - */ -int -add_syslog_log(const log_severity_list_t *severity, - const char* syslog_identity_tag) -{ - logfile_t *lf; - if (syslog_count++ == 0) { - /* This is the first syslog. */ - static char buf[256]; - if (syslog_identity_tag) { - tor_snprintf(buf, sizeof(buf), "Tor-%s", syslog_identity_tag); - } else { - tor_snprintf(buf, sizeof(buf), "Tor"); - } - openlog(buf, LOG_PID | LOG_NDELAY, LOGFACILITY); - } - - lf = tor_malloc_zero(sizeof(logfile_t)); - lf->fd = -1; - lf->severities = tor_memdup(severity, sizeof(log_severity_list_t)); - lf->filename = tor_strdup(""); - lf->is_syslog = 1; - - LOCK_LOGS(); - lf->next = logfiles; - logfiles = lf; - log_global_min_severity_ = get_min_log_level(); - UNLOCK_LOGS(); - return 0; -} -#endif /* defined(HAVE_SYSLOG_H) */ - -#ifdef HAVE_ANDROID_LOG_H -/** - * Add a log handler to send messages to the Android platform log facility. - */ -int -add_android_log(const log_severity_list_t *severity, - const char *android_tag) -{ - logfile_t *lf = NULL; - - lf = tor_malloc_zero(sizeof(logfile_t)); - lf->fd = -1; - lf->severities = tor_memdup(severity, sizeof(log_severity_list_t)); - lf->filename = tor_strdup(""); - lf->is_android = 1; - - if (android_tag == NULL) - lf->android_tag = tor_strdup("Tor"); - else { - char buf[256]; - tor_snprintf(buf, sizeof(buf), "Tor-%s", android_tag); - lf->android_tag = tor_strdup(buf); - } - - LOCK_LOGS(); - lf->next = logfiles; - logfiles = lf; - log_global_min_severity_ = get_min_log_level(); - UNLOCK_LOGS(); - return 0; -} -#endif // HAVE_ANDROID_LOG_H. - -/** If level is a valid log severity, return the corresponding - * numeric value. Otherwise, return -1. */ -int -parse_log_level(const char *level) -{ - if (!strcasecmp(level, "err")) - return LOG_ERR; - if (!strcasecmp(level, "warn")) - return LOG_WARN; - if (!strcasecmp(level, "notice")) - return LOG_NOTICE; - if (!strcasecmp(level, "info")) - return LOG_INFO; - if (!strcasecmp(level, "debug")) - return LOG_DEBUG; - return -1; -} - -/** Return the string equivalent of a given log level. */ -const char * -log_level_to_string(int level) -{ - return sev_to_string(level); -} - -/** NULL-terminated array of names for log domains such that domain_list[dom] - * is a description of dom. - * - * Remember to update doc/tor.1.txt if you modify this list. - * */ -static const char *domain_list[] = { - "GENERAL", "CRYPTO", "NET", "CONFIG", "FS", "PROTOCOL", "MM", - "HTTP", "APP", "CONTROL", "CIRC", "REND", "BUG", "DIR", "DIRSERV", - "OR", "EDGE", "ACCT", "HIST", "HANDSHAKE", "HEARTBEAT", "CHANNEL", - "SCHED", "GUARD", "CONSDIFF", "DOS", NULL -}; - -/** Return a bitmask for the log domain for which domain is the name, - * or 0 if there is no such name. */ -static log_domain_mask_t -parse_log_domain(const char *domain) -{ - int i; - for (i=0; domain_list[i]; ++i) { - if (!strcasecmp(domain, domain_list[i])) - return (1u<= ARRAY_LENGTH(domain_list)-1 || - bit >= N_LOGGING_DOMAINS) { - tor_snprintf(buf, buflen, "", (long)domain); - return buf+strlen(buf); - } - d = domain_list[bit]; - n = strlcpy(cp, d, eos-cp); - if (n >= buflen) { - tor_snprintf(buf, buflen, "", (long)domain); - return buf+strlen(buf); - } - cp += n; - domain &= ~(1<cfg_ptr. Advance cfg_ptr after - * the end of the severityPattern. Set the value of severity_out to - * the parsed pattern. Return 0 on success, -1 on failure. - * - * The syntax for a SeverityPattern is: - *
- *   SeverityPattern = *(DomainSeverity SP)* DomainSeverity
- *   DomainSeverity = (DomainList SP)? SeverityRange
- *   SeverityRange = MinSeverity ("-" MaxSeverity )?
- *   DomainList = "[" (SP? DomainSpec SP? ",") SP? DomainSpec "]"
- *   DomainSpec = "*" | Domain | "~" Domain
- * 
- * A missing MaxSeverity defaults to ERR. Severities and domains are - * case-insensitive. "~" indicates negation for a domain; negation happens - * last inside a DomainList. Only one SeverityRange without a DomainList is - * allowed per line. - */ -int -parse_log_severity_config(const char **cfg_ptr, - log_severity_list_t *severity_out) -{ - const char *cfg = *cfg_ptr; - int got_anything = 0; - int got_an_unqualified_range = 0; - memset(severity_out, 0, sizeof(*severity_out)); - - cfg = eat_whitespace(cfg); - while (*cfg) { - const char *dash, *space; - char *sev_lo, *sev_hi; - int low, high, i; - log_domain_mask_t domains = ~0u; - - if (*cfg == '[') { - int err = 0; - char *domains_str; - smartlist_t *domains_list; - log_domain_mask_t neg_domains = 0; - const char *closebracket = strchr(cfg, ']'); - if (!closebracket) - return -1; - domains = 0; - domains_str = tor_strndup(cfg+1, closebracket-cfg-1); - domains_list = smartlist_new(); - smartlist_split_string(domains_list, domains_str, ",", SPLIT_SKIP_SPACE, - -1); - tor_free(domains_str); - SMARTLIST_FOREACH_BEGIN(domains_list, const char *, domain) { - if (!strcmp(domain, "*")) { - domains = ~0u; - } else { - int d; - int negate=0; - if (*domain == '~') { - negate = 1; - ++domain; - } - d = parse_log_domain(domain); - if (!d) { - log_warn(LD_CONFIG, "No such logging domain as %s", domain); - err = 1; - } else { - if (negate) - neg_domains |= d; - else - domains |= d; - } - } - } SMARTLIST_FOREACH_END(domain); - SMARTLIST_FOREACH(domains_list, char *, d, tor_free(d)); - smartlist_free(domains_list); - if (err) - return -1; - if (domains == 0 && neg_domains) - domains = ~neg_domains; - else - domains &= ~neg_domains; - cfg = eat_whitespace(closebracket+1); - } else { - ++got_an_unqualified_range; - } - if (!strcasecmpstart(cfg, "file") || - !strcasecmpstart(cfg, "stderr") || - !strcasecmpstart(cfg, "stdout") || - !strcasecmpstart(cfg, "syslog") || - !strcasecmpstart(cfg, "android")) { - goto done; - } - if (got_an_unqualified_range > 1) - return -1; - - space = find_whitespace(cfg); - dash = strchr(cfg, '-'); - if (dash && dash < space) { - sev_lo = tor_strndup(cfg, dash-cfg); - sev_hi = tor_strndup(dash+1, space-(dash+1)); - } else { - sev_lo = tor_strndup(cfg, space-cfg); - sev_hi = tor_strdup("ERR"); - } - low = parse_log_level(sev_lo); - high = parse_log_level(sev_hi); - tor_free(sev_lo); - tor_free(sev_hi); - if (low == -1) - return -1; - if (high == -1) - return -1; - - got_anything = 1; - for (i=low; i >= high; --i) - severity_out->masks[SEVERITY_MASK_IDX(i)] |= domains; - - cfg = eat_whitespace(space); - } - - done: - *cfg_ptr = cfg; - return got_anything ? 0 : -1; -} - -/** Return the least severe log level that any current log is interested in. */ -int -get_min_log_level(void) -{ - logfile_t *lf; - int i; - int min = LOG_ERR; - for (lf = logfiles; lf; lf = lf->next) { - for (i = LOG_DEBUG; i > min; --i) - if (lf->severities->masks[SEVERITY_MASK_IDX(i)]) - min = i; - } - return min; -} - -/** Switch all logs to output at most verbose level. */ -void -switch_logs_debug(void) -{ - logfile_t *lf; - int i; - LOCK_LOGS(); - for (lf = logfiles; lf; lf=lf->next) { - for (i = LOG_DEBUG; i >= LOG_ERR; --i) - lf->severities->masks[SEVERITY_MASK_IDX(i)] = ~0u; - } - log_global_min_severity_ = get_min_log_level(); - UNLOCK_LOGS(); -} - -/** Truncate all the log files. */ -void -truncate_logs(void) -{ - logfile_t *lf; - for (lf = logfiles; lf; lf = lf->next) { - if (lf->fd >= 0) { - tor_ftruncate(lf->fd); - } - } -} diff --git a/src/lib/log/torlog.h b/src/lib/log/torlog.h deleted file mode 100644 index c24b638191..0000000000 --- a/src/lib/log/torlog.h +++ /dev/null @@ -1,276 +0,0 @@ -/* Copyright (c) 2001, Matej Pfajfar. - * Copyright (c) 2001-2004, Roger Dingledine. - * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2018, The Tor Project, Inc. */ -/* See LICENSE for licensing information */ - -/** - * \file torlog.h - * - * \brief Headers for log.c - **/ - -#ifndef TOR_TORLOG_H - -#include -#include "lib/cc/torint.h" -#include "lib/cc/compat_compiler.h" -#include "lib/testsupport/testsupport.h" - -#ifdef HAVE_SYSLOG_H -#include -#define LOG_WARN LOG_WARNING -#if LOG_DEBUG < LOG_ERR -#error "Your syslog.h thinks high numbers are more important. " \ - "We aren't prepared to deal with that." -#endif -#else /* !(defined(HAVE_SYSLOG_H)) */ -/* Note: Syslog's logging code refers to priorities, with 0 being the most - * important. Thus, all our comparisons needed to be reversed when we added - * syslog support. - * - * The upshot of this is that comments about log levels may be messed up: for - * "maximum severity" read "most severe" and "numerically *lowest* severity". - */ - -/** Debug-level severity: for hyper-verbose messages of no interest to - * anybody but developers. */ -#define LOG_DEBUG 7 -/** Info-level severity: for messages that appear frequently during normal - * operation. */ -#define LOG_INFO 6 -/** Notice-level severity: for messages that appear infrequently - * during normal operation; that the user will probably care about; - * and that are not errors. - */ -#define LOG_NOTICE 5 -/** Warn-level severity: for messages that only appear when something has gone - * wrong. */ -#define LOG_WARN 4 -/** Error-level severity: for messages that only appear when something has gone - * very wrong, and the Tor process can no longer proceed. */ -#define LOG_ERR 3 -#endif /* defined(HAVE_SYSLOG_H) */ - -/* Logging domains */ - -/** Catch-all for miscellaneous events and fatal errors. */ -#define LD_GENERAL (1u<<0) -/** The cryptography subsystem. */ -#define LD_CRYPTO (1u<<1) -/** Networking. */ -#define LD_NET (1u<<2) -/** Parsing and acting on our configuration. */ -#define LD_CONFIG (1u<<3) -/** Reading and writing from the filesystem. */ -#define LD_FS (1u<<4) -/** Other servers' (non)compliance with the Tor protocol. */ -#define LD_PROTOCOL (1u<<5) -/** Memory management. */ -#define LD_MM (1u<<6) -/** HTTP implementation. */ -#define LD_HTTP (1u<<7) -/** Application (socks) requests. */ -#define LD_APP (1u<<8) -/** Communication via the controller protocol. */ -#define LD_CONTROL (1u<<9) -/** Building, using, and managing circuits. */ -#define LD_CIRC (1u<<10) -/** Hidden services. */ -#define LD_REND (1u<<11) -/** Internal errors in this Tor process. */ -#define LD_BUG (1u<<12) -/** Learning and using information about Tor servers. */ -#define LD_DIR (1u<<13) -/** Learning and using information about Tor servers. */ -#define LD_DIRSERV (1u<<14) -/** Onion routing protocol. */ -#define LD_OR (1u<<15) -/** Generic edge-connection functionality. */ -#define LD_EDGE (1u<<16) -#define LD_EXIT LD_EDGE -/** Bandwidth accounting. */ -#define LD_ACCT (1u<<17) -/** Router history */ -#define LD_HIST (1u<<18) -/** OR handshaking */ -#define LD_HANDSHAKE (1u<<19) -/** Heartbeat messages */ -#define LD_HEARTBEAT (1u<<20) -/** Abstract channel_t code */ -#define LD_CHANNEL (1u<<21) -/** Scheduler */ -#define LD_SCHED (1u<<22) -/** Guard nodes */ -#define LD_GUARD (1u<<23) -/** Generation and application of consensus diffs. */ -#define LD_CONSDIFF (1u<<24) -/** Denial of Service mitigation. */ -#define LD_DOS (1u<<25) -/** Number of logging domains in the code. */ -#define N_LOGGING_DOMAINS 26 - -/** This log message is not safe to send to a callback-based logger - * immediately. Used as a flag, not a log domain. */ -#define LD_NOCB (1u<<31) -/** This log message should not include a function name, even if it otherwise - * would. Used as a flag, not a log domain. */ -#define LD_NOFUNCNAME (1u<<30) - -#ifdef TOR_UNIT_TESTS -/** This log message should not be intercepted by mock_saving_logv */ -#define LD_NO_MOCK (1u<<29) -#endif - -/** Mask of zero or more log domains, OR'd together. */ -typedef uint32_t log_domain_mask_t; - -/** Configures which severities are logged for each logging domain for a given - * log target. */ -typedef struct log_severity_list_t { - /** For each log severity, a bitmask of which domains a given logger is - * logging. */ - log_domain_mask_t masks[LOG_DEBUG-LOG_ERR+1]; -} log_severity_list_t; - -/** Callback type used for add_callback_log. */ -typedef void (*log_callback)(int severity, uint32_t domain, const char *msg); - -void init_logging(int disable_startup_queue); -int parse_log_level(const char *level); -const char *log_level_to_string(int level); -int parse_log_severity_config(const char **cfg, - log_severity_list_t *severity_out); -void set_log_severity_config(int minSeverity, int maxSeverity, - log_severity_list_t *severity_out); -void add_stream_log(const log_severity_list_t *severity, const char *name, - int fd); -int add_file_log(const log_severity_list_t *severity, - const char *filename, - int fd); - -#ifdef HAVE_SYSLOG_H -int add_syslog_log(const log_severity_list_t *severity, - const char* syslog_identity_tag); -#endif // HAVE_SYSLOG_H. -#ifdef HAVE_ANDROID_LOG_H -int add_android_log(const log_severity_list_t *severity, - const char *android_identity_tag); -#endif // HAVE_ANDROID_LOG_H. -int add_callback_log(const log_severity_list_t *severity, log_callback cb); -typedef void (*pending_callback_callback)(void); -void logs_set_pending_callback_callback(pending_callback_callback cb); -void logs_set_domain_logging(int enabled); -int get_min_log_level(void); -void switch_logs_debug(void); -void logs_free_all(void); -void add_temp_log(int min_severity); -void close_temp_logs(void); -void rollback_log_changes(void); -void mark_logs_temp(void); -void change_callback_log_severity(int loglevelMin, int loglevelMax, - log_callback cb); -void flush_pending_log_callbacks(void); -void flush_log_messages_from_startup(void); -void log_set_application_name(const char *name); -void set_log_time_granularity(int granularity_msec); -void truncate_logs(void); - -void tor_log(int severity, log_domain_mask_t domain, const char *format, ...) - CHECK_PRINTF(3,4); - -void tor_log_update_sigsafe_err_fds(void); - -struct smartlist_t; -void tor_log_get_logfile_names(struct smartlist_t *out); - -extern int log_global_min_severity_; - -void log_fn_(int severity, log_domain_mask_t domain, - const char *funcname, const char *format, ...) - CHECK_PRINTF(4,5); -struct ratelim_t; -void log_fn_ratelim_(struct ratelim_t *ratelim, int severity, - log_domain_mask_t domain, const char *funcname, - const char *format, ...) - CHECK_PRINTF(5,6); - -int log_message_is_interesting(int severity, log_domain_mask_t domain); -void tor_log_string(int severity, log_domain_mask_t domain, - const char *function, const char *string); - -#if defined(__GNUC__) && __GNUC__ <= 3 - -/* These are the GCC varidaic macros, so that older versions of GCC don't - * break. */ - -/** Log a message at level severity, using a pretty-printed version - * of the current function name. */ -#define log_fn(severity, domain, args...) \ - log_fn_(severity, domain, __FUNCTION__, args) -/** As log_fn, but use ratelim (an instance of ratelim_t) to control - * the frequency at which messages can appear. - */ -#define log_fn_ratelim(ratelim, severity, domain, args...) \ - log_fn_ratelim_(ratelim, severity, domain, __FUNCTION__, args) -#define log_debug(domain, args...) \ - STMT_BEGIN \ - if (PREDICT_UNLIKELY(log_global_min_severity_ == LOG_DEBUG)) \ - log_fn_(LOG_DEBUG, domain, __FUNCTION__, args); \ - STMT_END -#define log_info(domain, args...) \ - log_fn_(LOG_INFO, domain, __FUNCTION__, args) -#define log_notice(domain, args...) \ - log_fn_(LOG_NOTICE, domain, __FUNCTION__, args) -#define log_warn(domain, args...) \ - log_fn_(LOG_WARN, domain, __FUNCTION__, args) -#define log_err(domain, args...) \ - log_fn_(LOG_ERR, domain, __FUNCTION__, args) - -#else /* !(defined(__GNUC__) && __GNUC__ <= 3) */ - -/* Here are the c99 variadic macros, to work with non-GCC compilers */ - -#define log_debug(domain, args, ...) \ - STMT_BEGIN \ - if (PREDICT_UNLIKELY(log_global_min_severity_ == LOG_DEBUG)) \ - log_fn_(LOG_DEBUG, domain, __FUNCTION__, args, ##__VA_ARGS__); \ - STMT_END -#define log_info(domain, args,...) \ - log_fn_(LOG_INFO, domain, __FUNCTION__, args, ##__VA_ARGS__) -#define log_notice(domain, args,...) \ - log_fn_(LOG_NOTICE, domain, __FUNCTION__, args, ##__VA_ARGS__) -#define log_warn(domain, args,...) \ - log_fn_(LOG_WARN, domain, __FUNCTION__, args, ##__VA_ARGS__) -#define log_err(domain, args,...) \ - log_fn_(LOG_ERR, domain, __FUNCTION__, args, ##__VA_ARGS__) -/** Log a message at level severity, using a pretty-printed version - * of the current function name. */ -#define log_fn(severity, domain, args,...) \ - log_fn_(severity, domain, __FUNCTION__, args, ##__VA_ARGS__) -/** As log_fn, but use ratelim (an instance of ratelim_t) to control - * the frequency at which messages can appear. - */ -#define log_fn_ratelim(ratelim, severity, domain, args,...) \ - log_fn_ratelim_(ratelim, severity, domain, __FUNCTION__, \ - args, ##__VA_ARGS__) -#endif /* defined(__GNUC__) && __GNUC__ <= 3 */ - -/** This defines log levels that are linked in the Rust log module, rather - * than re-defining these in both Rust and C. - * - * C_RUST_COUPLED src/rust/tor_log LogSeverity, LogDomain - */ -extern const int LOG_WARN_; -extern const int LOG_NOTICE_; -extern const log_domain_mask_t LD_NET_; -extern const log_domain_mask_t LD_GENERAL_; - -#ifdef LOG_PRIVATE -MOCK_DECL(STATIC void, logv, (int severity, log_domain_mask_t domain, - const char *funcname, const char *suffix, const char *format, - va_list ap) CHECK_PRINTF(5,0)); -#endif - -# define TOR_TORLOG_H -#endif /* !defined(TOR_TORLOG_H) */ diff --git a/src/lib/log/util_bug.c b/src/lib/log/util_bug.c index e3c8df0d64..42b3670a71 100644 --- a/src/lib/log/util_bug.c +++ b/src/lib/log/util_bug.c @@ -9,7 +9,7 @@ #include "orconfig.h" #include "lib/log/util_bug.h" -#include "lib/log/torlog.h" +#include "lib/log/log.h" #include "lib/err/backtrace.h" #ifdef TOR_UNIT_TESTS #include "lib/smartlist_core/smartlist_core.h" diff --git a/src/lib/log/util_bug.h b/src/lib/log/util_bug.h index a0753c807b..61ee60f729 100644 --- a/src/lib/log/util_bug.h +++ b/src/lib/log/util_bug.h @@ -38,7 +38,7 @@ #include "orconfig.h" #include "lib/cc/compat_compiler.h" -#include "lib/log/torlog.h" +#include "lib/log/log.h" #include "lib/testsupport/testsupport.h" /* Replace assert() with a variant that sends failures to the log before diff --git a/src/lib/memarea/memarea.c b/src/lib/memarea/memarea.c index 3a93d89ee2..dd7c48c079 100644 --- a/src/lib/memarea/memarea.c +++ b/src/lib/memarea/memarea.c @@ -17,7 +17,7 @@ #include "lib/arch/bytes.h" #include "lib/cc/torint.h" #include "lib/container/smartlist.h" -#include "lib/log/torlog.h" +#include "lib/log/log.h" #include "lib/log/util_bug.h" #include "lib/malloc/malloc.h" diff --git a/src/lib/meminfo/meminfo.c b/src/lib/meminfo/meminfo.c index 01080367fa..648f54e0c5 100644 --- a/src/lib/meminfo/meminfo.c +++ b/src/lib/meminfo/meminfo.c @@ -15,7 +15,7 @@ #include "lib/cc/compat_compiler.h" #include "lib/cc/torint.h" #include "lib/fs/files.h" -#include "lib/log/torlog.h" +#include "lib/log/log.h" #include "lib/malloc/malloc.h" #ifdef HAVE_SYS_SYSCTL_H diff --git a/src/lib/net/address.c b/src/lib/net/address.c index ca0c2a46c4..619fa13e9b 100644 --- a/src/lib/net/address.c +++ b/src/lib/net/address.c @@ -42,7 +42,7 @@ #include "lib/net/socket.h" #include "lib/container/smartlist.h" #include "lib/ctime/di_ops.h" -#include "lib/log/torlog.h" +#include "lib/log/log.h" #include "lib/log/escape.h" #include "lib/malloc/malloc.h" #include "lib/net/inaddr.h" diff --git a/src/lib/net/buffers_net.c b/src/lib/net/buffers_net.c index 2e6a096a06..c52ea2784e 100644 --- a/src/lib/net/buffers_net.c +++ b/src/lib/net/buffers_net.c @@ -12,7 +12,7 @@ #define BUFFERS_PRIVATE #include "lib/net/buffers_net.h" #include "lib/container/buffers.h" -#include "lib/log/torlog.h" +#include "lib/log/log.h" #include "lib/log/util_bug.h" #include "lib/net/nettypes.h" diff --git a/src/lib/net/socket.c b/src/lib/net/socket.c index 1b3238d998..5847bb8734 100644 --- a/src/lib/net/socket.c +++ b/src/lib/net/socket.c @@ -15,7 +15,7 @@ #include "lib/cc/compat_compiler.h" #include "lib/err/torerr.h" #include "lib/lock/compat_mutex.h" -#include "lib/log/torlog.h" +#include "lib/log/log.h" #include "lib/log/util_bug.h" #ifdef _WIN32 diff --git a/src/lib/process/daemon.c b/src/lib/process/daemon.c index 6863d05d7e..671579838e 100644 --- a/src/lib/process/daemon.c +++ b/src/lib/process/daemon.c @@ -14,7 +14,7 @@ #ifndef _WIN32 #include "lib/fs/files.h" -#include "lib/log/torlog.h" +#include "lib/log/log.h" #include "lib/thread/threads.h" #ifdef HAVE_SYS_TYPES_H diff --git a/src/lib/process/env.c b/src/lib/process/env.c index 5b959d05f8..dc0b63b499 100644 --- a/src/lib/process/env.c +++ b/src/lib/process/env.c @@ -15,7 +15,7 @@ #include "lib/ctime/di_ops.h" #include "lib/container/smartlist.h" #include "lib/log/util_bug.h" -#include "lib/log/torlog.h" +#include "lib/log/log.h" #include "lib/malloc/malloc.h" #ifdef HAVE_UNISTD_H diff --git a/src/lib/process/pidfile.c b/src/lib/process/pidfile.c index 17ff8be600..ea008168ab 100644 --- a/src/lib/process/pidfile.c +++ b/src/lib/process/pidfile.c @@ -11,7 +11,7 @@ #include "orconfig.h" #include "lib/process/pidfile.h" -#include "lib/log/torlog.h" +#include "lib/log/log.h" #ifdef HAVE_SYS_TYPES_H #include diff --git a/src/lib/process/restrict.c b/src/lib/process/restrict.c index fc1a308806..bca325e5bc 100644 --- a/src/lib/process/restrict.c +++ b/src/lib/process/restrict.c @@ -11,7 +11,7 @@ #include "orconfig.h" #include "lib/process/restrict.h" #include "lib/intmath/cmp.h" -#include "lib/log/torlog.h" +#include "lib/log/log.h" #include "lib/log/util_bug.h" #include "lib/net/socket.h" diff --git a/src/lib/process/setuid.c b/src/lib/process/setuid.c index 13b352dad0..d038039ff4 100644 --- a/src/lib/process/setuid.c +++ b/src/lib/process/setuid.c @@ -17,7 +17,7 @@ #include "lib/container/smartlist.h" #include "lib/fs/userdb.h" -#include "lib/log/torlog.h" +#include "lib/log/log.h" #include "lib/log/util_bug.h" #include "lib/malloc/malloc.h" diff --git a/src/lib/process/subprocess.c b/src/lib/process/subprocess.c index d2bbb61c34..70851c15e0 100644 --- a/src/lib/process/subprocess.c +++ b/src/lib/process/subprocess.c @@ -13,7 +13,7 @@ #include "lib/container/smartlist.h" #include "lib/err/torerr.h" -#include "lib/log/torlog.h" +#include "lib/log/log.h" #include "lib/log/util_bug.h" #include "lib/log/win32err.h" #include "lib/malloc/malloc.h" diff --git a/src/lib/process/waitpid.c b/src/lib/process/waitpid.c index b829cb1b09..32ba4530da 100644 --- a/src/lib/process/waitpid.c +++ b/src/lib/process/waitpid.c @@ -13,7 +13,7 @@ #ifndef _WIN32 #include "lib/process/waitpid.h" -#include "lib/log/torlog.h" +#include "lib/log/log.h" #include "lib/log/util_bug.h" #include "lib/malloc/malloc.h" #include "ht.h" diff --git a/src/lib/sandbox/sandbox.c b/src/lib/sandbox/sandbox.c index 7768bee06e..5510754327 100644 --- a/src/lib/sandbox/sandbox.c +++ b/src/lib/sandbox/sandbox.c @@ -36,7 +36,7 @@ #include "lib/sandbox/sandbox.h" #include "lib/container/map.h" #include "lib/err/torerr.h" -#include "lib/log/torlog.h" +#include "lib/log/log.h" #include "lib/cc/torint.h" #include "lib/net/resolve.h" #include "lib/malloc/malloc.h" diff --git a/src/lib/thread/compat_pthreads.c b/src/lib/thread/compat_pthreads.c index 246c6254bb..934067e4c1 100644 --- a/src/lib/thread/compat_pthreads.c +++ b/src/lib/thread/compat_pthreads.c @@ -12,7 +12,7 @@ #include "orconfig.h" #include "lib/thread/threads.h" -#include "lib/log/torlog.h" +#include "lib/log/log.h" #include "lib/log/util_bug.h" #include diff --git a/src/lib/thread/compat_threads.c b/src/lib/thread/compat_threads.c index 972960e242..24129946b2 100644 --- a/src/lib/thread/compat_threads.c +++ b/src/lib/thread/compat_threads.c @@ -15,7 +15,7 @@ #include #include "lib/thread/threads.h" -#include "lib/log/torlog.h" +#include "lib/log/log.h" #include "lib/log/util_bug.h" #include diff --git a/src/lib/thread/compat_winthreads.c b/src/lib/thread/compat_winthreads.c index 7f9877d21e..799eeda1b4 100644 --- a/src/lib/thread/compat_winthreads.c +++ b/src/lib/thread/compat_winthreads.c @@ -15,7 +15,7 @@ #include #include #include "lib/thread/threads.h" -#include "lib/log/torlog.h" +#include "lib/log/log.h" #include "lib/log/util_bug.h" #include "lib/log/win32err.h" diff --git a/src/lib/thread/numcpus.c b/src/lib/thread/numcpus.c index b8763f118f..cca15eb7aa 100644 --- a/src/lib/thread/numcpus.c +++ b/src/lib/thread/numcpus.c @@ -10,7 +10,7 @@ #include "orconfig.h" #include "lib/thread/numcpus.h" -#include "lib/log/torlog.h" +#include "lib/log/log.h" #include "lib/log/util_bug.h" #ifdef HAVE_UNISTD_H diff --git a/src/lib/time/compat_time.c b/src/lib/time/compat_time.c index 2ea6eca988..d26cb6880d 100644 --- a/src/lib/time/compat_time.c +++ b/src/lib/time/compat_time.c @@ -13,7 +13,7 @@ #include "lib/time/compat_time.h" #include "lib/err/torerr.h" -#include "lib/log/torlog.h" +#include "lib/log/log.h" #include "lib/log/util_bug.h" #include "lib/intmath/muldiv.h" #include "lib/intmath/bits.h" diff --git a/src/lib/time/tvdiff.c b/src/lib/time/tvdiff.c index 6af12501c7..8617110e52 100644 --- a/src/lib/time/tvdiff.c +++ b/src/lib/time/tvdiff.c @@ -11,7 +11,7 @@ #include "lib/time/tvdiff.h" #include "lib/cc/compat_compiler.h" -#include "lib/log/torlog.h" +#include "lib/log/log.h" #ifdef _WIN32 #include diff --git a/src/lib/tls/buffers_tls.c b/src/lib/tls/buffers_tls.c index 0e112b59cf..69ae4f7fc0 100644 --- a/src/lib/tls/buffers_tls.c +++ b/src/lib/tls/buffers_tls.c @@ -15,7 +15,7 @@ #include "lib/container/buffers.h" #include "lib/tls/buffers_tls.h" #include "lib/cc/torint.h" -#include "lib/log/torlog.h" +#include "lib/log/log.h" #include "lib/log/util_bug.h" #include "lib/tls/tortls.h" diff --git a/src/lib/tls/tortls.c b/src/lib/tls/tortls.c index 1cd22a7eba..073cae02ba 100644 --- a/src/lib/tls/tortls.c +++ b/src/lib/tls/tortls.c @@ -52,7 +52,7 @@ ENABLE_GCC_WARNING(redundant-decls) #define TORTLS_PRIVATE #include "lib/tls/tortls.h" -#include "lib/log/torlog.h" +#include "lib/log/log.h" #include "lib/log/util_bug.h" #include "lib/container/smartlist.h" #include "lib/string/compat_string.h" diff --git a/src/lib/trace/debug.h b/src/lib/trace/debug.h index a764f552ea..191d94226d 100644 --- a/src/lib/trace/debug.h +++ b/src/lib/trace/debug.h @@ -9,7 +9,7 @@ #ifndef TOR_TRACE_LOG_DEBUG_H #define TOR_TRACE_LOG_DEBUG_H -#include "lib/log/torlog.h" +#include "lib/log/log.h" /* Stringify pre-processor trick. */ #define XSTR(d) STR(d) -- cgit v1.2.3-54-g00ecf