]> git.saurik.com Git - apple/security.git/blob - Security/utilities/src/SecCFError.c
Security-57031.30.12.tar.gz
[apple/security.git] / Security / utilities / src / SecCFError.c
1 /*
2 * Copyright (c) 2012-2014 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 #include <utilities/SecCFError.h>
26 #include <utilities/SecCFRelease.h>
27 #include <utilities/debugging.h>
28
29 bool SecKernError(kern_return_t result, CFErrorRef *error, CFStringRef format, ...) {
30 if (!result) return true;
31 if (error) {
32 va_list args;
33 CFIndex code = result;
34 CFErrorRef previousError = *error;
35
36 *error = NULL;
37 va_start(args, format);
38 SecCFCreateErrorWithFormatAndArguments(code, kSecKernDomain, previousError, error, NULL, format, args);
39 va_end(args);
40 }
41 return false;
42 }
43
44 bool SecCheckErrno(int result, CFErrorRef *error, CFStringRef format, ...) {
45 if (result == 0) return true;
46 if (error) {
47 va_list args;
48 int errnum = errno;
49 CFIndex code = errnum;
50 CFErrorRef previousError = *error;
51
52 *error = NULL;
53 va_start(args, format);
54 CFStringRef message = CFStringCreateWithFormatAndArguments(kCFAllocatorDefault, NULL, format, args);
55 va_end(args);
56 SecCFCreateErrorWithFormat(code, kSecErrnoDomain, previousError, error, NULL, CFSTR("%@: [%d] %s"), message, errnum, strerror(errnum));
57 CFReleaseSafe(message);
58 }
59 return false;
60 }
61
62 bool SecError(OSStatus status, CFErrorRef *error, CFStringRef format, ...) {
63 if (status == 0) return true;
64 if (error) {
65 va_list args;
66 CFIndex code = status;
67 CFErrorRef previousError = *error;
68
69 *error = NULL;
70 va_start(args, format);
71 SecCFCreateErrorWithFormatAndArguments(code, kSecErrorDomain, previousError, error, NULL, format, args);
72 va_end(args);
73 }
74 return false;
75 }
76
77 bool SecCFCreateError(CFIndex errorCode, CFStringRef domain, CFStringRef descriptionString,
78 CFErrorRef previousError, CFErrorRef *newError)
79 {
80 #pragma clang diagnostic push
81 #pragma GCC diagnostic ignored "-Wformat-security"
82 return SecCFCreateErrorWithFormat(errorCode, domain, previousError, newError, NULL, descriptionString);
83 #pragma clang diagnostic pop
84 }
85
86 bool SecCFCreateErrorWithFormat(CFIndex errorCode, CFStringRef domain, CFErrorRef previousError, CFErrorRef *newError,
87 CFDictionaryRef formatoptions, CFStringRef format, ...)
88 {
89 va_list args;
90 va_start(args, format);
91
92 bool result = SecCFCreateErrorWithFormatAndArguments(errorCode, domain, previousError, newError, formatoptions, format, args);
93
94 va_end(args);
95
96 return result;
97 }
98
99 bool SecCFCreateErrorWithFormatAndArguments(CFIndex errorCode, CFStringRef domain,
100 CFErrorRef previousError, CFErrorRef *newError,
101 CFDictionaryRef formatoptions, CFStringRef format, va_list args)
102 {
103 if (newError && !(*newError)) {
104 CFStringRef formattedString = CFStringCreateWithFormatAndArguments(NULL, formatoptions, format, args);
105
106 const void* keys[2] = { kCFErrorDescriptionKey, kCFErrorUnderlyingErrorKey};
107 const void* values[2] = { formattedString, previousError };
108 const CFIndex numEntriesToUse = (previousError != NULL) ? 2 : 1;
109
110 *newError = CFErrorCreateWithUserInfoKeysAndValues(kCFAllocatorDefault, domain, errorCode,
111 keys, values, numEntriesToUse);
112
113 CFReleaseNull(formattedString);
114 if (previousError)
115 secnotice("error", "encapsulated %@ with new error: %@", previousError, *newError);
116 } else {
117 if (previousError && newError && (previousError != *newError)) {
118 secnotice("error", "dropping %@", previousError);
119 CFRelease(previousError);
120 }
121 }
122
123 return false;
124 }