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