1/*
2 *  kext_tools_util.h
3 *  kext_tools
4 *
5 *  Created by Nik Gervae on 4/25/08.
6 *  Copyright 2008 Apple Inc. All rights reserved.
7 *
8 */
9#ifndef _KEXT_TOOLS_UTIL_H
10#define _KEXT_TOOLS_UTIL_H
11
12#include <CoreFoundation/CoreFoundation.h>
13#include <IOKit/kext/OSKext.h>
14#include <mach/mach_error.h>
15
16#include <getopt.h>
17#include <sysexits.h>
18#include <sys/stat.h>
19#include <sys/time.h>
20#include <sys/types.h>
21
22#pragma mark Types
23/*******************************************************************************
24* Types
25*******************************************************************************/
26typedef int ExitStatus;
27
28typedef enum {
29    kUsageLevelBrief = 0,
30    kUsageLevelFull  = 1
31} UsageLevel;
32
33typedef struct {
34    CFURLRef   saveDirURL;
35    Boolean    overwrite;
36    Boolean    fatal;
37} SaveFileContext;
38
39#pragma mark Constants
40/*******************************************************************************
41* Constants
42*******************************************************************************/
43#define _kKextPropertyValuesCacheBasename  "KextPropertyValues_"
44#define __kOSKextApplePrefix        CFSTR("com.apple.")
45
46#define kAppleInternalPath      "/AppleInternal"
47#define kDefaultKernelDevPath   "/System/Library/Kernels/kernel.development"
48#define kDefaultKernelSuffix    ".development"
49
50#pragma mark Macros
51/*********************************************************************
52* Macros
53*********************************************************************/
54
55#define SAFE_FREE(ptr)  do {          \
56    if (ptr) free(ptr);               \
57    } while (0)
58#define SAFE_FREE_NULL(ptr)  do {     \
59    if (ptr) free(ptr);               \
60    (ptr) = NULL;                     \
61    } while (0)
62#define SAFE_RELEASE(ptr)  do {       \
63    if (ptr) CFRelease(ptr);          \
64    } while (0)
65#define SAFE_RELEASE_NULL(ptr)  do {  \
66    if (ptr) CFRelease(ptr);          \
67    (ptr) = NULL;                     \
68    } while (0)
69
70#define RANGE_ALL(a)   CFRangeMake(0, CFArrayGetCount(a))
71
72#define COMPILE_TIME_ASSERT(pred)   switch(0){case 0:case pred:;}
73
74/*********************************************************************
75*********************************************************************/
76
77/* Library default is not to log Basic, but kextd & kextcache spawned
78 * by kextd want to do that.
79 */
80#define kDefaultServiceLogFilter ((OSKextLogSpec) kOSKextLogBasicLevel | \
81                                             kOSKextLogVerboseFlagsMask)
82
83#pragma mark Shared Command-line Option Definitions
84/*******************************************************************************
85* Command-line options. This data is used by getopt_long_only().
86*******************************************************************************/
87#define kOptNameArch                    "arch"
88#define kOptNameBundleIdentifier        "bundle-id"
89#define kOptNameRepository              "repository"
90
91#define kOptNameSafeBoot                "safe-boot"
92#define kOptNameSystemExtensions        "system-extensions"
93#define kOptNameKernel                  "kernel"
94#define kOptNameNoAuthentication        "no-authentication"
95
96#define kOptNameHelp                    "help"
97#define kOptNameQuiet                   "quiet"
98#define kOptNameVerbose                 "verbose"
99
100#define kOptNameLongindexHack           "________"
101
102// Can't use -a globally for -arch because of kextutil...?
103#define kOptBundleIdentifier 'b'
104// Can't use -r globally for -repository because of kextcache...?
105
106// Can't use -x globally for -safe-boot because of kextcache's -s...?
107// Can't use -e globally for -system-extensions because of kextutil...?
108// Can't use -k globally for -kernel because of kextcache...?
109#define kOptNoAuthentication 'z'
110
111#define kOptHelp             'h'
112#define kOptQuiet            'q'
113#define kOptVerbose          'v'
114
115// Long opts always defined in each program to avoid # collisions
116
117#pragma mark Function Protos
118/*********************************************************************
119* Function Protos
120*********************************************************************/
121
122Boolean createCFMutableArray(CFMutableArrayRef * arrayOut,
123    const CFArrayCallBacks * callbacks);
124Boolean createCFMutableDictionary(CFMutableDictionaryRef * dictionaryOut);
125Boolean createCFMutableSet(CFMutableSetRef * setOut,
126    const CFSetCallBacks * callbacks);
127Boolean createCFDataFromFile(CFDataRef  *dataRefOut,
128                             const char *filePath);
129
130void addToArrayIfAbsent(CFMutableArrayRef array, const void * value);
131
132ExitStatus checkPath(
133    const char * path,
134    const char * suffix,  // w/o the dot
135    Boolean      directoryRequired,
136    Boolean      writableRequired);
137
138ExitStatus setLogFilterForOpt(
139    int            argc,
140    char * const * argv,
141    OSKextLogSpec  forceOnFlags);
142
143void beQuiet(void);
144
145FILE *  g_log_stream;
146// tool_openlog(), tool_log() copied to bootroot.h for libBootRoot clients
147void tool_openlog(const char * name);
148void tool_log(
149    OSKextRef aKext,
150    OSKextLogSpec logSpec,
151    const char * format,
152    ...);
153void log_CFError(
154    OSKextRef     aKext __unused,
155    OSKextLogSpec msgLogSpec,
156    CFErrorRef    error);
157
158const char * safe_mach_error_string(mach_error_t error_code);
159
160#define REPLY_ERROR (-1)
161#define REPLY_NO     (0)
162#define REPLY_YES    (1)
163#define REPLY_ALL    (2)
164
165int user_approve(Boolean ask_all, int default_answer, const char * format, ...);
166
167const char * user_input(Boolean * eof, const char * format, ...);
168void saveFile(const void * vKey, const void * vValue, void * vContext);
169
170CFStringRef copyKextPath(OSKextRef aKext);
171Boolean readSystemKextPropertyValues(
172    CFStringRef        propertyKey,
173    const NXArchInfo * arch,
174    Boolean            forceUpdateFlag,
175    CFArrayRef       * valuesOut);
176
177ExitStatus writeToFile(
178    int           fileDescriptor,
179    const UInt8 * data,
180    CFIndex       length);
181
182ExitStatus statURL(CFURLRef anURL, struct stat * statBuffer);
183ExitStatus statPath(const char *path, struct stat *statBuffer);
184ExitStatus statParentPath(const char *thePath, struct stat *statBuffer);
185ExitStatus getLatestTimesFromCFURLArray(
186                                        CFArrayRef          fileURLArray,
187                                        struct timeval      fileTimes[2]);
188ExitStatus getLatestTimesFromDirURL(
189                                    CFURLRef       dirURL,
190                                    struct timeval dirTimeVals[2]);
191
192ExitStatus getLatestTimesFromDirPath(
193                                     const char *   dirPath,
194                                     struct timeval dirTimeVals[2]);
195
196ExitStatus getFilePathTimes(
197                            const char        * filePath,
198                            struct timeval      cacheFileTimes[2]);
199
200ExitStatus getParentPathTimes(
201                              const char        * thePath,
202                              struct timeval      cacheFileTimes[2] );
203
204void postNoteAboutKexts(
205                        CFStringRef theNotificationCenterName,
206                        CFMutableDictionaryRef theDict );
207
208void postNoteAboutKextLoadsMT(
209                            CFStringRef theNotificationCenterName,
210                            CFMutableArrayRef theKextPathArray );
211
212void addKextToAlertDict(
213                        CFMutableDictionaryRef *theDictPtr,
214                        OSKextRef theKext );
215
216char * getPathExtension(const char * pathPtr);
217
218// bootcaches.plist helpers
219CFDictionaryRef copyBootCachesDictForURL(CFURLRef theVolRootURL);
220Boolean getKernelPathForURL(
221                            CFURLRef theVolRootURL,
222                            char * theBuffer,
223                            int theBufferSize );
224
225// Development kernel support
226Boolean useDevelopmentKernel(const char * theKernelPath);
227Boolean isDebugSetInBootargs(void);
228
229
230/*********************************************************************
231* From IOKitUser/kext.subproj/OSKext.c.
232*********************************************************************/
233
234extern char * createUTF8CStringForCFString(CFStringRef aString);
235
236#endif /* _KEXT_TOOLS_UTIL_H */
237