]>
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 * 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/param.h>
58 #include <sys/socket.h>
59 #include <sys/syslog.h>
76 #include <asl_private.h>
84 #include <crt_externs.h>
86 #define LOG_NO_NOTIFY 0x1000
87 #define INTERNALLOG LOG_ERR|LOG_CONS|LOG_PERROR|LOG_PID
89 #ifdef BUILDING_VARIANT
90 __private_extern__
int _sl_LogFile
; /* fd for log */
91 __private_extern__
int _sl_connected
; /* have done connect */
92 __private_extern__
int _sl_LogStat
; /* status bits, set by openlog() */
93 __private_extern__
const char *_sl_LogTag
; /* string to tag the entry with */
94 __private_extern__
int _sl_LogFacility
; /* default facility code */
95 __private_extern__
int _sl_LogMask
; /* mask of priorities to be logged */
96 __private_extern__
int _sl_NotifyToken
; /* for remote control of priority filter */
97 __private_extern__
int _sl_NotifyMaster
; /* for remote control of priority filter */
98 #else /* !BUILDING_VARIANT */
99 __private_extern__
int _sl_LogFile
= -1; /* fd for log */
100 __private_extern__
int _sl_connected
= 0; /* have done connect */
101 __private_extern__
int _sl_LogStat
= 0; /* status bits, set by openlog() */
102 __private_extern__
const char *_sl_LogTag
= NULL
; /* string to tag the entry with */
103 __private_extern__
int _sl_LogFacility
= LOG_USER
; /* default facility code */
104 __private_extern__
int _sl_LogMask
= 0xff; /* mask of priorities to be logged */
105 __private_extern__
int _sl_NotifyToken
= -1; /* for remote control of max logged priority */
106 __private_extern__
int _sl_NotifyMaster
= -1; /* for remote control of max logged priority */
107 #endif /* BUILDING_VARIANT */
109 __private_extern__
void _sl_init_notify();
111 #define NOTIFY_SYSTEM_MASTER "com.apple.system.syslog.master"
112 #define NOTIFY_PREFIX_SYSTEM "com.apple.system.syslog"
113 #define NOTIFY_PREFIX_USER "user.syslog"
114 #define NOTIFY_STATE_OFFSET 1000
117 uint32_t notify_register_plain(const char *name
, int *out_token
);
118 const char *asl_syslog_faciliy_num_to_name(int);
122 * print message on log file; output is intended for syslogd(8).
126 syslog(int pri
, const char *fmt
, ...)
128 syslog(pri
, fmt
, va_alist
)
141 vsyslog(pri
, fmt
, ap
);
146 vsyslog(int pri
, const char *fmt
, va_list ap
)
148 int status
, i
, saved_errno
, filter
, rc_filter
;
152 uint32_t elen
, count
;
153 char *p
, *str
, *expanded
, *err_str
, hname
[MAXHOSTNAMELEN
+1];
155 int fd
, mask
, level
, facility
;
160 /* Check for invalid bits. */
161 if (pri
& ~(LOG_PRIMASK
| LOG_FACMASK
))
163 syslog(INTERNALLOG
, "syslog: unknown facility/priority: %x", pri
);
164 pri
&= (LOG_PRIMASK
| LOG_FACMASK
);
167 level
= LOG_PRI(pri
);
168 facility
= pri
& LOG_FACMASK
;
170 if (facility
== 0) facility
= _sl_LogFacility
;
172 /* Get remote-control priority filter */
173 filter
= _sl_LogMask
;
178 if (_sl_NotifyToken
>= 0)
180 if (notify_get_state(_sl_NotifyToken
, &cval
) == NOTIFY_STATUS_OK
)
190 if ((rc_filter
== 0) && (_sl_NotifyMaster
>= 0))
192 if (notify_get_state(_sl_NotifyMaster
, &cval
) == NOTIFY_STATUS_OK
)
201 mask
= LOG_MASK(level
);
202 if ((mask
& filter
) == 0) return;
204 /* Build the message. */
205 msg
= asl_new(ASL_TYPE_MSG
);
207 if (_sl_LogTag
== NULL
) _sl_LogTag
= *(*_NSGetArgv());
208 if (_sl_LogTag
!= NULL
)
210 asl_set(msg
, ASL_KEY_SENDER
, _sl_LogTag
);
213 str
= (char *)asl_syslog_faciliy_num_to_name(facility
);
214 if (str
!= NULL
) asl_set(msg
, ASL_KEY_FACILITY
, str
);
217 memset(&tval
, 0, sizeof(struct timeval
));
219 status
= gettimeofday(&tval
, NULL
);
223 asprintf(&str
, "%lu", tval
.tv_sec
);
226 asl_set(msg
, ASL_KEY_TIME
, str
);
231 asprintf(&str
, "%lu", tval
.tv_usec
* 1000);
234 asl_set(msg
, ASL_KEY_TIME_NSEC
, str
);
242 asprintf(&str
, "%lu", tick
);
245 asl_set(msg
, ASL_KEY_TIME
, str
);
252 asprintf(&str
, "%u", pid
);
255 asl_set(msg
, ASL_KEY_PID
, str
);
260 asprintf(&str
, "%d", getuid());
263 asl_set(msg
, ASL_KEY_UID
, str
);
268 asprintf(&str
, "%u", getgid());
271 asl_set(msg
, ASL_KEY_GID
, str
);
276 asprintf(&str
, "%u", level
);
279 asl_set(msg
, ASL_KEY_LEVEL
, str
);
283 status
= gethostname(hname
, MAXHOSTNAMELEN
);
284 if (status
< 0) asl_set(msg
, ASL_KEY_HOST
, "localhost");
285 else asl_set(msg
, ASL_KEY_HOST
, hname
);
289 for (i
= 0; fmt
[i
] != '\0'; i
++)
291 if ((fmt
[i
] == '%') && (fmt
[i
+1] == 'm')) count
++;
298 /* deal with malloc failures gracefully */
301 err_str
= strdup(strerror(saved_errno
));
302 if (err_str
== NULL
) count
= 0;
305 elen
= strlen(err_str
);
306 expanded
= malloc(i
+ (count
* elen
));
307 if (expanded
== NULL
) count
= 0;
311 if (expanded
== NULL
) expanded
= (char *)fmt
;
316 for (i
= 0; fmt
[i
] != '\0'; i
++)
318 if ((fmt
[i
] == '%') && (fmt
[i
+1] == 'm'))
320 memcpy(p
, err_str
, elen
);
333 if (err_str
!= NULL
) free(err_str
);
335 vasprintf(&str
, expanded
, ap
);
336 if (count
> 0) free(expanded
);
340 asl_set(msg
, ASL_KEY_MSG
, str
);
342 /* Output to stderr if requested. */
343 if (_sl_LogStat
& LOG_PERROR
)
346 if (_sl_LogStat
& LOG_PID
) asprintf(&p
, "%s[%u]: %s", (_sl_LogTag
== NULL
) ? "???" : _sl_LogTag
, pid
, str
);
347 else asprintf(&p
, "%s: %s", (_sl_LogTag
== NULL
) ? "???" : _sl_LogTag
, str
);
354 iov
[0].iov_len
= strlen(p
);
355 iov
[1].iov_base
= "\n";
357 writev(STDERR_FILENO
, iov
, 2);
365 /* Get connected, output the message to the local logger. */
366 str
= asl_format_message(msg
, ASL_MSG_FMT_RAW
, ASL_TIME_FMT_SEC
, ASL_ENCODE_ASL
, &count
);
370 asprintf(&p
, "%10u %s", count
, str
);
376 if (_sl_connected
== 0) openlog(_sl_LogTag
, _sl_LogStat
| LOG_NDELAY
, 0);
378 status
= send(_sl_LogFile
, p
, count
, 0);
382 openlog(_sl_LogTag
, _sl_LogStat
| LOG_NDELAY
, 0);
383 status
= send(_sl_LogFile
, p
, count
, 0);
398 * Output the message to the console.
400 if (_sl_LogStat
& LOG_CONS
&& (fd
= open(_PATH_CONSOLE
, O_WRONLY
| O_NOCTTY
| O_NONBLOCK
)) >= 0)
404 p
= asl_format_message(msg
, ASL_MSG_FMT_STD
, ASL_TIME_FMT_LCL
, ASL_ENCODE_SAFE
, &count
);
409 /* count includes trailing nul */
410 iov
.iov_len
= count
- 1;
423 #ifndef BUILDING_VARIANT
425 static struct sockaddr_un SyslogAddr
; /* AF_UNIX address of local logger */
427 __private_extern__
void
434 if (_sl_LogStat
& LOG_NO_NOTIFY
)
436 _sl_NotifyMaster
= -2;
437 _sl_NotifyToken
= -2;
441 if (_sl_NotifyMaster
== -1)
443 status
= notify_register_plain(NOTIFY_SYSTEM_MASTER
, &_sl_NotifyMaster
);
444 if (status
!= NOTIFY_STATUS_OK
) _sl_NotifyMaster
= -2;
447 if (_sl_NotifyToken
== -1)
449 _sl_NotifyToken
= -2;
452 prefix
= NOTIFY_PREFIX_USER
;
453 if (getuid() == 0) prefix
= NOTIFY_PREFIX_SYSTEM
;
454 asprintf(¬ify_name
, "%s.%d", prefix
, getpid());
456 if (notify_name
!= NULL
)
458 status
= notify_register_plain(notify_name
, &_sl_NotifyToken
);
460 if (status
!= NOTIFY_STATUS_OK
) _sl_NotifyToken
= -2;
466 openlog(ident
, logstat
, logfac
)
470 if (ident
!= NULL
) _sl_LogTag
= ident
;
472 _sl_LogStat
= logstat
;
474 if (logfac
!= 0 && (logfac
&~ LOG_FACMASK
) == 0) _sl_LogFacility
= logfac
;
476 if (_sl_LogFile
== -1)
478 SyslogAddr
.sun_family
= AF_UNIX
;
479 (void)strncpy(SyslogAddr
.sun_path
, _PATH_LOG
, sizeof(SyslogAddr
.sun_path
));
480 if (_sl_LogStat
& LOG_NDELAY
)
482 if ((_sl_LogFile
= socket(AF_UNIX
, SOCK_DGRAM
, 0)) == -1) return;
483 (void)fcntl(_sl_LogFile
, F_SETFD
, 1);
487 if ((_sl_LogFile
!= -1) && (_sl_connected
== 0))
489 if (connect(_sl_LogFile
, (struct sockaddr
*)&SyslogAddr
, sizeof(SyslogAddr
)) == -1)
491 (void)close(_sl_LogFile
);
506 if (_sl_LogFile
>= 0) {
507 (void)close(_sl_LogFile
);
513 /* setlogmask -- set the log mask level */
521 if (pmask
!= 0) _sl_LogMask
= pmask
;
525 #endif /* !BUILDING_VARIANT */