summaryrefslogtreecommitdiff
path: root/rsync/trace.c
Unidiff
Diffstat (limited to 'rsync/trace.c') (more/less context) (show whitespace changes)
-rw-r--r--rsync/trace.c225
1 files changed, 225 insertions, 0 deletions
diff --git a/rsync/trace.c b/rsync/trace.c
new file mode 100644
index 0000000..b7e2b87
--- a/dev/null
+++ b/rsync/trace.c
@@ -0,0 +1,225 @@
1/*= -*- c-basic-offset: 4; indent-tabs-mode: nil; -*-
2 *
3 * librsync -- library for network deltas
4 * $Id$
5 *
6 * Copyright (C) 2000, 2001 by Martin Pool <mbp@samba.org>
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 | Finality is death.
25 | Perfection is finality.
26 | Nothing is perfect.
27 | There are lumps in it.
28 */
29
30
31
32/*
33 * TODO: Have a bit set in the log level that says not to include the
34 * function name.
35 */
36
37#include <config_rsync.h>
38
39#include <unistd.h>
40#include <stdio.h>
41#include <sys/file.h>
42#include <string.h>
43#include <errno.h>
44#include <stdlib.h>
45#include <assert.h>
46#include <stdarg.h>
47
48#include "rsync.h"
49#include "util.h"
50#include "trace.h"
51
52
53rs_trace_fn_t *rs_trace_impl = rs_trace_stderr;
54
55int rs_trace_level = RS_LOG_INFO;
56
57#ifdef HAVE_PROGRAM_INVOCATION_NAME
58# define MY_NAME program_invocation_short_name
59#else
60# define MY_NAME "librsync"
61#endif
62
63static void rs_log_va(int level, char const *fn, char const *fmt, va_list va);
64
65#if SIZEOF_SIZE_T > SIZEOF_LONG
66# warning size_t is larger than a long integer, values in trace messages may be wrong
67#endif
68
69
70/**
71 * Log severity strings, if any. Must match ordering in
72 * ::rs_loglevel.
73 */
74static const char *rs_severities[] = {
75 "EMERGENCY! ", "ALERT! ", "CRITICAL! ", "ERROR: ", "Warning: ",
76 "", "", ""
77};
78
79
80
81/**
82 * \brief Set the destination of trace information.
83 *
84 * The callback scheme allows for use within applications that may
85 * have their own particular ways of reporting errors: log files for a
86 * web server, perhaps, and an error dialog for a browser.
87 *
88 * \todo Do we really need such fine-grained control, or just yes/no
89 * tracing?
90 */
91void
92rs_trace_to(rs_trace_fn_t * new_impl)
93{
94 rs_trace_impl = new_impl;
95}
96
97
98/**
99 * Set the least important message severity that will be output.
100 */
101void
102rs_trace_set_level(rs_loglevel level)
103{
104 rs_trace_level = level;
105}
106
107
108static void
109rs_log_va(int flags, char const *fn, char const *fmt, va_list va)
110{
111 int level = flags & RS_LOG_PRIMASK;
112
113 if (rs_trace_impl && level <= rs_trace_level) {
114 char buf[1000];
115 char full_buf[1000];
116
117 vsnprintf(buf, sizeof buf - 1, fmt, va);
118
119 if (flags & RS_LOG_NONAME) {
120 snprintf(full_buf, sizeof full_buf - 1,
121 "%s: %s%s\n",
122 MY_NAME, rs_severities[level], buf);
123 } else {
124 snprintf(full_buf, sizeof full_buf - 1,
125 "%s: %s(%s) %s\n",
126 MY_NAME, rs_severities[level], fn, buf);
127 }
128
129 rs_trace_impl(level, full_buf);
130 }
131}
132
133
134
135/**
136 * Called by a macro, used on platforms where we can't determine the
137 * calling function name.
138 */
139void
140rs_log0_nofn(int level, char const *fmt, ...)
141{
142 va_list va;
143
144 va_start(va, fmt);
145 rs_log_va(level, PACKAGE, fmt, va);
146 va_end(va);
147}
148
149
150/* Called by a macro that prepends the calling function name,
151 * etc. */
152void
153rs_log0(int level, char const *fn, char const *fmt, ...)
154{
155 va_list va;
156
157 va_start(va, fmt);
158 rs_log_va(level, fn, fmt, va);
159 va_end(va);
160}
161
162
163void
164rs_trace_stderr(int UNUSED(level), char const *msg)
165{
166 /* NOTE NO TRAILING NUL */
167 write(STDERR_FILENO, msg, strlen(msg));
168}
169
170
171/* This is called directly if the machine doesn't allow varargs
172 * macros. */
173void
174rs_fatal0(char const *s, ...)
175{
176 va_listva;
177
178 va_start(va, s);
179 rs_log_va(RS_LOG_CRIT, PACKAGE, s, va);
180 va_end(va);
181}
182
183
184/* This is called directly if the machine doesn't allow varargs
185 * macros. */
186void
187rs_error0(char const *s, ...)
188{
189 va_listva;
190
191 va_start(va, s);
192 rs_log_va(RS_LOG_ERR, PACKAGE, s, va);
193 va_end(va);
194}
195
196
197/* This is called directly if the machine doesn't allow varargs
198 * macros. */
199void
200rs_trace0(char const *s, ...)
201{
202 va_listva;
203
204 va_start(va, s);
205 rs_log_va(RS_LOG_DEBUG, PACKAGE, s, va);
206 va_end(va);
207}
208
209
210/**
211 * Return true if the library contains trace code; otherwise false.
212 * If this returns false, then trying to turn trace on will achieve
213 * nothing.
214 */
215int
216rs_supports_trace(void)
217{
218#ifdef DO_RS_TRACE
219 return 1;
220#else
221 return 0;
222 #endif /* !DO_RS_TRACE */
223}
224
225