/* $CoreSDI: log.c,v 1.15 2001/08/29 22:19:34 claudio Exp $ */ /* * Copyright (c) 2000, 2001, Core SDI S.A., Argentina * All rights reserved * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither name of the Core SDI S.A. nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef WIN32 /* Unix */ #include #include #include #include #include #include #include #include #include #else /* Win32 */ #include #include #include #include #include #include "exits.h" #include "winsyslog.h" #endif /* WIN32 */ #include "sysdep.h" #include "log.h" static int _facility = 0; static LOGFLAGS _flags = LOGF_NOLOG; #define CLEANUP_MAX 32 static int _cleanups = 0; static void *_arg[CLEANUP_MAX]; static void (*_func[CLEANUP_MAX])(void *); /* * _log_cleanup(): * Call all cleanup functions in stack order. */ static void _log_cleanup() { while (_cleanups--) _func[_cleanups](_arg[_cleanups]); } /* * log_init(): * Initialize log system. */ void log_init(LOGFLAGS flags, int facility) { _flags = flags; _facility = facility; } /* * log_vmsg(): * log_msg(): * Log generic (not empty) message. */ void log_vmsg(int level, const char *fmt, va_list ap) { char msg[LINE_MAX], *src; extern char *__progname; if (_flags & LOGF_NOLOG) return; if (*fmt == '\0') return; switch (level) { case LOG_INFO: src = ""; break; case LOG_WARNING: src = "Warning: "; break; case LOG_DEBUG: src = "Debug: "; break; case LOG_ERR: default: level = LOG_ERR; src = "Error: "; } /* Do not log empty messages */ if (*fmt != '\0') { if (_flags & LOGF_STDERR) { snprintf(msg, sizeof(msg), "%s: %s%s\n", __progname, src, fmt); vfprintf(stderr, msg, ap); } else { snprintf(msg, sizeof(msg), "%s%s\n", src, fmt); openlog(__progname, LOG_PID, _facility); vsyslog(_facility | level, msg, ap); closelog(); } } } void log_msg(int level, const char *fmt, ...) { va_list ap; va_start(ap, fmt); log_vmsg(level, fmt, ap); va_end(ap); } /* * log_session(): * Log session message. */ void log_session(const char *fmt, ...) { if (_flags & LOGF_SESSION) { va_list ap; va_start(ap, fmt); log_vmsg(LOG_INFO, fmt, ap); va_end(ap); } } /* * log_vcmd(): * Log username and command. */ void log_vcmd(const char *user, const char *status, const char *fmt, va_list ap) { char command[LINE_MAX]; vsnprintf(command, sizeof(command), fmt, ap); log_session("User: %s. Command: %s. Status: %s.", user, command, status); } /* * log_cmd(): * Log username and command. */ void log_cmd(const char *user, const char *status, const char *fmt, ...) { va_list ap; va_start(ap, fmt); log_vcmd(user, status, fmt, ap); va_end(ap); } /* * log_debug(): * Log debugging messages. */ void log_debug(const char *fmt, ...) { if (_flags & LOGF_DEBUG) { va_list ap; va_start(ap, fmt); log_vmsg(LOG_DEBUG, fmt, ap); va_end(ap); } } /* * log_warn(): * Log warning messages. */ void log_warn(const char *fmt, ...) { if (_flags & LOGF_ERROR) { va_list ap; va_start(ap, fmt); log_vmsg(LOG_WARNING, fmt, ap); va_end(ap); } } /* * log_err(): * Log error messages. */ void log_err(const char *fmt, ...) { if (_flags & LOGF_ERROR) { va_list ap; va_start(ap, fmt); log_vmsg(LOG_ERR, fmt, ap); va_end(ap); } } /* * log_fatal(): * Log fatal messages, call cleanup functions, and exit(3). * See cleanup_add(). */ void log_fatal(int ecode, const char *fmt, ...) { if (_flags & LOGF_ERROR) { va_list ap; va_start(ap, fmt); log_vmsg(LOG_ERR, fmt, ap); va_end(ap); } _log_cleanup(); exit(ecode); } /* * cleanup_add(): * Add a cleanup function. See log_fatal(). */ int cleanup_add(void(*fn)(void *), void *arg) { if (_cleanups < CLEANUP_MAX && fn != NULL) { _func[_cleanups] = fn; _arg[_cleanups++] = arg; return (0); } return (-1); } /* * cleanup_rm_all(): * Remove all cleanup functions. */ void cleanup_rm_all() { _cleanups = 0; }