log.c
上传用户:awang829
上传日期:2019-07-14
资源大小:2356k
文件大小:27k
源码类别:

网络

开发平台:

Unix_Linux

  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-2009, The Tor Project, Inc. */
  5. /* See LICENSE for licensing information */
  6. /**
  7.  * file log.c
  8.  * brief Functions to send messages to log files or the console.
  9.  **/
  10. #include "orconfig.h"
  11. #include <stdarg.h>
  12. #include <assert.h>
  13. // #include <stdio.h>
  14. #include <stdlib.h>
  15. #include <string.h>
  16. #ifdef HAVE_SYS_TIME_H
  17. #include <sys/time.h>
  18. #endif
  19. #ifdef HAVE_TIME_H
  20. #include <time.h>
  21. #endif
  22. #ifdef HAVE_UNISTD_H
  23. #include <unistd.h>
  24. #endif
  25. #ifdef HAVE_SYS_TYPES_H
  26. #include <sys/types.h>
  27. #endif
  28. #ifdef HAVE_FCNTL_H
  29. #include <fcntl.h>
  30. #endif
  31. #include "compat.h"
  32. #include "util.h"
  33. #define LOG_PRIVATE
  34. #include "log.h"
  35. #include "container.h"
  36. #include <event.h>
  37. #define TRUNCATED_STR "[...truncated]"
  38. #define TRUNCATED_STR_LEN 14
  39. /** Information for a single logfile; only used in log.c */
  40. typedef struct logfile_t {
  41.   struct logfile_t *next; /**< Next logfile_t in the linked list. */
  42.   char *filename; /**< Filename to open. */
  43.   int fd; /**< fd to receive log messages, or -1 for none. */
  44.   int seems_dead; /**< Boolean: true if the stream seems to be kaput. */
  45.   int needs_close; /**< Boolean: true if the stream gets closed on shutdown. */
  46.   int is_temporary; /**< Boolean: close after initializing logging subsystem.*/
  47.   int is_syslog; /**< Boolean: send messages to syslog. */
  48.   log_callback callback; /**< If not NULL, send messages to this function. */
  49.   log_severity_list_t *severities; /**< Which severity of messages should we
  50.                                     * log for each log domain? */
  51. } logfile_t;
  52. static void log_free(logfile_t *victim);
  53. /** Helper: map a log severity to descriptive string. */
  54. static INLINE const char *
  55. sev_to_string(int severity)
  56. {
  57.   switch (severity) {
  58.     case LOG_DEBUG:   return "debug";
  59.     case LOG_INFO:    return "info";
  60.     case LOG_NOTICE:  return "notice";
  61.     case LOG_WARN:    return "warn";
  62.     case LOG_ERR:     return "err";
  63.     default:          /* Call assert, not tor_assert, since tor_assert
  64.                        * calls log on failure. */
  65.                       assert(0); return "UNKNOWN";
  66.   }
  67. }
  68. /** Helper: decide whether to include the function name in the log message. */
  69. static INLINE int
  70. should_log_function_name(log_domain_mask_t domain, int severity)
  71. {
  72.   switch (severity) {
  73.     case LOG_DEBUG:
  74.     case LOG_INFO:
  75.       /* All debugging messages occur in interesting places. */
  76.       return 1;
  77.     case LOG_NOTICE:
  78.   case LOG_WARN:
  79.     case LOG_ERR:
  80.       /* We care about places where bugs occur. */
  81.       return (domain == LD_BUG);
  82.     default:
  83.       /* Call assert, not tor_assert, since tor_assert calls log on failure. */
  84.       assert(0); return 0;
  85.   }
  86. }
  87. /** A mutex to guard changes to logfiles and logging. */
  88. static tor_mutex_t log_mutex;
  89. static int log_mutex_initialized = 0;
  90. /** Linked list of logfile_t. */
  91. static logfile_t *logfiles = NULL;
  92. #ifdef HAVE_SYSLOG_H
  93. /** The number of open syslog log handlers that we have.  When this reaches 0,
  94.  * we can close our connection to the syslog facility. */
  95. static int syslog_count = 0;
  96. #endif
  97. #define LOCK_LOGS() STMT_BEGIN                                          
  98.   tor_mutex_acquire(&log_mutex);                                        
  99.   STMT_END
  100. #define UNLOCK_LOGS() STMT_BEGIN tor_mutex_release(&log_mutex); STMT_END
  101. /** What's the lowest log level anybody cares about?  Checking this lets us
  102.  * bail out early from log_debug if we aren't debugging.  */
  103. int _log_global_min_severity = LOG_NOTICE;
  104. static void delete_log(logfile_t *victim);
  105. static void close_log(logfile_t *victim);
  106. /** Name of the application: used to generate the message we write at the
  107.  * start of each new log. */
  108. static char *appname = NULL;
  109. /** Set the "application name" for the logs to <b>name</b>: we'll use this
  110.  * name in the message we write when starting up, and at the start of each new
  111.  * log.
  112.  *
  113.  * Tor uses this string to write the version number to the log file. */
  114. void
  115. log_set_application_name(const char *name)
  116. {
  117.   tor_free(appname);
  118.   appname = name ? tor_strdup(name) : NULL;
  119. }
  120. /** Helper: Write the standard prefix for log lines to a
  121.  * <b>buf_len</b> character buffer in <b>buf</b>.
  122.  */
  123. static INLINE size_t
  124. _log_prefix(char *buf, size_t buf_len, int severity)
  125. {
  126.   time_t t;
  127.   struct timeval now;
  128.   struct tm tm;
  129.   size_t n;
  130.   int r;
  131.   tor_gettimeofday(&now);
  132.   t = (time_t)now.tv_sec;
  133.   n = strftime(buf, buf_len, "%b %d %H:%M:%S", tor_localtime_r(&t, &tm));
  134.   r = tor_snprintf(buf+n, buf_len-n, ".%.3i [%s] ",
  135.                    (int)now.tv_usec / 1000, sev_to_string(severity));
  136.   if (r<0)
  137.     return buf_len-1;
  138.   else
  139.     return n+r;
  140. }
  141. /** If lf refers to an actual file that we have just opened, and the file
  142.  * contains no data, log an "opening new logfile" message at the top.
  143.  *
  144.  * Return -1 if the log is broken and needs to be deleted, else return 0.
  145.  */
  146. static int
  147. log_tor_version(logfile_t *lf, int reset)
  148. {
  149.   char buf[256];
  150.   size_t n;
  151.   int is_new;
  152.   if (!lf->needs_close)
  153.     /* If it doesn't get closed, it isn't really a file. */
  154.     return 0;
  155.   if (lf->is_temporary)
  156.     /* If it's temporary, it isn't really a file. */
  157.     return 0;
  158.   is_new = lf->fd >= 0 && tor_fd_getpos(lf->fd) == 0;
  159.   if (reset && !is_new)
  160.     /* We are resetting, but we aren't at the start of the file; no
  161.      * need to log again. */
  162.     return 0;
  163.   n = _log_prefix(buf, sizeof(buf), LOG_NOTICE);
  164.   if (appname) {
  165.     tor_snprintf(buf+n, sizeof(buf)-n,
  166.                  "%s opening %slog file.n", appname, is_new?"new ":"");
  167.   } else {
  168.     tor_snprintf(buf+n, sizeof(buf)-n,
  169.                  "Tor %s opening %slog file.n", VERSION, is_new?"new ":"");
  170.   }
  171.   if (write_all(lf->fd, buf, strlen(buf), 0) < 0) /* error */
  172.     return -1; /* failed */
  173.   return 0;
  174. }
  175. /** Helper: Format a log message into a fixed-sized buffer. (This is
  176.  * factored out of <b>logv</b> so that we never format a message more
  177.  * than once.)  Return a pointer to the first character of the message
  178.  * portion of the formatted string.
  179.  */
  180. static INLINE char *
  181. format_msg(char *buf, size_t buf_len,
  182.            log_domain_mask_t domain, int severity, const char *funcname,
  183.            const char *format, va_list ap, size_t *msg_len_out)
  184. {
  185.   size_t n;
  186.   int r;
  187.   char *end_of_prefix;
  188.   assert(buf_len >= 2); /* prevent integer underflow */
  189.   buf_len -= 2; /* subtract 2 characters so we have room for n */
  190.   n = _log_prefix(buf, buf_len, severity);
  191.   end_of_prefix = buf+n;
  192.   if (funcname && should_log_function_name(domain, severity)) {
  193.     r = tor_snprintf(buf+n, buf_len-n, "%s(): ", funcname);
  194.     if (r<0)
  195.       n = strlen(buf);
  196.     else
  197.       n += r;
  198.   }
  199.   if (domain == LD_BUG && buf_len-n > 6) {
  200.     memcpy(buf+n, "Bug: ", 6);
  201.     n += 5;
  202.   }
  203.   r = tor_vsnprintf(buf+n,buf_len-n,format,ap);
  204.   if (r < 0) {
  205.     /* The message was too long; overwrite the end of the buffer with
  206.      * "[...truncated]" */
  207.     if (buf_len >= TRUNCATED_STR_LEN) {
  208.       size_t offset = buf_len-TRUNCATED_STR_LEN;
  209.       /* We have an extra 2 characters after buf_len to hold the n,
  210.        * so it's safe to add 1 to the size here. */
  211.       strlcpy(buf+offset, TRUNCATED_STR, buf_len-offset+1);
  212.     }
  213.     /* Set 'n' to the end of the buffer, where we'll be writing n.
  214.      * Since we already subtracted 2 from buf_len, this is safe.*/
  215.     n = buf_len;
  216.   } else {
  217.     n += r;
  218.   }
  219.   buf[n]='n';
  220.   buf[n+1]='';
  221.   *msg_len_out = n+1;
  222.   return end_of_prefix;
  223. }
  224. /** Helper: sends a message to the appropriate logfiles, at loglevel
  225.  * <b>severity</b>.  If provided, <b>funcname</b> is prepended to the
  226.  * message.  The actual message is derived as from tor_snprintf(format,ap).
  227.  */
  228. static void
  229. logv(int severity, log_domain_mask_t domain, const char *funcname,
  230.      const char *format, va_list ap)
  231. {
  232.   char buf[10024];
  233.   size_t msg_len = 0;
  234.   int formatted = 0;
  235.   logfile_t *lf;
  236.   char *end_of_prefix=NULL;
  237.   /* Call assert, not tor_assert, since tor_assert calls log on failure. */
  238.   assert(format);
  239.   /* check that severity is sane.  Overrunning the masks array leads to
  240.    * interesting and hard to diagnose effects */
  241.   assert(severity >= LOG_ERR && severity <= LOG_DEBUG);
  242.   LOCK_LOGS();
  243.   lf = logfiles;
  244.   while (lf) {
  245.     if (! (lf->severities->masks[SEVERITY_MASK_IDX(severity)] & domain)) {
  246.       lf = lf->next;
  247.       continue;
  248.     }
  249.     if (! (lf->fd >= 0 || lf->is_syslog || lf->callback)) {
  250.       lf = lf->next;
  251.       continue;
  252.     }
  253.     if (lf->seems_dead) {
  254.       lf = lf->next;
  255.       continue;
  256.     }
  257.     if (!formatted) {
  258.       end_of_prefix =
  259.         format_msg(buf, sizeof(buf), domain, severity, funcname, format, ap,
  260.                    &msg_len);
  261.       formatted = 1;
  262.     }
  263.     if (lf->is_syslog) {
  264. #ifdef HAVE_SYSLOG_H
  265.       char *m = end_of_prefix;
  266. #ifdef MAXLINE
  267.       /* Some syslog implementations have limits on the length of what you can
  268.        * pass them, and some very old ones do not detect overflow so well.
  269.        * Regrettably, they call their maximum line length MAXLINE. */
  270. #if MAXLINE < 64
  271. #warn "MAXLINE is a very low number; it might not be from syslog.h after all"
  272. #endif
  273.       if (msg_len >= MAXLINE)
  274.         m = tor_strndup(end_of_prefix, MAXLINE-1);
  275. #endif
  276.       syslog(severity, "%s", m);
  277. #ifdef MAXLINE
  278.       if (m != end_of_prefix) {
  279.         tor_free(m);
  280.       }
  281. #endif
  282. #endif
  283.       lf = lf->next;
  284.       continue;
  285.     } else if (lf->callback) {
  286.       lf->callback(severity, domain, end_of_prefix);
  287.       lf = lf->next;
  288.       continue;
  289.     }
  290.     if (write_all(lf->fd, buf, msg_len, 0) < 0) { /* error */
  291.       /* don't log the error! mark this log entry to be blown away, and
  292.        * continue. */
  293.       lf->seems_dead = 1;
  294.     }
  295.     lf = lf->next;
  296.   }
  297.   UNLOCK_LOGS();
  298. }
  299. /** Output a message to the log. */
  300. void
  301. _log(int severity, log_domain_mask_t domain, const char *format, ...)
  302. {
  303.   va_list ap;
  304.   if (severity > _log_global_min_severity)
  305.     return;
  306.   va_start(ap,format);
  307.   logv(severity, domain, NULL, format, ap);
  308.   va_end(ap);
  309. }
  310. /** Output a message to the log, prefixed with a function name <b>fn</b>. */
  311. #ifdef __GNUC__
  312. void
  313. _log_fn(int severity, log_domain_mask_t domain, const char *fn,
  314.         const char *format, ...)
  315. {
  316.   va_list ap;
  317.   if (severity > _log_global_min_severity)
  318.     return;
  319.   va_start(ap,format);
  320.   logv(severity, domain, fn, format, ap);
  321.   va_end(ap);
  322. }
  323. #else
  324. const char *_log_fn_function_name=NULL;
  325. void
  326. _log_fn(int severity, log_domain_mask_t domain, const char *format, ...)
  327. {
  328.   va_list ap;
  329.   if (severity > _log_global_min_severity)
  330.     return;
  331.   va_start(ap,format);
  332.   logv(severity, domain, _log_fn_function_name, format, ap);
  333.   va_end(ap);
  334.   _log_fn_function_name = NULL;
  335. }
  336. void
  337. _log_debug(log_domain_mask_t domain, const char *format, ...)
  338. {
  339.   va_list ap;
  340.   /* For GCC we do this check in the macro. */
  341.   if (PREDICT_LIKELY(LOG_DEBUG > _log_global_min_severity))
  342.     return;
  343.   va_start(ap,format);
  344.   logv(LOG_DEBUG, domain, _log_fn_function_name, format, ap);
  345.   va_end(ap);
  346.   _log_fn_function_name = NULL;
  347. }
  348. void
  349. _log_info(log_domain_mask_t domain, const char *format, ...)
  350. {
  351.   va_list ap;
  352.   if (LOG_INFO > _log_global_min_severity)
  353.     return;
  354.   va_start(ap,format);
  355.   logv(LOG_INFO, domain, _log_fn_function_name, format, ap);
  356.   va_end(ap);
  357.   _log_fn_function_name = NULL;
  358. }
  359. void
  360. _log_notice(log_domain_mask_t domain, const char *format, ...)
  361. {
  362.   va_list ap;
  363.   if (LOG_NOTICE > _log_global_min_severity)
  364.     return;
  365.   va_start(ap,format);
  366.   logv(LOG_NOTICE, domain, _log_fn_function_name, format, ap);
  367.   va_end(ap);
  368.   _log_fn_function_name = NULL;
  369. }
  370. void
  371. _log_warn(log_domain_mask_t domain, const char *format, ...)
  372. {
  373.   va_list ap;
  374.   if (LOG_WARN > _log_global_min_severity)
  375.     return;
  376.   va_start(ap,format);
  377.   logv(LOG_WARN, domain, _log_fn_function_name, format, ap);
  378.   va_end(ap);
  379.   _log_fn_function_name = NULL;
  380. }
  381. void
  382. _log_err(log_domain_mask_t domain, const char *format, ...)
  383. {
  384.   va_list ap;
  385.   if (LOG_ERR > _log_global_min_severity)
  386.     return;
  387.   va_start(ap,format);
  388.   logv(LOG_ERR, domain, _log_fn_function_name, format, ap);
  389.   va_end(ap);
  390.   _log_fn_function_name = NULL;
  391. }
  392. #endif
  393. /** Free all storage held by <b>victim</b>. */
  394. static void
  395. log_free(logfile_t *victim)
  396. {
  397.   tor_free(victim->severities);
  398.   tor_free(victim->filename);
  399.   tor_free(victim);
  400. }
  401. /** Close all open log files, and free other static memory. */
  402. void
  403. logs_free_all(void)
  404. {
  405.   logfile_t *victim, *next;
  406.   LOCK_LOGS();
  407.   next = logfiles;
  408.   logfiles = NULL;
  409.   UNLOCK_LOGS();
  410.   while (next) {
  411.     victim = next;
  412.     next = next->next;
  413.     close_log(victim);
  414.     log_free(victim);
  415.   }
  416.   tor_free(appname);
  417.   /* We _could_ destroy the log mutex here, but that would screw up any logs
  418.    * that happened between here and the end of execution. */
  419. }
  420. /** Remove and free the log entry <b>victim</b> from the linked-list
  421.  * logfiles (it is probably present, but it might not be due to thread
  422.  * racing issues). After this function is called, the caller shouldn't
  423.  * refer to <b>victim</b> anymore.
  424.  *
  425.  * Long-term, we need to do something about races in the log subsystem
  426.  * in general. See bug 222 for more details.
  427.  */
  428. static void
  429. delete_log(logfile_t *victim)
  430. {
  431.   logfile_t *tmpl;
  432.   if (victim == logfiles)
  433.     logfiles = victim->next;
  434.   else {
  435.     for (tmpl = logfiles; tmpl && tmpl->next != victim; tmpl=tmpl->next) ;
  436. //    tor_assert(tmpl);
  437. //    tor_assert(tmpl->next == victim);
  438.     if (!tmpl)
  439.       return;
  440.     tmpl->next = victim->next;
  441.   }
  442.   log_free(victim);
  443. }
  444. /** Helper: release system resources (but not memory) held by a single
  445.  * logfile_t. */
  446. static void
  447. close_log(logfile_t *victim)
  448. {
  449.   if (victim->needs_close && victim->fd >= 0) {
  450.     close(victim->fd);
  451.     victim->fd = -1;
  452.   } else if (victim->is_syslog) {
  453. #ifdef HAVE_SYSLOG_H
  454.     if (--syslog_count == 0) {
  455.       /* There are no other syslogs; close the logging facility. */
  456.       closelog();
  457.     }
  458. #endif
  459.   }
  460. }
  461. /** Adjust a log severity configuration in <b>severity_out</b> to contain
  462.  * every domain between <b>loglevelMin</b> and <b>loglevelMax</b>, inclusive.
  463.  */
  464. void
  465. set_log_severity_config(int loglevelMin, int loglevelMax,
  466.                         log_severity_list_t *severity_out)
  467. {
  468.   int i;
  469.   tor_assert(loglevelMin >= loglevelMax);
  470.   tor_assert(loglevelMin >= LOG_ERR && loglevelMin <= LOG_DEBUG);
  471.   tor_assert(loglevelMax >= LOG_ERR && loglevelMax <= LOG_DEBUG);
  472.   memset(severity_out, 0, sizeof(log_severity_list_t));
  473.   for (i = loglevelMin; i >= loglevelMax; --i) {
  474.     severity_out->masks[SEVERITY_MASK_IDX(i)] = ~0u;
  475.   }
  476. }
  477. /** Add a log handler named <b>name</b> to send all messages in <b>severity</b>
  478.  * to <b>fd</b>. Copies <b>severity</b>. Helper: does no locking. */
  479. static void
  480. add_stream_log_impl(const log_severity_list_t *severity,
  481.                     const char *name, int fd)
  482. {
  483.   logfile_t *lf;
  484.   lf = tor_malloc_zero(sizeof(logfile_t));
  485.   lf->fd = fd;
  486.   lf->filename = tor_strdup(name);
  487.   lf->severities = tor_memdup(severity, sizeof(log_severity_list_t));
  488.   lf->next = logfiles;
  489.   logfiles = lf;
  490.   _log_global_min_severity = get_min_log_level();
  491. }
  492. /** Add a log handler named <b>name</b> to send all messages in <b>severity</b>
  493.  * to <b>fd</b>. Steals a reference to <b>severity</b>; the caller must
  494.  * not use it after calling this function. */
  495. void
  496. add_stream_log(const log_severity_list_t *severity,
  497.                const char *name, int fd)
  498. {
  499.   LOCK_LOGS();
  500.   add_stream_log_impl(severity, name, fd);
  501.   UNLOCK_LOGS();
  502. }
  503. /** Initialize the global logging facility */
  504. void
  505. init_logging(void)
  506. {
  507.   if (!log_mutex_initialized) {
  508.     tor_mutex_init(&log_mutex);
  509.     log_mutex_initialized = 1;
  510.   }
  511. }
  512. /** Add a log handler to receive messages during startup (before the real
  513.  * logs are initialized).
  514.  */
  515. void
  516. add_temp_log(int min_severity)
  517. {
  518.   log_severity_list_t *s = tor_malloc_zero(sizeof(log_severity_list_t));
  519.   set_log_severity_config(min_severity, LOG_ERR, s);
  520.   LOCK_LOGS();
  521.   add_stream_log_impl(s, "<temp>", fileno(stdout));
  522.   tor_free(s);
  523.   logfiles->is_temporary = 1;
  524.   UNLOCK_LOGS();
  525. }
  526. /**
  527.  * Add a log handler to send messages in <b>severity</b>
  528.  * to the function <b>cb</b>.
  529.  */
  530. int
  531. add_callback_log(const log_severity_list_t *severity, log_callback cb)
  532. {
  533.   logfile_t *lf;
  534.   lf = tor_malloc_zero(sizeof(logfile_t));
  535.   lf->fd = -1;
  536.   lf->severities = tor_memdup(severity, sizeof(log_severity_list_t));
  537.   lf->filename = tor_strdup("<callback>");
  538.   lf->callback = cb;
  539.   lf->next = logfiles;
  540.   LOCK_LOGS();
  541.   logfiles = lf;
  542.   _log_global_min_severity = get_min_log_level();
  543.   UNLOCK_LOGS();
  544.   return 0;
  545. }
  546. /** Adjust the configured severity of any logs whose callback function is
  547.  * <b>cb</b>. */
  548. void
  549. change_callback_log_severity(int loglevelMin, int loglevelMax,
  550.                              log_callback cb)
  551. {
  552.   logfile_t *lf;
  553.   log_severity_list_t severities;
  554.   set_log_severity_config(loglevelMin, loglevelMax, &severities);
  555.   LOCK_LOGS();
  556.   for (lf = logfiles; lf; lf = lf->next) {
  557.     if (lf->callback == cb) {
  558.       memcpy(lf->severities, &severities, sizeof(severities));
  559.     }
  560.   }
  561.   _log_global_min_severity = get_min_log_level();
  562.   UNLOCK_LOGS();
  563. }
  564. /** Close any log handlers added by add_temp_log() or marked by
  565.  * mark_logs_temp(). */
  566. void
  567. close_temp_logs(void)
  568. {
  569.   logfile_t *lf, **p;
  570.   LOCK_LOGS();
  571.   for (p = &logfiles; *p; ) {
  572.     if ((*p)->is_temporary) {
  573.       lf = *p;
  574.       /* we use *p here to handle the edge case of the head of the list */
  575.       *p = (*p)->next;
  576.       close_log(lf);
  577.       log_free(lf);
  578.     } else {
  579.       p = &((*p)->next);
  580.     }
  581.   }
  582.   _log_global_min_severity = get_min_log_level();
  583.   UNLOCK_LOGS();
  584. }
  585. /** Make all currently temporary logs (set to be closed by close_temp_logs)
  586.  * live again, and close all non-temporary logs. */
  587. void
  588. rollback_log_changes(void)
  589. {
  590.   logfile_t *lf;
  591.   LOCK_LOGS();
  592.   for (lf = logfiles; lf; lf = lf->next)
  593.     lf->is_temporary = ! lf->is_temporary;
  594.   UNLOCK_LOGS();
  595.   close_temp_logs();
  596. }
  597. /** Configure all log handles to be closed by close_temp_logs(). */
  598. void
  599. mark_logs_temp(void)
  600. {
  601.   logfile_t *lf;
  602.   LOCK_LOGS();
  603.   for (lf = logfiles; lf; lf = lf->next)
  604.     lf->is_temporary = 1;
  605.   UNLOCK_LOGS();
  606. }
  607. /**
  608.  * Add a log handler to send messages to <b>filename</b>. If opening the
  609.  * logfile fails, -1 is returned and errno is set appropriately (by open(2)).
  610.  */
  611. int
  612. add_file_log(const log_severity_list_t *severity, const char *filename)
  613. {
  614.   int fd;
  615.   logfile_t *lf;
  616.   fd = open(filename, O_WRONLY|O_CREAT|O_APPEND, 0644);
  617.   if (fd<0)
  618.     return -1;
  619.   if (tor_fd_seekend(fd)<0)
  620.     return -1;
  621.   LOCK_LOGS();
  622.   add_stream_log_impl(severity, filename, fd);
  623.   logfiles->needs_close = 1;
  624.   lf = logfiles;
  625.   _log_global_min_severity = get_min_log_level();
  626.   UNLOCK_LOGS();
  627.   if (log_tor_version(lf, 0) < 0) {
  628.     LOCK_LOGS();
  629.     delete_log(lf);
  630.     UNLOCK_LOGS();
  631.   }
  632.   return 0;
  633. }
  634. #ifdef HAVE_SYSLOG_H
  635. /**
  636.  * Add a log handler to send messages to they system log facility.
  637.  */
  638. int
  639. add_syslog_log(const log_severity_list_t *severity)
  640. {
  641.   logfile_t *lf;
  642.   if (syslog_count++ == 0)
  643.     /* This is the first syslog. */
  644.     openlog("Tor", LOG_PID | LOG_NDELAY, LOGFACILITY);
  645.   lf = tor_malloc_zero(sizeof(logfile_t));
  646.   lf->fd = -1;
  647.   lf->severities = tor_memdup(severity, sizeof(log_severity_list_t));
  648.   lf->filename = tor_strdup("<syslog>");
  649.   lf->is_syslog = 1;
  650.   LOCK_LOGS();
  651.   lf->next = logfiles;
  652.   logfiles = lf;
  653.   _log_global_min_severity = get_min_log_level();
  654.   UNLOCK_LOGS();
  655.   return 0;
  656. }
  657. #endif
  658. /** If <b>level</b> is a valid log severity, return the corresponding
  659.  * numeric value.  Otherwise, return -1. */
  660. int
  661. parse_log_level(const char *level)
  662. {
  663.   if (!strcasecmp(level, "err"))
  664.     return LOG_ERR;
  665.   if (!strcasecmp(level, "warn"))
  666.     return LOG_WARN;
  667.   if (!strcasecmp(level, "notice"))
  668.     return LOG_NOTICE;
  669.   if (!strcasecmp(level, "info"))
  670.     return LOG_INFO;
  671.   if (!strcasecmp(level, "debug"))
  672.     return LOG_DEBUG;
  673.   return -1;
  674. }
  675. /** Return the string equivalent of a given log level. */
  676. const char *
  677. log_level_to_string(int level)
  678. {
  679.   return sev_to_string(level);
  680. }
  681. /** NULL-terminated array of names for log domains such that domain_list[dom]
  682.  * is a description of <b>dom</b>. */
  683. static const char *domain_list[] = {
  684.   "GENERAL", "CRYPTO", "NET", "CONFIG", "FS", "PROTOCOL", "MM",
  685.   "HTTP", "APP", "CONTROL", "CIRC", "REND", "BUG", "DIR", "DIRSERV",
  686.   "OR", "EDGE", "ACCT", "HIST", NULL
  687. };
  688. /** Return a bitmask for the log domain for which <b>domain</b> is the name,
  689.  * or 0 if there is no such name. */
  690. static log_domain_mask_t
  691. parse_log_domain(const char *domain)
  692. {
  693.   int i;
  694.   for (i=0; domain_list[i]; ++i) {
  695.     if (!strcasecmp(domain, domain_list[i]))
  696.       return (1u<<i);
  697.   }
  698.   return 0;
  699. }
  700. #if 0
  701. /** Translate a bitmask of log domains to a string, or NULL if the bitmask
  702.  * is undecodable. */
  703. static const char *
  704. domain_to_string(log_domain_mask_t domain)
  705. {
  706.   int bit = tor_log2(domain);
  707.   if ((bit == 0 && domain == 0) || bit >= N_LOGGING_DOMAINS)
  708.     return NULL;
  709.   return domain_list[bit];
  710. }
  711. #endif
  712. /** Parse a log severity pattern in *<b>cfg_ptr</b>.  Advance cfg_ptr after
  713.  * the end of the severityPattern.  Set the value of <b>severity_out</b> to
  714.  * the parsed pattern.  Return 0 on success, -1 on failure.
  715.  *
  716.  * The syntax for a SeverityPattern is:
  717.  * <pre>
  718.  *   SeverityPattern = *(DomainSeverity SP)* DomainSeverity
  719.  *   DomainSeverity = (DomainList SP)? SeverityRange
  720.  *   SeverityRange = MinSeverity ("-" MaxSeverity )?
  721.  *   DomainList = "[" (SP? DomainSpec SP? ",") SP? DomainSpec "]"
  722.  *   DomainSpec = "*" | Domain | "~" Domain
  723.  * </pre>
  724.  * A missing MaxSeverity defaults to ERR.  Severities and domains are
  725.  * case-insensitive.  "~" indicates negation for a domain; negation happens
  726.  * last inside a DomainList.  Only one SeverityRange without a DomainList is
  727.  * allowed per line.
  728.  */
  729. int
  730. parse_log_severity_config(const char **cfg_ptr,
  731.                           log_severity_list_t *severity_out)
  732. {
  733.   const char *cfg = *cfg_ptr;
  734.   int got_anything = 0;
  735.   int got_an_unqualified_range = 0;
  736.   memset(severity_out, 0, sizeof(*severity_out));
  737.   cfg = eat_whitespace(cfg);
  738.   while (*cfg) {
  739.     const char *dash, *space;
  740.     char *sev_lo, *sev_hi;
  741.     int low, high, i;
  742.     log_domain_mask_t domains = ~0u;
  743.     if (*cfg == '[') {
  744.       int err = 0;
  745.       char *domains_str;
  746.       smartlist_t *domains_list;
  747.       log_domain_mask_t neg_domains = 0;
  748.       const char *closebracket = strchr(cfg, ']');
  749.       if (!closebracket)
  750.         return -1;
  751.       domains = 0;
  752.       domains_str = tor_strndup(cfg+1, closebracket-cfg-1);
  753.       domains_list = smartlist_create();
  754.       smartlist_split_string(domains_list, domains_str, ",", SPLIT_SKIP_SPACE,
  755.                              -1);
  756.       tor_free(domains_str);
  757.       SMARTLIST_FOREACH(domains_list, const char *, domain,
  758.           {
  759.             if (!strcmp(domain, "*")) {
  760.               domains = ~0u;
  761.             } else {
  762.               int d;
  763.               int negate=0;
  764.               if (*domain == '~') {
  765.                 negate = 1;
  766.                 ++domain;
  767.               }
  768.               d = parse_log_domain(domain);
  769.               if (!d) {
  770.                 log_warn(LD_CONFIG, "No such logging domain as %s", domain);
  771.                 err = 1;
  772.               } else {
  773.                 if (negate)
  774.                   neg_domains |= d;
  775.                 else
  776.                   domains |= d;
  777.               }
  778.             }
  779.           });
  780.       SMARTLIST_FOREACH(domains_list, char *, d, tor_free(d));
  781.       smartlist_free(domains_list);
  782.       if (err)
  783.         return -1;
  784.       domains &= ~neg_domains;
  785.       cfg = eat_whitespace(closebracket+1);
  786.     } else {
  787.       ++got_an_unqualified_range;
  788.     }
  789.     if (!strcasecmpstart(cfg, "file") ||
  790.         !strcasecmpstart(cfg, "stderr") ||
  791.         !strcasecmpstart(cfg, "stdout") ||
  792.         !strcasecmpstart(cfg, "syslog")) {
  793.       goto done;
  794.     }
  795.     if (got_an_unqualified_range > 1)
  796.       return -1;
  797.     space = strchr(cfg, ' ');
  798.     dash = strchr(cfg, '-');
  799.     if (!space)
  800.       space = strchr(cfg, '');
  801.     if (dash && dash < space) {
  802.       sev_lo = tor_strndup(cfg, dash-cfg);
  803.       sev_hi = tor_strndup(dash+1, space-(dash+1));
  804.     } else {
  805.       sev_lo = tor_strndup(cfg, space-cfg);
  806.       sev_hi = tor_strdup("ERR");
  807.     }
  808.     low = parse_log_level(sev_lo);
  809.     high = parse_log_level(sev_hi);
  810.     tor_free(sev_lo);
  811.     tor_free(sev_hi);
  812.     if (low == -1)
  813.       return -1;
  814.     if (high == -1)
  815.       return -1;
  816.     got_anything = 1;
  817.     for (i=low; i >= high; --i)
  818.       severity_out->masks[SEVERITY_MASK_IDX(i)] |= domains;
  819.     cfg = eat_whitespace(space);
  820.   }
  821.  done:
  822.   *cfg_ptr = cfg;
  823.   return got_anything ? 0 : -1;
  824. }
  825. /** Return the least severe log level that any current log is interested in. */
  826. int
  827. get_min_log_level(void)
  828. {
  829.   logfile_t *lf;
  830.   int i;
  831.   int min = LOG_ERR;
  832.   for (lf = logfiles; lf; lf = lf->next) {
  833.     for (i = LOG_DEBUG; i > min; --i)
  834.       if (lf->severities->masks[SEVERITY_MASK_IDX(i)])
  835.         min = i;
  836.   }
  837.   return min;
  838. }
  839. /** Switch all logs to output at most verbose level. */
  840. void
  841. switch_logs_debug(void)
  842. {
  843.   logfile_t *lf;
  844.   int i;
  845.   LOCK_LOGS();
  846.   for (lf = logfiles; lf; lf=lf->next) {
  847.     for (i = LOG_DEBUG; i >= LOG_ERR; --i)
  848.       lf->severities->masks[SEVERITY_MASK_IDX(i)] = ~0u;
  849.   }
  850.   _log_global_min_severity = get_min_log_level();
  851.   UNLOCK_LOGS();
  852. }
  853. #ifdef HAVE_EVENT_SET_LOG_CALLBACK
  854. /** A string which, if it appears in a libevent log, should be ignored. */
  855. static const char *suppress_msg = NULL;
  856. /** Callback function passed to event_set_log() so we can intercept
  857.  * log messages from libevent. */
  858. static void
  859. libevent_logging_callback(int severity, const char *msg)
  860. {
  861.   char buf[1024];
  862.   size_t n;
  863.   if (suppress_msg && strstr(msg, suppress_msg))
  864.     return;
  865.   n = strlcpy(buf, msg, sizeof(buf));
  866.   if (n && n < sizeof(buf) && buf[n-1] == 'n') {
  867.     buf[n-1] = '';
  868.   }
  869.   switch (severity) {
  870.     case _EVENT_LOG_DEBUG:
  871.       log(LOG_DEBUG, LD_NET, "Message from libevent: %s", buf);
  872.       break;
  873.     case _EVENT_LOG_MSG:
  874.       log(LOG_INFO, LD_NET, "Message from libevent: %s", buf);
  875.       break;
  876.     case _EVENT_LOG_WARN:
  877.       log(LOG_WARN, LD_GENERAL, "Warning from libevent: %s", buf);
  878.       break;
  879.     case _EVENT_LOG_ERR:
  880.       log(LOG_ERR, LD_GENERAL, "Error from libevent: %s", buf);
  881.       break;
  882.     default:
  883.       log(LOG_WARN, LD_GENERAL, "Message [%d] from libevent: %s",
  884.           severity, buf);
  885.       break;
  886.   }
  887. }
  888. /** Set hook to intercept log messages from libevent. */
  889. void
  890. configure_libevent_logging(void)
  891. {
  892.   event_set_log_callback(libevent_logging_callback);
  893. }
  894. /** Ignore any libevent log message that contains <b>msg</b>. */
  895. void
  896. suppress_libevent_log_msg(const char *msg)
  897. {
  898.   suppress_msg = msg;
  899. }
  900. #else
  901. void
  902. configure_libevent_logging(void)
  903. {
  904. }
  905. void
  906. suppress_libevent_log_msg(const char *msg)
  907. {
  908.   (void)msg;
  909. }
  910. #endif
  911. #if 0
  912. static void
  913. dump_log_info(logfile_t *lf)
  914. {
  915.   const char *tp;
  916.   if (lf->filename) {
  917.     printf("=== log into "%s" (%s-%s) (%stemporary)n", lf->filename,
  918.            sev_to_string(lf->min_loglevel),
  919.            sev_to_string(lf->max_loglevel),
  920.            lf->is_temporary?"":"not ");
  921.   } else if (lf->is_syslog) {
  922.     printf("=== syslog (%s-%s) (%stemporary)n",
  923.            sev_to_string(lf->min_loglevel),
  924.            sev_to_string(lf->max_loglevel),
  925.            lf->is_temporary?"":"not ");
  926.   } else {
  927.     printf("=== log (%s-%s) (%stemporary)n",
  928.            sev_to_string(lf->min_loglevel),
  929.            sev_to_string(lf->max_loglevel),
  930.            lf->is_temporary?"":"not ");
  931.   }
  932. }
  933. void
  934. describe_logs(void)
  935. {
  936.   logfile_t *lf;
  937.   printf("==== BEGIN LOGS ====n");
  938.   for (lf = logfiles; lf; lf = lf->next)
  939.     dump_log_info(lf);
  940.   printf("==== END LOGS ====n");
  941. }
  942. #endif