xref: /original-bsd/lib/libc/gen/syslog.c (revision e78e7ec3)
1 #ifndef lint
2 static char sccsid[] = "@(#)syslog.c	4.7 (Berkeley) 02/20/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 		    			/* mask of priorities to be logged */
43 static int	LogMask = ~(mask(KERN_EMERG)|mask(KERN_ALERT)|mask(KERN_ERR)|
44 		    mask(KERN_FAIL)|mask(KERN_RECOV)|mask(KERN_INFO));
45 
46 static struct sockaddr SyslogAddr;
47 
48 extern	int errno, sys_nerr;
49 extern	char *sys_errlist[];
50 
51 syslog(pri, fmt, p0, p1, p2, p3, p4)
52 	int pri;
53 	char *fmt;
54 {
55 	char buf[MAXLINE + 1], outline[MAXLINE + 1];
56 	register char *b, *f, *o;
57 	register int c;
58 	long now;
59 	int pid, olderrno = errno;
60 
61 	/* see if we should just throw out this message */
62 	if (pri <= 0 || pri >= 32 || (mask(pri) & LogMask) == 0)
63 		return;
64 	if (LogFile < 0)
65 		openlog(LogTag, LogStat & ~LOG_ODELAY, 0);
66 	o = outline;
67 	sprintf(o, "<%d>", pri);
68 	o += strlen(o);
69 	if (LogTag) {
70 		strcpy(o, LogTag);
71 		o += strlen(o);
72 	}
73 	if (LogStat & LOG_PID) {
74 		sprintf(o, "[%d]", getpid());
75 		o += strlen(o);
76 	}
77 	time(&now);
78 	sprintf(o, ": %.15s-- ", ctime(&now) + 4);
79 	o += strlen(o);
80 
81 	b = buf;
82 	f = fmt;
83 	while ((c = *f++) != '\0' && c != '\n' && b < &buf[MAXLINE]) {
84 		if (c != '%') {
85 			*b++ = c;
86 			continue;
87 		}
88 		if ((c = *f++) != 'm') {
89 			*b++ = '%';
90 			*b++ = c;
91 			continue;
92 		}
93 		if ((unsigned)olderrno > sys_nerr)
94 			sprintf(b, "error %d", olderrno);
95 		else
96 			strcpy(b, sys_errlist[olderrno]);
97 		b += strlen(b);
98 	}
99 	*b++ = '\n';
100 	*b = '\0';
101 	sprintf(o, buf, p0, p1, p2, p3, p4);
102 	c = strlen(outline);
103 	if (c > MAXLINE)
104 		c = MAXLINE;
105 	if (sendto(LogFile, outline, c, 0, &SyslogAddr, sizeof SyslogAddr) >= 0)
106 		return;
107 	if (!(LogStat & LOG_CONS) && !(mask(pri) & IMPORTANT))
108 		return;
109 	pid = fork();
110 	if (pid == -1)
111 		return;
112 	if (pid == 0) {
113 		LogFile = open(ctty, O_RDWR);
114 		strcat(o, "\r");
115 		write(LogFile, outline, c+1);
116 		close(LogFile);
117 		exit(0);
118 	}
119 	while ((c = wait((int *)0)) > 0 && c != pid)
120 		;
121 }
122 
123 /*
124  * OPENLOG -- open system log
125  */
126 openlog(ident, logstat, logmask)
127 	char *ident;
128 	int logstat, logmask;
129 {
130 
131 	LogTag = (ident != NULL) ? ident : "syslog";
132 	LogStat = logstat;
133 	if (logmask != 0)
134 		LogMask = logmask;
135 	if (LogFile >= 0)
136 		return;
137 	SyslogAddr.sa_family = AF_UNIX;
138 	strncpy(SyslogAddr.sa_data, logname, sizeof SyslogAddr.sa_data);
139 	if (!(LogStat & LOG_ODELAY)) {
140 		LogFile = socket(AF_UNIX, SOCK_DGRAM, 0);
141 		fcntl(LogFile, F_SETFD, 1);
142 	}
143 }
144 
145 /*
146  * CLOSELOG -- close the system log
147  */
148 closelog()
149 {
150 
151 	(void) close(LogFile);
152 	LogFile = -1;
153 }
154 
155 /*
156  * SETLOGMASK -- set the log mask level
157  */
158 setlogmask(pmask)
159 	int pmask;
160 {
161 	int omask;
162 
163 	omask = LogMask;
164 	if (pmask != 0)
165 		LogMask = pmask;
166 	return (omask);
167 }
168