log.c (43069B)
1 /* Copyright (c) 2001, Matej Pfajfar. 2 * Copyright (c) 2001-2004, Roger Dingledine. 3 * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. 4 * Copyright (c) 2007-2021, The Tor Project, Inc. */ 5 /* See LICENSE for licensing information */ 6 7 /** 8 * \file log.c 9 * \brief Functions to send messages to log files or the console. 10 **/ 11 12 #include "orconfig.h" 13 #include <stdarg.h> 14 #include <stdio.h> 15 #include <stdlib.h> 16 #include <string.h> 17 #ifdef HAVE_SYS_TIME_H 18 #include <sys/time.h> 19 #endif 20 #ifdef HAVE_TIME_H 21 #include <time.h> 22 #endif 23 #ifdef HAVE_UNISTD_H 24 #include <unistd.h> 25 #endif 26 #ifdef HAVE_SYS_TYPES_H 27 #include <sys/types.h> 28 #endif 29 #ifdef HAVE_FCNTL_H 30 #include <fcntl.h> 31 #endif 32 33 #define LOG_PRIVATE 34 #include "lib/log/log.h" 35 #include "lib/log/log_sys.h" 36 #include "lib/log/util_bug.h" 37 #include "lib/version/git_revision.h" 38 #include "lib/log/ratelim.h" 39 #include "lib/lock/compat_mutex.h" 40 #include "lib/smartlist_core/smartlist_core.h" 41 #include "lib/smartlist_core/smartlist_foreach.h" 42 #include "lib/smartlist_core/smartlist_split.h" 43 #include "lib/err/torerr.h" 44 #include "lib/intmath/bits.h" 45 #include "lib/string/compat_string.h" 46 #include "lib/string/printf.h" 47 #include "lib/malloc/malloc.h" 48 #include "lib/string/util_string.h" 49 #include "lib/wallclock/tor_gettimeofday.h" 50 #include "lib/wallclock/approx_time.h" 51 #include "lib/wallclock/time_to_tm.h" 52 #include "lib/fdio/fdio.h" 53 #include "lib/cc/ctassert.h" 54 55 /** @{ */ 56 /** The string we stick at the end of a log message when it is too long, 57 * and its length. */ 58 #define TRUNCATED_STR "[...truncated]" 59 #define TRUNCATED_STR_LEN 14 60 /** @} */ 61 62 /** Defining compile-time constants for Tor log levels (used by the Rust 63 * log wrapper at src/rust/tor_log) */ 64 const int LOG_WARN_ = LOG_WARN; 65 const int LOG_NOTICE_ = LOG_NOTICE; 66 const log_domain_mask_t LD_GENERAL_ = LD_GENERAL; 67 const log_domain_mask_t LD_NET_ = LD_NET; 68 69 /** Information for a single logfile; only used in log.c */ 70 typedef struct logfile_t { 71 struct logfile_t *next; /**< Next logfile_t in the linked list. */ 72 char *filename; /**< Filename to open. */ 73 int fd; /**< fd to receive log messages, or -1 for none. */ 74 int seems_dead; /**< Boolean: true if the stream seems to be kaput. */ 75 int needs_close; /**< Boolean: true if the stream gets closed on shutdown. */ 76 int is_temporary; /**< Boolean: close after initializing logging subsystem.*/ 77 int is_syslog; /**< Boolean: send messages to syslog. */ 78 log_callback callback; /**< If not NULL, send messages to this function. */ 79 log_severity_list_t *severities; /**< Which severity of messages should we 80 * log for each log domain? */ 81 } logfile_t; 82 83 static void log_free_(logfile_t *victim); 84 #define log_free(lg) \ 85 FREE_AND_NULL(logfile_t, log_free_, (lg)) 86 87 /** Helper: map a log severity to descriptive string. */ 88 static inline const char * 89 sev_to_string(int severity) 90 { 91 switch (severity) { 92 case LOG_DEBUG: return "debug"; 93 case LOG_INFO: return "info"; 94 case LOG_NOTICE: return "notice"; 95 case LOG_WARN: return "warn"; 96 case LOG_ERR: return "err"; 97 default: /* Call raw_assert, not tor_assert, since tor_assert 98 * calls log on failure. */ 99 raw_assert_unreached(); return "UNKNOWN"; // LCOV_EXCL_LINE 100 } 101 } 102 103 /** Helper: decide whether to include the function name in the log message. */ 104 static inline int 105 should_log_function_name(log_domain_mask_t domain, int severity) 106 { 107 switch (severity) { 108 case LOG_DEBUG: 109 case LOG_INFO: 110 /* All debugging messages occur in interesting places. */ 111 return (domain & LD_NOFUNCNAME) == 0; 112 case LOG_NOTICE: 113 case LOG_WARN: 114 case LOG_ERR: 115 /* We care about places where bugs occur. */ 116 return (domain & (LD_BUG|LD_NOFUNCNAME)) == LD_BUG; 117 default: 118 /* Call raw_assert, not tor_assert, since tor_assert calls 119 * log on failure. */ 120 raw_assert(0); return 0; // LCOV_EXCL_LINE 121 } 122 } 123 124 /** A mutex to guard changes to logfiles and logging. */ 125 static tor_mutex_t log_mutex; 126 /** True iff we have initialized log_mutex */ 127 static int log_mutex_initialized = 0; 128 129 /** Linked list of logfile_t. */ 130 static logfile_t *logfiles = NULL; 131 /** Boolean: do we report logging domains? */ 132 static int log_domains_are_logged = 0; 133 134 #ifdef HAVE_SYSLOG_H 135 /** The number of open syslog log handlers that we have. When this reaches 0, 136 * we can close our connection to the syslog facility. */ 137 static int syslog_count = 0; 138 #endif 139 140 /** Represents a log message that we are going to send to callback-driven 141 * loggers once we can do so in a non-reentrant way. */ 142 typedef struct pending_log_message_t { 143 int severity; /**< The severity of the message */ 144 log_domain_mask_t domain; /**< The domain of the message */ 145 char *fullmsg; /**< The message, with all decorations */ 146 char *msg; /**< The content of the message */ 147 } pending_log_message_t; 148 149 /** Log messages waiting to be replayed onto callback-based logs */ 150 static smartlist_t *pending_cb_messages = NULL; 151 152 /** Callback to invoke when pending_cb_messages becomes nonempty. */ 153 static pending_callback_callback pending_cb_cb = NULL; 154 155 /** Log messages waiting to be replayed once the logging system is initialized. 156 */ 157 static smartlist_t *pending_startup_messages = NULL; 158 159 /** Number of bytes of messages queued in pending_startup_messages. (This is 160 * the length of the messages, not the number of bytes used to store 161 * them.) */ 162 static size_t pending_startup_messages_len; 163 164 /** True iff we should store messages while waiting for the logs to get 165 * configured. */ 166 static int queue_startup_messages = 1; 167 168 /** True iff __PRETTY_FUNCTION__ includes parenthesized arguments. */ 169 static int pretty_fn_has_parens = 0; 170 171 /** Don't store more than this many bytes of messages while waiting for the 172 * logs to get configured. */ 173 #define MAX_STARTUP_MSG_LEN (1<<16) 174 175 /** Lock the log_mutex to prevent others from changing the logfile_t list */ 176 #define LOCK_LOGS() STMT_BEGIN \ 177 raw_assert(log_mutex_initialized); \ 178 tor_mutex_acquire(&log_mutex); \ 179 STMT_END 180 /** Unlock the log_mutex */ 181 #define UNLOCK_LOGS() STMT_BEGIN \ 182 raw_assert(log_mutex_initialized); \ 183 tor_mutex_release(&log_mutex); \ 184 STMT_END 185 186 /** What's the lowest log level anybody cares about? Checking this lets us 187 * bail out early from log_debug if we aren't debugging. */ 188 int log_global_min_severity_ = LOG_NOTICE; 189 190 static void delete_log(logfile_t *victim); 191 static void close_log(logfile_t *victim); 192 static void close_log_sigsafe(logfile_t *victim); 193 194 static char *domain_to_string(log_domain_mask_t domain, 195 char *buf, size_t buflen); 196 static inline char *format_msg(char *buf, size_t buf_len, 197 log_domain_mask_t domain, int severity, const char *funcname, 198 const char *suffix, 199 const char *format, va_list ap, size_t *msg_len_out) 200 CHECK_PRINTF(7,0); 201 202 /** Name of the application: used to generate the message we write at the 203 * start of each new log. */ 204 static char *appname = NULL; 205 206 /** Set the "application name" for the logs to <b>name</b>: we'll use this 207 * name in the message we write when starting up, and at the start of each new 208 * log. 209 * 210 * Tor uses this string to write the version number to the log file. */ 211 void 212 log_set_application_name(const char *name) 213 { 214 tor_free(appname); 215 appname = name ? tor_strdup(name) : NULL; 216 } 217 218 /** Return true if some of the running logs might be interested in a log 219 * message of the given severity in the given domains. If this function 220 * returns true, the log message might be ignored anyway, but if it returns 221 * false, it is definitely_ safe not to log the message. */ 222 int 223 log_message_is_interesting(int severity, log_domain_mask_t domain) 224 { 225 (void) domain; 226 return (severity <= log_global_min_severity_); 227 } 228 229 /** 230 * As tor_log, but takes an optional function name, and does not treat its 231 * <b>string</b> as a printf format. 232 * 233 * For use by Rust integration. 234 */ 235 void 236 tor_log_string(int severity, log_domain_mask_t domain, 237 const char *function, const char *string) 238 { 239 log_fn_(severity, domain, function, "%s", string); 240 } 241 242 /** Log time granularity in milliseconds. */ 243 static int log_time_granularity = 1; 244 245 /** Define log time granularity for all logs to be <b>granularity_msec</b> 246 * milliseconds. */ 247 MOCK_IMPL(void, 248 set_log_time_granularity,(int granularity_msec)) 249 { 250 log_time_granularity = granularity_msec; 251 tor_log_sigsafe_err_set_granularity(granularity_msec); 252 } 253 254 /** Helper: Write the standard prefix for log lines to a 255 * <b>buf_len</b> character buffer in <b>buf</b>. 256 */ 257 static inline size_t 258 log_prefix_(char *buf, size_t buf_len, int severity) 259 { 260 time_t t; 261 struct timeval now; 262 struct tm tm; 263 size_t n; 264 int r, ms; 265 266 tor_gettimeofday(&now); 267 t = (time_t)now.tv_sec; 268 ms = (int)now.tv_usec / 1000; 269 if (log_time_granularity >= 1000) { 270 t -= t % (log_time_granularity / 1000); 271 ms = 0; 272 } else { 273 ms -= ((int)now.tv_usec / 1000) % log_time_granularity; 274 } 275 276 n = strftime(buf, buf_len, "%b %d %H:%M:%S", 277 tor_localtime_r_msg(&t, &tm, NULL)); 278 r = tor_snprintf(buf+n, buf_len-n, ".%.3i [%s] ", ms, 279 sev_to_string(severity)); 280 281 if (r<0) 282 return buf_len-1; 283 else 284 return n+r; 285 } 286 287 /** If lf refers to an actual file that we have just opened, and the file 288 * contains no data, log an "opening new logfile" message at the top. 289 * 290 * Return -1 if the log is broken and needs to be deleted, else return 0. 291 */ 292 static int 293 log_tor_version(logfile_t *lf, int reset) 294 { 295 char buf[256]; 296 size_t n; 297 int is_new; 298 299 if (!lf->needs_close) 300 /* If it doesn't get closed, it isn't really a file. */ 301 return 0; 302 if (lf->is_temporary) 303 /* If it's temporary, it isn't really a file. */ 304 return 0; 305 306 is_new = lf->fd >= 0 && tor_fd_getpos(lf->fd) == 0; 307 308 if (reset && !is_new) 309 /* We are resetting, but we aren't at the start of the file; no 310 * need to log again. */ 311 return 0; 312 n = log_prefix_(buf, sizeof(buf), LOG_NOTICE); 313 if (appname) { 314 tor_snprintf(buf+n, sizeof(buf)-n, 315 "%s opening %slog file.\n", appname, is_new?"new ":""); 316 } else { 317 tor_snprintf(buf+n, sizeof(buf)-n, 318 "Tor %s opening %slog file.\n", VERSION, is_new?"new ":""); 319 } 320 if (write_all_to_fd_minimal(lf->fd, buf, strlen(buf)) < 0) /* error */ 321 return -1; /* failed */ 322 return 0; 323 } 324 325 /** Helper: Format a log message into a fixed-sized buffer. (This is 326 * factored out of <b>logv</b> so that we never format a message more 327 * than once.) Return a pointer to the first character of the message 328 * portion of the formatted string. 329 */ 330 static inline char * 331 format_msg(char *buf, size_t buf_len, 332 log_domain_mask_t domain, int severity, const char *funcname, 333 const char *suffix, 334 const char *format, va_list ap, size_t *msg_len_out) 335 { 336 size_t n; 337 int r; 338 char *end_of_prefix; 339 char *buf_end; 340 341 raw_assert(buf_len >= 16); /* prevent integer underflow and stupidity */ 342 buf_len -= 2; /* subtract 2 characters so we have room for \n\0 */ 343 buf_end = buf+buf_len; /* point *after* the last char we can write to */ 344 345 n = log_prefix_(buf, buf_len, severity); 346 end_of_prefix = buf+n; 347 348 if (log_domains_are_logged) { 349 char *cp = buf+n; 350 if (cp == buf_end) goto format_msg_no_room_for_domains; 351 *cp++ = '{'; 352 if (cp == buf_end) goto format_msg_no_room_for_domains; 353 cp = domain_to_string(domain, cp, (buf+buf_len-cp)); 354 if (cp == buf_end) goto format_msg_no_room_for_domains; 355 *cp++ = '}'; 356 if (cp == buf_end) goto format_msg_no_room_for_domains; 357 *cp++ = ' '; 358 if (cp == buf_end) goto format_msg_no_room_for_domains; 359 end_of_prefix = cp; 360 n = cp-buf; 361 format_msg_no_room_for_domains: 362 /* This will leave end_of_prefix and n unchanged, and thus cause 363 * whatever log domain string we had written to be clobbered. */ 364 ; 365 } 366 367 if (funcname && should_log_function_name(domain, severity)) { 368 r = tor_snprintf(buf+n, buf_len-n, 369 pretty_fn_has_parens ? "%s: " : "%s(): ", 370 funcname); 371 if (r<0) 372 n = strlen(buf); 373 else 374 n += r; 375 } 376 377 if (domain == LD_BUG && buf_len-n > 6) { 378 memcpy(buf+n, "Bug: ", 6); 379 n += 5; 380 } 381 382 r = tor_vsnprintf(buf+n,buf_len-n,format,ap); 383 if (r < 0) { 384 /* The message was too long; overwrite the end of the buffer with 385 * "[...truncated]" */ 386 if (buf_len >= TRUNCATED_STR_LEN) { 387 size_t offset = buf_len-TRUNCATED_STR_LEN; 388 /* We have an extra 2 characters after buf_len to hold the \n\0, 389 * so it's safe to add 1 to the size here. */ 390 strlcpy(buf+offset, TRUNCATED_STR, buf_len-offset+1); 391 } 392 /* Set 'n' to the end of the buffer, where we'll be writing \n\0. 393 * Since we already subtracted 2 from buf_len, this is safe.*/ 394 n = buf_len; 395 } else { 396 n += r; 397 if (suffix) { 398 size_t suffix_len = strlen(suffix); 399 if (buf_len-n >= suffix_len) { 400 memcpy(buf+n, suffix, suffix_len); 401 n += suffix_len; 402 } 403 } 404 } 405 406 if (domain == LD_BUG && 407 buf_len - n > strlen(tor_bug_suffix)+1) { 408 memcpy(buf+n, tor_bug_suffix, strlen(tor_bug_suffix)); 409 n += strlen(tor_bug_suffix); 410 } 411 412 buf[n]='\n'; 413 buf[n+1]='\0'; 414 *msg_len_out = n+1; 415 return end_of_prefix; 416 } 417 418 /* Create a new pending_log_message_t with appropriate values */ 419 static pending_log_message_t * 420 pending_log_message_new(int severity, log_domain_mask_t domain, 421 const char *fullmsg, const char *shortmsg) 422 { 423 pending_log_message_t *m = tor_malloc(sizeof(pending_log_message_t)); 424 m->severity = severity; 425 m->domain = domain; 426 m->fullmsg = fullmsg ? tor_strdup(fullmsg) : NULL; 427 m->msg = tor_strdup(shortmsg); 428 return m; 429 } 430 431 #define pending_log_message_free(msg) \ 432 FREE_AND_NULL(pending_log_message_t, pending_log_message_free_, (msg)) 433 434 /** Release all storage held by <b>msg</b>. */ 435 static void 436 pending_log_message_free_(pending_log_message_t *msg) 437 { 438 if (!msg) 439 return; 440 tor_free(msg->msg); 441 tor_free(msg->fullmsg); 442 tor_free(msg); 443 } 444 445 /** Helper function: returns true iff the log file, given in <b>lf</b>, is 446 * handled externally via the system log API, or is an 447 * external callback function. */ 448 static inline int 449 logfile_is_external(const logfile_t *lf) 450 { 451 raw_assert(lf); 452 return lf->is_syslog || lf->callback; 453 } 454 455 /** Return true iff <b>lf</b> would like to receive a message with the 456 * specified <b>severity</b> in the specified <b>domain</b>. 457 */ 458 static inline int 459 logfile_wants_message(const logfile_t *lf, int severity, 460 log_domain_mask_t domain) 461 { 462 if (! (lf->severities->masks[SEVERITY_MASK_IDX(severity)] & domain)) { 463 return 0; 464 } 465 if (! (lf->fd >= 0 || logfile_is_external(lf))) { 466 return 0; 467 } 468 if (lf->seems_dead) { 469 return 0; 470 } 471 472 return 1; 473 } 474 475 /** Send a message to <b>lf</b>. The full message, with time prefix and 476 * severity, is in <b>buf</b>. The message itself is in 477 * <b>msg_after_prefix</b>. If <b>callbacks_deferred</b> points to true, then 478 * we already deferred this message for pending callbacks and don't need to do 479 * it again. Otherwise, if we need to do it, do it, and set 480 * <b>callbacks_deferred</b> to 1. */ 481 static inline void 482 logfile_deliver(logfile_t *lf, const char *buf, size_t msg_len, 483 const char *msg_after_prefix, log_domain_mask_t domain, 484 int severity, int *callbacks_deferred) 485 { 486 487 if (lf->is_syslog) { 488 #ifdef HAVE_SYSLOG_H 489 #ifdef MAXLINE 490 /* Some syslog implementations have limits on the length of what you can 491 * pass them, and some very old ones do not detect overflow so well. 492 * Regrettably, they call their maximum line length MAXLINE. */ 493 #if MAXLINE < 64 494 #warning "MAXLINE is very low; it might not be from syslog.h." 495 #endif 496 char *m = msg_after_prefix; 497 if (msg_len >= MAXLINE) 498 m = tor_strndup(msg_after_prefix, MAXLINE-1); 499 syslog(severity, "%s", m); 500 if (m != msg_after_prefix) { 501 tor_free(m); 502 } 503 #else /* !defined(MAXLINE) */ 504 /* We have syslog but not MAXLINE. That's promising! */ 505 syslog(severity, "%s", msg_after_prefix); 506 #endif /* defined(MAXLINE) */ 507 #endif /* defined(HAVE_SYSLOG_H) */ 508 } else if (lf->callback) { 509 if (domain & LD_NOCB) { 510 if (!*callbacks_deferred && pending_cb_messages) { 511 smartlist_add(pending_cb_messages, 512 pending_log_message_new(severity,domain,NULL,msg_after_prefix)); 513 *callbacks_deferred = 1; 514 if (smartlist_len(pending_cb_messages) == 1 && pending_cb_cb) { 515 pending_cb_cb(); 516 } 517 } 518 } else { 519 lf->callback(severity, domain, msg_after_prefix); 520 } 521 } else { 522 if (write_all_to_fd_minimal(lf->fd, buf, msg_len) < 0) { /* error */ 523 /* don't log the error! mark this log entry to be blown away, and 524 * continue. */ 525 lf->seems_dead = 1; 526 } 527 } 528 } 529 530 /** Helper: sends a message to the appropriate logfiles, at loglevel 531 * <b>severity</b>. If provided, <b>funcname</b> is prepended to the 532 * message. The actual message is derived as from tor_snprintf(format,ap). 533 */ 534 MOCK_IMPL(STATIC void, 535 logv,(int severity, log_domain_mask_t domain, const char *funcname, 536 const char *suffix, const char *format, va_list ap)) 537 { 538 char buf[10240]; 539 size_t msg_len = 0; 540 int formatted = 0; 541 logfile_t *lf; 542 char *end_of_prefix=NULL; 543 int callbacks_deferred = 0; 544 545 /* Call raw_assert, not tor_assert, since tor_assert calls log on failure. */ 546 raw_assert(format); 547 /* check that severity is sane. Overrunning the masks array leads to 548 * interesting and hard to diagnose effects */ 549 raw_assert(severity >= LOG_ERR && severity <= LOG_DEBUG); 550 551 LOCK_LOGS(); 552 553 if ((! (domain & LD_NOCB)) && pending_cb_messages 554 && smartlist_len(pending_cb_messages)) 555 flush_pending_log_callbacks(); 556 557 if (queue_startup_messages && 558 pending_startup_messages_len < MAX_STARTUP_MSG_LEN) { 559 end_of_prefix = 560 format_msg(buf, sizeof(buf), domain, severity, funcname, suffix, 561 format, ap, &msg_len); 562 formatted = 1; 563 564 smartlist_add(pending_startup_messages, 565 pending_log_message_new(severity,domain,buf,end_of_prefix)); 566 pending_startup_messages_len += msg_len; 567 } 568 569 for (lf = logfiles; lf; lf = lf->next) { 570 if (! logfile_wants_message(lf, severity, domain)) 571 continue; 572 573 if (!formatted) { 574 end_of_prefix = 575 format_msg(buf, sizeof(buf), domain, severity, funcname, suffix, 576 format, ap, &msg_len); 577 formatted = 1; 578 } 579 580 logfile_deliver(lf, buf, msg_len, end_of_prefix, domain, severity, 581 &callbacks_deferred); 582 } 583 UNLOCK_LOGS(); 584 } 585 586 /** Output a message to the log. It gets logged to all logfiles that 587 * care about messages with <b>severity</b> in <b>domain</b>. The content 588 * is formatted printf-style based on <b>format</b> and extra arguments. 589 * */ 590 void 591 tor_log(int severity, log_domain_mask_t domain, const char *format, ...) 592 { 593 va_list ap; 594 595 /* check that domain is composed of known domains and flags */ 596 raw_assert((domain & (LD_ALL_DOMAINS|LD_ALL_FLAGS)) == domain); 597 598 if (severity > log_global_min_severity_) 599 return; 600 va_start(ap,format); 601 #ifdef TOR_UNIT_TESTS 602 if (domain & LD_NO_MOCK) 603 logv__real(severity, domain, NULL, NULL, format, ap); 604 else 605 #endif 606 logv(severity, domain, NULL, NULL, format, ap); 607 va_end(ap); 608 } 609 610 /** Helper function; return true iff the <b>n</b>-element array <b>array</b> 611 * contains <b>item</b>. */ 612 static int 613 int_array_contains(const int *array, int n, int item) 614 { 615 int j; 616 for (j = 0; j < n; ++j) { 617 if (array[j] == item) 618 return 1; 619 } 620 return 0; 621 } 622 623 /** Function to call whenever the list of logs changes to get ready to log 624 * from signal handlers. */ 625 void 626 tor_log_update_sigsafe_err_fds(void) 627 { 628 const logfile_t *lf; 629 int found_real_stderr = 0; 630 631 /* The fds are the file descriptors of tor's stdout, stderr, and file 632 * logs. The log and err modules flush these fds during their shutdowns. */ 633 int fds[TOR_SIGSAFE_LOG_MAX_FDS]; 634 int n_fds; 635 636 LOCK_LOGS(); 637 /* Reserve the first one for stderr. This is safe because when we daemonize, 638 * we dup2 /dev/null to stderr. */ 639 fds[0] = STDERR_FILENO; 640 n_fds = 1; 641 642 for (lf = logfiles; lf; lf = lf->next) { 643 /* Don't try callback to the control port, syslogs, or any 644 * other non-file descriptor log: We can't call arbitrary functions from a 645 * signal handler. 646 */ 647 if (lf->is_temporary || logfile_is_external(lf) 648 || lf->seems_dead || lf->fd < 0) 649 continue; 650 if (lf->severities->masks[SEVERITY_MASK_IDX(LOG_ERR)] & 651 (LD_BUG|LD_GENERAL)) { 652 if (lf->fd == STDERR_FILENO) 653 found_real_stderr = 1; 654 /* Avoid duplicates by checking the log module fd against fds */ 655 if (int_array_contains(fds, n_fds, lf->fd)) 656 continue; 657 /* Update fds using the log module's fd */ 658 fds[n_fds] = lf->fd; 659 n_fds++; 660 if (n_fds == TOR_SIGSAFE_LOG_MAX_FDS) 661 break; 662 } 663 } 664 665 if (!found_real_stderr && 666 int_array_contains(fds, n_fds, STDOUT_FILENO)) { 667 /* Don't use a virtual stderr when we're also logging to stdout. 668 * If we reached max_fds logs, we'll now have (max_fds - 1) logs. 669 * That's ok, max_fds is large enough that most tor instances don't exceed 670 * it. */ 671 raw_assert(n_fds >= 2); /* Don't tor_assert inside log fns */ 672 --n_fds; 673 fds[0] = fds[n_fds]; 674 } 675 676 UNLOCK_LOGS(); 677 678 tor_log_set_sigsafe_err_fds(fds, n_fds); 679 } 680 681 /** Add to <b>out</b> a copy of every currently configured log file name. Used 682 * to enable access to these filenames with the sandbox code. */ 683 void 684 tor_log_get_logfile_names(smartlist_t *out) 685 { 686 logfile_t *lf; 687 raw_assert(out); 688 689 LOCK_LOGS(); 690 691 for (lf = logfiles; lf; lf = lf->next) { 692 if (lf->is_temporary || logfile_is_external(lf)) 693 continue; 694 if (lf->filename == NULL) 695 continue; 696 smartlist_add_strdup(out, lf->filename); 697 } 698 699 UNLOCK_LOGS(); 700 } 701 702 /** Implementation of the log_fn backend, used when we have 703 * variadic macros. All arguments are as for log_fn, except for 704 * <b>fn</b>, which is the name of the calling function. */ 705 void 706 log_fn_(int severity, log_domain_mask_t domain, const char *fn, 707 const char *format, ...) 708 { 709 va_list ap; 710 if ((domain & LD_BUG) && (severity >= LOG_WARN)) 711 tor_bug_increment_count_(); 712 if (severity > log_global_min_severity_) 713 return; 714 va_start(ap,format); 715 logv(severity, domain, fn, NULL, format, ap); 716 va_end(ap); 717 } 718 void 719 log_fn_ratelim_(ratelim_t *ratelim, int severity, log_domain_mask_t domain, 720 const char *fn, const char *format, ...) 721 { 722 va_list ap; 723 char *m; 724 if ((domain & LD_BUG) && (severity >= LOG_WARN)) 725 tor_bug_increment_count_(); 726 if (severity > log_global_min_severity_) 727 return; 728 m = rate_limit_log(ratelim, approx_time()); 729 if (m == NULL) 730 return; 731 va_start(ap, format); 732 logv(severity, domain, fn, m, format, ap); 733 va_end(ap); 734 tor_free(m); 735 } 736 737 /** Free all storage held by <b>victim</b>. */ 738 static void 739 log_free_(logfile_t *victim) 740 { 741 if (!victim) 742 return; 743 tor_free(victim->severities); 744 tor_free(victim->filename); 745 tor_free(victim); 746 } 747 748 /** Close all open log files, and free other static memory. */ 749 void 750 logs_free_all(void) 751 { 752 logfile_t *victim, *next; 753 smartlist_t *messages, *messages2; 754 LOCK_LOGS(); 755 next = logfiles; 756 logfiles = NULL; 757 messages = pending_cb_messages; 758 pending_cb_messages = NULL; 759 pending_cb_cb = NULL; 760 messages2 = pending_startup_messages; 761 pending_startup_messages = NULL; 762 UNLOCK_LOGS(); 763 while (next) { 764 victim = next; 765 next = next->next; 766 close_log(victim); 767 log_free(victim); 768 } 769 tor_free(appname); 770 771 SMARTLIST_FOREACH(messages, pending_log_message_t *, msg, { 772 pending_log_message_free(msg); 773 }); 774 smartlist_free(messages); 775 776 if (messages2) { 777 SMARTLIST_FOREACH(messages2, pending_log_message_t *, msg, { 778 pending_log_message_free(msg); 779 }); 780 smartlist_free(messages2); 781 } 782 783 /* We _could_ destroy the log mutex here, but that would screw up any logs 784 * that happened between here and the end of execution. 785 * If tor is re-initialized, log_mutex_initialized will still be 1. So we 786 * won't trigger any undefined behaviour by trying to re-initialize the 787 * log mutex. */ 788 } 789 790 /** Flush the signal-safe log files. 791 * 792 * This function is safe to call from a signal handler. It is currently called 793 * by the BUG() macros, when terminating the process on an abnormal condition. 794 */ 795 void 796 logs_flush_sigsafe(void) 797 { 798 /* If we don't have fsync() in unistd.h, we can't flush the logs. */ 799 #ifdef HAVE_FSYNC 800 logfile_t *victim, *next; 801 /* We can't LOCK_LOGS() in a signal handler, because it may call 802 * signal-unsafe functions. And we can't deallocate memory, either. */ 803 next = logfiles; 804 logfiles = NULL; 805 while (next) { 806 victim = next; 807 next = next->next; 808 if (victim->needs_close) { 809 /* We can't do anything useful if the flush fails. */ 810 (void)fsync(victim->fd); 811 } 812 } 813 #endif /* defined(HAVE_FSYNC) */ 814 } 815 816 /** Remove and free the log entry <b>victim</b> from the linked-list 817 * logfiles (it is probably present, but it might not be due to thread 818 * racing issues). After this function is called, the caller shouldn't 819 * refer to <b>victim</b> anymore. 820 */ 821 static void 822 delete_log(logfile_t *victim) 823 { 824 logfile_t *tmpl; 825 if (victim == logfiles) 826 logfiles = victim->next; 827 else { 828 for (tmpl = logfiles; tmpl && tmpl->next != victim; tmpl=tmpl->next) ; 829 // raw_assert(tmpl); 830 // raw_assert(tmpl->next == victim); 831 if (!tmpl) 832 return; 833 tmpl->next = victim->next; 834 } 835 log_free(victim); 836 } 837 838 /** Helper: release system resources (but not memory) held by a single 839 * signal-safe logfile_t. If the log's resources can not be released in 840 * a signal handler, does nothing. */ 841 static void 842 close_log_sigsafe(logfile_t *victim) 843 { 844 if (victim->needs_close && victim->fd >= 0) { 845 /* We can't do anything useful here if close() fails: we're shutting 846 * down logging, and the err module only does fatal errors. */ 847 close(victim->fd); 848 victim->fd = -1; 849 } 850 } 851 852 /** Helper: release system resources (but not memory) held by a single 853 * logfile_t. */ 854 static void 855 close_log(logfile_t *victim) 856 { 857 if (victim->needs_close) { 858 close_log_sigsafe(victim); 859 } else if (victim->is_syslog) { 860 #ifdef HAVE_SYSLOG_H 861 if (--syslog_count == 0) { 862 /* There are no other syslogs; close the logging facility. */ 863 closelog(); 864 } 865 #endif /* defined(HAVE_SYSLOG_H) */ 866 } 867 } 868 869 /** Adjust a log severity configuration in <b>severity_out</b> to contain 870 * every domain between <b>loglevelMin</b> and <b>loglevelMax</b>, inclusive. 871 */ 872 void 873 set_log_severity_config(int loglevelMin, int loglevelMax, 874 log_severity_list_t *severity_out) 875 { 876 int i; 877 raw_assert(loglevelMin >= loglevelMax); 878 raw_assert(loglevelMin >= LOG_ERR && loglevelMin <= LOG_DEBUG); 879 raw_assert(loglevelMax >= LOG_ERR && loglevelMax <= LOG_DEBUG); 880 memset(severity_out, 0, sizeof(log_severity_list_t)); 881 for (i = loglevelMin; i >= loglevelMax; --i) { 882 severity_out->masks[SEVERITY_MASK_IDX(i)] = LD_ALL_DOMAINS; 883 } 884 } 885 886 /** Add a log handler named <b>name</b> to send all messages in <b>severity</b> 887 * to <b>fd</b>. Copies <b>severity</b>. Helper: does no locking. */ 888 MOCK_IMPL(STATIC void, 889 add_stream_log_impl,(const log_severity_list_t *severity, 890 const char *name, int fd)) 891 { 892 logfile_t *lf; 893 lf = tor_malloc_zero(sizeof(logfile_t)); 894 lf->fd = fd; 895 lf->filename = tor_strdup(name); 896 lf->severities = tor_memdup(severity, sizeof(log_severity_list_t)); 897 lf->next = logfiles; 898 899 logfiles = lf; 900 log_global_min_severity_ = get_min_log_level(); 901 } 902 903 /** Add a log handler named <b>name</b> to send all messages in <b>severity</b> 904 * to <b>fd</b>. Steals a reference to <b>severity</b>; the caller must 905 * not use it after calling this function. */ 906 void 907 add_stream_log(const log_severity_list_t *severity, const char *name, int fd) 908 { 909 LOCK_LOGS(); 910 add_stream_log_impl(severity, name, fd); 911 UNLOCK_LOGS(); 912 } 913 914 /** Initialize the global logging facility */ 915 void 916 init_logging(int disable_startup_queue) 917 { 918 if (!log_mutex_initialized) { 919 tor_mutex_init(&log_mutex); 920 tor_bug_init_counter(); 921 log_mutex_initialized = 1; 922 } 923 #ifdef __GNUC__ 924 if (strchr(__PRETTY_FUNCTION__, '(')) { 925 pretty_fn_has_parens = 1; 926 } 927 #endif 928 if (pending_cb_messages == NULL) 929 pending_cb_messages = smartlist_new(); 930 if (disable_startup_queue) 931 queue_startup_messages = 0; 932 if (pending_startup_messages == NULL && queue_startup_messages) { 933 pending_startup_messages = smartlist_new(); 934 } 935 } 936 937 /** Set whether we report logging domains as a part of our log messages. 938 */ 939 void 940 logs_set_domain_logging(int enabled) 941 { 942 LOCK_LOGS(); 943 log_domains_are_logged = enabled; 944 UNLOCK_LOGS(); 945 } 946 947 /** Add a log handler to accept messages when no other log is configured. 948 */ 949 void 950 add_default_log(int min_severity) 951 { 952 log_severity_list_t *s = tor_malloc_zero(sizeof(log_severity_list_t)); 953 set_log_severity_config(min_severity, LOG_ERR, s); 954 LOCK_LOGS(); 955 add_stream_log_impl(s, "<default>", fileno(stdout)); 956 tor_free(s); 957 UNLOCK_LOGS(); 958 } 959 960 /** 961 * Register "cb" as the callback to call when there are new pending log 962 * callbacks to be flushed with flush_pending_log_callbacks(). 963 * 964 * Note that this callback, if present, can be invoked from any thread. 965 * 966 * This callback must not log. 967 * 968 * It is intentional that this function contains the name "callback" twice: it 969 * sets a "callback" to be called on the condition that there is a "pending 970 * callback". 971 **/ 972 void 973 logs_set_pending_callback_callback(pending_callback_callback cb) 974 { 975 pending_cb_cb = cb; 976 } 977 978 /** 979 * Add a log handler to send messages in <b>severity</b> 980 * to the function <b>cb</b>. 981 */ 982 int 983 add_callback_log(const log_severity_list_t *severity, log_callback cb) 984 { 985 logfile_t *lf; 986 lf = tor_malloc_zero(sizeof(logfile_t)); 987 lf->fd = -1; 988 lf->severities = tor_memdup(severity, sizeof(log_severity_list_t)); 989 lf->filename = tor_strdup("<callback>"); 990 lf->callback = cb; 991 lf->next = logfiles; 992 993 LOCK_LOGS(); 994 logfiles = lf; 995 log_global_min_severity_ = get_min_log_level(); 996 UNLOCK_LOGS(); 997 return 0; 998 } 999 1000 /** Adjust the configured severity of any logs whose callback function is 1001 * <b>cb</b>. */ 1002 void 1003 change_callback_log_severity(int loglevelMin, int loglevelMax, 1004 log_callback cb) 1005 { 1006 logfile_t *lf; 1007 log_severity_list_t severities; 1008 set_log_severity_config(loglevelMin, loglevelMax, &severities); 1009 LOCK_LOGS(); 1010 for (lf = logfiles; lf; lf = lf->next) { 1011 if (lf->callback == cb) { 1012 memcpy(lf->severities, &severities, sizeof(severities)); 1013 } 1014 } 1015 log_global_min_severity_ = get_min_log_level(); 1016 UNLOCK_LOGS(); 1017 } 1018 1019 /** If there are any log messages that were generated with LD_NOCB waiting to 1020 * be sent to callback-based loggers, send them now. */ 1021 void 1022 flush_pending_log_callbacks(void) 1023 { 1024 logfile_t *lf; 1025 smartlist_t *messages, *messages_tmp; 1026 1027 LOCK_LOGS(); 1028 if (!pending_cb_messages || 0 == smartlist_len(pending_cb_messages)) { 1029 UNLOCK_LOGS(); 1030 return; 1031 } 1032 1033 messages = pending_cb_messages; 1034 pending_cb_messages = smartlist_new(); 1035 do { 1036 SMARTLIST_FOREACH_BEGIN(messages, pending_log_message_t *, msg) { 1037 const int severity = msg->severity; 1038 const log_domain_mask_t domain = msg->domain; 1039 for (lf = logfiles; lf; lf = lf->next) { 1040 if (! lf->callback || lf->seems_dead || 1041 ! (lf->severities->masks[SEVERITY_MASK_IDX(severity)] & domain)) { 1042 continue; 1043 } 1044 lf->callback(severity, domain, msg->msg); 1045 } 1046 pending_log_message_free(msg); 1047 } SMARTLIST_FOREACH_END(msg); 1048 smartlist_clear(messages); 1049 1050 messages_tmp = pending_cb_messages; 1051 pending_cb_messages = messages; 1052 messages = messages_tmp; 1053 } while (smartlist_len(messages)); 1054 1055 smartlist_free(messages); 1056 1057 UNLOCK_LOGS(); 1058 } 1059 1060 /** Flush all the messages we stored from startup while waiting for log 1061 * initialization. 1062 */ 1063 void 1064 flush_log_messages_from_startup(void) 1065 { 1066 logfile_t *lf; 1067 1068 LOCK_LOGS(); 1069 queue_startup_messages = 0; 1070 pending_startup_messages_len = 0; 1071 if (! pending_startup_messages) 1072 goto out; 1073 1074 SMARTLIST_FOREACH_BEGIN(pending_startup_messages, pending_log_message_t *, 1075 msg) { 1076 int callbacks_deferred = 0; 1077 for (lf = logfiles; lf; lf = lf->next) { 1078 if (! logfile_wants_message(lf, msg->severity, msg->domain)) 1079 continue; 1080 1081 /* We configure a temporary startup log that goes to stdout, so we 1082 * shouldn't replay to stdout/stderr*/ 1083 if (lf->fd == STDOUT_FILENO || lf->fd == STDERR_FILENO) { 1084 continue; 1085 } 1086 1087 logfile_deliver(lf, msg->fullmsg, strlen(msg->fullmsg), msg->msg, 1088 msg->domain, msg->severity, &callbacks_deferred); 1089 } 1090 pending_log_message_free(msg); 1091 } SMARTLIST_FOREACH_END(msg); 1092 smartlist_free(pending_startup_messages); 1093 pending_startup_messages = NULL; 1094 1095 out: 1096 UNLOCK_LOGS(); 1097 } 1098 1099 /** Close any log handlers marked by mark_logs_temp(). */ 1100 void 1101 close_temp_logs(void) 1102 { 1103 logfile_t *lf, **p; 1104 1105 LOCK_LOGS(); 1106 for (p = &logfiles; *p; ) { 1107 if ((*p)->is_temporary) { 1108 lf = *p; 1109 /* we use *p here to handle the edge case of the head of the list */ 1110 *p = (*p)->next; 1111 close_log(lf); 1112 log_free(lf); 1113 } else { 1114 p = &((*p)->next); 1115 } 1116 } 1117 1118 log_global_min_severity_ = get_min_log_level(); 1119 UNLOCK_LOGS(); 1120 } 1121 1122 /** Make all currently temporary logs (set to be closed by close_temp_logs) 1123 * live again, and close all non-temporary logs. */ 1124 void 1125 rollback_log_changes(void) 1126 { 1127 logfile_t *lf; 1128 LOCK_LOGS(); 1129 for (lf = logfiles; lf; lf = lf->next) 1130 lf->is_temporary = ! lf->is_temporary; 1131 UNLOCK_LOGS(); 1132 close_temp_logs(); 1133 } 1134 1135 /** Configure all log handles to be closed by close_temp_logs(). */ 1136 void 1137 mark_logs_temp(void) 1138 { 1139 logfile_t *lf; 1140 LOCK_LOGS(); 1141 for (lf = logfiles; lf; lf = lf->next) 1142 lf->is_temporary = 1; 1143 UNLOCK_LOGS(); 1144 } 1145 1146 /** 1147 * Add a log handler to send messages to <b>filename</b> via <b>fd</b>. If 1148 * opening the logfile failed, -1 is returned and errno is set appropriately 1149 * (by open(2)). Takes ownership of fd. 1150 */ 1151 MOCK_IMPL(int, 1152 add_file_log,(const log_severity_list_t *severity, 1153 const char *filename, 1154 int fd)) 1155 { 1156 logfile_t *lf; 1157 1158 if (fd<0) 1159 return -1; 1160 if (tor_fd_seekend(fd)<0) { 1161 close(fd); 1162 return -1; 1163 } 1164 1165 LOCK_LOGS(); 1166 add_stream_log_impl(severity, filename, fd); 1167 logfiles->needs_close = 1; 1168 lf = logfiles; 1169 log_global_min_severity_ = get_min_log_level(); 1170 1171 if (log_tor_version(lf, 0) < 0) { 1172 delete_log(lf); 1173 } 1174 UNLOCK_LOGS(); 1175 1176 return 0; 1177 } 1178 1179 #ifdef HAVE_SYSLOG_H 1180 /** 1181 * Add a log handler to send messages to they system log facility. 1182 * 1183 * If this is the first log handler, opens syslog with ident Tor or 1184 * Tor-<syslog_identity_tag> if that is not NULL. 1185 */ 1186 int 1187 add_syslog_log(const log_severity_list_t *severity, 1188 const char* syslog_identity_tag) 1189 { 1190 logfile_t *lf; 1191 if (syslog_count++ == 0) { 1192 /* This is the first syslog. */ 1193 static char buf[256]; 1194 if (syslog_identity_tag) { 1195 tor_snprintf(buf, sizeof(buf), "Tor-%s", syslog_identity_tag); 1196 } else { 1197 tor_snprintf(buf, sizeof(buf), "Tor"); 1198 } 1199 openlog(buf, LOG_PID | LOG_NDELAY, LOGFACILITY); 1200 } 1201 1202 lf = tor_malloc_zero(sizeof(logfile_t)); 1203 lf->fd = -1; 1204 lf->severities = tor_memdup(severity, sizeof(log_severity_list_t)); 1205 lf->filename = tor_strdup("<syslog>"); 1206 lf->is_syslog = 1; 1207 1208 LOCK_LOGS(); 1209 lf->next = logfiles; 1210 logfiles = lf; 1211 log_global_min_severity_ = get_min_log_level(); 1212 UNLOCK_LOGS(); 1213 return 0; 1214 } 1215 #endif /* defined(HAVE_SYSLOG_H) */ 1216 1217 /** If <b>level</b> is a valid log severity, return the corresponding 1218 * numeric value. Otherwise, return -1. */ 1219 int 1220 parse_log_level(const char *level) 1221 { 1222 if (!strcasecmp(level, "err")) 1223 return LOG_ERR; 1224 if (!strcasecmp(level, "warn")) 1225 return LOG_WARN; 1226 if (!strcasecmp(level, "notice")) 1227 return LOG_NOTICE; 1228 if (!strcasecmp(level, "info")) 1229 return LOG_INFO; 1230 if (!strcasecmp(level, "debug")) 1231 return LOG_DEBUG; 1232 return -1; 1233 } 1234 1235 /** Return the string equivalent of a given log level. */ 1236 const char * 1237 log_level_to_string(int level) 1238 { 1239 return sev_to_string(level); 1240 } 1241 1242 /** NULL-terminated array of names for log domains such that domain_list[dom] 1243 * is a description of <b>dom</b>. 1244 * 1245 * Remember to update doc/man/tor.1.txt if you modify this list. 1246 * */ 1247 static const char *domain_list[] = { 1248 "GENERAL", "CRYPTO", "NET", "CONFIG", "FS", "PROTOCOL", "MM", 1249 "HTTP", "APP", "CONTROL", "CIRC", "REND", "BUG", "DIR", "DIRSERV", 1250 "OR", "EDGE", "ACCT", "HIST", "HANDSHAKE", "HEARTBEAT", "CHANNEL", 1251 "SCHED", "GUARD", "CONSDIFF", "DOS", "PROCESS", "PT", "BTRACK", "MESG", 1252 NULL 1253 }; 1254 1255 CTASSERT(ARRAY_LENGTH(domain_list) == N_LOGGING_DOMAINS + 1); 1256 1257 CTASSERT(HIGHEST_RESERVED_LD_DOMAIN_ < LD_ALL_DOMAINS); 1258 CTASSERT(LD_ALL_DOMAINS < LOWEST_RESERVED_LD_FLAG_); 1259 CTASSERT(LOWEST_RESERVED_LD_FLAG_ < LD_ALL_FLAGS); 1260 1261 /** Return a bitmask for the log domain for which <b>domain</b> is the name, 1262 * or 0 if there is no such name. */ 1263 static log_domain_mask_t 1264 parse_log_domain(const char *domain) 1265 { 1266 int i; 1267 for (i=0; domain_list[i]; ++i) { 1268 if (!strcasecmp(domain, domain_list[i])) 1269 return (UINT64_C(1)<<i); 1270 } 1271 return 0; 1272 } 1273 1274 /** Translate a bitmask of log domains to a string. */ 1275 static char * 1276 domain_to_string(log_domain_mask_t domain, char *buf, size_t buflen) 1277 { 1278 char *cp = buf; 1279 char *eos = buf+buflen; 1280 1281 buf[0] = '\0'; 1282 if (! domain) 1283 return buf; 1284 while (1) { 1285 const char *d; 1286 int bit = tor_log2(domain); 1287 size_t n; 1288 if ((unsigned)bit >= ARRAY_LENGTH(domain_list)-1 || 1289 bit >= N_LOGGING_DOMAINS) { 1290 tor_snprintf(buf, buflen, "<BUG:Unknown domain %lx>", (long)domain); 1291 return buf+strlen(buf); 1292 } 1293 d = domain_list[bit]; 1294 n = strlcpy(cp, d, eos-cp); 1295 if (n >= buflen) { 1296 tor_snprintf(buf, buflen, "<BUG:Truncating domain %lx>", (long)domain); 1297 return buf+strlen(buf); 1298 } 1299 cp += n; 1300 domain &= ~(1<<bit); 1301 1302 if (domain == 0 || (eos-cp) < 2) 1303 return cp; 1304 1305 memcpy(cp, ",", 2); /*Nul-terminated ,"*/ 1306 cp++; 1307 } 1308 } 1309 1310 /** Parse a log severity pattern in *<b>cfg_ptr</b>. Advance cfg_ptr after 1311 * the end of the severityPattern. Set the value of <b>severity_out</b> to 1312 * the parsed pattern. Return 0 on success, -1 on failure. 1313 * 1314 * The syntax for a SeverityPattern is: 1315 * <pre> 1316 * SeverityPattern = *(DomainSeverity SP)* DomainSeverity 1317 * DomainSeverity = (DomainList SP)? SeverityRange 1318 * SeverityRange = MinSeverity ("-" MaxSeverity )? 1319 * DomainList = "[" (SP? DomainSpec SP? ",") SP? DomainSpec "]" 1320 * DomainSpec = "*" | Domain | "~" Domain 1321 * </pre> 1322 * A missing MaxSeverity defaults to ERR. Severities and domains are 1323 * case-insensitive. "~" indicates negation for a domain; negation happens 1324 * last inside a DomainList. Only one SeverityRange without a DomainList is 1325 * allowed per line. 1326 */ 1327 int 1328 parse_log_severity_config(const char **cfg_ptr, 1329 log_severity_list_t *severity_out) 1330 { 1331 const char *cfg = *cfg_ptr; 1332 int got_anything = 0; 1333 int got_an_unqualified_range = 0; 1334 memset(severity_out, 0, sizeof(*severity_out)); 1335 1336 cfg = eat_whitespace(cfg); 1337 while (*cfg) { 1338 const char *dash, *space; 1339 char *sev_lo, *sev_hi; 1340 int low, high, i; 1341 log_domain_mask_t domains = LD_ALL_DOMAINS; 1342 1343 if (*cfg == '[') { 1344 int err = 0; 1345 char *domains_str; 1346 smartlist_t *domains_list; 1347 log_domain_mask_t neg_domains = 0; 1348 const char *closebracket = strchr(cfg, ']'); 1349 if (!closebracket) 1350 return -1; 1351 domains = 0; 1352 domains_str = tor_strndup(cfg+1, closebracket-cfg-1); 1353 domains_list = smartlist_new(); 1354 smartlist_split_string(domains_list, domains_str, ",", SPLIT_SKIP_SPACE, 1355 -1); 1356 tor_free(domains_str); 1357 SMARTLIST_FOREACH_BEGIN(domains_list, const char *, domain) { 1358 if (!strcmp(domain, "*")) { 1359 domains = LD_ALL_DOMAINS; 1360 } else { 1361 log_domain_mask_t d; 1362 int negate=0; 1363 if (*domain == '~') { 1364 negate = 1; 1365 ++domain; 1366 } 1367 d = parse_log_domain(domain); 1368 if (!d) { 1369 log_warn(LD_CONFIG, "No such logging domain as %s", domain); 1370 err = 1; 1371 } else { 1372 if (negate) 1373 neg_domains |= d; 1374 else 1375 domains |= d; 1376 } 1377 } 1378 } SMARTLIST_FOREACH_END(domain); 1379 SMARTLIST_FOREACH(domains_list, char *, d, tor_free(d)); 1380 smartlist_free(domains_list); 1381 if (err) 1382 return -1; 1383 if (domains == 0 && neg_domains) 1384 domains = ~neg_domains; 1385 else 1386 domains &= ~neg_domains; 1387 cfg = eat_whitespace(closebracket+1); 1388 } else { 1389 ++got_an_unqualified_range; 1390 } 1391 if (!strcasecmpstart(cfg, "file") || 1392 !strcasecmpstart(cfg, "stderr") || 1393 !strcasecmpstart(cfg, "stdout") || 1394 !strcasecmpstart(cfg, "syslog")) { 1395 goto done; 1396 } 1397 if (got_an_unqualified_range > 1) 1398 return -1; 1399 1400 space = find_whitespace(cfg); 1401 dash = strchr(cfg, '-'); 1402 if (dash && dash < space) { 1403 sev_lo = tor_strndup(cfg, dash-cfg); 1404 sev_hi = tor_strndup(dash+1, space-(dash+1)); 1405 } else { 1406 sev_lo = tor_strndup(cfg, space-cfg); 1407 sev_hi = tor_strdup("ERR"); 1408 } 1409 low = parse_log_level(sev_lo); 1410 high = parse_log_level(sev_hi); 1411 tor_free(sev_lo); 1412 tor_free(sev_hi); 1413 if (low == -1) 1414 return -1; 1415 if (high == -1) 1416 return -1; 1417 1418 got_anything = 1; 1419 for (i=low; i >= high; --i) 1420 severity_out->masks[SEVERITY_MASK_IDX(i)] |= domains; 1421 1422 cfg = eat_whitespace(space); 1423 } 1424 1425 done: 1426 *cfg_ptr = cfg; 1427 return got_anything ? 0 : -1; 1428 } 1429 1430 /** Return the least severe log level that any current log is interested in. */ 1431 int 1432 get_min_log_level(void) 1433 { 1434 logfile_t *lf; 1435 int i; 1436 int min = LOG_ERR; 1437 for (lf = logfiles; lf; lf = lf->next) { 1438 for (i = LOG_DEBUG; i > min; --i) 1439 if (lf->severities->masks[SEVERITY_MASK_IDX(i)]) 1440 min = i; 1441 } 1442 return min; 1443 } 1444 1445 /** Switch all logs to output at most verbose level. */ 1446 void 1447 switch_logs_debug(void) 1448 { 1449 logfile_t *lf; 1450 int i; 1451 LOCK_LOGS(); 1452 for (lf = logfiles; lf; lf=lf->next) { 1453 for (i = LOG_DEBUG; i >= LOG_ERR; --i) 1454 lf->severities->masks[SEVERITY_MASK_IDX(i)] = LD_ALL_DOMAINS; 1455 } 1456 log_global_min_severity_ = get_min_log_level(); 1457 UNLOCK_LOGS(); 1458 } 1459 1460 /** Truncate all the log files. */ 1461 void 1462 truncate_logs(void) 1463 { 1464 logfile_t *lf; 1465 for (lf = logfiles; lf; lf = lf->next) { 1466 if (lf->fd >= 0) { 1467 tor_ftruncate(lf->fd); 1468 } 1469 } 1470 }