Commit | Line | Data |
---|---|---|
bb0cfa24 | 1 | /* |
c5282f4a MK |
2 | * Copyright (c) 1983, 1988 Regents of the University of California. |
3 | * All rights reserved. | |
4 | * | |
269a7923 | 5 | * %sccs.include.redist.c% |
bb0cfa24 DF |
6 | */ |
7 | ||
2ce81398 | 8 | #if defined(LIBC_SCCS) && !defined(lint) |
f2f3c44b | 9 | static char sccsid[] = "@(#)syslog.c 5.36 (Berkeley) %G%"; |
c5282f4a MK |
10 | #endif /* LIBC_SCCS and not lint */ |
11 | ||
b97c7a10 SL |
12 | #include <sys/types.h> |
13 | #include <sys/socket.h> | |
a52c86c2 | 14 | #include <sys/syslog.h> |
84f78f79 | 15 | #include <sys/uio.h> |
b97c7a10 | 16 | #include <netdb.h> |
f2f3c44b KB |
17 | |
18 | #include <errno.h> | |
19 | #include <fcntl.h> | |
20 | #include <paths.h> | |
21 | #include <stdio.h> | |
6ebcb998 | 22 | #include <string.h> |
f2f3c44b KB |
23 | #include <time.h> |
24 | #include <unistd.h> | |
25 | ||
c5980113 DS |
26 | #if __STDC__ |
27 | #include <stdarg.h> | |
28 | #else | |
137a7cf5 | 29 | #include <varargs.h> |
c5980113 | 30 | #endif |
b97c7a10 | 31 | |
bc51229a | 32 | static int LogFile = -1; /* fd for log */ |
12d303b4 | 33 | static int connected; /* have done connect */ |
61ed6dd0 | 34 | static int LogStat = 0; /* status bits, set by openlog() */ |
c5980113 | 35 | static const char *LogTag = "syslog"; /* string to tag the entry with */ |
a05c1f2b | 36 | static int LogFacility = LOG_USER; /* default facility code */ |
dbf23689 | 37 | static int LogMask = 0xff; /* mask of priorities to be logged */ |
b97c7a10 | 38 | |
8c095963 KB |
39 | /* |
40 | * syslog, vsyslog -- | |
41 | * print message on log file; output is intended for syslogd(8). | |
42 | */ | |
c5980113 DS |
43 | void |
44 | #if __STDC__ | |
45 | syslog(int pri, const char *fmt, ...) | |
46 | #else | |
47 | syslog(pri, fmt, va_alist) | |
48 | int pri; | |
b97c7a10 | 49 | char *fmt; |
c5980113 DS |
50 | va_dcl |
51 | #endif | |
137a7cf5 | 52 | { |
c5980113 DS |
53 | va_list ap; |
54 | ||
55 | #if __STDC__ | |
56 | va_start(ap, fmt); | |
57 | #else | |
58 | va_start(ap); | |
59 | #endif | |
60 | vsyslog(pri, fmt, ap); | |
61 | va_end(ap); | |
137a7cf5 KB |
62 | } |
63 | ||
c5980113 | 64 | void |
137a7cf5 KB |
65 | vsyslog(pri, fmt, ap) |
66 | int pri; | |
c5980113 | 67 | register const char *fmt; |
137a7cf5 | 68 | va_list ap; |
b97c7a10 | 69 | { |
61ed6dd0 KB |
70 | register int cnt; |
71 | register char *p; | |
53bc1422 | 72 | time_t now; |
27071b79 | 73 | int fd, saved_errno; |
53bc1422 KB |
74 | char *stdp, tbuf[2048], fmt_cpy[1024]; |
75 | ||
76 | #define INTERNALLOG LOG_ERR|LOG_CONS|LOG_PERROR|LOG_PID | |
77 | /* Check for invalid bits. */ | |
78 | if (pri & ~(LOG_PRIMASK|LOG_FACMASK)) { | |
79 | syslog(INTERNALLOG, | |
80 | "syslog: unknown facility/priority: %x", pri); | |
81 | pri &= LOG_PRIMASK|LOG_FACMASK; | |
82 | } | |
56772c3d | 83 | |
53bc1422 KB |
84 | /* Check priority against setlogmask values. */ |
85 | if (!LOG_MASK(LOG_PRI(pri)) & LogMask) | |
4eabad57 | 86 | return; |
b97c7a10 | 87 | |
09e4fb27 | 88 | saved_errno = errno; |
a05c1f2b EA |
89 | |
90 | /* set default facility if none specified */ | |
91 | if ((pri & LOG_FACMASK) == 0) | |
92 | pri |= LogFacility; | |
93 | ||
94 | /* build the message */ | |
61ed6dd0 KB |
95 | (void)time(&now); |
96 | (void)sprintf(tbuf, "<%d>%.15s ", pri, ctime(&now) + 4); | |
97 | for (p = tbuf; *p; ++p); | |
84f78f79 KB |
98 | if (LogStat & LOG_PERROR) |
99 | stdp = p; | |
bc51229a | 100 | if (LogTag) { |
61ed6dd0 KB |
101 | (void)strcpy(p, LogTag); |
102 | for (; *p; ++p); | |
bc51229a RC |
103 | } |
104 | if (LogStat & LOG_PID) { | |
61ed6dd0 KB |
105 | (void)sprintf(p, "[%d]", getpid()); |
106 | for (; *p; ++p); | |
bc51229a | 107 | } |
a05c1f2b | 108 | if (LogTag) { |
61ed6dd0 KB |
109 | *p++ = ':'; |
110 | *p++ = ' '; | |
a05c1f2b | 111 | } |
b97c7a10 | 112 | |
56772c3d KB |
113 | /* substitute error message for %m */ |
114 | { | |
115 | register char ch, *t1, *t2; | |
116 | char *strerror(); | |
117 | ||
118 | for (t1 = fmt_cpy; ch = *fmt; ++fmt) | |
119 | if (ch == '%' && fmt[1] == 'm') { | |
120 | ++fmt; | |
121 | for (t2 = strerror(saved_errno); | |
122 | *t1 = *t2++; ++t1); | |
123 | } | |
124 | else | |
125 | *t1++ = ch; | |
c58afa87 | 126 | *t1 = '\0'; |
56772c3d KB |
127 | } |
128 | ||
129 | (void)vsprintf(p, fmt_cpy, ap); | |
a05c1f2b | 130 | |
84f78f79 KB |
131 | cnt = strlen(tbuf); |
132 | ||
133 | /* output to stderr if requested */ | |
134 | if (LogStat & LOG_PERROR) { | |
135 | struct iovec iov[2]; | |
136 | register struct iovec *v = iov; | |
137 | ||
138 | v->iov_base = stdp; | |
139 | v->iov_len = cnt - (stdp - tbuf); | |
140 | ++v; | |
141 | v->iov_base = "\n"; | |
142 | v->iov_len = 1; | |
90793b84 | 143 | (void)writev(STDERR_FILENO, iov, 2); |
84f78f79 KB |
144 | } |
145 | ||
8c095963 | 146 | /* get connected, output the message to the local logger */ |
c5980113 DS |
147 | if (!connected) |
148 | openlog(LogTag, LogStat | LOG_NDELAY, 0); | |
149 | if (send(LogFile, tbuf, cnt, 0) >= 0) | |
4eabad57 | 150 | return; |
8c095963 KB |
151 | |
152 | /* see if should attempt the console */ | |
153 | if (!(LogStat&LOG_CONS)) | |
4eabad57 | 154 | return; |
a05c1f2b | 155 | |
27071b79 | 156 | /* |
8c095963 KB |
157 | * Output the message to the console; don't worry about blocking, |
158 | * if console blocks everything will. Make sure the error reported | |
159 | * is the one from the syslogd failure. | |
27071b79 | 160 | */ |
8c095963 KB |
161 | if ((fd = open(_PATH_CONSOLE, O_WRONLY, 0)) >= 0) { |
162 | (void)strcat(tbuf, "\r\n"); | |
163 | cnt += 2; | |
164 | p = index(tbuf, '>') + 1; | |
165 | (void)write(fd, p, cnt - (p - tbuf)); | |
166 | (void)close(fd); | |
4eabad57 | 167 | } |
b97c7a10 SL |
168 | } |
169 | ||
61ed6dd0 | 170 | static struct sockaddr SyslogAddr; /* AF_UNIX address of local logger */ |
8c095963 | 171 | |
c5980113 | 172 | void |
a05c1f2b | 173 | openlog(ident, logstat, logfac) |
c5980113 | 174 | const char *ident; |
a05c1f2b | 175 | int logstat, logfac; |
b97c7a10 | 176 | { |
a05c1f2b EA |
177 | if (ident != NULL) |
178 | LogTag = ident; | |
b97c7a10 | 179 | LogStat = logstat; |
c5282f4a MK |
180 | if (logfac != 0 && (logfac &~ LOG_FACMASK) == 0) |
181 | LogFacility = logfac; | |
8c095963 | 182 | |
12d303b4 MK |
183 | if (LogFile == -1) { |
184 | SyslogAddr.sa_family = AF_UNIX; | |
8c095963 | 185 | (void)strncpy(SyslogAddr.sa_data, _PATH_LOG, |
bea3da5c | 186 | sizeof(SyslogAddr.sa_data)); |
12d303b4 | 187 | if (LogStat & LOG_NDELAY) { |
8c095963 | 188 | if ((LogFile = socket(AF_UNIX, SOCK_DGRAM, 0)) == -1) |
4eabad57 | 189 | return; |
8c095963 | 190 | (void)fcntl(LogFile, F_SETFD, 1); |
12d303b4 | 191 | } |
5cd7a5ab | 192 | } |
8c095963 KB |
193 | if (LogFile != -1 && !connected) |
194 | if (connect(LogFile, &SyslogAddr, sizeof(SyslogAddr)) == -1) { | |
8c095963 | 195 | (void)close(LogFile); |
8c095963 | 196 | LogFile = -1; |
8c095963 KB |
197 | } else |
198 | connected = 1; | |
b97c7a10 SL |
199 | } |
200 | ||
c5980113 | 201 | void |
b97c7a10 SL |
202 | closelog() |
203 | { | |
4eabad57 | 204 | (void)close(LogFile); |
b97c7a10 | 205 | LogFile = -1; |
12d303b4 | 206 | connected = 0; |
b97c7a10 | 207 | } |
bc51229a | 208 | |
8c095963 | 209 | /* setlogmask -- set the log mask level */ |
53bc1422 | 210 | int |
df714f23 RC |
211 | setlogmask(pmask) |
212 | int pmask; | |
bc51229a | 213 | { |
df714f23 | 214 | int omask; |
bc51229a | 215 | |
df714f23 RC |
216 | omask = LogMask; |
217 | if (pmask != 0) | |
218 | LogMask = pmask; | |
219 | return (omask); | |
bc51229a | 220 | } |