xref: /csrg-svn/lib/libc/gen/syslog.c (revision 21362)
1*21362Sdist /*
2*21362Sdist  * Copyright (c) 1983 Regents of the University of California.
3*21362Sdist  * All rights reserved.  The Berkeley software License Agreement
4*21362Sdist  * specifies the terms and conditions for redistribution.
5*21362Sdist  */
6*21362Sdist 
712742Ssam #ifndef lint
8*21362Sdist static char sccsid[] = "@(#)syslog.c	5.1 (Berkeley) 05/30/85";
9*21362Sdist #endif not lint
1012742Ssam 
1112742Ssam /*
1212742Ssam  * SYSLOG -- print message on log file
1312742Ssam  *
1412742Ssam  * This routine looks a lot like printf, except that it
1512742Ssam  * outputs to the log file instead of the standard output.
1616414Sralph  * Also:
1716414Sralph  *	adds a timestamp,
1816414Sralph  *	prints the module name in front of the message,
1916414Sralph  *	has some other formatting types (or will sometime),
2016414Sralph  *	adds a newline on the end of the message.
2112742Ssam  *
2216414Sralph  * The output of this routine is intended to be read by /etc/syslogd.
2316943Sralph  *
2416943Sralph  * Author: Eric Allman
2516943Sralph  * Modified to use UNIX domain IPC by Ralph Campbell
2612742Ssam  */
2716414Sralph 
2812742Ssam #include <sys/types.h>
2912742Ssam #include <sys/socket.h>
3016414Sralph #include <sys/file.h>
3112742Ssam #include <syslog.h>
3212742Ssam #include <netdb.h>
3312742Ssam 
3416414Sralph #define	MAXLINE	1024			/* max message size */
3516414Sralph #define NULL	0			/* manifest */
3612742Ssam 
3717918Sralph #define mask(p)	(1 << (p))
3817918Sralph #define IMPORTANT (mask(KERN_EMERG)|mask(KERN_ALERT)|mask(KERN_ERR)|mask(KERN_FAIL)\
3917918Sralph 	|mask(KERN_RECOV)|mask(KERN_INFO)|mask(LOG_EMERG)|mask(LOG_ALERT)\
4017918Sralph 	|mask(LOG_CRIT)|mask(LOG_ERR)|mask(LOG_FAIL))
4117918Sralph 
4216414Sralph static char	logname[] = "/dev/log";
4316414Sralph static char	ctty[] = "/dev/console";
4412742Ssam 
4516414Sralph static int	LogFile = -1;		/* fd for log */
4616414Sralph static int	LogStat	= 0;		/* status bits, set by openlog() */
4716414Sralph static char	*LogTag = NULL;		/* string to tag the entry with */
4818020Sralph 		    			/* mask of priorities to be logged */
4918020Sralph static int	LogMask = ~(mask(KERN_EMERG)|mask(KERN_ALERT)|mask(KERN_ERR)|
5018020Sralph 		    mask(KERN_FAIL)|mask(KERN_RECOV)|mask(KERN_INFO));
5112742Ssam 
5216414Sralph static struct sockaddr SyslogAddr;
5316414Sralph 
5412742Ssam extern	int errno, sys_nerr;
5512742Ssam extern	char *sys_errlist[];
5612742Ssam 
5712742Ssam syslog(pri, fmt, p0, p1, p2, p3, p4)
5812742Ssam 	int pri;
5912742Ssam 	char *fmt;
6012742Ssam {
6116414Sralph 	char buf[MAXLINE + 1], outline[MAXLINE + 1];
6216414Sralph 	register char *b, *f, *o;
6316414Sralph 	register int c;
6416414Sralph 	long now;
6516943Sralph 	int pid, olderrno = errno;
6612742Ssam 
6712742Ssam 	/* see if we should just throw out this message */
6817918Sralph 	if (pri <= 0 || pri >= 32 || (mask(pri) & LogMask) == 0)
6912742Ssam 		return;
7016414Sralph 	if (LogFile < 0)
7117918Sralph 		openlog(LogTag, LogStat & ~LOG_ODELAY, 0);
7216414Sralph 	o = outline;
7316943Sralph 	sprintf(o, "<%d>", pri);
7416943Sralph 	o += strlen(o);
7516414Sralph 	if (LogTag) {
7616414Sralph 		strcpy(o, LogTag);
7716414Sralph 		o += strlen(o);
7816414Sralph 	}
7916414Sralph 	if (LogStat & LOG_PID) {
8016943Sralph 		sprintf(o, "[%d]", getpid());
8116414Sralph 		o += strlen(o);
8216414Sralph 	}
8316414Sralph 	time(&now);
8416943Sralph 	sprintf(o, ": %.15s-- ", ctime(&now) + 4);
8516414Sralph 	o += strlen(o);
8612742Ssam 
8716414Sralph 	b = buf;
8816414Sralph 	f = fmt;
8916414Sralph 	while ((c = *f++) != '\0' && c != '\n' && b < &buf[MAXLINE]) {
9016414Sralph 		if (c != '%') {
9116414Sralph 			*b++ = c;
9216414Sralph 			continue;
9312742Ssam 		}
9416414Sralph 		if ((c = *f++) != 'm') {
9516414Sralph 			*b++ = '%';
9616414Sralph 			*b++ = c;
9716414Sralph 			continue;
9812742Ssam 		}
9916943Sralph 		if ((unsigned)olderrno > sys_nerr)
10016943Sralph 			sprintf(b, "error %d", olderrno);
10112742Ssam 		else
10216943Sralph 			strcpy(b, sys_errlist[olderrno]);
10316414Sralph 		b += strlen(b);
10412742Ssam 	}
10516414Sralph 	*b++ = '\n';
10616414Sralph 	*b = '\0';
10716414Sralph 	sprintf(o, buf, p0, p1, p2, p3, p4);
10816414Sralph 	c = strlen(outline);
10916414Sralph 	if (c > MAXLINE)
11016414Sralph 		c = MAXLINE;
11116414Sralph 	if (sendto(LogFile, outline, c, 0, &SyslogAddr, sizeof SyslogAddr) >= 0)
11216414Sralph 		return;
11317918Sralph 	if (!(LogStat & LOG_CONS) && !(mask(pri) & IMPORTANT))
11416414Sralph 		return;
11516414Sralph 	pid = fork();
11616414Sralph 	if (pid == -1)
11716414Sralph 		return;
11816414Sralph 	if (pid == 0) {
11916414Sralph 		LogFile = open(ctty, O_RDWR);
12017918Sralph 		strcat(o, "\r");
12117918Sralph 		write(LogFile, outline, c+1);
12216414Sralph 		close(LogFile);
12316414Sralph 		exit(0);
12416414Sralph 	}
12516943Sralph 	while ((c = wait((int *)0)) > 0 && c != pid)
12616414Sralph 		;
12712742Ssam }
12812742Ssam 
12912742Ssam /*
13012742Ssam  * OPENLOG -- open system log
13112742Ssam  */
13216414Sralph openlog(ident, logstat, logmask)
13312742Ssam 	char *ident;
13416414Sralph 	int logstat, logmask;
13512742Ssam {
13612742Ssam 
13716943Sralph 	LogTag = (ident != NULL) ? ident : "syslog";
13812742Ssam 	LogStat = logstat;
13917526Sralph 	if (logmask != 0)
14016414Sralph 		LogMask = logmask;
14112742Ssam 	if (LogFile >= 0)
14212742Ssam 		return;
14316414Sralph 	SyslogAddr.sa_family = AF_UNIX;
14416414Sralph 	strncpy(SyslogAddr.sa_data, logname, sizeof SyslogAddr.sa_data);
14517918Sralph 	if (!(LogStat & LOG_ODELAY)) {
14617918Sralph 		LogFile = socket(AF_UNIX, SOCK_DGRAM, 0);
14717918Sralph 		fcntl(LogFile, F_SETFD, 1);
14817918Sralph 	}
14912742Ssam }
15012742Ssam 
15112742Ssam /*
15212742Ssam  * CLOSELOG -- close the system log
15312742Ssam  */
15412742Ssam closelog()
15512742Ssam {
15612742Ssam 
15712742Ssam 	(void) close(LogFile);
15812742Ssam 	LogFile = -1;
15912742Ssam }
16016414Sralph 
16116414Sralph /*
16216414Sralph  * SETLOGMASK -- set the log mask level
16316414Sralph  */
16417526Sralph setlogmask(pmask)
16517526Sralph 	int pmask;
16616414Sralph {
16717526Sralph 	int omask;
16816414Sralph 
16917526Sralph 	omask = LogMask;
17017526Sralph 	if (pmask != 0)
17117526Sralph 		LogMask = pmask;
17217526Sralph 	return (omask);
17316414Sralph }
174