]> git.saurik.com Git - apple/syslog.git/blob - libsystem_asl.tproj/src/syslog.c
1975d4d2b699756086cbe4d05e87e3e810a66288
[apple/syslog.git] / libsystem_asl.tproj / src / syslog.c
1 /*
2 * Copyright (c) 1999-2015 Apple Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
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
11 * file.
12 *
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.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24 /*
25 * Copyright (c) 1993
26 * The Regents of the University of California. All rights reserved.
27 *
28 * Redistribution and use in source and binary forms, with or without
29 * modification, are permitted provided that the following conditions
30 * are met:
31 * 1. Redistributions of source code must retain the above copyright
32 * notice, this list of conditions and the following disclaimer.
33 * 2. Redistributions in binary form must reproduce the above copyright
34 * notice, this list of conditions and the following disclaimer in the
35 * documentation and/or other materials provided with the distribution.
36 * 3. All advertising materials mentioning features or use of this software
37 * must display the following acknowledgement:
38 * This product includes software developed by the University of
39 * California, Berkeley and its contributors.
40 * 4. Neither the name of the University nor the names of its contributors
41 * may be used to endorse or promote products derived from this software
42 * without specific prior written permission.
43 *
44 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
45 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
46 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
47 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
48 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
49 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
50 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
51 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
52 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
53 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
54 * SUCH DAMAGE.
55 */
56
57 #include <stdio.h>
58
59 #include <sys/syslog.h>
60 #include <stdlib.h>
61 #include <string.h>
62 #include <stdint.h>
63 #include <pthread.h>
64 #include <dispatch/dispatch.h>
65 #include <asl.h>
66 #include <asl_msg.h>
67 #include <asl_private.h>
68 #include <os/trace.h>
69 #include <os/log_private.h>
70
71 #ifdef __STDC__
72 #include <stdarg.h>
73 #else
74 #include <varargs.h>
75 #endif
76
77 #define LOG_NO_NOTIFY 0x1000
78 extern const char *asl_syslog_faciliy_num_to_name(int n);
79
80 #ifdef BUILDING_VARIANT
81 __private_extern__ pthread_mutex_t _sl_lock;
82 __private_extern__ asl_object_t _sl_asl;
83 __private_extern__ char *_sl_ident;
84 __private_extern__ int _sl_fac;
85 __private_extern__ int _sl_opts;
86 __private_extern__ int _sl_mask;
87 #else /* !BUILDING_VARIANT */
88 __private_extern__ pthread_mutex_t _sl_lock = PTHREAD_MUTEX_INITIALIZER;
89 __private_extern__ asl_object_t _sl_asl = NULL;
90 __private_extern__ char *_sl_ident = NULL;
91 __private_extern__ int _sl_fac = 0;
92 __private_extern__ int _sl_opts = 0;
93 __private_extern__ int _sl_mask = 0;
94 #endif /* BUILDING_VARIANT */
95
96 #define EVAL_ASL (EVAL_SEND_ASL | EVAL_TEXT_FILE | EVAL_ASL_FILE)
97
98 static const uint8_t shim_syslog_to_trace_type[8] = {
99 OS_TRACE_TYPE_FAULT, OS_TRACE_TYPE_FAULT, OS_TRACE_TYPE_FAULT, // LOG_EMERG, LOG_ALERT, LOG_CRIT
100 OS_TRACE_TYPE_ERROR, // LOG_ERROR
101 OS_TRACE_TYPE_RELEASE, OS_TRACE_TYPE_RELEASE, OS_TRACE_TYPE_RELEASE, // LOG_WARN, LOG_NOTICE, LOG_INFO
102 OS_TRACE_TYPE_DEBUG // LOG_DEBUG
103 };
104
105 extern uint32_t _asl_evaluate_send(asl_object_t client, asl_object_t m, int slevel);
106 extern uint32_t _asl_lib_vlog(asl_object_t obj, uint32_t eval, asl_object_t msg, const char *format, va_list ap);
107
108
109 /* SHIM SPI */
110 asl_object_t
111 _syslog_asl_client()
112 {
113 pthread_mutex_lock(&_sl_lock);
114 if (_sl_asl == NULL)
115 {
116 _sl_asl = asl_open(NULL, NULL, ASL_OPT_SYSLOG_LEGACY);
117 _sl_mask = ASL_FILTER_MASK_UPTO(ASL_LEVEL_DEBUG);
118 asl_set_filter(_sl_asl, _sl_mask);
119 }
120 pthread_mutex_unlock(&_sl_lock);
121
122 return _sl_asl;
123 }
124
125 /*
126 * syslog, vsyslog --
127 * print message on log file; output is intended for syslogd(8).
128 */
129
130 void
131 vsyslog(int pri, const char *fmt, va_list ap)
132 {
133 int level = pri & LOG_PRIMASK;
134 uint32_t eval;
135
136 _syslog_asl_client();
137
138 eval = _asl_evaluate_send(_sl_asl, NULL, level);
139
140 if (eval & EVAL_SEND_TRACE)
141 {
142 va_list ap_copy;
143 uint8_t trace_type = shim_syslog_to_trace_type[level];
144
145 va_copy(ap_copy, ap);
146 os_log_shim_with_va_list(__builtin_return_address(0), OS_LOG_DEFAULT, trace_type, fmt, ap_copy, NULL);
147 va_end(ap_copy);
148 }
149
150 if (os_log_shim_legacy_logging_enabled() && (eval & EVAL_ASL))
151 {
152 asl_object_t msg = asl_new(ASL_TYPE_MSG);
153 const char *facility;
154 int fac = pri & LOG_FACMASK;
155
156 if (fac != 0)
157 {
158 facility = asl_syslog_faciliy_num_to_name(fac);
159 if (facility != NULL) asl_set(msg, ASL_KEY_FACILITY, facility);
160 }
161
162 if (eval & EVAL_SEND_TRACE) asl_set(msg, "ASLSHIM", "2");
163
164 _asl_lib_vlog(_sl_asl, eval, msg, fmt, ap);
165
166 asl_release(msg);
167 }
168 }
169
170 void
171 #ifdef __STDC__
172 syslog(int pri, const char *fmt, ...)
173 #else
174 syslog(pri, fmt, va_alist)
175 int pri;
176 char *fmt;
177 va_dcl
178 #endif
179 {
180 int level = pri & LOG_PRIMASK;
181 uint32_t eval;
182
183 _syslog_asl_client();
184
185 eval = _asl_evaluate_send(_sl_asl, NULL, level);
186
187 if (eval & EVAL_SEND_TRACE)
188 {
189 va_list ap;
190 uint8_t trace_type = shim_syslog_to_trace_type[level];
191
192 #ifdef __STDC__
193 va_start(ap, fmt);
194 #else
195 va_start(ap);
196 #endif
197 os_log_shim_with_va_list(__builtin_return_address(0), OS_LOG_DEFAULT, trace_type, fmt, ap, NULL);
198 va_end(ap);
199 }
200
201 if (os_log_shim_legacy_logging_enabled() && (eval & EVAL_ASL))
202 {
203 va_list ap;
204 asl_object_t msg = asl_new(ASL_TYPE_MSG);
205 const char *facility;
206 int fac = pri & LOG_FACMASK;
207
208 if (fac != 0)
209 {
210 facility = asl_syslog_faciliy_num_to_name(fac);
211 if (facility != NULL) asl_set(msg, ASL_KEY_FACILITY, facility);
212 }
213
214 if (eval & EVAL_SEND_TRACE) asl_set(msg, "ASLSHIM", "2");
215
216 #ifdef __STDC__
217 va_start(ap, fmt);
218 #else
219 va_start(ap);
220 #endif
221 _asl_lib_vlog(_sl_asl, eval, msg, fmt, ap);
222 va_end(ap);
223
224 asl_release(msg);
225 }
226 }
227
228 #ifndef BUILDING_VARIANT
229
230 void
231 openlog(const char *ident, int opts, int logfac)
232 {
233 const char *facility;
234 uint32_t asl_opts;
235
236 pthread_mutex_lock(&_sl_lock);
237
238 if (_sl_asl != NULL) asl_release(_sl_asl);
239 _sl_asl = NULL;
240
241 free(_sl_ident);
242 _sl_ident = NULL;
243
244 /* open with specified parameters */
245
246 if (ident != NULL) _sl_ident = strdup(ident);
247 /* NB we allow the strdup to fail silently */
248
249 _sl_fac = logfac;
250 facility = asl_syslog_faciliy_num_to_name(_sl_fac);
251
252 _sl_opts = opts;
253 asl_opts = ASL_OPT_SYSLOG_LEGACY;
254
255 if (_sl_opts & LOG_NO_NOTIFY) asl_opts |= ASL_OPT_NO_REMOTE;
256 if (_sl_opts & LOG_PERROR) asl_opts |= ASL_OPT_STDERR;
257
258 _sl_mask = ASL_FILTER_MASK_UPTO(ASL_LEVEL_DEBUG);
259
260 _sl_asl = asl_open(_sl_ident, facility, asl_opts);
261 asl_set_filter(_sl_asl, _sl_mask);
262
263 pthread_mutex_unlock(&_sl_lock);
264 }
265
266 void
267 closelog()
268 {
269 pthread_mutex_lock(&_sl_lock);
270
271 if (_sl_asl != NULL) asl_close(_sl_asl);
272 _sl_asl = NULL;
273
274 free(_sl_ident);
275 _sl_ident = NULL;
276
277 pthread_mutex_unlock(&_sl_lock);
278 }
279
280 /* setlogmask -- set the log mask level */
281 int
282 setlogmask(int mask)
283 {
284 int oldmask;
285
286 if (mask == 0) return _sl_mask;
287
288 pthread_mutex_lock(&_sl_lock);
289
290 _sl_mask = mask;
291 oldmask = asl_set_filter(_sl_asl, mask);
292 if (_sl_opts & LOG_PERROR) asl_set_output_file_filter(_sl_asl, STDERR_FILENO, mask);
293
294 pthread_mutex_unlock(&_sl_lock);
295
296 return oldmask;
297 }
298
299 #endif /* !BUILDING_VARIANT */