xref: /csrg-svn/lib/libc/gen/syslog.c (revision 34821)
121362Sdist /*
233786Skarels  * Copyright (c) 1983, 1988 Regents of the University of California.
333786Skarels  * All rights reserved.
433786Skarels  *
533786Skarels  * Redistribution and use in source and binary forms are permitted
6*34821Sbostic  * provided that the above copyright notice and this paragraph are
7*34821Sbostic  * duplicated in all such forms and that any documentation,
8*34821Sbostic  * advertising materials, and other materials related to such
9*34821Sbostic  * distribution and use acknowledge that the software was developed
10*34821Sbostic  * by the University of California, Berkeley.  The name of the
11*34821Sbostic  * University may not be used to endorse or promote products derived
12*34821Sbostic  * from this software without specific prior written permission.
13*34821Sbostic  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14*34821Sbostic  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15*34821Sbostic  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
1621362Sdist  */
1721362Sdist 
1826602Sdonn #if defined(LIBC_SCCS) && !defined(lint)
19*34821Sbostic static char sccsid[] = "@(#)syslog.c	5.16 (Berkeley) 06/27/88";
2033786Skarels #endif /* LIBC_SCCS and not lint */
2112742Ssam 
2212742Ssam /*
2312742Ssam  * SYSLOG -- print message on log file
2412742Ssam  *
2512742Ssam  * This routine looks a lot like printf, except that it
2612742Ssam  * outputs to the log file instead of the standard output.
2716414Sralph  * Also:
2816414Sralph  *	adds a timestamp,
2916414Sralph  *	prints the module name in front of the message,
3016414Sralph  *	has some other formatting types (or will sometime),
3116414Sralph  *	adds a newline on the end of the message.
3212742Ssam  *
3316414Sralph  * The output of this routine is intended to be read by /etc/syslogd.
3416943Sralph  *
3516943Sralph  * Author: Eric Allman
3616943Sralph  * Modified to use UNIX domain IPC by Ralph Campbell
3712742Ssam  */
3816414Sralph 
3912742Ssam #include <sys/types.h>
4012742Ssam #include <sys/socket.h>
4116414Sralph #include <sys/file.h>
4226870Skarels #include <sys/signal.h>
4326870Skarels #include <sys/syslog.h>
4412742Ssam #include <netdb.h>
4526870Skarels #include <strings.h>
4612742Ssam 
4716414Sralph #define	MAXLINE	1024			/* max message size */
4816414Sralph #define NULL	0			/* manifest */
4912742Ssam 
5024846Seric #define IMPORTANT 	LOG_ERR
5117918Sralph 
5216414Sralph static char	logname[] = "/dev/log";
5316414Sralph static char	ctty[] = "/dev/console";
5412742Ssam 
5516414Sralph static int	LogFile = -1;		/* fd for log */
5634563Skarels static int	connected;		/* have done connect */
5716414Sralph static int	LogStat	= 0;		/* status bits, set by openlog() */
5824846Seric static char	*LogTag = "syslog";	/* string to tag the entry with */
5924846Seric static int	LogMask = 0xff;		/* mask of priorities to be logged */
6024846Seric static int	LogFacility = LOG_USER;	/* default facility code */
6112742Ssam 
6224846Seric static struct sockaddr SyslogAddr;	/* AF_UNIX address of local logger */
6316414Sralph 
6412742Ssam extern	int errno, sys_nerr;
6512742Ssam extern	char *sys_errlist[];
6612742Ssam 
6712742Ssam syslog(pri, fmt, p0, p1, p2, p3, p4)
6812742Ssam 	int pri;
6912742Ssam 	char *fmt;
7012742Ssam {
7116414Sralph 	char buf[MAXLINE + 1], outline[MAXLINE + 1];
7216414Sralph 	register char *b, *f, *o;
7316414Sralph 	register int c;
7416414Sralph 	long now;
7516943Sralph 	int pid, olderrno = errno;
7612742Ssam 
7712742Ssam 	/* see if we should just throw out this message */
7834563Skarels 	if ((unsigned) LOG_FAC(pri) >= LOG_NFACILITIES ||
7934563Skarels 	    LOG_MASK(LOG_PRI(pri)) == 0 ||
8034392Skarels 	    (pri &~ (LOG_PRIMASK|LOG_FACMASK)) != 0)
8112742Ssam 		return;
8234563Skarels 	if (LogFile < 0 || !connected)
8325187Seric 		openlog(LogTag, LogStat | LOG_NDELAY, 0);
8424846Seric 
8524846Seric 	/* set default facility if none specified */
8624846Seric 	if ((pri & LOG_FACMASK) == 0)
8724846Seric 		pri |= LogFacility;
8824846Seric 
8924846Seric 	/* build the message */
9016414Sralph 	o = outline;
9132497Sbostic 	(void)sprintf(o, "<%d>", pri);
9216943Sralph 	o += strlen(o);
9324846Seric 	time(&now);
9432497Sbostic 	(void)sprintf(o, "%.15s ", ctime(&now) + 4);
9524846Seric 	o += strlen(o);
9616414Sralph 	if (LogTag) {
9716414Sralph 		strcpy(o, LogTag);
9816414Sralph 		o += strlen(o);
9916414Sralph 	}
10016414Sralph 	if (LogStat & LOG_PID) {
10132497Sbostic 		(void)sprintf(o, "[%d]", getpid());
10216414Sralph 		o += strlen(o);
10316414Sralph 	}
10424846Seric 	if (LogTag) {
10524846Seric 		strcpy(o, ": ");
10624846Seric 		o += 2;
10724846Seric 	}
10812742Ssam 
10916414Sralph 	b = buf;
11016414Sralph 	f = fmt;
11116414Sralph 	while ((c = *f++) != '\0' && c != '\n' && b < &buf[MAXLINE]) {
11216414Sralph 		if (c != '%') {
11316414Sralph 			*b++ = c;
11416414Sralph 			continue;
11512742Ssam 		}
11616414Sralph 		if ((c = *f++) != 'm') {
11716414Sralph 			*b++ = '%';
11816414Sralph 			*b++ = c;
11916414Sralph 			continue;
12012742Ssam 		}
12116943Sralph 		if ((unsigned)olderrno > sys_nerr)
12232497Sbostic 			(void)sprintf(b, "error %d", olderrno);
12312742Ssam 		else
12416943Sralph 			strcpy(b, sys_errlist[olderrno]);
12516414Sralph 		b += strlen(b);
12612742Ssam 	}
12716414Sralph 	*b++ = '\n';
12816414Sralph 	*b = '\0';
12932497Sbostic 	(void)sprintf(o, buf, p0, p1, p2, p3, p4);
13016414Sralph 	c = strlen(outline);
13116414Sralph 	if (c > MAXLINE)
13216414Sralph 		c = MAXLINE;
13324846Seric 
13424846Seric 	/* output the message to the local logger */
13534563Skarels 	if (send(LogFile, outline, c, 0) >= 0)
13616414Sralph 		return;
13727343Skarels 	if (!(LogStat & LOG_CONS))
13816414Sralph 		return;
13924846Seric 
14024846Seric 	/* output the message to the console */
14126508Skarels 	pid = vfork();
14216414Sralph 	if (pid == -1)
14316414Sralph 		return;
14416414Sralph 	if (pid == 0) {
14527795Skarels 		int fd;
14627795Skarels 
14724880Seric 		signal(SIGALRM, SIG_DFL);
14832303Sbostic 		sigsetmask(sigblock(0L) & ~sigmask(SIGALRM));
14924880Seric 		alarm(5);
15027795Skarels 		fd = open(ctty, O_WRONLY);
15124880Seric 		alarm(0);
15217918Sralph 		strcat(o, "\r");
15326870Skarels 		o = index(outline, '>') + 1;
15427795Skarels 		write(fd, o, c + 1 - (o - outline));
15527795Skarels 		close(fd);
15627795Skarels 		_exit(0);
15716414Sralph 	}
15827343Skarels 	if (!(LogStat & LOG_NOWAIT))
15927343Skarels 		while ((c = wait((int *)0)) > 0 && c != pid)
16027343Skarels 			;
16112742Ssam }
16212742Ssam 
16312742Ssam /*
16412742Ssam  * OPENLOG -- open system log
16512742Ssam  */
16624846Seric 
16724846Seric openlog(ident, logstat, logfac)
16812742Ssam 	char *ident;
16924846Seric 	int logstat, logfac;
17012742Ssam {
17124846Seric 	if (ident != NULL)
17224846Seric 		LogTag = ident;
17312742Ssam 	LogStat = logstat;
17433786Skarels 	if (logfac != 0 && (logfac &~ LOG_FACMASK) == 0)
17533786Skarels 		LogFacility = logfac;
17634563Skarels 	if (LogFile == -1) {
17734563Skarels 		SyslogAddr.sa_family = AF_UNIX;
17834563Skarels 		strncpy(SyslogAddr.sa_data, logname, sizeof SyslogAddr.sa_data);
17934563Skarels 		if (LogStat & LOG_NDELAY) {
18034563Skarels 			LogFile = socket(AF_UNIX, SOCK_DGRAM, 0);
18134563Skarels 			fcntl(LogFile, F_SETFD, 1);
18234563Skarels 		}
18317918Sralph 	}
18434563Skarels 	if (LogFile != -1 && !connected &&
18534563Skarels 	    connect(LogFile, &SyslogAddr, sizeof(SyslogAddr)) != -1)
18634563Skarels 		connected = 1;
18712742Ssam }
18812742Ssam 
18912742Ssam /*
19012742Ssam  * CLOSELOG -- close the system log
19112742Ssam  */
19225187Seric 
19312742Ssam closelog()
19412742Ssam {
19512742Ssam 
19612742Ssam 	(void) close(LogFile);
19712742Ssam 	LogFile = -1;
19834563Skarels 	connected = 0;
19912742Ssam }
20016414Sralph 
20116414Sralph /*
20216414Sralph  * SETLOGMASK -- set the log mask level
20316414Sralph  */
20417526Sralph setlogmask(pmask)
20517526Sralph 	int pmask;
20616414Sralph {
20717526Sralph 	int omask;
20816414Sralph 
20917526Sralph 	omask = LogMask;
21017526Sralph 	if (pmask != 0)
21117526Sralph 		LogMask = pmask;
21217526Sralph 	return (omask);
21316414Sralph }
214