xref: /csrg-svn/lib/libc/gen/syslog.c (revision 17526)
112742Ssam #ifndef lint
2*17526Sralph static char sccsid[] = "@(#)syslog.c	4.5 (Berkeley) 12/14/84";
312742Ssam #endif
412742Ssam 
512742Ssam /*
612742Ssam  * SYSLOG -- print message on log file
712742Ssam  *
812742Ssam  * This routine looks a lot like printf, except that it
912742Ssam  * outputs to the log file instead of the standard output.
1016414Sralph  * Also:
1116414Sralph  *	adds a timestamp,
1216414Sralph  *	prints the module name in front of the message,
1316414Sralph  *	has some other formatting types (or will sometime),
1416414Sralph  *	adds a newline on the end of the message.
1512742Ssam  *
1616414Sralph  * The output of this routine is intended to be read by /etc/syslogd.
1716943Sralph  *
1816943Sralph  * Author: Eric Allman
1916943Sralph  * Modified to use UNIX domain IPC by Ralph Campbell
2012742Ssam  */
2116414Sralph 
2212742Ssam #include <sys/types.h>
2312742Ssam #include <sys/socket.h>
2416414Sralph #include <sys/file.h>
2512742Ssam #include <syslog.h>
2612742Ssam #include <netdb.h>
2712742Ssam 
2816414Sralph #define	MAXLINE	1024			/* max message size */
2916414Sralph #define NULL	0			/* manifest */
3012742Ssam 
3116414Sralph static char	logname[] = "/dev/log";
3216414Sralph static char	ctty[] = "/dev/console";
3312742Ssam 
3416414Sralph static int	LogFile = -1;		/* fd for log */
3516414Sralph static int	LogStat	= 0;		/* status bits, set by openlog() */
3616414Sralph static char	*LogTag = NULL;		/* string to tag the entry with */
37*17526Sralph static int	LogMask = 0xffffffff;	/* mask of priorities to be logged */
3812742Ssam 
3916414Sralph static struct sockaddr SyslogAddr;
4016414Sralph 
4112742Ssam extern	int errno, sys_nerr;
4212742Ssam extern	char *sys_errlist[];
4312742Ssam 
4412742Ssam syslog(pri, fmt, p0, p1, p2, p3, p4)
4512742Ssam 	int pri;
4612742Ssam 	char *fmt;
4712742Ssam {
4816414Sralph 	char buf[MAXLINE + 1], outline[MAXLINE + 1];
4916414Sralph 	register char *b, *f, *o;
5016414Sralph 	register int c;
5116414Sralph 	long now;
5216943Sralph 	int pid, olderrno = errno;
5312742Ssam 
5412742Ssam 	/* see if we should just throw out this message */
55*17526Sralph 	if (pri <= 0 || pri >= 32 || ((1 << pri) & LogMask) == 0)
5612742Ssam 		return;
5716414Sralph 	if (LogFile < 0)
5816414Sralph 		openlog(NULL, 0, 0);
5916414Sralph 	o = outline;
6016943Sralph 	sprintf(o, "<%d>", pri);
6116943Sralph 	o += strlen(o);
6216414Sralph 	if (LogTag) {
6316414Sralph 		strcpy(o, LogTag);
6416414Sralph 		o += strlen(o);
6516414Sralph 	}
6616414Sralph 	if (LogStat & LOG_PID) {
6716943Sralph 		sprintf(o, "[%d]", getpid());
6816414Sralph 		o += strlen(o);
6916414Sralph 	}
7016414Sralph 	time(&now);
7116943Sralph 	sprintf(o, ": %.15s-- ", ctime(&now) + 4);
7216414Sralph 	o += strlen(o);
7312742Ssam 
7416414Sralph 	b = buf;
7516414Sralph 	f = fmt;
7616414Sralph 	while ((c = *f++) != '\0' && c != '\n' && b < &buf[MAXLINE]) {
7716414Sralph 		if (c != '%') {
7816414Sralph 			*b++ = c;
7916414Sralph 			continue;
8012742Ssam 		}
8116414Sralph 		if ((c = *f++) != 'm') {
8216414Sralph 			*b++ = '%';
8316414Sralph 			*b++ = c;
8416414Sralph 			continue;
8512742Ssam 		}
8616943Sralph 		if ((unsigned)olderrno > sys_nerr)
8716943Sralph 			sprintf(b, "error %d", olderrno);
8812742Ssam 		else
8916943Sralph 			strcpy(b, sys_errlist[olderrno]);
9016414Sralph 		b += strlen(b);
9112742Ssam 	}
9216414Sralph 	*b++ = '\n';
9316414Sralph 	*b = '\0';
9416414Sralph 	sprintf(o, buf, p0, p1, p2, p3, p4);
9516414Sralph 	c = strlen(outline);
9616414Sralph 	if (c > MAXLINE)
9716414Sralph 		c = MAXLINE;
9816414Sralph 	if (sendto(LogFile, outline, c, 0, &SyslogAddr, sizeof SyslogAddr) >= 0)
9916414Sralph 		return;
10016414Sralph 	if (pri > LOG_CRIT)
10116414Sralph 		return;
10216414Sralph 	pid = fork();
10316414Sralph 	if (pid == -1)
10416414Sralph 		return;
10516414Sralph 	if (pid == 0) {
10616414Sralph 		LogFile = open(ctty, O_RDWR);
10716414Sralph 		write(LogFile, outline, c);
10816414Sralph 		close(LogFile);
10916414Sralph 		exit(0);
11016414Sralph 	}
11116943Sralph 	while ((c = wait((int *)0)) > 0 && c != pid)
11216414Sralph 		;
11312742Ssam }
11412742Ssam 
11512742Ssam /*
11612742Ssam  * OPENLOG -- open system log
11712742Ssam  */
11816414Sralph openlog(ident, logstat, logmask)
11912742Ssam 	char *ident;
12016414Sralph 	int logstat, logmask;
12112742Ssam {
12212742Ssam 
12316943Sralph 	LogTag = (ident != NULL) ? ident : "syslog";
12412742Ssam 	LogStat = logstat;
125*17526Sralph 	if (logmask != 0)
12616414Sralph 		LogMask = logmask;
12712742Ssam 	if (LogFile >= 0)
12812742Ssam 		return;
12916414Sralph 	SyslogAddr.sa_family = AF_UNIX;
13016414Sralph 	strncpy(SyslogAddr.sa_data, logname, sizeof SyslogAddr.sa_data);
13116414Sralph 	LogFile = socket(AF_UNIX, SOCK_DGRAM, 0);
13216440Sralph 	fcntl(LogFile, F_SETFD, 1);
13312742Ssam }
13412742Ssam 
13512742Ssam /*
13612742Ssam  * CLOSELOG -- close the system log
13712742Ssam  */
13812742Ssam closelog()
13912742Ssam {
14012742Ssam 
14112742Ssam 	(void) close(LogFile);
14212742Ssam 	LogFile = -1;
14312742Ssam }
14416414Sralph 
14516414Sralph /*
14616414Sralph  * SETLOGMASK -- set the log mask level
14716414Sralph  */
148*17526Sralph setlogmask(pmask)
149*17526Sralph 	int pmask;
15016414Sralph {
151*17526Sralph 	int omask;
15216414Sralph 
153*17526Sralph 	omask = LogMask;
154*17526Sralph 	if (pmask != 0)
155*17526Sralph 		LogMask = pmask;
156*17526Sralph 	return (omask);
15716414Sralph }
158