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