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