/*- * Copyright (c) 2003 Andrey Simonenko * 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. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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. */ #include "config.h" #ifndef lint static const char rcsid[] ATTR_UNUSED = "@(#)$Id: ipastat_log.c,v 1.1.4.3 2006/04/09 20:55:56 simon Exp $"; #endif /* !lint */ #include #include #include #include #include "ipa_mod.h" #include "ipastat_log.h" /* * logmsg() and mod_logmsg() save errno on enter and restore errno * on exit, to allow external function to check value of errno, changed * by some function, which caused error. */ static int can_log = 1; /* If non-zero then can send logs. */ static const char *const priomsg[] = { /* IPA_LOG_xxx -> Message */ "", "W: ", "E: " }; /* vlogmsgx() or something like this. */ void (*xvlogmsgx)(int, const char *, va_list); long mypid; /* PID of current process. */ const char *log_ident; /* -i */ #ifdef WITH_PTHREAD # define STRERRBUF_SIZE 128 /* Size of buffer for strerror_r(). */ #endif /* * If a module decides to close and open log, then simply disallow * it to output anything to the log, since there is limited knowledge * what is stderr. */ void open_close_log(void) { can_log = 0; } /* * vprintf-like function, do not output message for errno. */ void vlogmsgx(int priority, const char *format, va_list ap) { fprintf(stderr, "%s[%ld]: %s", log_ident, mypid, priomsg[priority]); vfprintf(stderr, format, ap); fprintf(stderr, "\n"); } /* * Output the program name and a message. */ void logmsgx(int priority, const char *format, ...) { if (can_log) { va_list ap; va_start(ap, format); vlogmsgx(priority, format, ap); va_end(ap); } } /* * vprintf-like function, also output message for errno. */ void vlogmsg(int priority, const char *format, va_list ap) { int errno_save; #ifdef WITH_PTHREAD char strerrbuf[STRERRBUF_SIZE]; #endif errno_save = errno; /* Save errno. */ fprintf(stderr, "%s[%ld]: %s", log_ident, mypid, priomsg[priority]); vfprintf(stderr, format, ap); if (errno_save != 0) { #ifdef WITH_PTHREAD if (strerror_r(errno_save, strerrbuf, sizeof strerrbuf) == 0) fprintf(stderr, ": %s", strerrbuf); else fprintf(stderr, ": error code %d", errno_save); #else fprintf(stderr, ": %s", strerror(errno_save)); #endif } fprintf(stderr, "\n"); errno = errno_save; /* Restore errno. */ } /* * printf-like function, also output message for errno. */ void logmsg(int priority, const char *format, ...) { if (can_log) { int errno_save; va_list ap; errno_save = errno; /* Save errno. */ va_start(ap, format); vlogmsg(priority, format, ap); va_end(ap); errno = errno_save; /* Restore errno. */ } } /* * Call xvlomsgx() which is a pointer to some vlogmsgx-like function. */ void xlogmsgx(int priority, const char *format, ...) { va_list ap; va_start(ap, format); xvlogmsgx(priority, format, ap); va_end(ap); } /* * This function is called by modules to output their * log messages. */ void mod_logmsg(const char *mod_name, int priority, int code, const char *format, va_list ap) { if (can_log) { int errno_save; #ifdef WITH_PTHREAD char strerrbuf[STRERRBUF_SIZE]; #endif errno_save = errno; /* Save errno. */ fprintf(stderr, "%s[%ld]: MOD %s: %s", log_ident, mypid, mod_name, priomsg[priority]); vfprintf(stderr, format, ap); if (code != 0) { #ifdef WITH_PTHREAD if (strerror_r(errno_save, strerrbuf, sizeof strerrbuf) == 0) fprintf(stderr, ": %s", strerrbuf); else fprintf(stderr, ": error code %d", errno_save); #else fprintf(stderr, ": %s", strerror(code)); #endif } fprintf(stderr, "\n"); errno = errno_save; /* Restore errno. */ } } /* * Wrapper for log function from memfunc.c. */ void mvlogmsgx_wrapper(const char *format, va_list ap) { /* * Since mxxx functions log messages when errors * occurred, we simply use fix log priority here. */ vlogmsgx(IPA_LOG_ERR, format, ap); }