$treeview $search $mathjax $extrastylesheet
librsync
2.0.2
$projectbrief
|
$projectbrief
|
$searchbox |
00001 /*= -*- c-basic-offset: 4; indent-tabs-mode: nil; -*- 00002 * 00003 * librsync -- library for network deltas 00004 * 00005 * Copyright (C) 2000, 2001 by Martin Pool <mbp@sourcefrog.net> 00006 * 00007 * This program is free software; you can redistribute it and/or modify 00008 * it under the terms of the GNU Lesser General Public License as published by 00009 * the Free Software Foundation; either version 2.1 of the License, or 00010 * (at your option) any later version. 00011 * 00012 * This program is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 * GNU Lesser General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU Lesser General Public License 00018 * along with this program; if not, write to the Free Software 00019 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 00020 */ 00021 00022 /*= 00023 | Finality is death. 00024 | Perfection is finality. 00025 | Nothing is perfect. 00026 | There are lumps in it. 00027 */ 00028 00029 /** \file trace.c logging and debugging output. 00030 * 00031 * \todo Have a bit set in the log level that says not to include the function 00032 * name. */ 00033 00034 #include "config.h" 00035 #ifdef HAVE_UNISTD_H 00036 # include <unistd.h> 00037 #else 00038 # define STDERR_FILENO 2 00039 #endif 00040 #include <stdio.h> 00041 #ifdef HAVE_SYS_FILE_H 00042 # include <sys/file.h> 00043 #endif 00044 #include <string.h> 00045 #include <errno.h> 00046 #include <stdlib.h> 00047 #include <assert.h> 00048 #include <stdarg.h> 00049 00050 #include "librsync.h" 00051 #include "util.h" 00052 #include "trace.h" 00053 00054 rs_trace_fn_t *rs_trace_impl = rs_trace_stderr; 00055 00056 int rs_trace_level = RS_LOG_INFO; 00057 00058 #ifdef HAVE_PROGRAM_INVOCATION_NAME 00059 # define MY_NAME program_invocation_short_name 00060 #else 00061 # define MY_NAME "librsync" 00062 #endif 00063 00064 static void rs_log_va(int level, char const *fn, char const *fmt, va_list va); 00065 00066 /** Log severity strings, if any. Must match ordering in ::rs_loglevel. */ 00067 static const char *rs_severities[] = { 00068 "EMERGENCY! ", "ALERT! ", "CRITICAL! ", "ERROR: ", "Warning: ", 00069 "", "", "" 00070 }; 00071 00072 /** Set the destination of trace information. 00073 * 00074 * The callback scheme allows for use within applications that may have their 00075 * own particular ways of reporting errors: log files for a web server, 00076 * perhaps, and an error dialog for a browser. 00077 * 00078 * \todo Do we really need such fine-grained control, or just yes/no tracing? */ 00079 void rs_trace_to(rs_trace_fn_t *new_impl) 00080 { 00081 rs_trace_impl = new_impl; 00082 } 00083 00084 void rs_trace_set_level(rs_loglevel level) 00085 { 00086 rs_trace_level = level; 00087 } 00088 00089 static void rs_log_va(int flags, char const *fn, char const *fmt, va_list va) 00090 { 00091 int level = flags & RS_LOG_PRIMASK; 00092 00093 if (rs_trace_impl && level <= rs_trace_level) { 00094 char buf[1000]; 00095 char full_buf[1000]; 00096 00097 vsnprintf(buf, sizeof buf - 1, fmt, va); 00098 00099 if (flags & RS_LOG_NONAME) { 00100 snprintf(full_buf, sizeof full_buf - 1, "%s: %s%s\n", MY_NAME, 00101 rs_severities[level], buf); 00102 } else { 00103 snprintf(full_buf, sizeof full_buf - 1, "%s: %s(%s) %s\n", MY_NAME, 00104 rs_severities[level], fn, buf); 00105 } 00106 00107 rs_trace_impl(level, full_buf); 00108 } 00109 } 00110 00111 /* Called by a macro, used on platforms where we can't determine the calling 00112 function name. */ 00113 void rs_log0_nofn(int level, char const *fmt, ...) 00114 { 00115 va_list va; 00116 00117 va_start(va, fmt); 00118 rs_log_va(level, PACKAGE, fmt, va); 00119 va_end(va); 00120 } 00121 00122 /* Called by a macro that prepends the calling function name, etc. */ 00123 void rs_log0(int level, char const *fn, char const *fmt, ...) 00124 { 00125 va_list va; 00126 00127 va_start(va, fmt); 00128 rs_log_va(level, fn, fmt, va); 00129 va_end(va); 00130 } 00131 00132 void rs_trace_stderr(rs_loglevel UNUSED(level), char const *msg) 00133 { 00134 /* NOTE NO TRAILING NUL */ 00135 write(STDERR_FILENO, msg, strlen(msg)); 00136 } 00137 00138 /* This is called directly if the machine doesn't allow varargs macros. */ 00139 void rs_fatal0(char const *s, ...) 00140 { 00141 va_list va; 00142 00143 va_start(va, s); 00144 rs_log_va(RS_LOG_CRIT, PACKAGE, s, va); 00145 va_end(va); 00146 abort(); 00147 } 00148 00149 /* This is called directly if the machine doesn't allow varargs macros. */ 00150 void rs_error0(char const *s, ...) 00151 { 00152 va_list va; 00153 00154 va_start(va, s); 00155 rs_log_va(RS_LOG_ERR, PACKAGE, s, va); 00156 va_end(va); 00157 } 00158 00159 /* This is called directly if the machine doesn't allow varargs macros. */ 00160 void rs_trace0(char const *s, ...) 00161 { 00162 #ifdef DO_RS_TRACE 00163 va_list va; 00164 00165 va_start(va, s); 00166 rs_log_va(RS_LOG_DEBUG, PACKAGE, s, va); 00167 va_end(va); 00168 #endif /* !DO_RS_TRACE */ 00169 } 00170 00171 int rs_supports_trace(void) 00172 { 00173 #ifdef DO_RS_TRACE 00174 return 1; 00175 #else 00176 return 0; 00177 #endif /* !DO_RS_TRACE */ 00178 }