Mercurial > notdcc
view 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 |
line wrap: on
line source
/* Distributed Checksum Clearinghouse * * Copyright (c) 2008 by Rhyolite Software, LLC * * This agreement is not applicable to any entity which sells anti-spam * solutions to others or provides an anti-spam solution as part of a * security solution sold to other entities, or to a private network * which employs the DCC or uses data provided by operation of the DCC * but does not provide corresponding data to other users. * * Permission to use, copy, modify, and distribute this software without * changes for any purpose with or without fee is hereby granted, provided * that the above copyright notice and this permission notice appear in all * copies and any distributed versions or copies are either unchanged * or not called anything similar to "DCC" or "Distributed Checksum * Clearinghouse". * * Parties not eligible to receive a license under this agreement can * obtain a commercial license to use DCC by contacting Rhyolite Software * at sales@rhyolite.com. * * A commercial license would be for Distributed Checksum and Reputation * Clearinghouse software. That software includes additional features. This * free license for Distributed ChecksumClearinghouse Software does not in any * way grant permision to use Distributed Checksum and Reputation Clearinghouse * software * * THE SOFTWARE IS PROVIDED "AS IS" AND RHYOLITE SOFTWARE, LLC DISCLAIMS ALL * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL RHYOLITE SOFTWARE, LLC * BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS * SOFTWARE. * * Rhyolite Software DCC 1.3.103-1.53 $Revision$ */ #include "dcc_defs.h" #include "dcc_paths.h" #ifndef DCC_WIN32 #include <syslog.h> #endif extern void dcc_syslog_lock(void); extern void dcc_syslog_unlock(void); u_char trace_quiet; u_char dcc_no_syslog; int dcc_error_priority = LOG_ERR | LOG_MAIL; int dcc_trace_priority = LOG_NOTICE | LOG_MAIL; /* commonly used, but not thread safe */ int dcc_ex_code = EX_UNAVAILABLE; DCC_PATH dcc_progname; int dcc_progname_len; #ifdef HAVE___PROGNAME extern const char *__progname; #endif static void clean_stdfd(int stdfd) { struct stat sb; int fd; if (0 > fstat(stdfd, &sb) && errno == EBADF) { fd = open(_PATH_DEVNULL, 0, O_RDWR); if (fd < 0) /* ignore errors we can't help */ return; if (fd != stdfd) { dup2(fd, stdfd); close(fd); } } } /* prevent surprises from uses of stdio FDs by ensuring that the FDs are open */ void clean_stdio(void) { clean_stdfd(STDIN_FILENO); clean_stdfd(STDOUT_FILENO); clean_stdfd(STDERR_FILENO); } void dcc_syslog_init(u_char use_syslog, const char *argv0 UATTRIB, const char *suffix) { const char *p; /* Solaris defaults to "syslog" with a null identification string, * but does not seem to have __progname set by crt0. */ #undef GOT_PROGNAME #ifdef HAVE_GETPROGNAME p = getprogname(); # define GOT_PROGNAME #endif #if defined(HAVE___PROGNAME) && !defined(GOT_PROGNAME) p = __progname; # define GOT_PROGNAME #endif #ifndef GOT_PROGNAME p = strrchr(argv0, '/'); #ifdef DCC_WIN32 if (!p) p = strrchr(argv0, '\\'); #endif if (!p) p = argv0; else ++p; #ifdef DCC_WIN32 /* strip ".exe" from Windows progam name */ dcc_progname_len = strlen(p); if (dcc_progname_len > LITZ(".exe") && !CLITCMP(&p[dcc_progname_len-LITZ(".exe")], ".exe")) { char *p1 = strdup(p); p1[dcc_progname_len-LITZ(".exe")] = '\0'; p = p1; } #endif /* DCC_WIN32 */ #endif /* !GOT_PROGNAME */ snprintf(dcc_progname, sizeof(dcc_progname), "%s%s", p, suffix ? suffix : ""); dcc_progname_len = strlen(dcc_progname); /* ensure that stdout and stderr exist so that when we open * database or other files, we don't get file descriptor 1 or 2 * and then later write error messages to them. */ clean_stdio(); #ifdef DCC_WIN32 dcc_no_syslog = 1; #else /* Don't wait for the console if somehow we must use it, * because that messes up dccm. */ #ifndef LOG_NOWAIT #define LOG_NOWAIT 0 #endif openlog(dcc_progname, LOG_PID | LOG_NOWAIT, LOG_MAIL); if (!use_syslog) dcc_no_syslog = 1; #endif /* DCC_WIN32 */ } void dcc_vfatal_msg(const char *p, va_list args) { char logbuf[LOGBUF_SIZE]; int i; /* write the message with the "fatal error" addition as * a single message to syslog */ i = vsnprintf(logbuf, sizeof(logbuf), p, args); if (i >= ISZ(logbuf)) strcpy(&logbuf[ISZ(logbuf)-sizeof("...")], "..."); fflush(stdout); /* keep stderr and stdout straight */ fprintf(stderr, "%s; fatal error\n", logbuf); fflush(stderr); if (dcc_no_syslog) return; dcc_syslog_lock(); syslog(dcc_error_priority, "%s; fatal error", logbuf); closelog(); dcc_syslog_unlock(); } int dcc_verror_msg(const char *p, va_list args) { char logbuf[LOGBUF_SIZE]; int i; i = vsnprintf(logbuf, sizeof(logbuf), p, args); if (i >= ISZ(logbuf)) { strcpy(&logbuf[ISZ(logbuf)-sizeof("...")], "..."); i = ISZ(logbuf)-1; } else if (i == 0) { i = snprintf(logbuf, sizeof(logbuf), "(empty error message)"); } fflush(stdout); /* keep stderr and stdout straight */ fwrite(logbuf, i, 1, stderr); if (logbuf[i-1] != '\n') { fwrite("\n", 1, 1, stderr); ++i; } if (!dcc_no_syslog) { dcc_syslog_lock(); syslog(dcc_error_priority, "%s", logbuf); dcc_syslog_unlock(); } return i; } void PATTRIB(1,2) dcc_error_msg(const char *p, ...) { va_list args; va_start(args, p); dcc_verror_msg(p, args); va_end(args); } void dcc_vtrace_msg(const char *p, va_list args) { char logbuf[LOGBUF_SIZE]; int i; /* Some systems including Linux with gcc 3.4.2 on AMD 64 processors * do not allow two uses of a va_list but requires va_copy() * Other systems do not have any notion of va_copy(). */ i = vsnprintf(logbuf, sizeof(logbuf), p, args); if (i >= ISZ(logbuf)) strcpy(&logbuf[ISZ(logbuf)-sizeof("...")], "..."); fflush(stdout); /* keep stderr and stdout straight */ fprintf(stderr, "%s\n", logbuf); if (!dcc_no_syslog) { dcc_syslog_lock(); syslog(dcc_trace_priority, "%s", logbuf); dcc_syslog_unlock(); } } void PATTRIB(1,2) dcc_trace_msg(const char *p, ...) { va_list args; va_start(args, p); dcc_vtrace_msg(p, args); va_end(args); } /* send only to system log if being quiet */ void PATTRIB(1,2) quiet_trace_msg(const char *p, ...) { va_list args; va_start(args, p); if (trace_quiet) { vsyslog(dcc_trace_priority, p, args); } else { dcc_vtrace_msg(p, args); } va_end(args); } void dcc_vpemsg(int ex_code, DCC_EMSG emsg, const char *msg, va_list args) { if (!emsg) { dcc_verror_msg(msg, args); } else { dcc_ex_code = ex_code; vsnprintf(emsg, sizeof(DCC_EMSG), msg, args); } } void PATTRIB(3,4) dcc_pemsg(int ex_code, DCC_EMSG emsg, const char *msg, ...) { va_list args; va_start(args, msg); dcc_vpemsg(ex_code, emsg, msg, args); va_end(args); } const char * fnm_lno(DCC_FNM_LNO_BUF *buf, const char *fnm, int lno) { DCC_PATH tmp; if (!fnm || *fnm == '\0') { buf->b[0] = '\0'; } else { fnm2abs(tmp, fnm, ""); snprintf(buf->b, sizeof(buf->b), DCC_FNM_LNO_PAT, lno, tmp); } return buf->b; } int dcc_vearly_log(EARLY_LOG *el, const char *p, va_list args) { # define ELIPS_STR "...\n" int max_len, len; max_len = sizeof(el->buf) - el->len; if (max_len <= 0) return 0; len = vsnprintf(&el->buf[el->len], max_len, p, args); if (len < max_len) { el->len += len; return len; } else { memcpy(&el->buf[sizeof(el->buf)-LITZ(ELIPS_STR)], ELIPS_STR, LITZ(ELIPS_STR)); el->len = sizeof(el->buf); return max_len; } #undef ELIPS_STR } const char * optopt2str(int i) { static char b[] = "-x"; b[1] = i; return b; }