1/*
2 * Copyright (c) 2006 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_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. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23#include "kextfind_tables.h"
24#include "kextfind_query.h"
25#include "kextfind_report.h"
26
27int longopt = 0;
28
29struct option opt_info[] = {
30    // real options
31    { kOptNameHelp,             no_argument,        NULL,     kOptHelp },
32    { kOptNameCaseInsensitive,  no_argument,        NULL,     kOptCaseInsensitive },
33    { kOptNameSearchItem,       required_argument,  NULL,     kOptSearchItem },
34    { kOptNameSystemExtensions, no_argument,        NULL,     kOptSystemExtensions },
35    { kOptNameDefaultArch,      required_argument,  &longopt, kLongOptDefaultArch },
36    { kOptNameSubstring,        no_argument,        NULL,     kOptSubstring },
37#ifdef EXTRA_INFO
38    { kOptNameExtraInfo,        no_argument,        &longopt, kLongOptExtraInfo },
39#endif
40    { kOptNameRelativePaths,    no_argument,        &longopt, kLongOptRelativePaths },
41    { kOptNameNoPaths,          no_argument,        &longopt, kLongOptNoPaths },
42#ifdef MEEK_PICKY
43    { kOptNameMeek,             no_argument,        &longopt, kLongOptMeek },
44    { kOptNamePicky,            no_argument,        &longopt, kLongOptPicky },
45#endif /* MEEK_PICKY */
46
47   /* We register the query predicates so that they are handled correctly
48    * even with the few short options we have (without these, -invalid gets
49    * recognized as -i plus more options, and -false as '-f alse').
50    *
51    * Query "options" are handled by simply terminating the getopt loop.
52    */
53    QUERY_PREDICATES
54
55    QUERY_COMMANDS
56
57    { &kKeywordReport[1],       no_argument,        &longopt, kLongOptQueryPredicate },
58
59    { NULL, 0, NULL, 0 }  // sentinel to terminate list
60};
61
62/* Each long ("name") predicate is used to register at least a parse callback,
63 * but not always an eval callback; some sets of predicates get funneled
64 * together *after* parsing, so we register them here with their own triggers
65 * but at parse time their predicates get reset to the shared one so that at
66 * eval time they use the same function.
67 *
68 * The -property, and -property-exists keywords, for example, both parse into
69 * -property predicates, but the other two set some data in the query element
70 * that the single evalProperty() function looks for and uses to tweak its
71 * behavior.
72 */
73struct querySetup queryCallbackList[] = {
74    {   CFSTR(kPredNameProperty), CFSTR(kPredCharProperty),
75        parseProperty, evalProperty },
76    {   CFSTR(kPredNamePropertyExists), CFSTR(kPredCharPropertyExists),
77        parseProperty, NULL },
78
79    {   CFSTR(kPredNameMatchProperty), CFSTR(kPredCharMatchProperty),
80        parseMatchProperty, evalMatchProperty },
81    {   CFSTR(kPredNameMatchPropertyExists), CFSTR(kPredCharMatchPropertyExists),
82        parseMatchProperty, NULL },
83
84    {   CFSTR(kPredNameLoaded), NULL,
85        parseFlag, NULL },
86    {   CFSTR(kPredNameValid), CFSTR(kPredCharValid),
87        parseFlag, NULL },
88    {   CFSTR(kPredNameAuthentic), CFSTR(kPredCharAuthentic),
89        parseFlag, NULL },
90    {   CFSTR(kPredNameDependenciesMet), CFSTR(kPredCharDependenciesMet),
91        parseFlag, NULL },
92    {   CFSTR(kPredNameLoadable), CFSTR(kPredCharLoadable),
93        parseFlag, NULL },
94    {   CFSTR(kPredNameWarnings), CFSTR(kPredCharWarnings),
95        parseFlag, NULL },
96    {   CFSTR(kPredNameIsLibrary), CFSTR(kPredCharIsLibrary),
97        parseFlag, NULL },
98
99    {   CFSTR(kPredNameDuplicate), CFSTR(kPredCharDuplicate),
100        parseFlag, NULL },
101
102    {   CFSTR(kPredNameInvalid), CFSTR(kPredCharInvalid),
103        parseFlag, NULL },
104    {   CFSTR(kPredNameInauthentic), CFSTR(kPredCharInauthentic),
105        parseFlag, NULL },
106    {   CFSTR(kPredNameDependenciesMissing), CFSTR(kPredCharDependenciesMissing),
107        parseFlag, NULL },
108    {   CFSTR(kPredNameNonloadable), CFSTR(kPredCharNonloadable),
109        parseFlag, NULL },
110
111    {   CFSTR(kPredNameHasPlugins), NULL,
112        parseFlag, NULL },
113    {   CFSTR(kPredNameIsPlugin), NULL,
114        parseFlag, NULL },
115    {   CFSTR(kPredNameHasDebugProperties), NULL,
116        parseFlag, NULL },
117    {   CFSTR(kPredNameIsKernelResource), NULL,
118        parseFlag, NULL },
119
120    {   CFSTR(kPredNameVersion), CFSTR(kPredCharVersion),
121        parseVersion, evalVersion },
122    {   CFSTR(kPredNameCompatibleWithVersion), NULL,
123        parseCompatibleWithVersion, evalCompatibleWithVersion },
124    {   CFSTR(kPredNameIntegrity), NULL,
125        parseIntegrity, evalIntegrity },
126
127    {   CFSTR(kPredNameArch), NULL,
128        parseArch, evalArch },
129    {   CFSTR(kPredNameArchExact), CFSTR(kPredCharArchExact),
130        parseArch, evalArchExact },
131    {   CFSTR(kPredNameExecutable), CFSTR(kPredCharExecutable),
132        parseFlag, NULL },
133    {   CFSTR(kPredNameNoExecutable), CFSTR(kPredCharNoExecutable),
134        parseFlag, NULL },
135    {   CFSTR(kPredNameDefinesSymbol), CFSTR(kPredCharDefinesSymbol),
136        parseDefinesOrReferencesSymbol, evalDefinesOrReferencesSymbol },
137    {   CFSTR(kPredNameReferencesSymbol), CFSTR(kPredCharReferencesSymbol),
138        parseDefinesOrReferencesSymbol, evalDefinesOrReferencesSymbol },
139
140    {   CFSTR(kPredNameBundleID), CFSTR(kPredCharBundleID),
141        parseShorthand, NULL },
142    {   CFSTR(kPredNameBundleName), CFSTR(kPredCharBundleName),
143        parseBundleName, evalBundleName },
144
145    {   CFSTR(kPredNameRoot), CFSTR(kPredCharRoot),
146        parseShorthand, NULL },
147    {   CFSTR(kPredNameConsole), CFSTR(kPredCharConsole),
148        parseShorthand, NULL },
149    {   CFSTR(kPredNameLocalRoot), CFSTR(kPredCharLocalRoot),
150        parseShorthand, NULL },
151    {   CFSTR(kPredNameNetworkRoot), CFSTR(kPredCharNetworkRoot),
152        parseShorthand, NULL },
153    {   CFSTR(kPredNameSafeBoot), CFSTR(kPredCharSafeBoot),
154        parseShorthand, NULL },
155
156    {   CFSTR(kPredNameEcho), NULL,
157        parseCommand, NULL },
158    {   CFSTR(kPredNamePrint), NULL,
159        parseCommand, NULL },
160    {   CFSTR(kPredNamePrint0), NULL,
161        parseCommand, NULL },
162    {   CFSTR(kPredNamePrintDiagnostics), CFSTR(kPredCharPrintDiagnostics),
163        parseCommand, NULL },
164    {   CFSTR(kPredNamePrintProperty), CFSTR(kPredCharPrintProperty),
165        parseCommand, NULL },
166    {   CFSTR(kPredNamePrintArches), CFSTR(kPredCharPrintArches),
167        parseCommand, NULL },
168    {   CFSTR(kPredNamePrintDependencies), NULL,
169        parseCommand, NULL },
170    {   CFSTR(kPredNamePrintDependents), NULL,
171        parseCommand, NULL },
172    {   CFSTR(kPredNamePrintIntegrity), NULL,
173        parseCommand, NULL },
174    {   CFSTR(kPredNamePrintPlugins), NULL,
175        parseCommand, NULL },
176    {   CFSTR(kPredNamePrintInfoDictionary), CFSTR(kPredCharPrintInfoDictionary),
177        parseCommand, NULL },
178    {   CFSTR(kPredNamePrintExecutable), CFSTR(kPredCharPrintExecutable),
179        parseCommand, NULL },
180
181    {   CFSTR(kPredNameExec), NULL, parseExec, evalExec },
182
183   /* These two special predicates are used internally for all "flag" and
184    * command precidates, which all reset their predicates at parse time and
185    * save the original keyword.
186    */
187    {   CFSTR(kPredNameFlag), NULL,
188        NULL, evalFlag },
189    {   CFSTR(kPredNameCommand), NULL,
190        NULL, evalCommand },
191
192    { NULL, NULL, NULL, NULL }  // sentinel to terminate list
193
194};
195
196/* The report callback list reuses many query and command predicate keywords,
197 * but parses and evaluates a lot of them differently!
198 */
199struct querySetup reportCallbackList[] = {
200    {   CFSTR(kPredNameProperty), CFSTR(kPredCharProperty),
201        reportParseProperty, reportEvalProperty },
202
203    {   CFSTR(kPredNameLoaded), NULL,
204        reportParseFlag, NULL },
205    {   CFSTR(kPredNameValid), CFSTR(kPredCharValid),
206        reportParseFlag, NULL },
207    {   CFSTR(kPredNameAuthentic), CFSTR(kPredCharAuthentic),
208        reportParseFlag, NULL },
209    {   CFSTR(kPredNameDependenciesMet), CFSTR(kPredCharDependenciesMet),
210        reportParseFlag, NULL },
211    {   CFSTR(kPredNameLoadable), CFSTR(kPredCharLoadable),
212        reportParseFlag, NULL },
213    {   CFSTR(kPredNameWarnings), CFSTR(kPredCharWarnings),
214        reportParseFlag, NULL },
215    {   CFSTR(kPredNameIsLibrary), CFSTR(kPredCharIsLibrary),
216        reportParseFlag, NULL },
217
218    {   CFSTR(kPredNameHasPlugins), NULL,
219        reportParseFlag, NULL },
220    {   CFSTR(kPredNameIsPlugin), NULL,
221        reportParseFlag, NULL },
222    {   CFSTR(kPredNameHasDebugProperties), NULL,
223        reportParseFlag, NULL },
224    {   CFSTR(kPredNameIsKernelResource), NULL,
225        reportParseFlag, NULL },
226    {   CFSTR(kPredNameIntegrity), NULL,
227        reportParseFlag, NULL },
228
229    {   CFSTR(kPredNameVersion), CFSTR(kPredCharVersion),
230        reportParseShorthand, reportEvalProperty },
231
232    {   CFSTR(kPredNameArch), NULL,
233        reportParseArch, reportEvalArch },
234    {   CFSTR(kPredNameArchExact), CFSTR(kPredCharArchExact),
235        reportParseArch, reportEvalArchExact },
236    {   CFSTR(kPredNameExecutable), CFSTR(kPredCharExecutable),
237        reportParseFlag, NULL },
238    {   CFSTR(kPredNameSymbol), CFSTR(kPredCharSymbol),
239        reportParseDefinesOrReferencesSymbol, reportEvalDefinesOrReferencesSymbol },
240
241    {   CFSTR(kPredNameBundleID), CFSTR(kPredCharBundleID),
242        reportParseShorthand, NULL },
243    {   CFSTR(kPredNameBundleName), CFSTR(kPredCharBundleName),
244        reportParseCommand, NULL },
245
246    {   CFSTR(kPredNameDuplicate), CFSTR(kPredCharDuplicate),
247        reportParseFlag, NULL },
248
249    {   CFSTR(kPredNamePrint), NULL,
250        reportParseCommand, NULL },
251    {   CFSTR(kPredNamePrintProperty), CFSTR(kPredCharPrintProperty),
252        reportParseCommand, NULL },
253    {   CFSTR(kPredNamePrintArches), CFSTR(kPredCharPrintArches),
254        reportParseCommand, NULL },
255    {   CFSTR(kPredNamePrintDependencies), NULL,
256        reportParseCommand, NULL },
257    {   CFSTR(kPredNamePrintDependents), NULL,
258        reportParseCommand, NULL },
259    {   CFSTR(kPredNamePrintPlugins), NULL,
260        reportParseCommand, NULL },
261    {   CFSTR(kPredNamePrintIntegrity), NULL,
262        reportParseCommand, NULL },
263    {   CFSTR(kPredNamePrintInfoDictionary), CFSTR(kPredCharPrintInfoDictionary),
264        reportParseCommand, NULL },
265    {   CFSTR(kPredNamePrintExecutable), CFSTR(kPredCharPrintExecutable),
266        reportParseCommand, NULL },
267
268   /* These two special predicates are used internally for all "flag" and
269    * command precidates, which all reset their predicates at reportParse time and
270    * save the original keyword.
271    */
272    {   CFSTR(kPredNameFlag), NULL,
273        NULL, reportEvalFlag },
274    {   CFSTR(kPredNameCommand), NULL,
275        NULL, reportEvalCommand },
276
277    { NULL, NULL, NULL, NULL }  // sentinel to terminate list
278
279};
280