]>
git.saurik.com Git - apple/xnu.git/blob - bsd/kern/kern_asl.c
2 * Copyright (c) 2013 Apple Computer, Inc. All rights reserved.
4 * @APPLE_OSREFERENCE_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. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
29 #include <sys/errno.h>
30 #include <sys/types.h>
31 #include <sys/malloc.h>
34 #include <sys/kauth.h>
35 #include <sys/mount.h>
36 #include <sys/vnode.h>
37 #include <sys/syslog.h>
38 #include <sys/vnode_internal.h>
39 #include <sys/fslog.h>
40 #include <sys/mount_internal.h>
43 #include <dev/random/randomdev.h>
45 #include <uuid/uuid.h>
49 /* String to append as format modifier for each key-value pair */
50 #define KASL_KEYVAL_FMT "[%s %s] "
51 #define KASL_KEYVAL_FMT_LEN (sizeof(KASL_KEYVAL_FMT) - 1)
53 #define KASL_NEWLINE_CHAR "\n"
54 #define KASL_NEWLINE_CHAR_LEN (sizeof(KASL_NEWLINE_CHAR) - 1)
56 /* Length of entire ASL message in 10 characters. Kernel defaults to zero */
57 #define KASL_ASL_MSG_LEN " 0"
59 /* Length of default format string to be used by printf */
60 #define MAX_FMT_LEN 256
63 /* Function to print input values as key-value pairs in format
64 * identifiable by Apple system log (ASL) facility. All key-value pairs
65 * are assumed to be pointer to strings and are provided using two ways -
66 * (a) va_list argument which is a list of varying number of arguments
67 * created by the caller of this function.
68 * (b) variable number of arguments passed to this function.
71 * level - Priority level for this ASL message
72 * facility - Facility for this ASL message.
73 * num_pairs - Number of key-value pairs provided by vargs argument.
74 * vargs - List of key-value pairs.
75 * ... - Additional key-value pairs (apart from vargs) as variable
76 * argument list. A NULL value indicates the end of the
77 * variable argument list.
80 * zero - On success, when it prints all key-values pairs provided.
81 * E2BIG - When it cannot print all key-value pairs provided and had
82 * to truncate the output.
85 kern_asl_msg_va(int level
, const char *facility
, int num_pairs
, va_list vargs
, ...)
88 char fmt
[MAX_FMT_LEN
]; /* Format string to use with vaddlog */
95 /* Mask extra bits, if any, from priority level */
96 level
= LOG_PRI(level
);
98 /* Create the first part of format string consisting of ASL
99 * message length, level, and facility.
102 snprintf(fmt
, MAX_FMT_LEN
, "%s [%s %d] [%s %s] ",
104 KASL_KEY_LEVEL
, level
,
105 KASL_KEY_FACILITY
, facility
);
107 snprintf(fmt
, MAX_FMT_LEN
, "%s [%s %d] ",
109 KASL_KEY_LEVEL
, level
);
112 /* Determine the number of key-value format string [%s %s] that
113 * should be added in format string for every key-value pair provided
114 * in va_list. Calculate maximum number of format string that can be
115 * accommodated in the remaining format buffer (after saving space
116 * for newline character). If the caller provided pairs in va_list
117 * is more than calculated pairs, truncate extra pairs.
119 len
= MAX_FMT_LEN
- strlen(fmt
) - KASL_NEWLINE_CHAR_LEN
- 1;
120 calc_pairs
= len
/ KASL_KEYVAL_FMT_LEN
;
121 if (num_pairs
<= calc_pairs
) {
122 calc_pairs
= num_pairs
;
127 /* Append format strings [%s %s] for the key-value pairs in vargs */
128 len
= MAX_FMT_LEN
- KASL_NEWLINE_CHAR_LEN
;
129 for (i
= 0; i
< calc_pairs
; i
++) {
130 (void) strlcat(fmt
, KASL_KEYVAL_FMT
, len
);
133 /* Count number of variable arguments provided to this function
134 * and determine total number of key-value pairs.
138 ptr
= va_arg(ap
, char *);
141 ptr
= va_arg(ap
, char *);
146 /* If user provided variable number of arguments, append them as
147 * as real key-value "[k v]" into the format string. If the format
148 * string is too small, ignore the key-value pair completely.
155 /* Calculate bytes available for key-value pairs after reserving
156 * bytes for newline character and NULL terminator
158 len
= MAX_FMT_LEN
- strlen(fmt
) - KASL_NEWLINE_CHAR_LEN
- 1;
159 offset
= strlen(fmt
);
162 for (i
= 0; i
< calc_pairs
; i
++) {
163 key
= va_arg(ap
, char *);
164 val
= va_arg(ap
, char *);
166 /* Calculate bytes required to store next key-value pair
167 * as "[key val] " including space for '[', ']', and
170 pairlen
= strlen(key
) + strlen(val
) + 4;
176 /* len + 1 because one byte has been set aside for NULL
177 * terminator in calculation of 'len' above
179 snprintf((fmt
+ offset
), len
+ 1, KASL_KEYVAL_FMT
,
188 (void) strlcat(fmt
, KASL_NEWLINE_CHAR
, MAX_FMT_LEN
);
190 /* Print the key-value pairs in ASL format */
194 * Note: can't use os_log_with_args() here because 'fmt' is
195 * constructed on the stack i.e. doesn't come from a text
196 * section. More importantly, the newer logging system
197 * doesn't grok ASL either.
204 kern_asl_msg(int level
, const char *facility
, int num_pairs
, ...)
209 va_start(ap
, num_pairs
);
210 err
= kern_asl_msg_va(level
, facility
,
211 num_pairs
, ap
, NULL
);
217 /* Search if given string contains '[' and ']'. If any, escape it by
218 * prefixing with a '\'. If the length of the string is not big enough,
219 * no changes are done and error is returned.
222 * str - string that can contain '[' or ']', should be NULL terminated
223 * len - length, in bytes, of valid data, including NULL character.
224 * buflen - size of buffer that contains the string
227 escape_str(char *str
, int len
, int buflen
)
232 /* Count number of characters to escape */
236 if ((*src
== '[') || (*src
== ']')) {
243 * Check if the buffer has enough space to escape all
246 if ((buflen
- len
) < count
) {
254 if ((*src
== '[') || (*src
== ']')) {
255 /* Last char copied needs to be escaped */