]>
git.saurik.com Git - apple/libc.git/blob - gen/syslog.c
75e47729fd863f4e5b7a4cc5dac8933840980237
2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
25 * The Regents of the University of California. All rights reserved.
27 * Redistribution and use in source and binary forms, with or without
28 * modification, are permitted provided that the following conditions
30 * 1. Redistributions of source code must retain the above copyright
31 * notice, this list of conditions and the following disclaimer.
32 * 2. Redistributions in binary form must reproduce the above copyright
33 * notice, this list of conditions and the following disclaimer in the
34 * documentation and/or other materials provided with the distribution.
35 * 3. All advertising materials mentioning features or use of this software
36 * must display the following acknowledgement:
37 * This product includes software developed by the University of
38 * California, Berkeley and its contributors.
39 * 4. Neither the name of the University nor the names of its contributors
40 * may be used to endorse or promote products derived from this software
41 * without specific prior written permission.
43 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
44 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
45 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
46 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
47 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
48 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
49 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
50 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
51 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
52 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
56 #include <sys/types.h>
57 #include <sys/socket.h>
58 #include <sys/syslog.h>
79 #include <crt_externs.h>
81 #define LOG_NO_NOTIFY 0x1000
83 #ifdef BUILDING_VARIANT
84 __private_extern__
int _sl_LogFile
; /* fd for log */
85 __private_extern__
int _sl_connected
; /* have done connect */
86 __private_extern__
int _sl_LogStat
; /* status bits, set by openlog() */
87 __private_extern__
const char *_sl_LogTag
; /* string to tag the entry with */
88 __private_extern__
int _sl_LogFacility
; /* default facility code */
89 __private_extern__
int _sl_LogMask
; /* mask of priorities to be logged */
90 __private_extern__
int _sl_NotifyToken
; /* for remote control of priority filter */
91 __private_extern__
int _sl_NotifyMaster
; /* for remote control of priority filter */
92 #else /* !BUILDING_VARIANT */
93 __private_extern__
int _sl_LogFile
= -1; /* fd for log */
94 __private_extern__
int _sl_connected
= 0; /* have done connect */
95 __private_extern__
int _sl_LogStat
= 0; /* status bits, set by openlog() */
96 __private_extern__
const char *_sl_LogTag
= NULL
; /* string to tag the entry with */
97 __private_extern__
int _sl_LogFacility
= LOG_USER
; /* default facility code */
98 __private_extern__
int _sl_LogMask
= 0xff; /* mask of priorities to be logged */
99 __private_extern__
int _sl_NotifyToken
= -1; /* for remote control of max logged priority */
100 __private_extern__
int _sl_NotifyMaster
= -1; /* for remote control of max logged priority */
101 #endif /* BUILDING_VARIANT */
103 __private_extern__
void _sl_init_notify();
105 #define NOTIFY_SYSTEM_MASTER "com.apple.system.syslog.master"
106 #define NOTIFY_PREFIX_SYSTEM "com.apple.system.syslog"
107 #define NOTIFY_PREFIX_USER "user.syslog"
108 #define NOTIFY_STATE_OFFSET 1000
111 uint32_t notify_get_state(int token
, int *state
);
112 uint32_t notify_register_plain(const char *name
, int *out_token
);
116 * print message on log file; output is intended for syslogd(8).
120 syslog(int pri
, const char *fmt
, ...)
122 syslog(pri
, fmt
, va_alist
)
135 vsyslog(pri
, fmt
, ap
);
140 vsyslog(pri
, fmt
, ap
)
142 register const char *fmt
;
146 register char ch
, *p
, *t
;
148 int fd
, saved_errno
, filter
, cval
, rc_filter
, primask
;
149 #define TBUF_LEN 2048
151 char *stdp
, tbuf
[TBUF_LEN
], fmt_cpy
[FMT_LEN
];
152 int tbuf_left
, fmt_left
, prlen
;
154 #define INTERNALLOG LOG_ERR|LOG_CONS|LOG_PERROR|LOG_PID
155 /* Check for invalid bits. */
156 if (pri
& ~(LOG_PRIMASK
|LOG_FACMASK
))
158 syslog(INTERNALLOG
, "syslog: unknown facility/priority: %x", pri
);
159 pri
&= LOG_PRIMASK
|LOG_FACMASK
;
162 /* Get remote-control priority filter */
163 filter
= _sl_LogMask
;
168 if (_sl_NotifyToken
>= 0)
170 if (notify_get_state(_sl_NotifyToken
, &cval
) == NOTIFY_STATUS_OK
)
180 if ((rc_filter
== 0) && (_sl_NotifyMaster
>= 0))
182 if (notify_get_state(_sl_NotifyMaster
, &cval
) == NOTIFY_STATUS_OK
)
191 primask
= LOG_MASK(LOG_PRI(pri
));
192 if ((primask
& filter
) == 0) return;
196 /* Set default facility if none specified. */
197 if ((pri
& LOG_FACMASK
) == 0) pri
|= _sl_LogFacility
;
199 /* Build the message. */
202 * Although it's tempting, we can't ignore the possibility of
203 * overflowing the buffer when assembling the "fixed" portion
204 * of the message. Strftime's "%h" directive expands to the
205 * locale's abbreviated month name, but if the user has the
206 * ability to construct to his own locale files, it may be
212 tbuf_left
= TBUF_LEN
;
216 if (prlen >= tbuf_left) \
217 prlen = tbuf_left - 1; \
219 tbuf_left -= prlen; \
222 prlen
= snprintf(p
, tbuf_left
, "<%d>", pri
);
225 prlen
= strftime(p
, tbuf_left
, "%h %e %T ", localtime(&now
));
228 if (_sl_LogStat
& LOG_PERROR
) stdp
= p
;
230 if (_sl_LogTag
== NULL
) _sl_LogTag
= *(*_NSGetArgv());
232 if (_sl_LogTag
!= NULL
)
234 prlen
= snprintf(p
, tbuf_left
, "%s", _sl_LogTag
);
238 if (_sl_LogStat
& LOG_PID
)
240 prlen
= snprintf(p
, tbuf_left
, "[%d]", getpid());
244 if (_sl_LogTag
!= NULL
)
259 * We wouldn't need this mess if printf handled %m, or if
260 * strerror() had been invented before syslog().
262 for (t
= fmt_cpy
, fmt_left
= FMT_LEN
; (ch
= *fmt
); ++fmt
)
264 if (ch
== '%' && fmt
[1] == 'm')
267 prlen
= snprintf(t
, fmt_left
, "%s", strerror(saved_errno
));
268 if (prlen
>= fmt_left
) prlen
= fmt_left
- 1;
284 prlen
= vsnprintf(p
, tbuf_left
, fmt_cpy
, ap
);
288 /* Output to stderr if requested. */
289 if (_sl_LogStat
& LOG_PERROR
)
293 iov
[0].iov_base
= stdp
;
294 iov
[0].iov_len
= cnt
- (stdp
- tbuf
);
295 iov
[1].iov_base
= "\n";
297 (void)writev(STDERR_FILENO
, iov
, 2);
300 /* Get connected, output the message to the local logger. */
301 if (_sl_connected
== 0) openlog(_sl_LogTag
, _sl_LogStat
| LOG_NDELAY
, 0);
302 if (send(_sl_LogFile
, tbuf
, cnt
, 0) >= 0) return;
305 * Output the message to the console; don't worry about blocking,
306 * if console blocks everything will. Make sure the error reported
307 * is the one from the syslogd failure.
309 if (_sl_LogStat
& LOG_CONS
&& (fd
= open(_PATH_CONSOLE
, O_WRONLY
, 0)) >= 0)
313 p
= strchr(tbuf
, '>') + 1;
315 iov
[0].iov_len
= cnt
- (p
- tbuf
);
316 iov
[1].iov_base
= "\r\n";
318 (void)writev(fd
, iov
, 2);
323 #ifndef BUILDING_VARIANT
325 static struct sockaddr_un SyslogAddr
; /* AF_UNIX address of local logger */
327 __private_extern__
void
334 if (_sl_LogStat
& LOG_NO_NOTIFY
)
336 _sl_NotifyMaster
= -2;
337 _sl_NotifyToken
= -2;
341 if (_sl_NotifyMaster
== -1)
343 status
= notify_register_plain(NOTIFY_SYSTEM_MASTER
, &_sl_NotifyMaster
);
344 if (status
!= NOTIFY_STATUS_OK
) _sl_NotifyMaster
= -2;
347 if (_sl_NotifyToken
== -1)
349 _sl_NotifyToken
= -2;
352 prefix
= NOTIFY_PREFIX_USER
;
353 if (getuid() == 0) prefix
= NOTIFY_PREFIX_SYSTEM
;
354 asprintf(¬ify_name
, "%s.%d", prefix
, getpid());
356 if (notify_name
!= NULL
)
358 status
= notify_register_plain(notify_name
, &_sl_NotifyToken
);
360 if (status
!= NOTIFY_STATUS_OK
) _sl_NotifyToken
= -2;
366 openlog(ident
, logstat
, logfac
)
370 if (ident
!= NULL
) _sl_LogTag
= ident
;
372 _sl_LogStat
= logstat
;
374 if (logfac
!= 0 && (logfac
&~ LOG_FACMASK
) == 0) _sl_LogFacility
= logfac
;
376 if (_sl_LogFile
== -1)
378 SyslogAddr
.sun_family
= AF_UNIX
;
379 (void)strncpy(SyslogAddr
.sun_path
, _PATH_LOG
, sizeof(SyslogAddr
.sun_path
));
380 if (_sl_LogStat
& LOG_NDELAY
)
382 if ((_sl_LogFile
= socket(AF_UNIX
, SOCK_DGRAM
, 0)) == -1) return;
383 (void)fcntl(_sl_LogFile
, F_SETFD
, 1);
387 if ((_sl_LogFile
!= -1) && (_sl_connected
== 0))
389 if (connect(_sl_LogFile
, (struct sockaddr
*)&SyslogAddr
, sizeof(SyslogAddr
)) == -1)
391 (void)close(_sl_LogFile
);
406 (void)close(_sl_LogFile
);
411 /* setlogmask -- set the log mask level */
419 if (pmask
!= 0) _sl_LogMask
= pmask
;
423 #endif /* !BUILDING_VARIANT */