log/log_internal.c

Go to the documentation of this file.
00001 // Copyright (C) 2006-2007 Benedikt Böhm <hollow@gentoo.org>
00002 //
00003 // This program is free software; you can redistribute it and/or
00004 // modify it under the terms of the GNU General Public License
00005 // as published by the Free Software Foundation; either version 2
00006 // of the License, or (at your option) any later version.
00007 //
00008 // This program is distributed in the hope that it will be useful,
00009 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00010 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00011 // GNU General Public License for more details.
00012 //
00013 // You should have received a copy of the GNU General Public License
00014 // along with this program; if not, write to the Free Software
00015 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
00016 
00017 #include <unistd.h>
00018 #include <stdlib.h>
00019 #include <errno.h>
00020 #include <stdarg.h>
00021 #include <syslog.h>
00022 #include <string.h>
00023 #include <time.h>
00024 
00025 #include "log.h"
00026 #include "mem.h"
00027 #include "printf.h"
00028 #include "str.h"
00029 
00030 extern log_options_t *_log_options;
00031 
00032 static int errno_orig = 0;
00033 
00034 static
00035 void log_fd(int fd, int prio, const char *msg)
00036 {
00037         char timebuf[17];
00038         time_t curtime = time(0);
00039 
00040         if (!(_log_options->log_mask & (1 << prio)))
00041                 return;
00042 
00043         if (_log_options->log_opts & LOGO_PRIO) {
00044                 switch (prio) {
00045                         case LOGP_ALERT: _lucid_dprintf(fd, "[alert]"); break;
00046                         case LOGP_ERROR: _lucid_dprintf(fd, "[error]"); break;
00047                         case LOGP_WARN:  _lucid_dprintf(fd, "[warn ]"); break;
00048                         case LOGP_NOTE:  _lucid_dprintf(fd, "[note ]"); break;
00049                         case LOGP_INFO:  _lucid_dprintf(fd, "[info ]"); break;
00050                         case LOGP_DEBUG: _lucid_dprintf(fd, "[debug]"); break;
00051                         case LOGP_TRACE: _lucid_dprintf(fd, "[trace]"); break;
00052                         default:         _lucid_dprintf(fd, "[none ]"); break;
00053                 }
00054         }
00055 
00056         if (_log_options->log_opts & LOGO_TIME) {
00057                 mem_set(timebuf, 0, 17);
00058                 strftime(timebuf, 17, "%b %d %T", localtime(&curtime));
00059                 _lucid_dprintf(fd, " %s", timebuf);
00060         }
00061 
00062         if (_log_options->log_opts & LOGO_IDENT)
00063                 _lucid_dprintf(fd, " %s", _log_options->log_ident);
00064 
00065         if (_log_options->log_opts & LOGO_PID)
00066                 _lucid_dprintf(fd, "[%d]", getpid());
00067 
00068         _lucid_dprintf(fd, "%s%s\n",
00069                         _log_options->log_opts ? ": " : "", msg);
00070 }
00071 
00072 static
00073 int prio_to_syslog(int prio)
00074 {
00075         switch (prio) {
00076                 case LOGP_ALERT: return LOG_ALERT;
00077                 case LOGP_ERROR: return LOG_ERR;
00078                 case LOGP_WARN:  return LOG_WARNING;
00079                 case LOGP_NOTE:  return LOG_NOTICE;
00080                 case LOGP_INFO:  return LOG_INFO;
00081                 case LOGP_DEBUG: return LOG_DEBUG;
00082         }
00083 
00084         return -1;
00085 }
00086 
00087 static
00088 void log_internal(int prio, int strerr, const char *fmt, va_list ap)
00089 {
00090         char *buf, *msg;
00091 
00092         if (!_log_options)
00093                 return;
00094 
00095         _lucid_vasprintf(&msg, fmt, ap);
00096 
00097         if (strerr) {
00098                 buf = msg;
00099                 _lucid_asprintf(&msg, "%s: %s", buf, strerror(errno_orig));
00100                 mem_free(buf);
00101         }
00102 
00103         if (_log_options->log_dest & LOGD_STDERR)
00104                 log_fd(STDERR_FILENO, prio, msg);
00105 
00106         if (_log_options->log_dest & LOGD_FILE)
00107                 log_fd(_log_options->log_fd, prio, msg);
00108 
00109         if (_log_options->log_dest & LOGD_SYSLOG) {
00110                 if ((prio = prio_to_syslog(prio)) >= 0)
00111                         syslog(_log_options->log_facility|prio, "%s", msg);
00112         }
00113 
00114         mem_free(msg);
00115 }
00116 
00117 int log_traceme(const char *file, const char *func, int line)
00118 {
00119         char *base = str_path_basename(file);
00120 
00121         int rc = log_trace("@%s() in %s:%d", func, base, line);
00122 
00123         mem_free(base);
00124 
00125         return rc;
00126 }
00127 
00128 #define LOGFUNC(name, level, rc) \
00129 int log_ ## name (const char *fmt, ...) { \
00130         va_list ap; va_start(ap, fmt); \
00131         log_internal(level, 0, fmt, ap); \
00132         va_end(ap); \
00133         return rc; \
00134 }
00135 
00136 LOGFUNC(alert,  LOGP_ALERT, EXIT_FAILURE)
00137 LOGFUNC(error,  LOGP_ERROR, EXIT_FAILURE)
00138 LOGFUNC(warn,   LOGP_WARN,  EXIT_SUCCESS)
00139 LOGFUNC(notice, LOGP_NOTE,  EXIT_SUCCESS)
00140 LOGFUNC(info,   LOGP_INFO,  EXIT_SUCCESS)
00141 LOGFUNC(debug,  LOGP_DEBUG, EXIT_SUCCESS)
00142 LOGFUNC(trace,  LOGP_TRACE, EXIT_SUCCESS)
00143 
00144 #define LOGFUNCDIE(name, level) \
00145 void log_ ## name ## _and_die(const char *fmt, ...) { \
00146         va_list ap; va_start(ap, fmt); \
00147         log_internal(level, 0, fmt, ap); \
00148         va_end(ap); \
00149         exit(EXIT_FAILURE); \
00150 }
00151 
00152 LOGFUNCDIE(alert, LOGP_ALERT)
00153 LOGFUNCDIE(error, LOGP_ERROR)
00154 
00155 #define LOGPFUNC(name, level, rc) \
00156 int log_p ## name (const char *fmt, ...) { \
00157         errno_orig = errno; \
00158         va_list ap; va_start(ap, fmt); \
00159         log_internal(level, 1, fmt, ap); \
00160         va_end(ap); \
00161         return rc; \
00162 }
00163 
00164 LOGPFUNC(alert,  LOGP_ALERT, EXIT_FAILURE)
00165 LOGPFUNC(error,  LOGP_ERROR, EXIT_FAILURE)
00166 LOGPFUNC(warn,   LOGP_WARN,  EXIT_SUCCESS)
00167 LOGPFUNC(notice, LOGP_NOTE,  EXIT_SUCCESS)
00168 LOGPFUNC(info,   LOGP_INFO,  EXIT_SUCCESS)
00169 LOGPFUNC(debug,  LOGP_DEBUG, EXIT_SUCCESS)
00170 LOGPFUNC(trace,  LOGP_TRACE, EXIT_SUCCESS)
00171 
00172 #define LOGPFUNCDIE(name, level) \
00173 void log_p ## name ## _and_die(const char *fmt, ...) { \
00174         errno_orig = errno; \
00175         va_list ap; va_start(ap, fmt); \
00176         log_internal(level, 1, fmt, ap); \
00177         va_end(ap); \
00178         exit(EXIT_FAILURE); \
00179 }
00180 
00181 LOGPFUNCDIE(alert, LOGP_ALERT)
00182 LOGPFUNCDIE(error, LOGP_ERROR)

Generated on Tue Jun 19 20:38:26 2007 for lucid by  doxygen 1.5.2