2 * Copyright (c) 2009 Apple Inc. All rights reserved.
4 * @APPLE_OSREFERENCE_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. 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.
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
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.
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
31 #include <CoreFoundation/CoreFoundation.h>
35 #define kCFBundleGetInfoStringKey CFSTR("CFBundleGetInfoString")
36 #define kNSHumanReadableCopyrightKey CFSTR("NSHumanReadableCopyright")
38 const char *gProgname
= NULL
;
40 static void usage(void);
41 static void printFormat(void);
42 static char *convert_cfstring(CFStringRef the_string
);
44 /******************************************************************************
45 ******************************************************************************/
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
);
56 /******************************************************************************
57 ******************************************************************************/
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");
74 /******************************************************************************
75 ******************************************************************************/
77 convert_cfstring(CFStringRef the_string
)
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;
86 the_data
= CFStringCreateExternalRepresentation(kCFAllocatorDefault
,
87 the_string
, kCFStringEncodingUTF8
, 0);
89 fprintf(stderr
, "Failed to convert string\n");
93 data_bytes
= CFDataGetBytePtr(the_data
);
95 fprintf(stderr
, "Failed to get converted string bytes\n");
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");
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");
113 result
= converted_string
;
115 if (the_data
) CFRelease(the_data
);
119 /******************************************************************************
120 ******************************************************************************/
122 main(int argc
, const char *argv
[])
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
142 anURL
= CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault
,
143 (const UInt8
*) argv
[1], strlen(argv
[1]), /* isDirectory */ FALSE
);
145 fprintf(stderr
, "Can't create path from %s\n", argv
[1]);
149 aBundle
= CFBundleCreate(kCFAllocatorDefault
, anURL
);
151 fprintf(stderr
, "Can't create bundle at path %s\n", argv
[1]);
155 aDict
= CFBundleGetInfoDictionary(aBundle
);
157 fprintf(stderr
, "Can't get info dictionary from bundle\n");
161 infoCopyrightString
= CFDictionaryGetValue(aDict
, kCFBundleGetInfoStringKey
);
162 readableCopyrightString
= CFDictionaryGetValue(aDict
, kNSHumanReadableCopyrightKey
);
164 if (!infoCopyrightString
&& !readableCopyrightString
) {
165 fprintf(stderr
, "This kext does not have a value for NSHumanReadableCopyright");
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");
174 infoStr
= convert_cfstring(infoCopyrightString
);
175 if (!infoStr
) goto finish
;
177 infoCopyrightIsValid
= kxld_validate_copyright_string(infoStr
);
180 if (readableCopyrightString
) {
181 readableStr
= convert_cfstring(readableCopyrightString
);
182 if (!readableStr
) goto finish
;
184 readableCopyrightIsValid
= kxld_validate_copyright_string(readableStr
);
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");
193 fprintf(stderr
, "Error: There is no valid copyright string for this kext.\n\n");
201 if (anURL
) CFRelease(anURL
);
202 if (aBundle
) CFRelease(aBundle
);
203 if (infoStr
) free(infoStr
);
204 if (readableStr
) free(readableStr
);