document distributed with 4.3BSD
[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
2ce81398 7#if defined(LIBC_SCCS) && !defined(lint)
5dcc7110 8static char sccsid[] = "@(#)syslog.c 5.9 (Berkeley) %G%";
2ce81398 9#endif LIBC_SCCS and 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>
a52c86c2
MK
31#include <sys/signal.h>
32#include <sys/syslog.h>
b97c7a10 33#include <netdb.h>
a52c86c2 34#include <strings.h>
b97c7a10 35
bc51229a
RC
36#define MAXLINE 1024 /* max message size */
37#define NULL 0 /* manifest */
38
a05c1f2b
EA
39#define PRIMASK(p) (1 << ((p) & LOG_PRIMASK))
40#define PRIFAC(p) (((p) & LOG_FACMASK) >> 3)
41#define IMPORTANT LOG_ERR
5cd7a5ab 42
bc51229a
RC
43static char logname[] = "/dev/log";
44static char ctty[] = "/dev/console";
b97c7a10 45
bc51229a
RC
46static int LogFile = -1; /* fd for log */
47static int LogStat = 0; /* status bits, set by openlog() */
a05c1f2b
EA
48static char *LogTag = "syslog"; /* string to tag the entry with */
49static int LogMask = 0xff; /* mask of priorities to be logged */
50static int LogFacility = LOG_USER; /* default facility code */
b97c7a10 51
a05c1f2b 52static struct sockaddr SyslogAddr; /* AF_UNIX address of local logger */
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 */
a05c1f2b 68 if (pri <= 0 || PRIFAC(pri) >= LOG_NFACILITIES || (PRIMASK(pri) & LogMask) == 0)
b97c7a10 69 return;
bc51229a 70 if (LogFile < 0)
fadfb2f6 71 openlog(LogTag, LogStat | LOG_NDELAY, 0);
a05c1f2b
EA
72
73 /* set default facility if none specified */
74 if ((pri & LOG_FACMASK) == 0)
75 pri |= LogFacility;
76
77 /* build the message */
bc51229a 78 o = outline;
4d707151
RC
79 sprintf(o, "<%d>", pri);
80 o += strlen(o);
a05c1f2b
EA
81 time(&now);
82 sprintf(o, "%.15s ", ctime(&now) + 4);
83 o += strlen(o);
bc51229a
RC
84 if (LogTag) {
85 strcpy(o, LogTag);
86 o += strlen(o);
87 }
88 if (LogStat & LOG_PID) {
4d707151 89 sprintf(o, "[%d]", getpid());
bc51229a
RC
90 o += strlen(o);
91 }
a05c1f2b
EA
92 if (LogTag) {
93 strcpy(o, ": ");
94 o += 2;
95 }
b97c7a10 96
bc51229a
RC
97 b = buf;
98 f = fmt;
99 while ((c = *f++) != '\0' && c != '\n' && b < &buf[MAXLINE]) {
100 if (c != '%') {
101 *b++ = c;
102 continue;
b97c7a10 103 }
bc51229a
RC
104 if ((c = *f++) != 'm') {
105 *b++ = '%';
106 *b++ = c;
107 continue;
b97c7a10 108 }
4d707151
RC
109 if ((unsigned)olderrno > sys_nerr)
110 sprintf(b, "error %d", olderrno);
b97c7a10 111 else
4d707151 112 strcpy(b, sys_errlist[olderrno]);
bc51229a 113 b += strlen(b);
b97c7a10 114 }
bc51229a
RC
115 *b++ = '\n';
116 *b = '\0';
117 sprintf(o, buf, p0, p1, p2, p3, p4);
118 c = strlen(outline);
119 if (c > MAXLINE)
120 c = MAXLINE;
a05c1f2b
EA
121
122 /* output the message to the local logger */
bc51229a
RC
123 if (sendto(LogFile, outline, c, 0, &SyslogAddr, sizeof SyslogAddr) >= 0)
124 return;
c229b84c 125 if (!(LogStat & LOG_CONS))
bc51229a 126 return;
a05c1f2b
EA
127
128 /* output the message to the console */
fe98dde4 129 pid = vfork();
bc51229a
RC
130 if (pid == -1)
131 return;
132 if (pid == 0) {
ba519163
EA
133 signal(SIGALRM, SIG_DFL);
134 sigsetmask(sigblock(0) & ~sigmask(SIGALRM));
135 alarm(5);
a05c1f2b 136 LogFile = open(ctty, O_WRONLY);
ba519163 137 alarm(0);
5cd7a5ab 138 strcat(o, "\r");
a52c86c2 139 o = index(outline, '>') + 1;
c229b84c 140 write(LogFile, o, c + 1 - (o - outline));
bc51229a
RC
141 close(LogFile);
142 exit(0);
143 }
c229b84c
MK
144 if (!(LogStat & LOG_NOWAIT))
145 while ((c = wait((int *)0)) > 0 && c != pid)
146 ;
b97c7a10
SL
147}
148
149/*
150 * OPENLOG -- open system log
151 */
a05c1f2b
EA
152
153openlog(ident, logstat, logfac)
b97c7a10 154 char *ident;
a05c1f2b 155 int logstat, logfac;
b97c7a10 156{
a05c1f2b
EA
157 if (ident != NULL)
158 LogTag = ident;
b97c7a10 159 LogStat = logstat;
a05c1f2b
EA
160 if (logfac != 0)
161 LogFacility = logfac & LOG_FACMASK;
b97c7a10
SL
162 if (LogFile >= 0)
163 return;
bc51229a
RC
164 SyslogAddr.sa_family = AF_UNIX;
165 strncpy(SyslogAddr.sa_data, logname, sizeof SyslogAddr.sa_data);
fadfb2f6 166 if (LogStat & LOG_NDELAY) {
5cd7a5ab
RC
167 LogFile = socket(AF_UNIX, SOCK_DGRAM, 0);
168 fcntl(LogFile, F_SETFD, 1);
169 }
b97c7a10
SL
170}
171
172/*
173 * CLOSELOG -- close the system log
174 */
fadfb2f6 175
b97c7a10
SL
176closelog()
177{
178
179 (void) close(LogFile);
180 LogFile = -1;
181}
bc51229a
RC
182
183/*
184 * SETLOGMASK -- set the log mask level
185 */
df714f23
RC
186setlogmask(pmask)
187 int pmask;
bc51229a 188{
df714f23 189 int omask;
bc51229a 190
df714f23
RC
191 omask = LogMask;
192 if (pmask != 0)
193 LogMask = pmask;
194 return (omask);
bc51229a 195}