X-Git-Url: http://mj.ucw.cz/gitweb/?a=blobdiff_plain;f=ucw%2Flog-syslog.c;h=ee8b9e8353d8fbe09599a3954085ab80ee1063ab;hb=0db6e10eac28f38bfc3b325b13ad95107c58ce1e;hp=9883f78987a04f0687fdbcfe06763bcd9fb4d06c;hpb=464a5c3067d1fbed8e2f9899e8e3459e7948e07e;p=libucw.git diff --git a/ucw/log-syslog.c b/ucw/log-syslog.c index 9883f789..ee8b9e83 100644 --- a/ucw/log-syslog.c +++ b/ucw/log-syslog.c @@ -8,61 +8,116 @@ * of the GNU Lesser General Public License. */ -#include "ucw/lib.h" -#include "ucw/log.h" +#include +#include +#include #include -/* destructor for syslog logs */ -static void ls_syslog_close(struct log_stream *ls) +struct syslog_stream { + struct log_stream ls; + int facility; +}; + +static int syslog_open_count; + +static void +syslog_close(struct log_stream *ls UNUSED) { - ASSERT(ls); - if(ls->name) - xfree(ls->name); + if (!--syslog_open_count) + closelog(); +} + +/* 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 ls_syslog_convert_level(int level) +/* Convert severity level to syslog constants */ +static int +syslog_level(int level) { - switch(level) - { - case L_DEBUG: return LOG_DEBUG; - case L_INFO: return LOG_INFO; - case L_INFO_R: return LOG_INFO; - case L_WARN: return LOG_WARNING; - case L_WARN_R: return LOG_WARNING; - case L_ERROR: return LOG_ERR; - case L_ERROR_R: return LOG_ERR; - case L_FATAL: return LOG_CRIT; - default: return LOG_NOTICE; - } + static const int levels[] = { + [L_DEBUG] = LOG_DEBUG, + [L_INFO] = LOG_INFO, + [L_INFO_R] = LOG_INFO, + [L_WARN] = LOG_WARNING, + [L_WARN_R] = LOG_WARNING, + [L_ERROR] = LOG_ERR, + [L_ERROR_R] = LOG_ERR, + [L_FATAL] = LOG_CRIT, + }; + return ((level < (int)ARRAY_SIZE(levels)) ? levels[level] : LOG_NOTICE); } /* simple syslog write handler */ -static int ls_syslog_handler(struct log_stream *ls, const char *m, u32 flags) +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); - prio = ls_syslog_convert_level(LS_GET_LEVEL(flags)) | (ls->idata); - if (ls->name) - syslog(prio | (ls->idata), "%s: %s", ls->name, m); - else - syslog(prio | (ls->idata), "%s", 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 *ls_syslog_new(int facility, const char *name) +struct log_stream * +log_new_syslog(const char *facility, int options) { - struct log_stream *ls=ls_new(); - if (name) ls->name = xstrdup(name); - ls->idata = facility; - ls->msgfmt = LSFMT_NONE; - ls->handler = ls_syslog_handler; - ls->close = ls_syslog_close; + 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); +}