2 * Copyright (c) 1983, 1988 Regents of the University of California.
5 * Redistribution and use in source and binary forms are permitted provided
6 * that: (1) source distributions retain this entire copyright notice and
7 * comment, and (2) distributions including binaries display the following
8 * acknowledgement: ``This product includes software developed by the
9 * University of California, Berkeley and its contributors'' in the
10 * documentation or other materials provided with the distribution and in
11 * all advertising materials mentioning features or use of this software.
12 * Neither the name of the University nor the names of its contributors may
13 * be used to endorse or promote products derived from this software without
14 * specific prior written permission.
15 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
16 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
17 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
20 #if defined(LIBC_SCCS) && !defined(lint)
21 static char sccsid[] = "@(#)syslog.c 5.28 (Berkeley) 6/27/90";
22 #endif /* LIBC_SCCS and not lint */
25 * SYSLOG -- print message on log file
27 * This routine looks a lot like printf, except that it outputs to the
28 * log file instead of the standard output. Also:
30 * prints the module name in front of the message,
31 * has some other formatting types (or will sometime),
32 * adds a newline on the end of the message.
34 * The output of this routine is intended to be read by syslogd(8).
37 * Modified to use UNIX domain IPC by Ralph Campbell
39 * Sat Dec 11 11:58:31 CST 1993: Dr. Wettstein
40 * Changes to allow compilation with no complains under -Wall.
42 * Thu Jan 18 11:16:11 CST 1996: Dr. Wettstein
43 * Added patch to close potential security hole. This is the same
44 * patch which was announced in the linux-security mailing lists
45 * and incorporated into the libc version of syslog.c.
47 * Sun Mar 11 20:23:44 CET 2001: Martin Schulze <joey@infodrom.ffis.de>
48 * Use SOCK_DGRAM for loggin, renables it to work.
50 * Wed Aug 27 17:48:16 CEST 2003: Martin Schulze <joey@Infodrom.org>
51 * Improved patch by Michael Pomraning <mjp@securepipe.com> to
52 * reconnect klogd to the logger after it went away.
55 #include <sys/types.h>
56 #include <sys/socket.h>
58 #include <sys/signal.h>
59 #include <sys/syslog.h>
62 #include "pathnames.h"
76 #define _PATH_LOGNAME "/dev/log"
78 static int LogFile = -1; /* fd for log */
79 static int connected; /* have done connect */
80 static int LogStat = 0; /* status bits, set by openlog() */
81 static const char *LogTag = "syslog"; /* string to tag the entry with */
82 static int LogFacility = LOG_USER; /* default facility code */
85 syslog(int pri, const char *fmt, ...)
90 vsyslog(pri, fmt, ap);
105 char tbuf[2048], fmt_cpy[1024], *stdp = (char *) 0;
109 /* see if we should just throw out this message */
110 if (!LOG_MASK(LOG_PRI(pri)) || (pri &~ (LOG_PRIMASK|LOG_FACMASK)))
112 if (LogFile < 0 || !connected)
113 openlog(LogTag, LogStat | LOG_NDELAY, LogFacility);
115 /* set default facility if none specified */
116 if ((pri & LOG_FACMASK) == 0)
119 /* build the message */
121 (void)sprintf(tbuf, "<%d>%.15s ", pri, ctime(&now) + 4);
122 for (p = tbuf; *p; ++p);
123 if (LogStat & LOG_PERROR)
126 (void)strcpy(p, LogTag);
129 if (LogStat & LOG_PID) {
130 (void)sprintf(p, "[%d]", getpid());
138 /* substitute error message for %m */
140 register char ch, *t1, *t2;
144 (ch = *fmt) != '\0' && t1<fmt_cpy+sizeof(fmt_cpy);
146 if (ch == '%' && fmt[1] == 'm') {
148 for (t2 = strerror(saved_errno);
149 (*t1 = *t2++); ++t1);
156 (void)vsprintf(p, fmt_cpy, ap);
160 /* output to stderr if requested */
161 if (LogStat & LOG_PERROR) {
163 register struct iovec *v = iov;
166 v->iov_len = cnt - (stdp - tbuf);
170 (void)writev(2, iov, 2);
173 /* output the message to the local logger */
174 result = write(LogFile, tbuf, cnt + 1);
177 && (errno == ECONNRESET || errno == ENOTCONN || errno == ECONNREFUSED)) {
179 openlog(LogTag, LogStat | LOG_NDELAY, LogFacility);
180 result = write(LogFile, tbuf, cnt + 1);
183 if (result >= 0 || !(LogStat&LOG_CONS))
187 * output the message to the console; don't worry about
188 * blocking, if console blocks everything will.
190 if ((fd = open(_PATH_CONSOLE, O_WRONLY|O_NOCTTY, 0)) < 0)
192 (void)strcat(tbuf, "\r\n");
194 p = index(tbuf, '>') + 1;
195 (void)write(fd, p, cnt - (p - tbuf));
200 static struct sockaddr SyslogAddr; /* AF_UNIX address of local logger */
203 * OPENLOG -- open system log
206 openlog(ident, logstat, logfac)
214 #ifdef ALLOW_KERNEL_LOGGING
215 if ((logfac &~ LOG_FACMASK) == 0)
217 if (logfac != 0 && (logfac &~ LOG_FACMASK) == 0)
219 LogFacility = logfac;
223 SyslogAddr.sa_family = AF_UNIX;
224 strncpy(SyslogAddr.sa_data, _PATH_LOGNAME,
225 sizeof(SyslogAddr.sa_data));
226 if (LogStat & LOG_NDELAY) {
227 LogFile = socket(AF_UNIX, SOCK_DGRAM, 0);
228 /* fcntl(LogFile, F_SETFD, 1); */
231 if (LogFile != -1 && !connected &&
232 connect(LogFile, &SyslogAddr, sizeof(SyslogAddr.sa_family)+
233 strlen(SyslogAddr.sa_data)) != -1)
235 LogFile = fileno(stdout);
241 * CLOSELOG -- close the system log
247 (void) close(LogFile);
253 static int LogMask = 0xff; /* mask of priorities to be logged */
255 * SETLOGMASK -- set the log mask level