1/* 2 * kextcache_main.h 3 * kext_tools 4 * 5 * Created by nik on 5/20/08. 6 * Copyright 2008 __MyCompanyName__. All rights reserved. 7 * 8 */ 9#ifndef _KEXTCACHE_MAIN_H 10#define _KEXTCACHE_MAIN_H 11 12#include <CoreFoundation/CoreFoundation.h> 13#include <IOKit/kext/OSKext.h> 14 15#include <getopt.h> 16#include <sysexits.h> 17 18#include <IOKit/kext/OSKext.h> 19 20#include "kext_tools_util.h" 21#include "kernelcache.h" 22#include "bootroot_internal.h" 23 24#pragma mark Basic Types & Constants 25/******************************************************************************* 26* Constants 27*******************************************************************************/ 28 29enum { 30 kKextcacheExitOK = EX_OK, 31 kKextcacheExitNotFound, 32 kKextcacheExitArchNotFound, 33 kKextcacheExitKextBad, 34 kKextcacheExitStale, 35 36 // don't think we use it 37 kKextcacheExitUnspecified = 11, 38 39 // don't actually exit with this, it's just a sentinel value 40 kKextcacheExitHelp = 33, 41 kKextcacheExitNoStart 42}; 43 44#pragma mark Command-line Option Definitions 45/******************************************************************************* 46* Command-line options. This data is used by getopt_long_only(). 47* 48* Options common to all kext tools are in kext_tools_util.h. 49*******************************************************************************/ 50 51/* Mkext-generation flags. 52 */ 53// kOptNameMkext always represents most recent format supported 54#define kOptNameMkext "mkext" 55#define kOptNameMkext1 "mkext1" 56#define kOptNameMkext2 "mkext2" 57#define kOptNameSystemMkext "system-mkext" 58#define kOptNameVolumeRoot "volume-root" 59 60// kOptNameBundleIdentifier in kext_tools_util.h 61// kOptNameSystemExtensions in kext_tools_util.h 62 63#define kOptNameLocalRoot "local-root" 64#define kOptNameLocalRootAll "local-root-all" 65#define kOptNameNetworkRoot "network-root" 66#define kOptNameNetworkRootAll "network-root-all" 67#define kOptNameSafeBoot "safe-boot" 68#define kOptNameSafeBootAll "safe-boot-all" 69 70/* Prelinked-kernel-generation flags. 71 */ 72#define kOptNamePrelinkedKernel "prelinked-kernel" 73#define kOptNameSystemPrelinkedKernel "system-prelinked-kernel" 74#define kOptNameKernel "kernel" 75#define kOptNameAllLoaded "all-loaded" 76#define kOptNameSymbols "symbols" 77 78/* Embedded prelinked-kernel-generation flags. 79 */ 80#define kOptNameAllPersonalities "all-personalities" 81#define kOptNameNoLinkFailures "no-link-failures" 82#define kOptNameStripSymbols "strip-symbols" 83 84/* Misc. cache update flags. 85 */ 86#define kOptNameSystemCaches "system-caches" 87 88/* Boot!=root flags. 89 */ 90#define kOptNameInvalidate "invalidate" 91#define kOptNameUpdate "update-volume" 92#define kOptNameForce "force" 93#define kOptNameInstaller "Installer" 94#define kOptNameCachesOnly "caches-only" 95#define kOptNameEarlyBoot "Boot" 96 97/* Misc flags. 98 */ 99#define kOptNameNoAuthentication "no-authentication" 100#define kOptNameTests "print-diagnostics" 101#define kOptNameCompressed "compressed" 102#define kOptNameUncompressed "uncompressed" 103 104#define kOptArch 'a' 105// 'b' in kext_tools_util.h 106#define kOptPrelinkedKernel 'c' 107#define kOptSystemMkext 'e' 108#if !NO_BOOT_ROOT 109#define kOptForce 'f' 110#endif /* !NO_BOOT_ROOT */ 111 112// xxx - do we want a longopt for this? 113#define kOptLowPriorityFork 'F' 114// 'h' in kext_tools_util.h 115#define kOptInvalidate 'i' 116#define kOptRepositoryCaches 'k' 117#define kOptKernel 'K' 118#define kOptLocalRoot 'l' 119#define kOptLocalRootAll 'L' 120// kOptMkext always represents most recent format supported 121#define kOptMkext 'm' 122#define kOptNetworkRoot 'n' 123#define kOptNetworkRootAll 'N' 124// 'q' in kext_tools_util.h 125#define kOptAllLoaded 'r' 126#define kOptSafeBoot 's' 127#define kOptSafeBootAll 'S' 128#define kOptTests 't' 129#if !NO_BOOT_ROOT 130#define kOptUpdate 'u' 131#define kOptCheckUpdate 'U' 132#endif /* !NO_BOOT_ROOT */ 133// 'v' in kext_tools_util.h 134#define kOptNoAuthentication 'z' 135 136/* Options with no single-letter variant. */ 137// Do not use -1, that's getopt() end-of-args return value 138// and can cause confusion 139#define kLongOptLongindexHack (-2) 140#define kLongOptMkext1 (-3) 141#define kLongOptMkext2 (-4) 142// kLongOptMkext always represents most recent format supported 143#define kLongOptMkext kLongOptMkext2 144#define kLongOptCompressed (-5) 145#define kLongOptUncompressed (-6) 146#define kLongOptSymbols (-7) 147#define kLongOptSystemCaches (-8) 148#define kLongOptSystemPrelinkedKernel (-9) 149#define kLongOptVolumeRoot (-10) 150#define kLongOptAllPersonalities (-11) 151#define kLongOptNoLinkFailures (-12) 152#define kLongOptStripSymbols (-13) 153#define kLongOptInstaller (-14) 154#define kLongOptCachesOnly (-15) 155#define kLongOptEarlyBoot (-16) 156 157#if !NO_BOOT_ROOT 158#define kOptChars ":a:b:c:efFhi:kK:lLm:nNqrsStu:U:vz" 159#else 160#define kOptChars ":a:b:c:eFhkK:lLm:nNqrsStvz" 161#endif /* !NO_BOOT_ROOT */ 162/* Some options are now obsolete: 163 * -F (fork) 164 * -k (update plist cache) 165 */ 166 167int longopt = 0; 168 169struct option sOptInfo[] = { 170 { kOptNameLongindexHack, no_argument, &longopt, kLongOptLongindexHack }, 171 172 { kOptNameHelp, no_argument, NULL, kOptHelp }, 173 { kOptNameQuiet, no_argument, NULL, kOptQuiet }, 174 { kOptNameVerbose, optional_argument, NULL, kOptVerbose }, 175 { kOptNameCompressed, no_argument, &longopt, kLongOptCompressed }, 176 { kOptNameUncompressed, no_argument, &longopt, kLongOptUncompressed }, 177 178 { kOptNameArch, required_argument, NULL, kOptArch }, 179 180 { kOptNameMkext1, required_argument, &longopt, kLongOptMkext1 }, 181 { kOptNameMkext2, required_argument, &longopt, kLongOptMkext2 }, 182 { kOptNameMkext, required_argument, NULL, kOptMkext }, 183 { kOptNameSystemMkext, no_argument, NULL, kOptSystemMkext }, 184 { kOptNameVolumeRoot, required_argument, &longopt, kLongOptVolumeRoot }, 185 186 { kOptNameSystemCaches, no_argument, &longopt, kLongOptSystemCaches }, 187 188 { kOptNameBundleIdentifier, required_argument, NULL, kOptBundleIdentifier }, 189 190 { kOptNameLocalRoot, no_argument, NULL, kOptLocalRoot }, 191 { kOptNameLocalRootAll, no_argument, NULL, kOptLocalRootAll }, 192 { kOptNameNetworkRoot, no_argument, NULL, kOptNetworkRoot }, 193 { kOptNameNetworkRootAll, no_argument, NULL, kOptNetworkRootAll, }, 194 { kOptNameSafeBoot, no_argument, NULL, kOptSafeBoot }, 195 { kOptNameSafeBootAll, no_argument, NULL, kOptSafeBootAll }, 196 197 { kOptNamePrelinkedKernel, optional_argument, NULL, kOptPrelinkedKernel }, 198 { kOptNameSystemPrelinkedKernel, no_argument, &longopt, kLongOptSystemPrelinkedKernel }, 199 { kOptNameKernel, required_argument, NULL, kOptKernel }, 200 { kOptNameAllLoaded, no_argument, NULL, kOptAllLoaded }, 201 { kOptNameSymbols, required_argument, &longopt, kLongOptSymbols }, 202 203 { kOptNameAllPersonalities, no_argument, &longopt, kLongOptAllPersonalities }, 204 { kOptNameNoLinkFailures, no_argument, &longopt, kLongOptNoLinkFailures }, 205 { kOptNameStripSymbols, no_argument, &longopt, kLongOptStripSymbols }, 206 207#if !NO_BOOT_ROOT 208 { kOptNameInvalidate, required_argument, NULL, kOptInvalidate }, 209 { kOptNameUpdate, required_argument, NULL, kOptUpdate }, 210 { kOptNameForce, no_argument, NULL, kOptForce }, 211 { kOptNameInstaller, no_argument, &longopt, kLongOptInstaller }, 212 { kOptNameCachesOnly, no_argument, &longopt, kLongOptCachesOnly }, 213 { kOptNameEarlyBoot, no_argument, &longopt, kLongOptEarlyBoot }, 214#endif /* !NO_BOOT_ROOT */ 215 216 { kOptNameNoAuthentication, no_argument, NULL, kOptNoAuthentication }, 217 { kOptNameTests, no_argument, NULL, kOptTests }, 218 219#if !NO_BOOT_ROOT 220 { NULL, required_argument, NULL, kOptCheckUpdate }, 221#endif /* !NO_BOOT_ROOT */ 222 { NULL, no_argument, NULL, kOptLowPriorityFork }, 223 224 { NULL, 0, NULL, 0 } // sentinel to terminate list 225}; 226 227typedef struct { 228 OSKextRequiredFlags requiredFlagsRepositoriesOnly; // -l/-n/-s 229 OSKextRequiredFlags requiredFlagsAll; // -L/-N/-S 230 231 Boolean updateSystemCaches; // -system-caches 232 Boolean lowPriorityFlag; // -F 233 Boolean printTestResults; // -t 234 Boolean skipAuthentication; // -z 235 236 CFURLRef volumeRootURL; // for mkext/prelinked kernel 237 238 char * mkextPath; // mkext option arg 239 int mkextVersion; // -mkext1/-mkext2 0 (no mkext, 1 (old format), 240 // or 2 (new format) 241 242 char * prelinkedKernelPath; // -c option 243 Boolean needDefaultPrelinkedKernelInfo; // -c option w/o arg; 244 // prelinkedKernelURL is parent 245 // directory of final kernelcache 246 // until we create the cache 247 248 Boolean needLoadedKextInfo; // -r option 249 Boolean generatePrelinkedSymbols; // -symbols option 250 Boolean includeAllPersonalities; // -all-personalities option 251 Boolean noLinkFailures; // -no-link-failures option 252 Boolean stripSymbols; // -strip-symbols option 253 CFURLRef compressedPrelinkedKernelURL; // -uncompress option 254 255 CFURLRef updateVolumeURL; // -u / -U OR -i / -invalidate options 256 257 // see BRUpdateOpts_t in bootroot_internal.h 258 BRUpdateOpts_t updateOpts; // -U, -f, -Installer, ... 259 260 char * kernelPath; // overriden by -kernel option 261 CFDataRef kernelFile; // contents of kernelURL 262 CFURLRef symbolDirURL; // -s option; 263 264 CFMutableSetRef kextIDs; // -b; must release 265 CFMutableArrayRef argURLs; // directories & kexts in order 266 CFMutableArrayRef repositoryURLs; // array of CFURLRefs for extensions dirs 267 CFMutableArrayRef namedKextURLs; 268 CFMutableArrayRef targetArchs; 269 Boolean explicitArch; // user-provided instead of inferred host arches 270 271 CFArrayRef allKexts; // directories + named 272 CFArrayRef repositoryKexts; // all from directories (may include named) 273 CFArrayRef namedKexts; 274 CFArrayRef loadedKexts; 275 276 struct timeval kernelTimes[2]; // access and mod times of kernel file 277 struct timeval extensionsDirTimes[2]; // access and mod times of extensions directory with most recent change 278 Boolean compress; 279 Boolean uncompress; 280} KextcacheArgs; 281 282#pragma mark Function Prototypes 283/******************************************************************************* 284* Function Prototypes 285*******************************************************************************/ 286ExitStatus readArgs( 287 int * argc, 288 char * const ** argv, 289 KextcacheArgs * toolArgs); 290void setDefaultArchesIfNeeded(KextcacheArgs * toolArgs); 291void addArch( 292 KextcacheArgs * toolArgs, 293 const NXArchInfo * arch); 294const NXArchInfo * addArchForName( 295 KextcacheArgs * toolArgs, 296 const char * archname); 297ExitStatus readPrelinkedKernelArgs( 298 KextcacheArgs * toolArgs, 299 int argc, 300 char * const * argv, 301 Boolean isLongopt); 302ExitStatus setPrelinkedKernelArgs( 303 KextcacheArgs * toolArgs, 304 char * filename); 305Boolean setDefaultKernel(KextcacheArgs * toolArgs); 306Boolean setDefaultPrelinkedKernel(KextcacheArgs * toolArgs); 307void setSystemExtensionsFolders(KextcacheArgs * toolArgs); 308ExitStatus doUpdateVolume(KextcacheArgs *toolArgs); 309 310void checkKextdSpawnedFilter(Boolean kernelFlag); 311ExitStatus checkArgs(KextcacheArgs * toolArgs); 312 313ExitStatus getLoadedKextInfo(KextcacheArgs *toolArgs); 314ExitStatus updateSystemPlistCaches(KextcacheArgs * toolArgs); 315ExitStatus updateDirectoryCaches( 316 KextcacheArgs * toolArgs, 317 CFURLRef folderURL); 318ExitStatus createMkext( 319 KextcacheArgs * toolArgs, 320 Boolean * fatalOut); 321ExitStatus filterKextsForCache( 322 KextcacheArgs * toolArgs, 323 CFMutableArrayRef kextArray, 324 const NXArchInfo * arch, 325 Boolean * fatalOut); 326Boolean checkKextForArchive( 327 KextcacheArgs toolArgs, 328 OSKextRef aKext, 329 const char * archiveTypeName, 330 const NXArchInfo * archInfo, 331 OSKextRequiredFlags requiredFlags); 332Boolean kextMatchesFilter( 333 KextcacheArgs * toolArgs, 334 OSKextRef theKext, 335 OSKextRequiredFlags requiredFlags); 336ExitStatus getFileURLModTimePlusOne( 337 CFURLRef fileURL, 338 struct timeval * origModTime, 339 struct timeval cacheFileTimes[2]); 340ExitStatus getFilePathModTimePlusOne( 341 const char * filePath, 342 struct timeval * origModTime, 343 struct timeval cacheFileTimes[2]); 344Boolean kextMatchesLoadedKextInfo( 345 KextcacheArgs * toolArgs, 346 OSKextRef theKext); 347ExitStatus createPrelinkedKernelArchs( 348 KextcacheArgs * toolArgs, 349 CFMutableArrayRef * prelinkArchsOut); 350ExitStatus createExistingPrelinkedSlices( 351 KextcacheArgs * toolArgs, 352 CFMutableArrayRef * prelinkedSlicesOut, 353 CFMutableArrayRef * prelinkedArchsOut); 354ExitStatus createPrelinkedKernel( 355 KextcacheArgs * toolArgs); 356CFArrayRef mergeArchs( 357 CFArrayRef archSet1, 358 CFArrayRef archSet2); 359ExitStatus createPrelinkedKernelForArch( 360 KextcacheArgs * toolArgs, 361 CFDataRef * prelinkedKernelOut, 362 CFDictionaryRef * prelinkedSymbolsOut, 363 const NXArchInfo * archInfo); 364ExitStatus getExpectedPrelinkedKernelModTime( 365 KextcacheArgs * toolArgs, 366 struct timeval cacheFileTimes[2], 367 Boolean * updateModTimeOut); 368ExitStatus compressPrelinkedKernel( 369 CFURLRef volumeRootURL, 370 const char * prelinkedKernelPath, 371 Boolean compress); 372 373void usage(UsageLevel usageLevel); 374 375#endif /* _KEXTCACHE_MAIN_H */ 376