1 /* -*- c-file-style: "java"; indent-tabs-mode: nil; tab-width: 4; fill-column: 78 -*- 2 * 3 * librsync -- generate and apply network deltas 4 * 5 * Copyright (C) 2000, 2001, 2002, 2003, 2004 by Martin Pool 6 * Copyright 2007 Google Inc. 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU Lesser General Public License as published by 10 * the Free Software Foundation; either version 2.1 of the License, or 11 * (at your option) any later version. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU Lesser General Public License for more details. 17 * 18 * You should have received a copy of the GNU Lesser General Public License 19 * along with this program; if not, write to the Free Software 20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 21 */ 22 23 24 /** 25 * @file 26 * 27 * Reusable trace library. 28 * 29 * @todo A function like perror that includes strerror output. Apache 30 * does this by adding flags as well as the severity level which say 31 * whether such information should be included. 32 * 33 * @todo Also check in configure for the C9X predefined identifier `_function', or 34 * whatever it's called. 35 **/ 36 37 /* Provide simple macro statement wrappers (adapted from glib, and originally from Perl): 38 * RS_STMT_START { statements; } RS_STMT_END; 39 * can be used as a single statement, as in 40 * if (x) RS_STMT_START { ... } RS_STMT_END; else ... 41 * 42 * For gcc we will wrap the statements within `({' and `})' braces. 43 * For SunOS they will be wrapped within `if (1)' and `else (void) 0', 44 * and otherwise within `do' and `while (0)'. 45 */ 46 #if !(defined (RS_STMT_START) && defined (RS_STMT_END)) 47 # if defined (__GNUC__) && !defined (__STRICT_ANSI__) && !defined (__cplusplus) 48 # define RS_STMT_START (void)( 49 # define RS_STMT_END ) 50 # else 51 # if (defined (sun) || defined (__sun__)) 52 # define RS_STMT_START if (1) 53 # define RS_STMT_END else (void)0 54 # else 55 # define RS_STMT_START do 56 # define RS_STMT_END while (0) 57 # endif 58 # endif 59 #endif 60 61 62 #include <stdarg.h> 63 64 /* unconditionally on */ 65 #define DO_RS_TRACE 66 67 /** 68 * Log severity levels. 69 * 70 * These have the same numeric values as the levels for syslog, at 71 * least in glibc. 72 * 73 * Trace may be turned off. 74 * 75 * Error is always on, but you can return and continue in some way. 76 */ 77 typedef enum { 78 RS_LOG_EMERG = 0, /**< System is unusable */ 79 RS_LOG_ALERT = 1, /**< Action must be taken immediately */ 80 RS_LOG_CRIT = 2, /**< Critical conditions */ 81 RS_LOG_ERR = 3, /**< Error conditions */ 82 RS_LOG_WARNING = 4, /**< Warning conditions */ 83 RS_LOG_NOTICE = 5, /**< Normal but significant condition */ 84 RS_LOG_INFO = 6, /**< Informational */ 85 RS_LOG_DEBUG = 7 /**< Debug-level messages */ 86 } rs_loglevel; 87 88 int rs_loglevel_from_name(const char *name); 89 90 enum { 91 RS_LOG_PRIMASK = 7, /**< Mask to extract priority 92 part. \internal */ 93 94 RS_LOG_NONAME = 8, /**< \b Don't show function name in 95 message. */ 96 97 RS_LOG_NO_PROGRAM = 16, 98 RS_LOG_NO_PID = 32 99 }; 100 101 102 /** 103 * \typedef rs_logger_fn 104 * \brief Callback to write out log messages. 105 * \param level a syslog level. 106 * \param msg message to be logged. 107 * 108 * \param private Opaque data passed in when logger was added. For 109 * example, pointer to file descriptor. 110 */ 111 typedef void rs_logger_fn(int flags, const char *fn, 112 char const *msg, va_list, 113 void *private_ptr, int private_int); 114 115 void rs_format_msg(char *buf, size_t, int, const char *, 116 const char *fmt, va_list); 117 118 void rs_trace_set_level(rs_loglevel level); 119 120 void rs_add_logger(rs_logger_fn *, int level, void *, int); 121 void rs_remove_logger(rs_logger_fn *, int level, void *, int); 122 void rs_remove_all_loggers(void); 123 124 125 void rs_logger_file(int level, const char *fn, char const *fmt, va_list va, 126 void *, int); 127 128 void rs_logger_syslog(int level, const char *fn, char const *fmt, va_list va, 129 void *, int); 130 131 /** Check whether the library was compiled with debugging trace support. */ 132 int rs_supports_trace(void); 133 134 void rs_log0(int level, char const *fn, char const *fmt, ...) 135 #if defined(__GNUC__) 136 __attribute__ ((format(printf, 3, 4))) 137 #endif /* __GNUC__ */ 138 ; 139 140 141 /* TODO: Check for the __FUNCTION__ thing, rather than gnuc */ 142 #if defined(HAVE_VARARG_MACROS) && defined(__GNUC__) 143 144 #if 1 || defined(DO_RS_TRACE) 145 # define rs_trace(fmt, arg...) \ 146 do { rs_log0(RS_LOG_DEBUG, __FUNCTION__, fmt , ##arg); \ 147 } while (0) 148 #else 149 # define rs_trace(s, str...) 150 #endif /* !DO_RS_TRACE */ 151 152 #define rs_log(l, s, str...) do { \ 153 rs_log0((l), __FUNCTION__, (s) , ##str); \ 154 } while (0) 155 156 157 #define rs_log_crit(s, str...) do { \ 158 rs_log0(RS_LOG_CRIT, __FUNCTION__, (s) , ##str); \ 159 } while (0) 160 161 #define rs_log_error(s, str...) do { \ 162 rs_log0(RS_LOG_ERR, __FUNCTION__, (s) , ##str); \ 163 } while (0) 164 165 #define rs_log_notice(s, str...) do { \ 166 rs_log0(RS_LOG_NOTICE, __FUNCTION__, (s) , ##str); \ 167 } while (0) 168 169 #define rs_log_warning(s, str...) do { \ 170 rs_log0(RS_LOG_WARNING, __FUNCTION__, (s) , ##str); \ 171 } while (0) 172 173 #define rs_log_info(s, str...) do { \ 174 rs_log0(RS_LOG_INFO, __FUNCTION__, (s) , ##str); \ 175 } while (0) 176 177 #else /* not defined HAVE_VARARG_MACROS */ 178 179 /* If we don't have gcc vararg macros, then we fall back to making the 180 * log routines just plain functions. On platforms without gcc (boo 181 * hiss!) this means at least you get some messages, but not the nice 182 * function names etc. */ 183 #define rs_log rs_log0_nofn 184 185 #define rs_trace rs_log_trace_nofn 186 #define rs_log_info rs_log_info_nofn 187 #define rs_log_notice rs_log_notice_nofn 188 #define rs_log_warning rs_log_warning_nofn 189 #define rs_log_error rs_log_error_nofn 190 #define rs_log_crit rs_log_critical_nofn 191 #endif /* HAVE_VARARG_MACROS */ 192 193 194 195 void rs_log_trace_nofn(char const *s, ...); 196 void rs_log_info_nofn(char const *, ...); 197 void rs_log_notice_nofn(char const *, ...); 198 void rs_log_warning_nofn(char const *s, ...); 199 void rs_log_error_nofn(char const *s, ...); 200 void rs_log_critical_nofn(char const *, ...); 201 202 void rs_log0_nofn(int level, char const *fmt, ...); 203 204 205 206 /** 207 * \macro rs_trace_enabled() 208 * 209 * Call this before putting too much effort into generating trace 210 * messages. 211 */ 212 213 /* really bool */ 214 extern int rs_trace_syslog; 215 extern int rs_trace_level; 216 217 #ifdef DO_RS_TRACE 218 # define rs_trace_enabled() ((rs_trace_level & RS_LOG_PRIMASK) >= RS_LOG_DEBUG) 219 #else 220 # define rs_trace_enabled() 0 221 #endif 222 223 /** 224 * Name of the program, to be included in log messages. 225 * 226 * @note This must be defined exactly once in each program that links to 227 * trace.c 228 **/ 229 extern const char *rs_program_name; 230 231 void dcc_job_summary_clear(void); 232 void dcc_job_summary(void); 233 void dcc_job_summary_append(const char *s); 234