librsync  2.0.1
trace.c
1 /*= -*- c-basic-offset: 4; indent-tabs-mode: nil; -*-
2  *
3  * librsync -- library for network deltas
4  *
5  * Copyright (C) 2000, 2001 by Martin Pool <mbp@sourcefrog.net>
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU Lesser General Public License as published by
9  * the Free Software Foundation; either version 2.1 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20  */
21 
22  /*
23  | Finality is death.
24  | Perfection is finality.
25  | Nothing is perfect.
26  | There are lumps in it.
27  */
28 
29 
30 
31 /*
32  * TODO: Have a bit set in the log level that says not to include the
33  * function name.
34  */
35 
36 #include "config.h"
37 #ifdef HAVE_UNISTD_H
38 #include <unistd.h>
39 #else
40 #define STDERR_FILENO 2
41 #endif
42 #include <stdio.h>
43 #ifdef HAVE_SYS_FILE_H
44 #include <sys/file.h>
45 #endif
46 #include <string.h>
47 #include <errno.h>
48 #include <stdlib.h>
49 #include <assert.h>
50 #include <stdarg.h>
51 
52 #include "librsync.h"
53 #include "util.h"
54 #include "trace.h"
55 
56 rs_trace_fn_t *rs_trace_impl = rs_trace_stderr;
57 
58 int rs_trace_level = RS_LOG_INFO;
59 
60 #ifdef HAVE_PROGRAM_INVOCATION_NAME
61 # define MY_NAME program_invocation_short_name
62 #else
63 # define MY_NAME "librsync"
64 #endif
65 
66 static void rs_log_va(int level, char const *fn, char const *fmt, va_list va);
67 
68 
69 /**
70  * Log severity strings, if any. Must match ordering in
71  * ::rs_loglevel.
72  */
73 static const char *rs_severities[] = {
74  "EMERGENCY! ", "ALERT! ", "CRITICAL! ", "ERROR: ", "Warning: ",
75  "", "", ""
76 };
77 
78 
79 
80 /**
81  * \brief Set the destination of trace information.
82  *
83  * The callback scheme allows for use within applications that may
84  * have their own particular ways of reporting errors: log files for a
85  * web server, perhaps, and an error dialog for a browser.
86  *
87  * \todo Do we really need such fine-grained control, or just yes/no
88  * tracing?
89  */
90 void
92 {
93  rs_trace_impl = new_impl;
94 }
95 
96 
97 void
99 {
100  rs_trace_level = level;
101 }
102 
103 
104 static void
105 rs_log_va(int flags, char const *fn, char const *fmt, va_list va)
106 {
107  int level = flags & RS_LOG_PRIMASK;
108 
109  if (rs_trace_impl && level <= rs_trace_level) {
110  char buf[1000];
111  char full_buf[1000];
112 
113  vsnprintf(buf, sizeof buf - 1, fmt, va);
114 
115  if (flags & RS_LOG_NONAME) {
116  snprintf(full_buf, sizeof full_buf - 1,
117  "%s: %s%s\n",
118  MY_NAME, rs_severities[level], buf);
119  } else {
120  snprintf(full_buf, sizeof full_buf - 1,
121  "%s: %s(%s) %s\n",
122  MY_NAME, rs_severities[level], fn, buf);
123  }
124 
125  rs_trace_impl(level, full_buf);
126  }
127 }
128 
129 
130 
131 /**
132  * Called by a macro, used on platforms where we can't determine the
133  * calling function name.
134  */
135 void
136 rs_log0_nofn(int level, char const *fmt, ...)
137 {
138  va_list va;
139 
140  va_start(va, fmt);
141  rs_log_va(level, PACKAGE, fmt, va);
142  va_end(va);
143 }
144 
145 
146 /* Called by a macro that prepends the calling function name,
147  * etc. */
148 void
149 rs_log0(int level, char const *fn, char const *fmt, ...)
150 {
151  va_list va;
152 
153  va_start(va, fmt);
154  rs_log_va(level, fn, fmt, va);
155  va_end(va);
156 }
157 
158 
159 void
160 rs_trace_stderr(rs_loglevel UNUSED(level), char const *msg)
161 {
162  /* NOTE NO TRAILING NUL */
163  write(STDERR_FILENO, msg, strlen(msg));
164 }
165 
166 
167 /* This is called directly if the machine doesn't allow varargs
168  * macros. */
169 void
170 rs_fatal0(char const *s, ...)
171 {
172  va_list va;
173 
174  va_start(va, s);
175  rs_log_va(RS_LOG_CRIT, PACKAGE, s, va);
176  va_end(va);
177  abort();
178 }
179 
180 
181 /* This is called directly if the machine doesn't allow varargs
182  * macros. */
183 void
184 rs_error0(char const *s, ...)
185 {
186  va_list va;
187 
188  va_start(va, s);
189  rs_log_va(RS_LOG_ERR, PACKAGE, s, va);
190  va_end(va);
191 }
192 
193 
194 /* This is called directly if the machine doesn't allow varargs
195  * macros. */
196 void
197 rs_trace0(char const *s, ...)
198 {
199 #ifdef DO_RS_TRACE
200  va_list va;
201 
202  va_start(va, s);
203  rs_log_va(RS_LOG_DEBUG, PACKAGE, s, va);
204  va_end(va);
205 #endif /* !DO_RS_TRACE */
206 }
207 
208 
209 int
211 {
212 #ifdef DO_RS_TRACE
213  return 1;
214 #else
215  return 0;
216 #endif /* !DO_RS_TRACE */
217 }
void rs_trace_fn_t(rs_loglevel level, char const *msg)
Callback to write out log messages.
Definition: librsync.h:138
void rs_trace_to(rs_trace_fn_t *)
Set trace callback.
Definition: trace.c:91
int rs_supports_trace(void)
Check whether the library was compiled with debugging trace.
Definition: trace.c:210
Error conditions.
Definition: librsync.h:123
Public header for librsync.
Informational.
Definition: librsync.h:126
void rs_trace_stderr(rs_loglevel level, char const *msg)
Default trace callback that writes to stderr.
Critical conditions.
Definition: librsync.h:122
void rs_trace_set_level(rs_loglevel level)
Set the least important message severity that will be output.
Definition: trace.c:98
rs_loglevel
Log severity levels.
Definition: librsync.h:119
Debug-level messages.
Definition: librsync.h:127