X-Git-Url: http://mj.ucw.cz/gitweb/?a=blobdiff_plain;f=ucw%2Flog-syslog.c;h=ee8b9e8353d8fbe09599a3954085ab80ee1063ab;hb=b4aae2e94174b491161bd461b049c6d1b3b3602f;hp=dc1df456504687e35e5221e00d22a00a240e4927;hpb=e4e9c9fbf717d89be923695603d0cd5fc6c40cfa;p=libucw.git diff --git a/ucw/log-syslog.c b/ucw/log-syslog.c index dc1df456..ee8b9e83 100644 --- a/ucw/log-syslog.c +++ b/ucw/log-syslog.c @@ -8,20 +8,64 @@ * of the GNU Lesser General Public License. */ -#include "ucw/lib.h" -#include "ucw/log.h" +#include +#include +#include #include -/* Destructor */ +struct syslog_stream { + struct log_stream ls; + int facility; +}; + +static int syslog_open_count; + static void -syslog_close(struct log_stream *ls) +syslog_close(struct log_stream *ls UNUSED) { - if (ls->name) - xfree(ls->name); + if (!--syslog_open_count) + closelog(); } -/* convert severity level to syslog constants */ +/* Convert syslog facility to its identifier. */ +static int +syslog_facility(const char *name) +{ + // Unfortunately, there is no standard way how to get at the list of facility names + static const struct { + const char *name; + int id; + } facilities[] = { + { "auth", LOG_AUTH }, + { "authpriv", LOG_AUTHPRIV }, + { "cron", LOG_CRON }, + { "daemon", LOG_DAEMON }, + { "ftp", LOG_FTP }, + { "kern", LOG_KERN }, + { "lpr", LOG_LPR }, + { "mail", LOG_MAIL }, + { "news", LOG_NEWS }, + { "syslog", LOG_SYSLOG }, + { "user", LOG_USER }, + { "uucp", LOG_UUCP }, + { "local0", LOG_LOCAL0 }, + { "local1", LOG_LOCAL1 }, + { "local2", LOG_LOCAL2 }, + { "local3", LOG_LOCAL3 }, + { "local4", LOG_LOCAL4 }, + { "local5", LOG_LOCAL5 }, + { "local6", LOG_LOCAL6 }, + { "local7", LOG_LOCAL7 }, + }; + + for (uns i=0; i < ARRAY_SIZE(facilities); i++) + if (!strcmp(facilities[i].name, name)) + return facilities[i].id; + return -1; +} + +/* Convert severity level to syslog constants */ static int syslog_level(int level) { @@ -42,31 +86,38 @@ syslog_level(int level) static int syslog_handler(struct log_stream *ls, struct log_msg *m) { + struct syslog_stream *ss = (struct syslog_stream *) ls; int prio; ASSERT(ls); ASSERT(m); - // FIXME: Logging of PID - prio = syslog_level(LS_GET_LEVEL(m->flags)) | (ls->idata); - if (ls->name) - syslog(prio | (ls->idata), "%s: %s", ls->name, m->m); - else - syslog(prio | (ls->idata), "%s", m->m); + prio = syslog_level(LS_GET_LEVEL(m->flags)) | ss->facility; + syslog(prio, "%s", m->m); return 0; } -/* assign log to a syslog facility */ -/* initialize with no formatting (syslog adds these inforamtion) */ -/* name is optional prefix (NULL for none) */ struct log_stream * -log_new_syslog(int facility, const char *name) +log_new_syslog(const char *facility, int options) { - struct log_stream *ls = log_new_stream(); - if (name) - ls->name = xstrdup(name); - ls->idata = facility; - ls->msgfmt = LSFMT_NONE; + int fac = syslog_facility(facility); + if (fac < 0) + die("No such syslog facility: %s", facility); + + struct log_stream *ls = log_new_stream(sizeof(struct syslog_stream)); + struct syslog_stream *ss = (struct syslog_stream *) ls; + ls->name = "syslog"; + ls->msgfmt = 0; ls->handler = syslog_handler; ls->close = syslog_close; + ss->facility = fac; + + if (!syslog_open_count++) + openlog(log_title, options, LOG_INFO); return ls; } + +int +log_syslog_facility_exists(const char *facility) +{ + return (syslog_facility(facility) >= 0); +}