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