xref: /csrg-svn/lib/libc/gen/syslog.c (revision 12742)
1*12742Ssam #ifndef lint
2*12742Ssam static char SccsId[] =	"@(#)syslog.c	4.1 (Berkeley) 05/27/83";
3*12742Ssam #endif
4*12742Ssam 
5*12742Ssam /*
6*12742Ssam  * SYSLOG -- print message on log file
7*12742Ssam  *
8*12742Ssam  * This routine looks a lot like printf, except that it
9*12742Ssam  * outputs to the log file instead of the standard output.
10*12742Ssam  * Also, it prints the module name in front of lines,
11*12742Ssam  * and has some other formatting types (or will sometime).
12*12742Ssam  * Also, it adds a newline on the end of messages.
13*12742Ssam  *
14*12742Ssam  * The output of this routine is intended to be read by
15*12742Ssam  * /etc/syslog, which will add timestamps.
16*12742Ssam  */
17*12742Ssam #include <sys/types.h>
18*12742Ssam #include <sys/socket.h>
19*12742Ssam #include <netinet/in.h>
20*12742Ssam 
21*12742Ssam #include <syslog.h>
22*12742Ssam #include <netdb.h>
23*12742Ssam 
24*12742Ssam #define	MAXLINE	1024		/* max message size */
25*12742Ssam #define BUFSLOP	20		/* space to allow for "extra stuff" */
26*12742Ssam #define NULL	0		/* manifest */
27*12742Ssam 
28*12742Ssam int	LogFile = -1;		/* fd for log */
29*12742Ssam int	LogStat	= 0;		/* status bits, set by initlog */
30*12742Ssam char	*LogTag = NULL;		/* string to tag the entry with */
31*12742Ssam int	LogMask = LOG_DEBUG;	/* lowest priority to be logged */
32*12742Ssam 
33*12742Ssam struct sockaddr_in SyslogAddr;
34*12742Ssam static char *SyslogHost = LOG_HOST;
35*12742Ssam 
36*12742Ssam extern	int errno, sys_nerr;
37*12742Ssam extern	char *sys_errlist[];
38*12742Ssam 
39*12742Ssam syslog(pri, fmt, p0, p1, p2, p3, p4)
40*12742Ssam 	int pri;
41*12742Ssam 	char *fmt;
42*12742Ssam {
43*12742Ssam 	char buf[MAXLINE+BUFSLOP], outline[MAXLINE + 1];
44*12742Ssam 	register char *b, *f;
45*12742Ssam 
46*12742Ssam 	if (LogFile < 0)
47*12742Ssam 		openlog(0, 0);
48*12742Ssam 	/* see if we should just throw out this message */
49*12742Ssam 	if (pri > LogMask)
50*12742Ssam 		return;
51*12742Ssam 	for (b = buf, f = fmt; f && *f; b = buf) {
52*12742Ssam 		register char c;
53*12742Ssam 
54*12742Ssam 		if (pri > 0 && (LogStat & LOG_COOLIT) == 0) {
55*12742Ssam 			sprintf(b, "<%d>", pri);
56*12742Ssam 			b += strlen(b);
57*12742Ssam 		}
58*12742Ssam 		if (LogStat & LOG_PID) {
59*12742Ssam 			sprintf(b, "%d ", getpid());
60*12742Ssam 			b += strlen(b);
61*12742Ssam 		}
62*12742Ssam 		if (LogTag) {
63*12742Ssam 			sprintf(b, "%s: ", LogTag);
64*12742Ssam 			b += strlen(b);
65*12742Ssam 		}
66*12742Ssam 		while ((c = *f++) != '\0' && c != '\n' && b < buf + MAXLINE) {
67*12742Ssam 			if (c != '%') {
68*12742Ssam 				*b++ = c;
69*12742Ssam 				continue;
70*12742Ssam 			}
71*12742Ssam 			c = *f++;
72*12742Ssam 			if (c != 'm') {
73*12742Ssam 				*b++ = '%', *b++ = c, *b++ = '\0';
74*12742Ssam 				continue;
75*12742Ssam 			}
76*12742Ssam 			if ((unsigned)errno > sys_nerr)
77*12742Ssam 				sprintf(b, "error %d", errno);
78*12742Ssam 			else
79*12742Ssam 				strcat(b, sys_errlist[errno]);
80*12742Ssam 			b += strlen(b);
81*12742Ssam 		}
82*12742Ssam 		if (c == '\0')
83*12742Ssam 			f--;
84*12742Ssam 		*b++ = '\n', *b = '\0';
85*12742Ssam 		sprintf(outline, buf, p0, p1, p2, p3, p4);
86*12742Ssam 		errno = 0;
87*12742Ssam 		if (LogStat & LOG_DGRAM)
88*12742Ssam 			(void) sendto(LogFile, outline, strlen(outline), 0,
89*12742Ssam 				   &SyslogAddr, sizeof SyslogAddr);
90*12742Ssam 		else
91*12742Ssam 			(void) write(LogFile, outline, strlen(outline));
92*12742Ssam 		if (errno)
93*12742Ssam 			perror("syslog: sendto");
94*12742Ssam 	}
95*12742Ssam }
96*12742Ssam 
97*12742Ssam /*
98*12742Ssam  * OPENLOG -- open system log
99*12742Ssam  */
100*12742Ssam openlog(ident, logstat)
101*12742Ssam 	char *ident;
102*12742Ssam 	int logstat;
103*12742Ssam {
104*12742Ssam 	struct servent *sp;
105*12742Ssam 	struct hostent *hp;
106*12742Ssam 
107*12742Ssam 	LogTag = ident;
108*12742Ssam 	LogStat = logstat;
109*12742Ssam 	if (LogFile >= 0)
110*12742Ssam 		return;
111*12742Ssam 	sp = getservbyname("syslog", "udp");
112*12742Ssam 	hp = gethostbyname(SyslogHost);
113*12742Ssam 	if (sp == NULL || hp == NULL)
114*12742Ssam 		goto bad;
115*12742Ssam 	LogFile = socket(AF_INET, SOCK_DGRAM, 0);
116*12742Ssam 	if (LogFile < 0) {
117*12742Ssam 		perror("syslog: socket");
118*12742Ssam 		goto bad;
119*12742Ssam 	}
120*12742Ssam 	bzero(&SyslogAddr, sizeof SyslogAddr);
121*12742Ssam 	SyslogAddr.sin_family = hp->h_addrtype;
122*12742Ssam 	bcopy(hp->h_addr, (char *)&SyslogAddr.sin_addr, hp->h_length);
123*12742Ssam 	SyslogAddr.sin_port = sp->s_port;
124*12742Ssam 	LogStat |= LOG_DGRAM;
125*12742Ssam 	return;
126*12742Ssam bad:
127*12742Ssam 	LogStat |= LOG_COOLIT;
128*12742Ssam 	LogStat &= ~LOG_DGRAM;
129*12742Ssam 	LogMask = LOG_CRIT;
130*12742Ssam 	LogFile = open("/dev/console", 1);
131*12742Ssam 	if (LogFile < 0) {
132*12742Ssam 		perror("syslog: /dev/console");
133*12742Ssam 		LogFile = 2;
134*12742Ssam 	}
135*12742Ssam }
136*12742Ssam 
137*12742Ssam /*
138*12742Ssam  * CLOSELOG -- close the system log
139*12742Ssam  */
140*12742Ssam closelog()
141*12742Ssam {
142*12742Ssam 
143*12742Ssam 	(void) close(LogFile);
144*12742Ssam 	LogFile = -1;
145*12742Ssam }
146