2 * Copyright (c) 2006-2010 Apple 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@
26 * debugging.c - non-trivial debug support
28 #include <security_utilities/debugging.h>
29 #include <CoreFoundation/CFSet.h>
30 #include <CoreFoundation/CFString.h>
39 #define MAX_SCOPE_LENGTH 12
42 static CFStringRef
copyScopeName(const char *scope
, CFIndex scopeLen
) {
43 if (scopeLen
> MAX_SCOPE_LENGTH
)
44 scopeLen
= MAX_SCOPE_LENGTH
- 1;
45 return CFStringCreateWithBytes(kCFAllocatorDefault
, (const UInt8
*)scope
,
46 scopeLen
, kCFStringEncodingUTF8
, false);
49 pthread_once_t __security_debug_once
= PTHREAD_ONCE_INIT
;
50 static const char *gDebugScope
;
51 static CFMutableSetRef scopeSet
;
52 static bool negate
= false;
54 static void __security_debug_init(void) {
55 const char *cur_scope
= gDebugScope
= getenv("DEBUGSCOPE");
57 if (!strcmp(cur_scope
, "all")) {
60 } else if (!strcmp(cur_scope
, "none")) {
64 scopeSet
= CFSetCreateMutable(kCFAllocatorDefault
, 0,
65 &kCFTypeSetCallBacks
);
66 if (cur_scope
[0] == '-') {
74 while ((sep
= strchr(cur_scope
, ','))) {
75 CFStringRef scopeName
= copyScopeName(cur_scope
,
77 CFSetAddValue(scopeSet
, scopeName
);
82 CFStringRef scopeName
= copyScopeName(cur_scope
,
84 CFSetAddValue(scopeSet
, scopeName
);
95 void __security_debug(CFStringRef scope
, const char *function
,
96 const char *file
, int line
, CFStringRef format
, ...)
99 pthread_once(&__security_debug_once
, __security_debug_init
);
101 /* Scope NULL is always enabled. */
103 /* Check if the scope is enabled. */
105 if (negate
== CFSetContainsValue(scopeSet
, scope
)) {
108 } else if (!negate
) {
115 va_start(args
, format
);
116 CFStringRef message
= CFStringCreateWithFormatAndArguments(
117 kCFAllocatorDefault
, NULL
, format
, args
);
119 time_t now
= time(NULL
);
120 char *date
= ctime(&now
);
122 CFStringRef logStr
= CFStringCreateWithFormat(kCFAllocatorDefault
, NULL
,
123 CFSTR("%s %@ %s %@\n"), date
+ 4,
124 scope
? scope
: CFSTR(""), function
, message
);
127 if (CFStringGetCString(logStr
, logMsg
, sizeof(logMsg
), kCFStringEncodingUTF8
)) {
128 char scopeStr
[MAX_SCOPE_LENGTH
+ 1];
129 aslmsg msg
= asl_new(ASL_TYPE_MSG
);
131 if (CFStringGetCString(scope
, scopeStr
, sizeof(scopeStr
),
132 kCFStringEncodingUTF8
)) {
133 asl_set(msg
, ASL_KEY_FACILITY
, scopeStr
);
135 asl_set(msg
, ASL_KEY_LEVEL
, ASL_STRING_INFO
);
137 asl_set(msg
, ASL_KEY_LEVEL
, ASL_STRING_ERR
);
139 asl_set(msg
, ASL_KEY_MSG
, logMsg
);