]> git.saurik.com Git - apple/xnu.git/blob - libkern/kxld/tests/kextcopyright.c
xnu-1486.2.11.tar.gz
[apple/xnu.git] / libkern / kxld / tests / kextcopyright.c
1 #include <stdio.h>
2
3 #include <CoreFoundation/CoreFoundation.h>
4
5 #include <kxld.h>
6
7 #define kCFBundleGetInfoStringKey CFSTR("CFBundleGetInfoString")
8 #define kNSHumanReadableCopyrightKey CFSTR("NSHumanReadableCopyright")
9
10 const char *gProgname = NULL;
11
12 static void usage(void);
13 static void printFormat(void);
14 static char *convert_cfstring(CFStringRef the_string);
15
16 /******************************************************************************
17 ******************************************************************************/
18 static void
19 usage(void)
20 {
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);
24
25 printFormat();
26 }
27
28 /******************************************************************************
29 ******************************************************************************/
30 static void
31 printFormat(void)
32 {
33 fprintf(stderr,
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");
44 }
45
46 /******************************************************************************
47 ******************************************************************************/
48 char *
49 convert_cfstring(CFStringRef the_string)
50 {
51 char *result = NULL;
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;
57
58 the_data = CFStringCreateExternalRepresentation(kCFAllocatorDefault,
59 the_string, kCFStringEncodingUTF8, 0);
60 if (!the_data) {
61 fprintf(stderr, "Failed to convert string\n");
62 goto finish;
63 }
64
65 data_bytes = CFDataGetBytePtr(the_data);
66 if (!data_bytes) {
67 fprintf(stderr, "Failed to get converted string bytes\n");
68 goto finish;
69 }
70
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");
75 goto finish;
76 }
77
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");
82 goto finish;
83 }
84
85 result = converted_string;
86 finish:
87 return result;
88 }
89
90 /******************************************************************************
91 ******************************************************************************/
92 int
93 main(int argc, const char *argv[])
94 {
95 int result = 1;
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
105
106 gProgname = argv[0];
107
108 if (argc != 2) {
109 usage();
110 goto finish;
111 }
112
113 anURL = CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault,
114 (const UInt8 *) argv[1], strlen(argv[1]), /* isDirectory */ FALSE);
115 if (!anURL) {
116 fprintf(stderr, "Can't create path from %s\n", argv[1]);
117 goto finish;
118 }
119
120 aBundle = CFBundleCreate(kCFAllocatorDefault, anURL);
121 if (!aBundle) {
122 fprintf(stderr, "Can't create bundle at path %s\n", argv[1]);
123 goto finish;
124 }
125
126 aDict = CFBundleGetInfoDictionary(aBundle);
127 if (!aDict) {
128 fprintf(stderr, "Can't get info dictionary from bundle\n");
129 goto finish;
130 }
131
132 infoCopyrightString = CFDictionaryGetValue(aDict, kCFBundleGetInfoStringKey);
133 readableCopyrightString = CFDictionaryGetValue(aDict, kNSHumanReadableCopyrightKey);
134
135 if (!infoCopyrightString && !readableCopyrightString) {
136 fprintf(stderr, "This kext does not have a value for NSHumanReadableCopyright");
137 goto finish;
138 }
139
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");
144
145 infoStr = convert_cfstring(infoCopyrightString);
146 if (!infoStr) goto finish;
147
148 infoCopyrightIsValid = kxld_validate_copyright_string(infoStr);
149 }
150
151 if (readableCopyrightString) {
152 readableStr = convert_cfstring(readableCopyrightString);
153 if (!readableStr) goto finish;
154
155 readableCopyrightIsValid = kxld_validate_copyright_string(readableStr);
156 }
157
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");
163 } else {
164 fprintf(stderr, "Error: There is no valid copyright string for this kext.\n\n");
165 printFormat();
166 goto finish;
167 }
168 }
169
170 result = 0;
171 finish:
172 if (anURL) CFRelease(anURL);
173 if (aBundle) CFRelease(aBundle);
174 if (infoStr) free(infoStr);
175 if (readableStr) free(readableStr);
176
177 return result;
178 }
179