]> git.saurik.com Git - apple/syslog.git/blob - libsystem_asl.tproj/src/syslog.c
ae0c402f15ef137da7ec8e8790d69f8992d87348
[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/log.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 os_log_type_t shim_syslog_to_log_type[8] = {
99 OS_LOG_TYPE_DEFAULT, // LOG_EMERG
100 OS_LOG_TYPE_DEFAULT, // LOG_ALERT
101 OS_LOG_TYPE_DEFAULT, // LOG_CRIT
102 OS_LOG_TYPE_DEFAULT, // LOG_ERR
103 OS_LOG_TYPE_DEFAULT, // LOG_WARNING
104 OS_LOG_TYPE_DEFAULT, // LOG_NOTICE
105 OS_LOG_TYPE_INFO, // LOG_INFO
106 OS_LOG_TYPE_DEBUG // LOG_DEBUG
107 };
108
109 extern uint32_t _asl_evaluate_send(asl_object_t client, asl_object_t m, int slevel);
110 extern uint32_t _asl_lib_vlog(asl_object_t obj, uint32_t eval, asl_object_t msg, const char *format, va_list ap);
111 extern uint32_t _asl_lib_vlog_text(asl_object_t obj, uint32_t eval, asl_object_t msg, const char *format, va_list ap);
112
113
114 /* SHIM SPI */
115 asl_object_t
116 _syslog_asl_client()
117 {
118 pthread_mutex_lock(&_sl_lock);
119 if (_sl_asl == NULL)
120 {
121 _sl_asl = asl_open(NULL, NULL, ASL_OPT_SYSLOG_LEGACY);
122 _sl_mask = ASL_FILTER_MASK_UPTO(ASL_LEVEL_DEBUG);
123 asl_set_filter(_sl_asl, _sl_mask);
124 }
125 pthread_mutex_unlock(&_sl_lock);
126
127 return _sl_asl;
128 }
129
130 /*
131 * syslog, vsyslog --
132 * print message on log file; output is intended for syslogd(8).
133 */
134
135 void
136 vsyslog(int pri, const char *fmt, va_list ap)
137 {
138 int level = pri & LOG_PRIMASK;
139 int fac = pri & LOG_FACMASK;
140 uint32_t eval;
141 void *addr;
142
143 _syslog_asl_client();
144
145 eval = _asl_evaluate_send(_sl_asl, NULL, level);
146
147 /* don't send install messages to Activity Tracing */
148 if (fac == LOG_INSTALL || (fac == 0 && _sl_fac == LOG_INSTALL)) {
149 eval &= ~EVAL_SEND_TRACE;
150 }
151
152 addr = __builtin_return_address(0);
153
154 if ((eval & EVAL_SEND_TRACE) && os_log_shim_enabled(addr))
155 {
156 va_list ap_copy;
157 os_log_type_t type = shim_syslog_to_log_type[level];
158
159 va_copy(ap_copy, ap);
160 os_log_with_args(OS_LOG_DEFAULT, type, fmt, ap_copy, addr);
161 va_end(ap_copy);
162
163 if (eval & EVAL_TEXT_FILE)
164 {
165 asl_object_t msg = asl_new(ASL_TYPE_MSG);
166 const char *facility;
167
168 if (fac != 0)
169 {
170 facility = asl_syslog_faciliy_num_to_name(fac);
171 if (facility != NULL) asl_set(msg, ASL_KEY_FACILITY, facility);
172 }
173
174 _asl_lib_vlog_text(_sl_asl, eval, msg, fmt, ap);
175
176 asl_release(msg);
177 }
178 }
179 else if (eval & EVAL_ASL)
180 {
181 asl_object_t msg = asl_new(ASL_TYPE_MSG);
182 const char *facility;
183
184 if (fac != 0)
185 {
186 facility = asl_syslog_faciliy_num_to_name(fac);
187 if (facility != NULL) asl_set(msg, ASL_KEY_FACILITY, facility);
188 }
189
190 _asl_lib_vlog(_sl_asl, eval, msg, fmt, ap);
191
192 asl_release(msg);
193 }
194 }
195
196 void
197 #ifdef __STDC__
198 syslog(int pri, const char *fmt, ...)
199 #else
200 syslog(pri, fmt, va_alist)
201 int pri;
202 char *fmt;
203 va_dcl
204 #endif
205 {
206 int level = pri & LOG_PRIMASK;
207 int fac = pri & LOG_FACMASK;
208 uint32_t eval;
209 void *addr;
210
211 _syslog_asl_client();
212
213 eval = _asl_evaluate_send(_sl_asl, NULL, level);
214
215 /* don't send install messages to Activity Tracing */
216 if (fac == LOG_INSTALL || (fac == 0 && _sl_fac == LOG_INSTALL)) {
217 eval &= ~EVAL_SEND_TRACE;
218 }
219
220 addr = __builtin_return_address(0);
221
222 if ((eval & EVAL_SEND_TRACE) && os_log_shim_enabled(addr))
223 {
224 va_list ap;
225 os_log_type_t type = shim_syslog_to_log_type[level];
226
227 #ifdef __STDC__
228 va_start(ap, fmt);
229 #else
230 va_start(ap);
231 #endif
232 os_log_with_args(OS_LOG_DEFAULT, type, fmt, ap, addr);
233 va_end(ap);
234
235 if (eval & EVAL_TEXT_FILE)
236 {
237 va_list ap;
238 asl_object_t msg = asl_new(ASL_TYPE_MSG);
239 const char *facility;
240
241 if (fac != 0)
242 {
243 facility = asl_syslog_faciliy_num_to_name(fac);
244 if (facility != NULL) asl_set(msg, ASL_KEY_FACILITY, facility);
245 }
246
247 #ifdef __STDC__
248 va_start(ap, fmt);
249 #else
250 va_start(ap);
251 #endif
252 _asl_lib_vlog_text(_sl_asl, eval, msg, fmt, ap);
253 va_end(ap);
254
255 asl_release(msg);
256 }
257 }
258 else if (eval & EVAL_ASL)
259 {
260 va_list ap;
261 asl_object_t msg = asl_new(ASL_TYPE_MSG);
262 const char *facility;
263
264 if (fac != 0)
265 {
266 facility = asl_syslog_faciliy_num_to_name(fac);
267 if (facility != NULL) asl_set(msg, ASL_KEY_FACILITY, facility);
268 }
269
270 #ifdef __STDC__
271 va_start(ap, fmt);
272 #else
273 va_start(ap);
274 #endif
275 _asl_lib_vlog(_sl_asl, eval, msg, fmt, ap);
276 va_end(ap);
277
278 asl_release(msg);
279 }
280 }
281
282 #ifndef BUILDING_VARIANT
283
284 void
285 openlog(const char *ident, int opts, int logfac)
286 {
287 const char *facility;
288 uint32_t asl_opts;
289
290 pthread_mutex_lock(&_sl_lock);
291
292 if (_sl_asl != NULL) asl_release(_sl_asl);
293 _sl_asl = NULL;
294
295 free(_sl_ident);
296 _sl_ident = NULL;
297
298 /* open with specified parameters */
299
300 if (ident != NULL) _sl_ident = strdup(ident);
301 /* NB we allow the strdup to fail silently */
302
303 _sl_fac = logfac;
304 facility = asl_syslog_faciliy_num_to_name(_sl_fac);
305
306 _sl_opts = opts;
307 asl_opts = ASL_OPT_SYSLOG_LEGACY;
308
309 if (_sl_opts & LOG_NO_NOTIFY) asl_opts |= ASL_OPT_NO_REMOTE;
310 if (_sl_opts & LOG_PERROR) asl_opts |= ASL_OPT_STDERR;
311
312 _sl_mask = ASL_FILTER_MASK_UPTO(ASL_LEVEL_DEBUG);
313
314 _sl_asl = asl_open(_sl_ident, facility, asl_opts);
315 asl_set_filter(_sl_asl, _sl_mask);
316
317 pthread_mutex_unlock(&_sl_lock);
318 }
319
320 void
321 closelog()
322 {
323 pthread_mutex_lock(&_sl_lock);
324
325 if (_sl_asl != NULL) asl_close(_sl_asl);
326 _sl_asl = NULL;
327
328 free(_sl_ident);
329 _sl_ident = NULL;
330
331 _sl_fac = 0;
332
333 pthread_mutex_unlock(&_sl_lock);
334 }
335
336 /* setlogmask -- set the log mask level */
337 int
338 setlogmask(int mask)
339 {
340 int oldmask;
341
342 if (mask == 0) return _sl_mask;
343
344 pthread_mutex_lock(&_sl_lock);
345
346 _sl_mask = mask;
347 oldmask = asl_set_filter(_sl_asl, mask);
348 if (_sl_opts & LOG_PERROR) asl_set_output_file_filter(_sl_asl, STDERR_FILENO, mask);
349
350 pthread_mutex_unlock(&_sl_lock);
351
352 return oldmask;
353 }
354
355 #endif /* !BUILDING_VARIANT */