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>
40 #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(const char *scope
, const char *function
,
96 const char *file
, int line
, const char *format
, ...)
99 pthread_once(&__security_debug_once
, __security_debug_init
);
101 CFStringRef scopeName
= NULL
;
102 /* Scope NULL is always enabled. */
104 /* Check if the scope is enabled. */
106 scopeName
= copyScopeName(scope
, strlen(scope
));
107 if (negate
== CFSetContainsValue(scopeSet
, scopeName
)) {
108 CFRelease(scopeName
);
111 } else if (!negate
) {
116 CFStringRef formatStr
= CFStringCreateWithCString(kCFAllocatorDefault
,
117 format
, kCFStringEncodingUTF8
);
119 va_start(args
, format
);
120 CFStringRef message
= CFStringCreateWithFormatAndArguments(
121 kCFAllocatorDefault
, NULL
, formatStr
, args
);
123 time_t now
= time(NULL
);
124 char *date
= ctime(&now
);
126 CFStringRef logStr
= CFStringCreateWithFormat(kCFAllocatorDefault
, NULL
,
127 CFSTR("%s %-*s %s %@\n"), date
+ 4, MAX_SCOPE_LENGTH
- 1,
128 scope
? scope
: "", function
, message
);
131 if (CFStringGetCString(logStr
, logMsg
, sizeof(logMsg
), kCFStringEncodingUTF8
)) {
133 asl_log(NULL
, NULL
, ASL_LEVEL_INFO
, logMsg
);
135 aslmsg msg
= asl_new(ASL_TYPE_MSG
);
137 asl_set(msg
, ASL_KEY_FACILITY
, scope
);
139 asl_set(msg
, ASL_KEY_LEVEL
, ASL_STRING_INFO
);
140 asl_set(msg
, ASL_KEY_MSG
, logMsg
);
147 CFRelease(formatStr
);
149 CFRelease(scopeName
);