xref: /csrg-svn/lib/libc/gen/syslog.c (revision 17918)
1 #ifndef lint
2 static char sccsid[] = "@(#)syslog.c	4.6 (Berkeley) 02/04/85";
3 #endif
4 
5 /*
6  * SYSLOG -- print message on log file
7  *
8  * This routine looks a lot like printf, except that it
9  * outputs to the log file instead of the standard output.
10  * Also:
11  *	adds a timestamp,
12  *	prints the module name in front of the message,
13  *	has some other formatting types (or will sometime),
14  *	adds a newline on the end of the message.
15  *
16  * The output of this routine is intended to be read by /etc/syslogd.
17  *
18  * Author: Eric Allman
19  * Modified to use UNIX domain IPC by Ralph Campbell
20  */
21 
22 #include <sys/types.h>
23 #include <sys/socket.h>
24 #include <sys/file.h>
25 #include <syslog.h>
26 #include <netdb.h>
27 
28 #define	MAXLINE	1024			/* max message size */
29 #define NULL	0			/* manifest */
30 
31 #define mask(p)	(1 << (p))
32 #define IMPORTANT (mask(KERN_EMERG)|mask(KERN_ALERT)|mask(KERN_ERR)|mask(KERN_FAIL)\
33 	|mask(KERN_RECOV)|mask(KERN_INFO)|mask(LOG_EMERG)|mask(LOG_ALERT)\
34 	|mask(LOG_CRIT)|mask(LOG_ERR)|mask(LOG_FAIL))
35 
36 static char	logname[] = "/dev/log";
37 static char	ctty[] = "/dev/console";
38 
39 static int	LogFile = -1;		/* fd for log */
40 static int	LogStat	= 0;		/* status bits, set by openlog() */
41 static char	*LogTag = NULL;		/* string to tag the entry with */
42 static int	LogMask = 0xffffffff;	/* mask of priorities to be logged */
43 
44 static struct sockaddr SyslogAddr;
45 
46 extern	int errno, sys_nerr;
47 extern	char *sys_errlist[];
48 
49 syslog(pri, fmt, p0, p1, p2, p3, p4)
50 	int pri;
51 	char *fmt;
52 {
53 	char buf[MAXLINE + 1], outline[MAXLINE + 1];
54 	register char *b, *f, *o;
55 	register int c;
56 	long now;
57 	int pid, olderrno = errno;
58 
59 	/* see if we should just throw out this message */
60 	if (pri <= 0 || pri >= 32 || (mask(pri) & LogMask) == 0)
61 		return;
62 	if (LogFile < 0)
63 		openlog(LogTag, LogStat & ~LOG_ODELAY, 0);
64 	o = outline;
65 	sprintf(o, "<%d>", pri);
66 	o += strlen(o);
67 	if (LogTag) {
68 		strcpy(o, LogTag);
69 		o += strlen(o);
70 	}
71 	if (LogStat & LOG_PID) {
72 		sprintf(o, "[%d]", getpid());
73 		o += strlen(o);
74 	}
75 	time(&now);
76 	sprintf(o, ": %.15s-- ", ctime(&now) + 4);
77 	o += strlen(o);
78 
79 	b = buf;
80 	f = fmt;
81 	while ((c = *f++) != '\0' && c != '\n' && b < &buf[MAXLINE]) {
82 		if (c != '%') {
83 			*b++ = c;
84 			continue;
85 		}
86 		if ((c = *f++) != 'm') {
87 			*b++ = '%';
88 			*b++ = c;
89 			continue;
90 		}
91 		if ((unsigned)olderrno > sys_nerr)
92 			sprintf(b, "error %d", olderrno);
93 		else
94 			strcpy(b, sys_errlist[olderrno]);
95 		b += strlen(b);
96 	}
97 	*b++ = '\n';
98 	*b = '\0';
99 	sprintf(o, buf, p0, p1, p2, p3, p4);
100 	c = strlen(outline);
101 	if (c > MAXLINE)
102 		c = MAXLINE;
103 	if (sendto(LogFile, outline, c, 0, &SyslogAddr, sizeof SyslogAddr) >= 0)
104 		return;
105 	if (!(LogStat & LOG_CONS) && !(mask(pri) & IMPORTANT))
106 		return;
107 	pid = fork();
108 	if (pid == -1)
109 		return;
110 	if (pid == 0) {
111 		LogFile = open(ctty, O_RDWR);
112 		strcat(o, "\r");
113 		write(LogFile, outline, c+1);
114 		close(LogFile);
115 		exit(0);
116 	}
117 	while ((c = wait((int *)0)) > 0 && c != pid)
118 		;
119 }
120 
121 /*
122  * OPENLOG -- open system log
123  */
124 openlog(ident, logstat, logmask)
125 	char *ident;
126 	int logstat, logmask;
127 {
128 
129 	LogTag = (ident != NULL) ? ident : "syslog";
130 	LogStat = logstat;
131 	if (logmask != 0)
132 		LogMask = logmask;
133 	if (LogFile >= 0)
134 		return;
135 	SyslogAddr.sa_family = AF_UNIX;
136 	strncpy(SyslogAddr.sa_data, logname, sizeof SyslogAddr.sa_data);
137 	if (!(LogStat & LOG_ODELAY)) {
138 		LogFile = socket(AF_UNIX, SOCK_DGRAM, 0);
139 		fcntl(LogFile, F_SETFD, 1);
140 	}
141 }
142 
143 /*
144  * CLOSELOG -- close the system log
145  */
146 closelog()
147 {
148 
149 	(void) close(LogFile);
150 	LogFile = -1;
151 }
152 
153 /*
154  * SETLOGMASK -- set the log mask level
155  */
156 setlogmask(pmask)
157 	int pmask;
158 {
159 	int omask;
160 
161 	omask = LogMask;
162 	if (pmask != 0)
163 		LogMask = pmask;
164 	return (omask);
165 }
166