Home | History | Annotate | Line # | Download | only in gen
      1 /*	$NetBSD: syslog.c,v 1.58 2017/01/12 18:16:52 christos Exp $	*/
      2 
      3 /*
      4  * Copyright (c) 1983, 1988, 1993
      5  *	The Regents of the University of California.  All rights reserved.
      6  *
      7  * Redistribution and use in source and binary forms, with or without
      8  * modification, are permitted provided that the following conditions
      9  * are met:
     10  * 1. Redistributions of source code must retain the above copyright
     11  *    notice, this list of conditions and the following disclaimer.
     12  * 2. Redistributions in binary form must reproduce the above copyright
     13  *    notice, this list of conditions and the following disclaimer in the
     14  *    documentation and/or other materials provided with the distribution.
     15  * 3. Neither the name of the University nor the names of its contributors
     16  *    may be used to endorse or promote products derived from this software
     17  *    without specific prior written permission.
     18  *
     19  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     22  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     23  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     29  * SUCH DAMAGE.
     30  */
     31 
     32 #include <sys/cdefs.h>
     33 #if defined(LIBC_SCCS) && !defined(lint)
     34 #if 0
     35 static char sccsid[] = "@(#)syslog.c	8.5 (Berkeley) 4/29/95";
     36 #else
     37 __RCSID("$NetBSD: syslog.c,v 1.58 2017/01/12 18:16:52 christos Exp $");
     38 #endif
     39 #endif /* LIBC_SCCS and not lint */
     40 
     41 #include "namespace.h"
     42 #include <sys/types.h>
     43 #include <sys/param.h>
     44 #include <sys/socket.h>
     45 #include <sys/syslog.h>
     46 #include <sys/uio.h>
     47 #include <sys/un.h>
     48 #include <netdb.h>
     49 
     50 #include <errno.h>
     51 #include <stdio.h>
     52 #include <fcntl.h>
     53 #include <paths.h>
     54 #include <stdarg.h>
     55 #include <stdio.h>
     56 #include <stdlib.h>
     57 #include <string.h>
     58 #include <time.h>
     59 #include <unistd.h>
     60 
     61 #include "syslog_private.h"
     62 #include "reentrant.h"
     63 #include "extern.h"
     64 
     65 #ifdef __weak_alias
     66 __weak_alias(syslog,_syslog)
     67 __weak_alias(vsyslog,_vsyslog)
     68 __weak_alias(syslogp,_syslogp)
     69 __weak_alias(vsyslogp,_vsyslogp)
     70 __weak_alias(closelog,_closelog)
     71 __weak_alias(openlog,_openlog)
     72 __weak_alias(setlogmask,_setlogmask)
     73 #endif
     74 
     75 static struct syslog_data _syslog_data = SYSLOG_DATA_INIT;
     76 
     77 #ifdef _REENTRANT
     78 static mutex_t	syslog_mutex = MUTEX_INITIALIZER;
     79 #endif
     80 
     81 static size_t
     82 timefun(char *p, size_t tbuf_left)
     83 {
     84 	struct timeval tv;
     85 	time_t now;
     86 	struct tm tmnow;
     87 	size_t prlen;
     88 	char *op = p;
     89 
     90 	if (gettimeofday(&tv, NULL) == -1)
     91 		return snprintf_ss(p, tbuf_left, "-");
     92 
     93 	/* strftime() implies tzset(), localtime_r() doesn't. */
     94 	tzset();
     95 	now = (time_t) tv.tv_sec;
     96 	localtime_r(&now, &tmnow);
     97 
     98 	prlen = strftime(p, tbuf_left, "%FT%T", &tmnow);
     99 	DEC();
    100 	prlen = snprintf(p, tbuf_left, ".%06ld", (long)tv.tv_usec);
    101 	DEC();
    102 	prlen = strftime(p, tbuf_left-1, "%z", &tmnow);
    103 	/* strftime gives eg. "+0200", but we need "+02:00" */
    104 	if (prlen == 5) {
    105 		p[prlen+1] = p[prlen];
    106 		p[prlen]   = p[prlen-1];
    107 		p[prlen-1] = p[prlen-2];
    108 		p[prlen-2] = ':';
    109 		prlen += 1;
    110 	}
    111 	DEC();
    112 	return (size_t)(p - op);
    113 }
    114 
    115 static int
    116 lock(const struct syslog_data *data)
    117 {
    118 	int rv = data == &_syslog_data;
    119 	if (rv)
    120 		mutex_lock(&syslog_mutex);
    121 	return rv;
    122 }
    123 
    124 static int
    125 unlock(const struct syslog_data *data)
    126 {
    127 	int rv = data == &_syslog_data;
    128 	if (rv)
    129 		mutex_unlock(&syslog_mutex);
    130 	return rv;
    131 }
    132 
    133 static struct syslog_fun _syslog_fun = {
    134 	timefun,
    135 	strerror_r,
    136 	vsnprintf,
    137 	lock,
    138 	unlock,
    139 };
    140 
    141 void
    142 openlog(const char *ident, int logstat, int logfac)
    143 {
    144 	openlog_r(ident, logstat, logfac, &_syslog_data);
    145 }
    146 
    147 void
    148 closelog(void)
    149 {
    150 	closelog_r(&_syslog_data);
    151 }
    152 
    153 /* setlogmask -- set the log mask level */
    154 int
    155 setlogmask(int pmask)
    156 {
    157 	return setlogmask_r(pmask, &_syslog_data);
    158 }
    159 
    160 void
    161 openlog_r(const char *ident, int logstat, int logfac, struct syslog_data *data)
    162 {
    163 	lock(data);
    164 	_openlog_unlocked_r(ident, logstat, logfac, data);
    165 	unlock(data);
    166 }
    167 
    168 void
    169 closelog_r(struct syslog_data *data)
    170 {
    171 	lock(data);
    172 	_closelog_unlocked_r(data);
    173 	data->log_tag = NULL;
    174 	unlock(data);
    175 }
    176 
    177 /*
    178  * syslog, vsyslog --
    179  *	print message on log file; output is intended for syslogd(8).
    180  */
    181 void
    182 syslog(int pri, const char *fmt, ...)
    183 {
    184 	va_list ap;
    185 
    186 	va_start(ap, fmt);
    187 	_vxsyslogp_r(pri, &_syslog_fun, &_syslog_data, NULL, NULL, fmt, ap);
    188 	va_end(ap);
    189 }
    190 
    191 void
    192 vsyslog(int pri, const char *fmt, va_list ap)
    193 {
    194 	_vxsyslogp_r(pri, &_syslog_fun, &_syslog_data, NULL, NULL, fmt, ap);
    195 }
    196 
    197 /*
    198  * syslogp, vsyslogp --
    199  *	like syslog but take additional arguments for MSGID and SD
    200  */
    201 void
    202 syslogp(int pri, const char *msgid, const char *sdfmt, const char *msgfmt, ...)
    203 {
    204 	va_list ap;
    205 
    206 	va_start(ap, msgfmt);
    207 	_vxsyslogp_r(pri, &_syslog_fun, &_syslog_data,
    208 	    msgid, sdfmt, msgfmt, ap);
    209 	va_end(ap);
    210 }
    211 
    212 void
    213 vsyslogp(int pri, const char *msgid, const char *sdfmt, const char *msgfmt,
    214     va_list ap)
    215 {
    216 	_vxsyslogp_r(pri, &_syslog_fun, &_syslog_data,
    217 	    msgid, sdfmt, msgfmt, ap);
    218 }
    219 
    220 void
    221 vsyslogp_r(int pri, struct syslog_data *data, const char *msgid,
    222     const char *sdfmt, const char *msgfmt, va_list ap)
    223 {
    224 	_vxsyslogp_r(pri, &_syslog_fun, data, msgid, sdfmt, msgfmt, ap);
    225 }
    226 
    227 void
    228 syslog_r(int pri, struct syslog_data *data, const char *fmt, ...)
    229 {
    230 	va_list ap;
    231 
    232 	va_start(ap, fmt);
    233 	_vxsyslogp_r(pri, &_syslog_fun, data, NULL, NULL, fmt, ap);
    234 	va_end(ap);
    235 }
    236 
    237 void
    238 syslogp_r(int pri, struct syslog_data *data, const char *msgid,
    239 	const char *sdfmt, const char *msgfmt, ...)
    240 {
    241 	va_list ap;
    242 
    243 	va_start(ap, msgfmt);
    244 	_vxsyslogp_r(pri, &_syslog_fun, data, msgid, sdfmt, msgfmt, ap);
    245 	va_end(ap);
    246 }
    247 
    248 void
    249 vsyslog_r(int pri, struct syslog_data *data, const char *fmt, va_list ap)
    250 {
    251 	_vxsyslogp_r(pri, &_syslog_fun, data, NULL, NULL, fmt, ap);
    252 }
    253