#ifndef _KEXTCACHE_MAIN_H
#define _KEXTCACHE_MAIN_H
#include <CoreFoundation/CoreFoundation.h>
#include <IOKit/kext/OSKext.h>
#include <getopt.h>
#include <sysexits.h>
#include <IOKit/kext/OSKext.h>
#include "kext_tools_util.h"
#include "kernelcache.h"
#include "bootroot_internal.h"
#pragma mark Basic Types & Constants
enum {
kKextcacheExitOK = EX_OK,
kKextcacheExitNotFound,
kKextcacheExitArchNotFound,
kKextcacheExitKextBad,
kKextcacheExitStale,
kKextcacheExitUnspecified = 11,
kKextcacheExitHelp = 33,
kKextcacheExitNoStart
};
#pragma mark Command-line Option Definitions
#define kOptNameMkext "mkext"
#define kOptNameMkext1 "mkext1"
#define kOptNameMkext2 "mkext2"
#define kOptNameSystemMkext "system-mkext"
#define kOptNameVolumeRoot "volume-root"
#define kOptNameLocalRoot "local-root"
#define kOptNameLocalRootAll "local-root-all"
#define kOptNameNetworkRoot "network-root"
#define kOptNameNetworkRootAll "network-root-all"
#define kOptNameSafeBoot "safe-boot"
#define kOptNameSafeBootAll "safe-boot-all"
#define kOptNamePrelinkedKernel "prelinked-kernel"
#define kOptNameSystemPrelinkedKernel "system-prelinked-kernel"
#define kOptNameKernel "kernel"
#define kOptNameAllLoaded "all-loaded"
#define kOptNameSymbols "symbols"
#define kOptNameAllPersonalities "all-personalities"
#define kOptNameNoLinkFailures "no-link-failures"
#define kOptNameStripSymbols "strip-symbols"
#define kOptNameSystemCaches "system-caches"
#define kOptNameInvalidate "invalidate"
#define kOptNameUpdate "update-volume"
#define kOptNameForce "force"
#define kOptNameInstaller "Installer"
#define kOptNameCachesOnly "caches-only"
#define kOptNameEarlyBoot "Boot"
#define kOptNameNoAuthentication "no-authentication"
#define kOptNameTests "print-diagnostics"
#define kOptNameCompressed "compressed"
#define kOptNameUncompressed "uncompressed"
#define kOptArch 'a'
#define kOptPrelinkedKernel 'c'
#define kOptSystemMkext 'e'
#if !NO_BOOT_ROOT
#define kOptForce 'f'
#endif
#define kOptLowPriorityFork 'F'
#define kOptInvalidate 'i'
#define kOptRepositoryCaches 'k'
#define kOptKernel 'K'
#define kOptLocalRoot 'l'
#define kOptLocalRootAll 'L'
#define kOptMkext 'm'
#define kOptNetworkRoot 'n'
#define kOptNetworkRootAll 'N'
#define kOptAllLoaded 'r'
#define kOptSafeBoot 's'
#define kOptSafeBootAll 'S'
#define kOptTests 't'
#if !NO_BOOT_ROOT
#define kOptUpdate 'u'
#define kOptCheckUpdate 'U'
#endif
#define kOptNoAuthentication 'z'
#define kLongOptLongindexHack (-2)
#define kLongOptMkext1 (-3)
#define kLongOptMkext2 (-4)
#define kLongOptMkext kLongOptMkext2
#define kLongOptCompressed (-5)
#define kLongOptUncompressed (-6)
#define kLongOptSymbols (-7)
#define kLongOptSystemCaches (-8)
#define kLongOptSystemPrelinkedKernel (-9)
#define kLongOptVolumeRoot (-10)
#define kLongOptAllPersonalities (-11)
#define kLongOptNoLinkFailures (-12)
#define kLongOptStripSymbols (-13)
#define kLongOptInstaller (-14)
#define kLongOptCachesOnly (-15)
#define kLongOptEarlyBoot (-16)
#if !NO_BOOT_ROOT
#define kOptChars ":a:b:c:efFhi:kK:lLm:nNqrsStu:U:vz"
#else
#define kOptChars ":a:b:c:eFhkK:lLm:nNqrsStvz"
#endif
int longopt = 0;
struct option sOptInfo[] = {
{ kOptNameLongindexHack, no_argument, &longopt, kLongOptLongindexHack },
{ kOptNameHelp, no_argument, NULL, kOptHelp },
{ kOptNameQuiet, no_argument, NULL, kOptQuiet },
{ kOptNameVerbose, optional_argument, NULL, kOptVerbose },
{ kOptNameCompressed, no_argument, &longopt, kLongOptCompressed },
{ kOptNameUncompressed, no_argument, &longopt, kLongOptUncompressed },
{ kOptNameArch, required_argument, NULL, kOptArch },
{ kOptNameMkext1, required_argument, &longopt, kLongOptMkext1 },
{ kOptNameMkext2, required_argument, &longopt, kLongOptMkext2 },
{ kOptNameMkext, required_argument, NULL, kOptMkext },
{ kOptNameSystemMkext, no_argument, NULL, kOptSystemMkext },
{ kOptNameVolumeRoot, required_argument, &longopt, kLongOptVolumeRoot },
{ kOptNameSystemCaches, no_argument, &longopt, kLongOptSystemCaches },
{ kOptNameBundleIdentifier, required_argument, NULL, kOptBundleIdentifier },
{ kOptNameLocalRoot, no_argument, NULL, kOptLocalRoot },
{ kOptNameLocalRootAll, no_argument, NULL, kOptLocalRootAll },
{ kOptNameNetworkRoot, no_argument, NULL, kOptNetworkRoot },
{ kOptNameNetworkRootAll, no_argument, NULL, kOptNetworkRootAll, },
{ kOptNameSafeBoot, no_argument, NULL, kOptSafeBoot },
{ kOptNameSafeBootAll, no_argument, NULL, kOptSafeBootAll },
{ kOptNamePrelinkedKernel, optional_argument, NULL, kOptPrelinkedKernel },
{ kOptNameSystemPrelinkedKernel, no_argument, &longopt, kLongOptSystemPrelinkedKernel },
{ kOptNameKernel, required_argument, NULL, kOptKernel },
{ kOptNameAllLoaded, no_argument, NULL, kOptAllLoaded },
{ kOptNameSymbols, required_argument, &longopt, kLongOptSymbols },
{ kOptNameAllPersonalities, no_argument, &longopt, kLongOptAllPersonalities },
{ kOptNameNoLinkFailures, no_argument, &longopt, kLongOptNoLinkFailures },
{ kOptNameStripSymbols, no_argument, &longopt, kLongOptStripSymbols },
#if !NO_BOOT_ROOT
{ kOptNameInvalidate, required_argument, NULL, kOptInvalidate },
{ kOptNameUpdate, required_argument, NULL, kOptUpdate },
{ kOptNameForce, no_argument, NULL, kOptForce },
{ kOptNameInstaller, no_argument, &longopt, kLongOptInstaller },
{ kOptNameCachesOnly, no_argument, &longopt, kLongOptCachesOnly },
{ kOptNameEarlyBoot, no_argument, &longopt, kLongOptEarlyBoot },
#endif
{ kOptNameNoAuthentication, no_argument, NULL, kOptNoAuthentication },
{ kOptNameTests, no_argument, NULL, kOptTests },
#if !NO_BOOT_ROOT
{ NULL, required_argument, NULL, kOptCheckUpdate },
#endif
{ NULL, no_argument, NULL, kOptLowPriorityFork },
{ NULL, 0, NULL, 0 } };
typedef struct {
OSKextRequiredFlags requiredFlagsRepositoriesOnly; OSKextRequiredFlags requiredFlagsAll;
Boolean updateSystemCaches; Boolean lowPriorityFlag; Boolean printTestResults; Boolean skipAuthentication;
CFURLRef volumeRootURL;
char * mkextPath; int mkextVersion;
char * prelinkedKernelPath; Boolean needDefaultPrelinkedKernelInfo;
Boolean needLoadedKextInfo; Boolean generatePrelinkedSymbols; Boolean includeAllPersonalities; Boolean noLinkFailures; Boolean stripSymbols; CFURLRef compressedPrelinkedKernelURL;
CFURLRef updateVolumeURL;
BRUpdateOpts_t updateOpts;
char * kernelPath; CFDataRef kernelFile; CFURLRef symbolDirURL;
CFMutableSetRef kextIDs; CFMutableArrayRef argURLs; CFMutableArrayRef repositoryURLs; CFMutableArrayRef namedKextURLs;
CFMutableArrayRef targetArchs;
Boolean explicitArch;
CFArrayRef allKexts; CFArrayRef repositoryKexts; CFArrayRef namedKexts;
CFArrayRef loadedKexts;
struct timeval kernelTimes[2]; struct timeval extensionsDirTimes[2]; Boolean compress;
Boolean uncompress;
} KextcacheArgs;
#pragma mark Function Prototypes
ExitStatus readArgs(
int * argc,
char * const ** argv,
KextcacheArgs * toolArgs);
void setDefaultArchesIfNeeded(KextcacheArgs * toolArgs);
void addArch(
KextcacheArgs * toolArgs,
const NXArchInfo * arch);
const NXArchInfo * addArchForName(
KextcacheArgs * toolArgs,
const char * archname);
ExitStatus readPrelinkedKernelArgs(
KextcacheArgs * toolArgs,
int argc,
char * const * argv,
Boolean isLongopt);
ExitStatus setPrelinkedKernelArgs(
KextcacheArgs * toolArgs,
char * filename);
Boolean setDefaultKernel(KextcacheArgs * toolArgs);
Boolean setDefaultPrelinkedKernel(KextcacheArgs * toolArgs);
void setSystemExtensionsFolders(KextcacheArgs * toolArgs);
ExitStatus doUpdateVolume(KextcacheArgs *toolArgs);
void checkKextdSpawnedFilter(Boolean kernelFlag);
ExitStatus checkArgs(KextcacheArgs * toolArgs);
ExitStatus getLoadedKextInfo(KextcacheArgs *toolArgs);
ExitStatus updateSystemPlistCaches(KextcacheArgs * toolArgs);
ExitStatus updateDirectoryCaches(
KextcacheArgs * toolArgs,
CFURLRef folderURL);
ExitStatus createMkext(
KextcacheArgs * toolArgs,
Boolean * fatalOut);
ExitStatus filterKextsForCache(
KextcacheArgs * toolArgs,
CFMutableArrayRef kextArray,
const NXArchInfo * arch,
Boolean * fatalOut);
Boolean checkKextForArchive(
KextcacheArgs toolArgs,
OSKextRef aKext,
const char * archiveTypeName,
const NXArchInfo * archInfo,
OSKextRequiredFlags requiredFlags);
Boolean kextMatchesFilter(
KextcacheArgs * toolArgs,
OSKextRef theKext,
OSKextRequiredFlags requiredFlags);
ExitStatus getFileURLModTimePlusOne(
CFURLRef fileURL,
struct timeval * origModTime,
struct timeval cacheFileTimes[2]);
ExitStatus getFilePathModTimePlusOne(
const char * filePath,
struct timeval * origModTime,
struct timeval cacheFileTimes[2]);
Boolean kextMatchesLoadedKextInfo(
KextcacheArgs * toolArgs,
OSKextRef theKext);
ExitStatus createPrelinkedKernelArchs(
KextcacheArgs * toolArgs,
CFMutableArrayRef * prelinkArchsOut);
ExitStatus createExistingPrelinkedSlices(
KextcacheArgs * toolArgs,
CFMutableArrayRef * prelinkedSlicesOut,
CFMutableArrayRef * prelinkedArchsOut);
ExitStatus createPrelinkedKernel(
KextcacheArgs * toolArgs);
CFArrayRef mergeArchs(
CFArrayRef archSet1,
CFArrayRef archSet2);
ExitStatus createPrelinkedKernelForArch(
KextcacheArgs * toolArgs,
CFDataRef * prelinkedKernelOut,
CFDictionaryRef * prelinkedSymbolsOut,
const NXArchInfo * archInfo);
ExitStatus getExpectedPrelinkedKernelModTime(
KextcacheArgs * toolArgs,
struct timeval cacheFileTimes[2],
Boolean * updateModTimeOut);
ExitStatus compressPrelinkedKernel(
CFURLRef volumeRootURL,
const char * prelinkedKernelPath,
Boolean compress);
void usage(UsageLevel usageLevel);
#endif