Mercurial > notdcc
comparison dcclib/error_msg.c @ 0:c7f6b056b673
First import of vendor version
author | Peter Gervai <grin@grin.hu> |
---|---|
date | Tue, 10 Mar 2009 13:49:58 +0100 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:c7f6b056b673 |
---|---|
1 /* Distributed Checksum Clearinghouse | |
2 * | |
3 * Copyright (c) 2008 by Rhyolite Software, LLC | |
4 * | |
5 * This agreement is not applicable to any entity which sells anti-spam | |
6 * solutions to others or provides an anti-spam solution as part of a | |
7 * security solution sold to other entities, or to a private network | |
8 * which employs the DCC or uses data provided by operation of the DCC | |
9 * but does not provide corresponding data to other users. | |
10 * | |
11 * Permission to use, copy, modify, and distribute this software without | |
12 * changes for any purpose with or without fee is hereby granted, provided | |
13 * that the above copyright notice and this permission notice appear in all | |
14 * copies and any distributed versions or copies are either unchanged | |
15 * or not called anything similar to "DCC" or "Distributed Checksum | |
16 * Clearinghouse". | |
17 * | |
18 * Parties not eligible to receive a license under this agreement can | |
19 * obtain a commercial license to use DCC by contacting Rhyolite Software | |
20 * at sales@rhyolite.com. | |
21 * | |
22 * A commercial license would be for Distributed Checksum and Reputation | |
23 * Clearinghouse software. That software includes additional features. This | |
24 * free license for Distributed ChecksumClearinghouse Software does not in any | |
25 * way grant permision to use Distributed Checksum and Reputation Clearinghouse | |
26 * software | |
27 * | |
28 * THE SOFTWARE IS PROVIDED "AS IS" AND RHYOLITE SOFTWARE, LLC DISCLAIMS ALL | |
29 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES | |
30 * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL RHYOLITE SOFTWARE, LLC | |
31 * BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES | |
32 * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, | |
33 * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, | |
34 * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS | |
35 * SOFTWARE. | |
36 * | |
37 * Rhyolite Software DCC 1.3.103-1.53 $Revision$ | |
38 */ | |
39 | |
40 #include "dcc_defs.h" | |
41 #include "dcc_paths.h" | |
42 #ifndef DCC_WIN32 | |
43 #include <syslog.h> | |
44 #endif | |
45 | |
46 extern void dcc_syslog_lock(void); | |
47 extern void dcc_syslog_unlock(void); | |
48 | |
49 u_char trace_quiet; | |
50 | |
51 u_char dcc_no_syslog; | |
52 | |
53 int dcc_error_priority = LOG_ERR | LOG_MAIL; | |
54 int dcc_trace_priority = LOG_NOTICE | LOG_MAIL; | |
55 | |
56 | |
57 /* commonly used, but not thread safe */ | |
58 int dcc_ex_code = EX_UNAVAILABLE; | |
59 | |
60 | |
61 DCC_PATH dcc_progname; | |
62 int dcc_progname_len; | |
63 | |
64 #ifdef HAVE___PROGNAME | |
65 extern const char *__progname; | |
66 #endif | |
67 | |
68 | |
69 static void | |
70 clean_stdfd(int stdfd) | |
71 { | |
72 struct stat sb; | |
73 int fd; | |
74 | |
75 if (0 > fstat(stdfd, &sb) && errno == EBADF) { | |
76 fd = open(_PATH_DEVNULL, 0, O_RDWR); | |
77 if (fd < 0) /* ignore errors we can't help */ | |
78 return; | |
79 if (fd != stdfd) { | |
80 dup2(fd, stdfd); | |
81 close(fd); | |
82 } | |
83 } | |
84 } | |
85 | |
86 | |
87 | |
88 /* prevent surprises from uses of stdio FDs by ensuring that the FDs are open */ | |
89 void | |
90 clean_stdio(void) | |
91 { | |
92 clean_stdfd(STDIN_FILENO); | |
93 clean_stdfd(STDOUT_FILENO); | |
94 clean_stdfd(STDERR_FILENO); | |
95 } | |
96 | |
97 | |
98 | |
99 void | |
100 dcc_syslog_init(u_char use_syslog, | |
101 const char *argv0 UATTRIB, const char *suffix) | |
102 { | |
103 const char *p; | |
104 | |
105 /* Solaris defaults to "syslog" with a null identification string, | |
106 * but does not seem to have __progname set by crt0. */ | |
107 #undef GOT_PROGNAME | |
108 #ifdef HAVE_GETPROGNAME | |
109 p = getprogname(); | |
110 # define GOT_PROGNAME | |
111 #endif | |
112 #if defined(HAVE___PROGNAME) && !defined(GOT_PROGNAME) | |
113 p = __progname; | |
114 # define GOT_PROGNAME | |
115 #endif | |
116 #ifndef GOT_PROGNAME | |
117 p = strrchr(argv0, '/'); | |
118 #ifdef DCC_WIN32 | |
119 if (!p) | |
120 p = strrchr(argv0, '\\'); | |
121 #endif | |
122 if (!p) | |
123 p = argv0; | |
124 else | |
125 ++p; | |
126 #ifdef DCC_WIN32 | |
127 /* strip ".exe" from Windows progam name */ | |
128 dcc_progname_len = strlen(p); | |
129 if (dcc_progname_len > LITZ(".exe") | |
130 && !CLITCMP(&p[dcc_progname_len-LITZ(".exe")], ".exe")) { | |
131 char *p1 = strdup(p); | |
132 p1[dcc_progname_len-LITZ(".exe")] = '\0'; | |
133 p = p1; | |
134 } | |
135 #endif /* DCC_WIN32 */ | |
136 #endif /* !GOT_PROGNAME */ | |
137 snprintf(dcc_progname, sizeof(dcc_progname), "%s%s", | |
138 p, suffix ? suffix : ""); | |
139 dcc_progname_len = strlen(dcc_progname); | |
140 | |
141 /* ensure that stdout and stderr exist so that when we open | |
142 * database or other files, we don't get file descriptor 1 or 2 | |
143 * and then later write error messages to them. */ | |
144 clean_stdio(); | |
145 | |
146 #ifdef DCC_WIN32 | |
147 dcc_no_syslog = 1; | |
148 #else | |
149 /* Don't wait for the console if somehow we must use it, | |
150 * because that messes up dccm. */ | |
151 #ifndef LOG_NOWAIT | |
152 #define LOG_NOWAIT 0 | |
153 #endif | |
154 openlog(dcc_progname, LOG_PID | LOG_NOWAIT, LOG_MAIL); | |
155 if (!use_syslog) | |
156 dcc_no_syslog = 1; | |
157 #endif /* DCC_WIN32 */ | |
158 } | |
159 | |
160 | |
161 | |
162 void | |
163 dcc_vfatal_msg(const char *p, va_list args) | |
164 { | |
165 char logbuf[LOGBUF_SIZE]; | |
166 int i; | |
167 | |
168 /* write the message with the "fatal error" addition as | |
169 * a single message to syslog */ | |
170 i = vsnprintf(logbuf, sizeof(logbuf), p, args); | |
171 if (i >= ISZ(logbuf)) | |
172 strcpy(&logbuf[ISZ(logbuf)-sizeof("...")], "..."); | |
173 | |
174 fflush(stdout); /* keep stderr and stdout straight */ | |
175 fprintf(stderr, "%s; fatal error\n", logbuf); | |
176 fflush(stderr); | |
177 | |
178 if (dcc_no_syslog) | |
179 return; | |
180 | |
181 dcc_syslog_lock(); | |
182 syslog(dcc_error_priority, "%s; fatal error", logbuf); | |
183 closelog(); | |
184 dcc_syslog_unlock(); | |
185 } | |
186 | |
187 | |
188 | |
189 int | |
190 dcc_verror_msg(const char *p, va_list args) | |
191 { | |
192 char logbuf[LOGBUF_SIZE]; | |
193 int i; | |
194 | |
195 i = vsnprintf(logbuf, sizeof(logbuf), p, args); | |
196 if (i >= ISZ(logbuf)) { | |
197 strcpy(&logbuf[ISZ(logbuf)-sizeof("...")], "..."); | |
198 i = ISZ(logbuf)-1; | |
199 } else if (i == 0) { | |
200 i = snprintf(logbuf, sizeof(logbuf), "(empty error message)"); | |
201 } | |
202 | |
203 fflush(stdout); /* keep stderr and stdout straight */ | |
204 fwrite(logbuf, i, 1, stderr); | |
205 if (logbuf[i-1] != '\n') { | |
206 fwrite("\n", 1, 1, stderr); | |
207 ++i; | |
208 } | |
209 | |
210 if (!dcc_no_syslog) { | |
211 dcc_syslog_lock(); | |
212 syslog(dcc_error_priority, "%s", logbuf); | |
213 dcc_syslog_unlock(); | |
214 } | |
215 | |
216 return i; | |
217 } | |
218 | |
219 | |
220 | |
221 void PATTRIB(1,2) | |
222 dcc_error_msg(const char *p, ...) | |
223 { | |
224 va_list args; | |
225 | |
226 va_start(args, p); | |
227 dcc_verror_msg(p, args); | |
228 va_end(args); | |
229 } | |
230 | |
231 | |
232 | |
233 void | |
234 dcc_vtrace_msg(const char *p, va_list args) | |
235 { | |
236 char logbuf[LOGBUF_SIZE]; | |
237 int i; | |
238 | |
239 /* Some systems including Linux with gcc 3.4.2 on AMD 64 processors | |
240 * do not allow two uses of a va_list but requires va_copy() | |
241 * Other systems do not have any notion of va_copy(). */ | |
242 i = vsnprintf(logbuf, sizeof(logbuf), p, args); | |
243 if (i >= ISZ(logbuf)) | |
244 strcpy(&logbuf[ISZ(logbuf)-sizeof("...")], "..."); | |
245 | |
246 fflush(stdout); /* keep stderr and stdout straight */ | |
247 fprintf(stderr, "%s\n", logbuf); | |
248 | |
249 if (!dcc_no_syslog) { | |
250 dcc_syslog_lock(); | |
251 syslog(dcc_trace_priority, "%s", logbuf); | |
252 dcc_syslog_unlock(); | |
253 } | |
254 } | |
255 | |
256 | |
257 | |
258 void PATTRIB(1,2) | |
259 dcc_trace_msg(const char *p, ...) | |
260 { | |
261 va_list args; | |
262 | |
263 va_start(args, p); | |
264 dcc_vtrace_msg(p, args); | |
265 va_end(args); | |
266 } | |
267 | |
268 | |
269 | |
270 /* send only to system log if being quiet */ | |
271 void PATTRIB(1,2) | |
272 quiet_trace_msg(const char *p, ...) | |
273 { | |
274 va_list args; | |
275 | |
276 va_start(args, p); | |
277 if (trace_quiet) { | |
278 vsyslog(dcc_trace_priority, p, args); | |
279 } else { | |
280 dcc_vtrace_msg(p, args); | |
281 } | |
282 va_end(args); | |
283 } | |
284 | |
285 | |
286 | |
287 void | |
288 dcc_vpemsg(int ex_code, DCC_EMSG emsg, const char *msg, va_list args) | |
289 { | |
290 if (!emsg) { | |
291 dcc_verror_msg(msg, args); | |
292 } else { | |
293 dcc_ex_code = ex_code; | |
294 vsnprintf(emsg, sizeof(DCC_EMSG), msg, args); | |
295 } | |
296 } | |
297 | |
298 | |
299 | |
300 void PATTRIB(3,4) | |
301 dcc_pemsg(int ex_code, DCC_EMSG emsg, const char *msg, ...) | |
302 { | |
303 va_list args; | |
304 | |
305 va_start(args, msg); | |
306 dcc_vpemsg(ex_code, emsg, msg, args); | |
307 va_end(args); | |
308 } | |
309 | |
310 | |
311 | |
312 const char * | |
313 fnm_lno(DCC_FNM_LNO_BUF *buf, const char *fnm, int lno) | |
314 { | |
315 DCC_PATH tmp; | |
316 | |
317 if (!fnm || *fnm == '\0') { | |
318 buf->b[0] = '\0'; | |
319 } else { | |
320 fnm2abs(tmp, fnm, ""); | |
321 snprintf(buf->b, sizeof(buf->b), DCC_FNM_LNO_PAT, lno, tmp); | |
322 } | |
323 return buf->b; | |
324 } | |
325 | |
326 | |
327 | |
328 int | |
329 dcc_vearly_log(EARLY_LOG *el, const char *p, va_list args) | |
330 { | |
331 # define ELIPS_STR "...\n" | |
332 int max_len, len; | |
333 | |
334 max_len = sizeof(el->buf) - el->len; | |
335 if (max_len <= 0) | |
336 return 0; | |
337 | |
338 len = vsnprintf(&el->buf[el->len], max_len, p, args); | |
339 if (len < max_len) { | |
340 el->len += len; | |
341 return len; | |
342 } else { | |
343 memcpy(&el->buf[sizeof(el->buf)-LITZ(ELIPS_STR)], | |
344 ELIPS_STR, LITZ(ELIPS_STR)); | |
345 el->len = sizeof(el->buf); | |
346 return max_len; | |
347 } | |
348 | |
349 #undef ELIPS_STR | |
350 } | |
351 | |
352 | |
353 | |
354 const char * | |
355 optopt2str(int i) | |
356 { | |
357 static char b[] = "-x"; | |
358 | |
359 b[1] = i; | |
360 return b; | |
361 } |