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