#include "utility.h"
#include <sys/resource.h>
CFStringRef createCFString(char * string)
{
return CFStringCreateWithCString(kCFAllocatorDefault, string,
kCFStringEncodingUTF8);
}
Boolean check_dir(const char * dirname, int writeable, int print_err)
{
int result = true; struct stat stat_buf;
if (stat(dirname, &stat_buf) != 0) {
if (print_err) {
perror(dirname);
}
result = false;
goto finish;
}
if ( !(stat_buf.st_mode & S_IFDIR) ) {
if (print_err) {
qerror("%s is not a directory\n", dirname);
}
result = false;
goto finish;
}
if (writeable) {
if (access(dirname, W_OK) != 0) {
if (print_err) {
qerror("%s is not writeable\n", dirname);
}
result = false;
goto finish;
}
}
finish:
return result;
}
void qerror(const char * format, ...)
{
va_list ap;
if (g_verbose_level <= kKXKextManagerLogLevelSilent) return;
va_start(ap, format);
vfprintf(stderr, format, ap);
va_end(ap);
fflush(stderr);
return;
}
void basic_log(const char * format, ...)
{
va_list ap;
fprintf(stdout, "%s: ", progname);
va_start(ap, format);
vfprintf(stdout, format, ap);
va_end(ap);
fprintf(stdout, "\n");
fflush(stdout);
return;
}
void verbose_log(const char * format, ...)
{
va_list ap;
if (g_verbose_level < kKXKextManagerLogLevelDefault) return;
fprintf(stdout, "%s: ", progname);
va_start(ap, format);
vfprintf(stdout, format, ap);
va_end(ap);
fprintf(stdout, "\n");
fflush(stdout);
return;
}
void error_log(const char * format, ...)
{
va_list ap;
if (g_verbose_level <= kKXKextManagerLogLevelSilent) return;
fprintf(stderr, "%s: ", progname);
va_start(ap, format);
vfprintf(stderr, format, ap);
va_end(ap);
fprintf(stderr, "\n");
fflush(stderr);
return;
}
int addKextsToManager(
KXKextManagerRef aManager,
CFArrayRef kextNames,
CFMutableArrayRef kextNamesToUse,
Boolean do_tests)
{
int result = 1; KXKextManagerError kxresult = kKXKextManagerErrorNone;
CFIndex i, count;
OSKextRef theKext = NULL; CFURLRef kextURL = NULL;
count = CFArrayGetCount(kextNames);
for (i = 0; i < count; i++) {
char name_buffer[PATH_MAX];
CFStringRef kextName = (CFStringRef)CFArrayGetValueAtIndex(
kextNames, i);
if (kextURL) {
CFRelease(kextURL);
kextURL = NULL;
}
kextURL = CFURLCreateWithFileSystemPath(kCFAllocatorDefault,
kextName, kCFURLPOSIXPathStyle, true);
if (!kextURL) {
qerror("memory allocation failure\n");
result = -1;
goto finish;
}
if (!CFStringGetCString(kextName,
name_buffer, sizeof(name_buffer) - 1, kCFStringEncodingUTF8)) {
qerror("memory allocation or string conversion error\n");
result = -1;
goto finish;
}
kxresult = KXKextManagerAddKextWithURL(aManager, kextURL, true, &theKext);
if (kxresult != kKXKextManagerErrorNone) {
result = 0;
qerror("can't add kernel extension %s (%s)",
name_buffer, KXKextManagerErrorStaticCStringForError(kxresult));
qerror(" (run %s on this kext with -t for diagnostic output)\n",
progname);
#if 0
if (do_tests && theKext && g_verbose_level >= kKXKextManagerLogLevelErrorsOnly) {
qerror("kernel extension problems:\n");
KXKextPrintDiagnostics(theKext, stderr);
}
continue;
#endif 0
}
if (kextNamesToUse && theKext &&
(kxresult == kKXKextManagerErrorNone || do_tests)) {
CFArrayAppendValue(kextNamesToUse, kextName);
}
}
finish:
if (kextURL) CFRelease(kextURL);
return result;
}
int fork_program(const char * argv0, char * const argv[], int delay, Boolean wait)
{
int result = -2;
int status;
pid_t pid;
switch (pid = fork()) {
case -1: goto finish;
break;
case 0: if (!wait) {
result = daemon(0, 0);
if (result == -1) {
goto finish;
}
setiopolicy_np(IOPOL_TYPE_DISK, IOPOL_SCOPE_PROCESS, IOPOL_THROTTLE);
}
if (delay) {
sleep(delay);
}
execv(argv0, argv);
exit(1);
default: waitpid(pid, &status, 0);
status = WEXITSTATUS(status);
if (wait) {
result = status;
} else if (status != 0) {
result = -1;
} else {
result = pid;
}
break;
}
finish:
return result;
}