]> git.saurik.com Git - apple/xnu.git/blob - libkern/kxld/tests/kextcopyright.c
xnu-3789.70.16.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) CFRelease(the_data);
116 return result;
117 }
118
119 /******************************************************************************
120 ******************************************************************************/
121 int
122 main(int argc, const char *argv[])
123 {
124 int result = 1;
125 boolean_t infoCopyrightIsValid = false;
126 boolean_t readableCopyrightIsValid = false;
127 CFURLRef anURL = NULL; // must release
128 CFBundleRef aBundle = NULL; // must release
129 CFDictionaryRef aDict = NULL; // do not release
130 CFStringRef infoCopyrightString = NULL; // do not release
131 CFStringRef readableCopyrightString = NULL; // do not release
132 char *infoStr = NULL; // must free
133 char *readableStr = NULL; // must free
134
135 gProgname = argv[0];
136
137 if (argc != 2) {
138 usage();
139 goto finish;
140 }
141
142 anURL = CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault,
143 (const UInt8 *) argv[1], strlen(argv[1]), /* isDirectory */ FALSE);
144 if (!anURL) {
145 fprintf(stderr, "Can't create path from %s\n", argv[1]);
146 goto finish;
147 }
148
149 aBundle = CFBundleCreate(kCFAllocatorDefault, anURL);
150 if (!aBundle) {
151 fprintf(stderr, "Can't create bundle at path %s\n", argv[1]);
152 goto finish;
153 }
154
155 aDict = CFBundleGetInfoDictionary(aBundle);
156 if (!aDict) {
157 fprintf(stderr, "Can't get info dictionary from bundle\n");
158 goto finish;
159 }
160
161 infoCopyrightString = CFDictionaryGetValue(aDict, kCFBundleGetInfoStringKey);
162 readableCopyrightString = CFDictionaryGetValue(aDict, kNSHumanReadableCopyrightKey);
163
164 if (!infoCopyrightString && !readableCopyrightString) {
165 fprintf(stderr, "This kext does not have a value for NSHumanReadableCopyright");
166 goto finish;
167 }
168
169 if (infoCopyrightString) {
170 fprintf(stderr, "Warning: This kext has a value for CFBundleGetInfoString.\n"
171 "This key is obsolete, and may be removed from the kext's Info.plist.\n"
172 "It has been replaced by CFBundleVersion and NSHumanReadableCopyright.\n\n");
173
174 infoStr = convert_cfstring(infoCopyrightString);
175 if (!infoStr) goto finish;
176
177 infoCopyrightIsValid = kxld_validate_copyright_string(infoStr);
178 }
179
180 if (readableCopyrightString) {
181 readableStr = convert_cfstring(readableCopyrightString);
182 if (!readableStr) goto finish;
183
184 readableCopyrightIsValid = kxld_validate_copyright_string(readableStr);
185 }
186
187 if (!readableCopyrightIsValid) {
188 if (infoCopyrightIsValid) {
189 fprintf(stderr, "Warning: The copyright string in NSHumanReadableCopyright is invalid,\n"
190 "but the string in CFBundleGetInfoString is valid. CFBundleGetInfoString is\n"
191 "obsolete. Please migrate your copyright string to NSHumanReadableCopyright.\n\n");
192 } else {
193 fprintf(stderr, "Error: There is no valid copyright string for this kext.\n\n");
194 printFormat();
195 goto finish;
196 }
197 }
198
199 result = 0;
200 finish:
201 if (anURL) CFRelease(anURL);
202 if (aBundle) CFRelease(aBundle);
203 if (infoStr) free(infoStr);
204 if (readableStr) free(readableStr);
205
206 return result;
207 }
208