]>
git.saurik.com Git - apple/libc.git/blob - gen/syslog.c
2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
8 * This file contains Original Code and/or Modifications of Original Code
9 * as defined in and that are subject to the Apple Public Source License
10 * Version 2.0 (the 'License'). You may not use this file except in
11 * compliance with the License. Please obtain a copy of the License at
12 * http://www.opensource.apple.com/apsl/ and read it before using this
15 * The Original Code and all software distributed under the License are
16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20 * Please see the License for the specific language governing rights and
21 * limitations under the License.
23 * @APPLE_LICENSE_HEADER_END@
27 * The Regents of the University of California. All rights reserved.
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
32 * 1. Redistributions of source code must retain the above copyright
33 * notice, this list of conditions and the following disclaimer.
34 * 2. Redistributions in binary form must reproduce the above copyright
35 * notice, this list of conditions and the following disclaimer in the
36 * documentation and/or other materials provided with the distribution.
37 * 3. All advertising materials mentioning features or use of this software
38 * must display the following acknowledgement:
39 * This product includes software developed by the University of
40 * California, Berkeley and its contributors.
41 * 4. Neither the name of the University nor the names of its contributors
42 * may be used to endorse or promote products derived from this software
43 * without specific prior written permission.
45 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
46 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
47 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
48 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
49 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
50 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
51 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
52 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
53 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
54 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
58 #include <sys/types.h>
59 #include <sys/socket.h>
60 #include <sys/syslog.h>
79 #include <crt_externs.h>
81 static int LogFile
= -1; /* fd for log */
82 static int connected
; /* have done connect */
83 static int LogStat
= 0; /* status bits, set by openlog() */
84 static const char *LogTag
= NULL
; /* string to tag the entry with */
85 static int LogFacility
= LOG_USER
; /* default facility code */
86 static int LogMask
= 0xff; /* mask of priorities to be logged */
90 * print message on log file; output is intended for syslogd(8).
94 syslog(int pri
, const char *fmt
, ...)
96 syslog(pri
, fmt
, va_alist
)
109 vsyslog(pri
, fmt
, ap
);
114 vsyslog(pri
, fmt
, ap
)
116 register const char *fmt
;
120 register char ch
, *p
, *t
;
123 #define TBUF_LEN 2048
125 char *stdp
, tbuf
[TBUF_LEN
], fmt_cpy
[FMT_LEN
];
126 int tbuf_left
, fmt_left
, prlen
;
128 #define INTERNALLOG LOG_ERR|LOG_CONS|LOG_PERROR|LOG_PID
129 /* Check for invalid bits. */
130 if (pri
& ~(LOG_PRIMASK
|LOG_FACMASK
)) {
132 "syslog: unknown facility/priority: %x", pri
);
133 pri
&= LOG_PRIMASK
|LOG_FACMASK
;
136 /* Check priority against setlogmask values. */
137 if (!(LOG_MASK(LOG_PRI(pri
)) & LogMask
))
142 /* Set default facility if none specified. */
143 if ((pri
& LOG_FACMASK
) == 0)
146 /* Build the message. */
149 * Although it's tempting, we can't ignore the possibility of
150 * overflowing the buffer when assembling the "fixed" portion
151 * of the message. Strftime's "%h" directive expands to the
152 * locale's abbreviated month name, but if the user has the
153 * ability to construct to his own locale files, it may be
159 tbuf_left
= TBUF_LEN
;
163 if (prlen >= tbuf_left) \
164 prlen = tbuf_left - 1; \
166 tbuf_left -= prlen; \
169 prlen
= snprintf(p
, tbuf_left
, "<%d>", pri
);
172 prlen
= strftime(p
, tbuf_left
, "%h %e %T ", localtime(&now
));
175 if (LogStat
& LOG_PERROR
)
178 LogTag
= *(*_NSGetArgv());
179 if (LogTag
!= NULL
) {
180 prlen
= snprintf(p
, tbuf_left
, "%s", LogTag
);
183 if (LogStat
& LOG_PID
) {
184 prlen
= snprintf(p
, tbuf_left
, "[%d]", getpid());
187 if (LogTag
!= NULL
) {
199 * We wouldn't need this mess if printf handled %m, or if
200 * strerror() had been invented before syslog().
202 for (t
= fmt_cpy
, fmt_left
= FMT_LEN
; (ch
= *fmt
); ++fmt
) {
203 if (ch
== '%' && fmt
[1] == 'm') {
205 prlen
= snprintf(t
, fmt_left
, "%s",
206 strerror(saved_errno
));
207 if (prlen
>= fmt_left
)
208 prlen
= fmt_left
- 1;
220 prlen
= vsnprintf(p
, tbuf_left
, fmt_cpy
, ap
);
224 /* Output to stderr if requested. */
225 if (LogStat
& LOG_PERROR
) {
228 iov
[0].iov_base
= stdp
;
229 iov
[0].iov_len
= cnt
- (stdp
- tbuf
);
230 iov
[1].iov_base
= "\n";
232 (void)writev(STDERR_FILENO
, iov
, 2);
235 /* Get connected, output the message to the local logger. */
237 openlog(LogTag
, LogStat
| LOG_NDELAY
, 0);
238 if (send(LogFile
, tbuf
, cnt
, 0) >= 0)
242 * Output the message to the console; don't worry about blocking,
243 * if console blocks everything will. Make sure the error reported
244 * is the one from the syslogd failure.
246 if (LogStat
& LOG_CONS
&&
247 (fd
= open(_PATH_CONSOLE
, O_WRONLY
, 0)) >= 0) {
250 p
= strchr(tbuf
, '>') + 1;
252 iov
[0].iov_len
= cnt
- (p
- tbuf
);
253 iov
[1].iov_base
= "\r\n";
255 (void)writev(fd
, iov
, 2);
260 static struct sockaddr_un SyslogAddr
; /* AF_UNIX address of local logger */
263 openlog(ident
, logstat
, logfac
)
270 if (logfac
!= 0 && (logfac
&~ LOG_FACMASK
) == 0)
271 LogFacility
= logfac
;
274 SyslogAddr
.sun_family
= AF_UNIX
;
275 (void)strncpy(SyslogAddr
.sun_path
, _PATH_LOG
,
276 sizeof(SyslogAddr
.sun_path
));
277 if (LogStat
& LOG_NDELAY
) {
278 if ((LogFile
= socket(AF_UNIX
, SOCK_DGRAM
, 0)) == -1)
280 (void)fcntl(LogFile
, F_SETFD
, 1);
283 if (LogFile
!= -1 && !connected
)
284 if (connect(LogFile
, (struct sockaddr
*)&SyslogAddr
, sizeof(SyslogAddr
)) == -1) {
285 (void)close(LogFile
);
294 (void)close(LogFile
);
299 /* setlogmask -- set the log mask level */