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