]> git.saurik.com Git - apple/xnu.git/blob - libkern/kxld/tests/kextcopyright.c
xnu-7195.101.1.tar.gz
[apple/xnu.git] / libkern / kxld / tests / kextcopyright.c
1 /*
2 * Copyright (c) 2009 Apple Inc. All rights reserved.
3 *
4 * @APPLE_OSREFERENCE_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. 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.
14 *
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
17 *
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.
25 *
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27 */
28
29 #include <stdio.h>
30
31 #include <CoreFoundation/CoreFoundation.h>
32
33 #include <kxld.h>
34
35 #define kCFBundleGetInfoStringKey CFSTR("CFBundleGetInfoString")
36 #define kNSHumanReadableCopyrightKey CFSTR("NSHumanReadableCopyright")
37
38 const char *gProgname = NULL;
39
40 static void usage(void);
41 static void printFormat(void);
42 static char *convert_cfstring(CFStringRef the_string);
43
44 /******************************************************************************
45 ******************************************************************************/
46 static void
47 usage(void)
48 {
49 printf("usage: %s [path to kext]\n\n"
50 "This program validates the copyright string in a kext's info "
51 "dictionary.\n\n", gProgname);
52
53 printFormat();
54 }
55
56 /******************************************************************************
57 ******************************************************************************/
58 static void
59 printFormat(void)
60 {
61 fprintf(stderr,
62 "The copyright string should be contained in the NSHumanReadableCopyright key.\n"
63 "It should be of the format:\n"
64 "\tCopyright © [year(s) of publication] Apple Inc. All rights reserved.\n\n"
65 "where [year(s) of publication] is a comma-separated list of years and/or\n"
66 "year ranges, e.g., 2004, 2006-2008. Years must be four digits. Year ranges\n"
67 "may not contain spaces and must use four digits for both years.\n\n"
68 "The following are examples of valid copyright strings:\n"
69 "\tCopyright © 2008 Apple Inc. All rights reserved.\n"
70 "\tCopyright © 2004-2008 Apple Inc. All rights reserved.\n"
71 "\tCopyright © 1998,2000-2002,2004,2006-2008 Apple Inc. All rights reserved.\n");
72 }
73
74 /******************************************************************************
75 ******************************************************************************/
76 char *
77 convert_cfstring(CFStringRef the_string)
78 {
79 char *result = NULL;
80 CFDataRef the_data = NULL;
81 const UInt8 *data_bytes = NULL;
82 char *converted_string = NULL;
83 u_long converted_len = 0;
84 u_long bytes_copied = 0;
85
86 the_data = CFStringCreateExternalRepresentation(kCFAllocatorDefault,
87 the_string, kCFStringEncodingUTF8, 0);
88 if (!the_data) {
89 fprintf(stderr, "Failed to convert string\n");
90 goto finish;
91 }
92
93 data_bytes = CFDataGetBytePtr(the_data);
94 if (!data_bytes) {
95 fprintf(stderr, "Failed to get converted string bytes\n");
96 goto finish;
97 }
98
99 converted_len = strlen((const char *)data_bytes) + 1; // +1 for nul
100 converted_string = malloc(converted_len);
101 if (!converted_string) {
102 fprintf(stderr, "Failed to allocate memory\n");
103 goto finish;
104 }
105
106 bytes_copied = strlcpy(converted_string, (const char *) data_bytes,
107 converted_len) + 1; // +1 for nul
108 if (bytes_copied != converted_len) {
109 fprintf(stderr, "Failed to copy converted string\n");
110 goto finish;
111 }
112
113 result = converted_string;
114 finish:
115 if (the_data) {
116 CFRelease(the_data);
117 }
118 return result;
119 }
120
121 /******************************************************************************
122 ******************************************************************************/
123 int
124 main(int argc, const char *argv[])
125 {
126 int result = 1;
127 boolean_t infoCopyrightIsValid = false;
128 boolean_t readableCopyrightIsValid = false;
129 CFURLRef anURL = NULL; // must release
130 CFBundleRef aBundle = NULL; // must release
131 CFDictionaryRef aDict = NULL; // do not release
132 CFStringRef infoCopyrightString = NULL; // do not release
133 CFStringRef readableCopyrightString = NULL; // do not release
134 char *infoStr = NULL; // must free
135 char *readableStr = NULL; // must free
136
137 gProgname = argv[0];
138
139 if (argc != 2) {
140 usage();
141 goto finish;
142 }
143
144 anURL = CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault,
145 (const UInt8 *) argv[1], strlen(argv[1]), /* isDirectory */ FALSE);
146 if (!anURL) {
147 fprintf(stderr, "Can't create path from %s\n", argv[1]);
148 goto finish;
149 }
150
151 aBundle = CFBundleCreate(kCFAllocatorDefault, anURL);
152 if (!aBundle) {
153 fprintf(stderr, "Can't create bundle at path %s\n", argv[1]);
154 goto finish;
155 }
156
157 aDict = CFBundleGetInfoDictionary(aBundle);
158 if (!aDict) {
159 fprintf(stderr, "Can't get info dictionary from bundle\n");
160 goto finish;
161 }
162
163 infoCopyrightString = CFDictionaryGetValue(aDict, kCFBundleGetInfoStringKey);
164 readableCopyrightString = CFDictionaryGetValue(aDict, kNSHumanReadableCopyrightKey);
165
166 if (!infoCopyrightString && !readableCopyrightString) {
167 fprintf(stderr, "This kext does not have a value for NSHumanReadableCopyright");
168 goto finish;
169 }
170
171 if (infoCopyrightString) {
172 fprintf(stderr, "Warning: This kext has a value for CFBundleGetInfoString.\n"
173 "This key is obsolete, and may be removed from the kext's Info.plist.\n"
174 "It has been replaced by CFBundleVersion and NSHumanReadableCopyright.\n\n");
175
176 infoStr = convert_cfstring(infoCopyrightString);
177 if (!infoStr) {
178 goto finish;
179 }
180
181 infoCopyrightIsValid = kxld_validate_copyright_string(infoStr);
182 }
183
184 if (readableCopyrightString) {
185 readableStr = convert_cfstring(readableCopyrightString);
186 if (!readableStr) {
187 goto finish;
188 }
189
190 readableCopyrightIsValid = kxld_validate_copyright_string(readableStr);
191 }
192
193 if (!readableCopyrightIsValid) {
194 if (infoCopyrightIsValid) {
195 fprintf(stderr, "Warning: The copyright string in NSHumanReadableCopyright is invalid,\n"
196 "but the string in CFBundleGetInfoString is valid. CFBundleGetInfoString is\n"
197 "obsolete. Please migrate your copyright string to NSHumanReadableCopyright.\n\n");
198 } else {
199 fprintf(stderr, "Error: There is no valid copyright string for this kext.\n\n");
200 printFormat();
201 goto finish;
202 }
203 }
204
205 result = 0;
206 finish:
207 if (anURL) {
208 CFRelease(anURL);
209 }
210 if (aBundle) {
211 CFRelease(aBundle);
212 }
213 if (infoStr) {
214 free(infoStr);
215 }
216 if (readableStr) {
217 free(readableStr);
218 }
219
220 return result;
221 }