include malloc.h
[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)
1b43787d 8static char sccsid[] = "@(#)syslog.c 5.11 (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 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 */
81a81470
MK
67 if (pri <= 0 || PRIFAC(pri) >= LOG_NFACILITIES ||
68 (LOG_MASK(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) {
ad1bd1a6
MK
133 int fd;
134
ba519163 135 signal(SIGALRM, SIG_DFL);
1b43787d 136 sigsetmask(sigblock(0L) & ~sigmask(SIGALRM));
ba519163 137 alarm(5);
ad1bd1a6 138 fd = open(ctty, O_WRONLY);
ba519163 139 alarm(0);
5cd7a5ab 140 strcat(o, "\r");
a52c86c2 141 o = index(outline, '>') + 1;
ad1bd1a6
MK
142 write(fd, o, c + 1 - (o - outline));
143 close(fd);
144 _exit(0);
bc51229a 145 }
c229b84c
MK
146 if (!(LogStat & LOG_NOWAIT))
147 while ((c = wait((int *)0)) > 0 && c != pid)
148 ;
b97c7a10
SL
149}
150
151/*
152 * OPENLOG -- open system log
153 */
a05c1f2b
EA
154
155openlog(ident, logstat, logfac)
b97c7a10 156 char *ident;
a05c1f2b 157 int logstat, logfac;
b97c7a10 158{
a05c1f2b
EA
159 if (ident != NULL)
160 LogTag = ident;
b97c7a10 161 LogStat = logstat;
a05c1f2b
EA
162 if (logfac != 0)
163 LogFacility = logfac & LOG_FACMASK;
b97c7a10
SL
164 if (LogFile >= 0)
165 return;
bc51229a
RC
166 SyslogAddr.sa_family = AF_UNIX;
167 strncpy(SyslogAddr.sa_data, logname, sizeof SyslogAddr.sa_data);
fadfb2f6 168 if (LogStat & LOG_NDELAY) {
5cd7a5ab
RC
169 LogFile = socket(AF_UNIX, SOCK_DGRAM, 0);
170 fcntl(LogFile, F_SETFD, 1);
171 }
b97c7a10
SL
172}
173
174/*
175 * CLOSELOG -- close the system log
176 */
fadfb2f6 177
b97c7a10
SL
178closelog()
179{
180
181 (void) close(LogFile);
182 LogFile = -1;
183}
bc51229a
RC
184
185/*
186 * SETLOGMASK -- set the log mask level
187 */
df714f23
RC
188setlogmask(pmask)
189 int pmask;
bc51229a 190{
df714f23 191 int omask;
bc51229a 192
df714f23
RC
193 omask = LogMask;
194 if (pmask != 0)
195 LogMask = pmask;
196 return (omask);
bc51229a 197}