3 #include <CoreFoundation/CoreFoundation.h>
7 #define kCFBundleGetInfoStringKey CFSTR("CFBundleGetInfoString")
8 #define kNSHumanReadableCopyrightKey CFSTR("NSHumanReadableCopyright")
10 const char *gProgname
= NULL
;
12 static void usage(void);
13 static void printFormat(void);
14 static char *convert_cfstring(CFStringRef the_string
);
16 /******************************************************************************
17 ******************************************************************************/
21 printf("usage: %s [path to kext]\n\n"
22 "This program validates the copyright string in a kext's info "
23 "dictionary.\n\n", gProgname
);
28 /******************************************************************************
29 ******************************************************************************/
34 "The copyright string should be contained in the NSHumanReadableCopyright key.\n"
35 "It should be of the format:\n"
36 "\tCopyright © [year(s) of publication] Apple Inc. All rights reserved.\n\n"
37 "where [year(s) of publication] is a comma-separated list of years and/or\n"
38 "year ranges, e.g., 2004, 2006-2008. Years must be four digits. Year ranges\n"
39 "may not contain spaces and must use four digits for both years.\n\n"
40 "The following are examples of valid copyright strings:\n"
41 "\tCopyright © 2008 Apple Inc. All rights reserved.\n"
42 "\tCopyright © 2004-2008 Apple Inc. All rights reserved.\n"
43 "\tCopyright © 1998,2000-2002,2004,2006-2008 Apple Inc. All rights reserved.\n");
46 /******************************************************************************
47 ******************************************************************************/
49 convert_cfstring(CFStringRef the_string
)
52 CFDataRef the_data
= NULL
;
53 const UInt8
*data_bytes
= NULL
;
54 char *converted_string
= NULL
;
55 u_long converted_len
= 0;
56 u_long bytes_copied
= 0;
58 the_data
= CFStringCreateExternalRepresentation(kCFAllocatorDefault
,
59 the_string
, kCFStringEncodingUTF8
, 0);
61 fprintf(stderr
, "Failed to convert string\n");
65 data_bytes
= CFDataGetBytePtr(the_data
);
67 fprintf(stderr
, "Failed to get converted string bytes\n");
71 converted_len
= strlen((const char *)data_bytes
) + 1; // +1 for nul
72 converted_string
= malloc(converted_len
);
73 if (!converted_string
) {
74 fprintf(stderr
, "Failed to allocate memory\n");
78 bytes_copied
= strlcpy(converted_string
, (const char *) data_bytes
,
79 converted_len
) + 1; // +1 for nul
80 if (bytes_copied
!= converted_len
) {
81 fprintf(stderr
, "Failed to copy converted string\n");
85 result
= converted_string
;
90 /******************************************************************************
91 ******************************************************************************/
93 main(int argc
, const char *argv
[])
96 boolean_t infoCopyrightIsValid
= false;
97 boolean_t readableCopyrightIsValid
= false;
98 CFURLRef anURL
= NULL
; // must release
99 CFBundleRef aBundle
= NULL
; // must release
100 CFDictionaryRef aDict
= NULL
; // do not release
101 CFStringRef infoCopyrightString
= NULL
; // do not release
102 CFStringRef readableCopyrightString
= NULL
; // do not release
103 char *infoStr
= NULL
; // must free
104 char *readableStr
= NULL
; // must free
113 anURL
= CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault
,
114 (const UInt8
*) argv
[1], strlen(argv
[1]), /* isDirectory */ FALSE
);
116 fprintf(stderr
, "Can't create path from %s\n", argv
[1]);
120 aBundle
= CFBundleCreate(kCFAllocatorDefault
, anURL
);
122 fprintf(stderr
, "Can't create bundle at path %s\n", argv
[1]);
126 aDict
= CFBundleGetInfoDictionary(aBundle
);
128 fprintf(stderr
, "Can't get info dictionary from bundle\n");
132 infoCopyrightString
= CFDictionaryGetValue(aDict
, kCFBundleGetInfoStringKey
);
133 readableCopyrightString
= CFDictionaryGetValue(aDict
, kNSHumanReadableCopyrightKey
);
135 if (!infoCopyrightString
&& !readableCopyrightString
) {
136 fprintf(stderr
, "This kext does not have a value for NSHumanReadableCopyright");
140 if (infoCopyrightString
) {
141 fprintf(stderr
, "Warning: This kext has a value for CFBundleGetInfoString.\n"
142 "This key is obsolete, and may be removed from the kext's Info.plist.\n"
143 "It has been replaced by CFBundleVersion and NSHumanReadableCopyright.\n\n");
145 infoStr
= convert_cfstring(infoCopyrightString
);
146 if (!infoStr
) goto finish
;
148 infoCopyrightIsValid
= kxld_validate_copyright_string(infoStr
);
151 if (readableCopyrightString
) {
152 readableStr
= convert_cfstring(readableCopyrightString
);
153 if (!readableStr
) goto finish
;
155 readableCopyrightIsValid
= kxld_validate_copyright_string(readableStr
);
158 if (!readableCopyrightIsValid
) {
159 if (infoCopyrightIsValid
) {
160 fprintf(stderr
, "Warning: The copyright string in NSHumanReadableCopyright is invalid,\n"
161 "but the string in CFBundleGetInfoString is valid. CFBundleGetInfoString is\n"
162 "obsolete. Please migrate your copyright string to NSHumanReadableCopyright.\n\n");
164 fprintf(stderr
, "Error: There is no valid copyright string for this kext.\n\n");
172 if (anURL
) CFRelease(anURL
);
173 if (aBundle
) CFRelease(aBundle
);
174 if (infoStr
) free(infoStr
);
175 if (readableStr
) free(readableStr
);