X-Git-Url: https://git.saurik.com/apple/system_cmds.git/blobdiff_plain/34d340d711a2b033f5da480ed7b5eb147679a588..530d02b6d6489eaa76ff9853c2897b2dc48d2d8e:/nvram.tproj/nvram.c diff --git a/nvram.tproj/nvram.c b/nvram.tproj/nvram.c index fc9a242..3711499 100644 --- a/nvram.tproj/nvram.c +++ b/nvram.tproj/nvram.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2005 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2000-2016 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -26,11 +26,13 @@ cc -o nvram nvram.c -framework CoreFoundation -framework IOKit -Wall #include #include #include +#include #include +#include +#include +#include // Prototypes -static void Error(char *format, long item); -static void FatalError(long exitValue, char *format, long item); static void UsageMessage(char *message); static void ParseFile(char *fileName); static void ParseXMLFile(char *fileName); @@ -46,11 +48,35 @@ static void ClearOFVariables(void); static void ClearOFVariable(const void *key,const void *value,void *context); static CFTypeRef ConvertValueToCFTypeRef(CFTypeID typeID, char *value); +static void NVRamSyncNow(char *name); + // Global Variables static char *gToolName; static io_registry_entry_t gOptionsRef; static bool gUseXML; +static bool gUseForceSync; + +#if TARGET_OS_BRIDGE /* Stuff for nvram bridge -> intel */ +#include +#include + +static kern_return_t LinkMacNVRAMSymbols(void); +static kern_return_t GetMacOFVariable(char *name, char **value); +static kern_return_t SetMacOFVariable(char *name, char *value); +static void DeleteMacOFVariable(char *name); + +static bool gBridgeToIntel; +static void *gDL_handle; +static void *gNvramInterface; + +static void (*hostInterfaceInitialize_fptr)(void); +static void *(*createNvramHostInterface_fptr)(const char *handle); +static kern_return_t (*destroyNvramHostInterface_fptr)(void *interface); +static kern_return_t (*getNVRAMVariable_fptr)(void *interface, char *name, char **buffer, uint32_t *size); +static kern_return_t (*setNVRAMVariable_fptr)(void *interface, char *name, char *buffer, uint32_t size); +static void (*hostInterfaceDeinitialize_fptr)(void); /* may not need? */ +#endif /* TARGET_OS_BRIDGE */ int main(int argc, char **argv) { @@ -58,24 +84,24 @@ int main(int argc, char **argv) char *str, errorMessage[256]; kern_return_t result; mach_port_t masterPort; - + int argcount = 0; + // Get the name of the command. gToolName = strrchr(argv[0], '/'); if (gToolName != 0) gToolName++; else gToolName = argv[0]; - + result = IOMasterPort(bootstrap_port, &masterPort); if (result != KERN_SUCCESS) { - FatalError(-1, "Error (%d) getting the IOMaster port", result); - exit(-1); + errx(1, "Error getting the IOMaster port: %s", + mach_error_string(result)); } - + gOptionsRef = IORegistryEntryFromPath(masterPort, "IODeviceTree:/options"); if (gOptionsRef == 0) { - FatalError(-1, "nvram is not supported on this system.", -1); - exit(-1); + errx(1, "nvram is not supported on this system"); } - + for (cnt = 1; cnt < argc; cnt++) { str = argv[cnt]; if (str[0] == '-' && str[1] != 0) { @@ -83,6 +109,12 @@ int main(int argc, char **argv) for (str += 1 ; *str; str++) { switch (*str) { case 'p' : +#if TARGET_OS_BRIDGE + if (gBridgeToIntel) { + fprintf(stderr, "-p not supported for Mac NVRAM store.\n"); + return 1; + } +#endif PrintOFVariables(); break; @@ -91,6 +123,12 @@ int main(int argc, char **argv) break; case 'f': +#if TARGET_OS_BRIDGE + if (gBridgeToIntel) { + fprintf(stderr, "-f not supported for Mac NVRAM store.\n"); + return 1; + } +#endif cnt++; if (cnt < argc && *argv[cnt] != '-') { ParseFile(argv[cnt]); @@ -98,8 +136,14 @@ int main(int argc, char **argv) UsageMessage("missing filename"); } break; - + case 'd': +#if TARGET_OS_BRIDGE + if (gBridgeToIntel) { + fprintf(stderr, "-d not supported for Mac NVRAM store.\n"); + return 1; + } +#endif cnt++; if (cnt < argc && *argv[cnt] != '-') { DeleteOFVariable(argv[cnt]); @@ -107,11 +151,32 @@ int main(int argc, char **argv) UsageMessage("missing name"); } break; - + case 'c': +#if TARGET_OS_BRIDGE + if (gBridgeToIntel) { + fprintf(stderr, "-c not supported for Mac NVRAM store.\n"); + return 1; + } +#endif ClearOFVariables(); break; - + case 's': + // -s option is unadvertised -- advises the kernel more forcibly to + // commit the variable to nonvolatile storage + gUseForceSync = true; + break; +#if TARGET_OS_BRIDGE + case 'm': + // -m option is unadvertised -- used to set nvram variables on the Intel side + // from the ARM side (Bridge -> Mac) + fprintf(stdout, "Using Mac NVRAM store.\n"); + + LinkMacNVRAMSymbols(); + gBridgeToIntel = true; + break; +#endif + default: strcpy(errorMessage, "no such option as --"); errorMessage[strlen(errorMessage)-1] = *str; @@ -120,51 +185,30 @@ int main(int argc, char **argv) } } else { // Other arguments will be firmware variable requests. + argcount++; SetOrGetOFVariable(str); } } - - IOObjectRelease(gOptionsRef); - - return 0; -} - -// Error(format, item) -// -// Print a message on standard error. -// -static void Error(char *format, long item) -{ - fprintf(stderr, "%s: ", gToolName); - fprintf(stderr, format, item); - fprintf(stderr, "\n"); -} + // radar:25206371 + if (argcount == 0 && gUseForceSync == true) { + NVRamSyncNow(""); + } + IOObjectRelease(gOptionsRef); -// FatalError(exitValue, format, item) -// -// Print a message on standard error and exit with value. -// -static void FatalError(long exitValue, char *format, long item) -{ - fprintf(stderr, "%s: ", gToolName); - fprintf(stderr, format, item); - fprintf(stderr, "\n"); - - exit(exitValue); + return 0; } - // UsageMessage(message) // // Print the usage information and exit. // static void UsageMessage(char *message) { - Error("(usage: %s)", (long)message); - - printf("%s [-x] [-p] [-f filename] [-d name] name[=value] ...\n", gToolName); + warnx("(usage: %s)", message); + + printf("%s [-x] [-p] [-f filename] [-d name] [-c] name[=value] ...\n", gToolName); printf("\t-x use XML format for printing or reading variables\n"); printf("\t (must appear before -p or -f)\n"); printf("\t-p print all firmware variables\n"); @@ -174,7 +218,7 @@ static void UsageMessage(char *message) printf("\tname=value set named variable\n"); printf("\tname print variable\n"); printf("Note that arguments and options are executed in order.\n"); - + exit(1); } @@ -189,7 +233,7 @@ enum { kCollectValue, kContinueValue, kSetenv, - + kMaxStringSize = 0x800, kMaxNameSize = 0x100 }; @@ -201,27 +245,29 @@ enum { // static void ParseFile(char *fileName) { - long state, tc, ni = 0, vi = 0; + long state, ni = 0, vi = 0; + int tc; char name[kMaxNameSize]; char value[kMaxStringSize]; FILE *patches; + kern_return_t kret; if (gUseXML) { ParseXMLFile(fileName); return; } - + patches = fopen(fileName, "r"); if (patches == 0) { - FatalError(errno, "Couldn't open patch file - '%s'", (long)fileName); + err(1, "Couldn't open patch file - '%s'", fileName); } - + state = kFirstColumn; while ((tc = getc(patches)) != EOF) { - if(ni==(kMaxNameSize-1)) - FatalError(-1,"Name exceeded max length of %d",kMaxNameSize); + if(ni==(kMaxNameSize-1)) + errx(1, "Name exceeded max length of %d", kMaxNameSize); if(vi==(kMaxStringSize-1)) - FatalError(-1,"Value exceeded max length of %d",kMaxStringSize); + errx(1, "Value exceeded max length of %d", kMaxStringSize); switch (state) { case kFirstColumn : ni = 0; @@ -237,7 +283,7 @@ static void ParseFile(char *fileName) name[ni++] = tc; } break; - + case kScanComment : if (tc == '\n') { state = kFirstColumn; @@ -245,7 +291,7 @@ static void ParseFile(char *fileName) // state stays kScanComment. } break; - + case kFindName : if (tc == '\n') { state = kFirstColumn; @@ -256,11 +302,11 @@ static void ParseFile(char *fileName) name[ni++] = tc; } break; - + case kCollectName : if (tc == '\n') { name[ni] = 0; - Error("Name must be followed by white space - '%s'", (long)name); + warnx("Name must be followed by white space - '%s'", name); state = kFirstColumn; } else if (isspace(tc)) { state = kFindValue; @@ -269,7 +315,7 @@ static void ParseFile(char *fileName) // state staus kCollectName. } break; - + case kFindValue : case kContinueValue : if (tc == '\n') { @@ -281,7 +327,7 @@ static void ParseFile(char *fileName) value[vi++] = tc; } break; - + case kCollectValue : if (tc == '\n') { if (value[vi-1] == '\\') { @@ -296,23 +342,23 @@ static void ParseFile(char *fileName) } break; } - + if (state == kSetenv) { name[ni] = 0; value[vi] = 0; - if (SetOFVariable(name, value) != KERN_SUCCESS) { - FatalError(-1, "Error (-1) setting variable - '%s'", (long)name); + if ((kret = SetOFVariable(name, value)) != KERN_SUCCESS) { + errx(1, "Error setting variable - '%s': %s", name, + mach_error_string(kret)); } state = kFirstColumn; } } - + if (state != kFirstColumn) { - FatalError(-1, "Last line ended abruptly", 0); + errx(1, "Last line ended abruptly"); } } - // ParseXMLFile(fileName) // // Open and parse the specified file in XML format, @@ -321,56 +367,65 @@ static void ParseFile(char *fileName) static void ParseXMLFile(char *fileName) { CFPropertyListRef plist; - CFURLRef fileURL = NULL; - CFStringRef filePath = NULL; - CFStringRef errorString = NULL; - CFDataRef data = NULL; - SInt32 errorCode = 0; - - filePath = CFStringCreateWithCString(kCFAllocatorDefault, fileName, kCFStringEncodingUTF8); - if (filePath == NULL) { - FatalError(-1, "Could not create file path string", 0); + int fd; + struct stat sb; + char *buffer; + CFReadStreamRef stream; + CFPropertyListFormat format = kCFPropertyListBinaryFormat_v1_0; + + fd = open(fileName, O_RDONLY | O_NOFOLLOW, S_IFREG); + if (fd == -1) { + errx(1, "Could not open %s: %s", fileName, strerror(errno)); } - // Create a URL that specifies the file we will create to - // hold the XML data. - fileURL = CFURLCreateWithFileSystemPath( kCFAllocatorDefault, - filePath, - kCFURLPOSIXPathStyle, - false /* not a directory */ ); - if (fileURL == NULL) { - FatalError(-1, "Could not create file path URL", 0); + if (fstat(fd, &sb) == -1) { + errx(1, "Could not fstat %s: %s", fileName, strerror(errno)); } - CFRelease(filePath); + if (sb.st_size > UINT32_MAX) { + errx(1, "too big for our purposes"); + } - if (! CFURLCreateDataAndPropertiesFromResource( - kCFAllocatorDefault, - fileURL, - &data, - NULL, - NULL, - &errorCode) || data == NULL ) { - FatalError(-1, "Error reading XML file (%d)", errorCode); + buffer = malloc((size_t)sb.st_size); + if (buffer == NULL) { + errx(1, "Could not allocate buffer"); } - CFRelease(fileURL); + if (read(fd, buffer, (size_t)sb.st_size) != sb.st_size) { + errx(1, "Could not read %s: %s", fileName, strerror(errno)); + } - plist = CFPropertyListCreateFromXMLData(kCFAllocatorDefault, - data, - kCFPropertyListImmutable, - &errorString); + close(fd); - CFRelease(data); + stream = CFReadStreamCreateWithBytesNoCopy(kCFAllocatorDefault, + (const UInt8 *)buffer, + (CFIndex)sb.st_size, + kCFAllocatorNull); + if (stream == NULL) { + errx(1, "Could not create stream from serialized data"); + } - if (plist == NULL) { - FatalError(-1, "Error parsing XML file", 0); + if (!CFReadStreamOpen(stream)) { + errx(1, "Could not open the stream"); } - if (errorString != NULL) { - FatalError(-1, "Error parsing XML file: %s", (long)CFStringGetCStringPtr(errorString, kCFStringEncodingUTF8)); + plist = CFPropertyListCreateWithStream(kCFAllocatorDefault, + stream, + (CFIndex)sb.st_size, + kCFPropertyListImmutable, + &format, + NULL); + + if (plist == NULL) { + errx(1, "Error parsing XML file"); } + CFReadStreamClose(stream); + + CFRelease(stream); + + free(buffer); + CFDictionaryApplyFunction(plist, &SetOFVariableFromFile, 0); CFRelease(plist); @@ -389,10 +444,10 @@ static void SetOrGetOFVariable(char *str) CFStringRef nameRef; CFTypeRef valueRef; kern_return_t result; - + // OF variable name is first. name = str; - + // Find the equal sign for set while (*str) { if (*str == '=') { @@ -402,27 +457,92 @@ static void SetOrGetOFVariable(char *str) } str++; } - + if (set == 1) { // On sets, the OF variable's value follows the equal sign. value = str; - - result = SetOFVariable(name, value); +#if TARGET_OS_BRIDGE + if (gBridgeToIntel) { + result = SetMacOFVariable(name, value); + } + else +#endif + { + result = SetOFVariable(name, value); + NVRamSyncNow(name); /* Try syncing the new data to device, best effort! */ + } if (result != KERN_SUCCESS) { - FatalError(-1, "Error (-1) setting variable - '%s'", (long)name); + errx(1, "Error setting variable - '%s': %s", name, + mach_error_string(result)); } } else { - result = GetOFVariable(name, &nameRef, &valueRef); - if (result != KERN_SUCCESS) { - FatalError(-1, "Error (-1) getting variable - '%s'", (long)name); +#if TARGET_OS_BRIDGE + if (gBridgeToIntel) { + result = GetMacOFVariable(name, &value); + if (result != KERN_SUCCESS) { + errx(1, "Error getting variable - '%s': %s", name, + mach_error_string(result)); + } + nameRef = CFStringCreateWithCString(kCFAllocatorDefault, name, kCFStringEncodingUTF8); + valueRef = CFStringCreateWithCString(kCFAllocatorDefault, value, kCFStringEncodingUTF8); + } + else +#endif + { + result = GetOFVariable(name, &nameRef, &valueRef); + if (result != KERN_SUCCESS) { + errx(1, "Error getting variable - '%s': %s", name, + mach_error_string(result)); + } } - + PrintOFVariable(nameRef, valueRef, 0); CFRelease(nameRef); CFRelease(valueRef); } } +#if TARGET_OS_BRIDGE +static kern_return_t LinkMacNVRAMSymbols() +{ + gDL_handle = dlopen("libMacEFIHostInterface.dylib", RTLD_LAZY); + if (gDL_handle == NULL) { + errx(errno, "Failed to dlopen libMacEFIHostInterface.dylib"); + return KERN_FAILURE; /* NOTREACHED */ + } + + hostInterfaceInitialize_fptr = dlsym(gDL_handle, "hostInterfaceInitialize"); + if (hostInterfaceInitialize_fptr == NULL) { + errx(errno, "failed to link hostInterfaceInitialize"); + } + createNvramHostInterface_fptr = dlsym(gDL_handle, "createNvramHostInterface"); + if (createNvramHostInterface_fptr == NULL) { + errx(errno, "failed to link createNvramHostInterface"); + } + destroyNvramHostInterface_fptr = dlsym(gDL_handle, "destroyNvramHostInterface"); + if (destroyNvramHostInterface_fptr == NULL) { + errx(errno, "failed to link destroyNvramHostInterface"); + } + getNVRAMVariable_fptr = dlsym(gDL_handle, "getNVRAMVariable"); + if (getNVRAMVariable_fptr == NULL) { + errx(errno, "failed to link getNVRAMVariable"); + } + setNVRAMVariable_fptr = dlsym(gDL_handle, "setNVRAMVariable"); + if (setNVRAMVariable_fptr == NULL) { + errx(errno, "failed to link setNVRAMVariable"); + } + hostInterfaceDeinitialize_fptr = dlsym(gDL_handle, "hostInterfaceDeinitialize"); + if (hostInterfaceDeinitialize_fptr == NULL) { + errx(errno, "failed to link hostInterfaceDeinitialize"); + } + + /* also do the initialization */ + hostInterfaceInitialize_fptr(); + gNvramInterface = createNvramHostInterface_fptr(NULL); + + return KERN_SUCCESS; +} +#endif // GetOFVariable(name, nameRef, valueRef) // @@ -435,15 +555,32 @@ static kern_return_t GetOFVariable(char *name, CFStringRef *nameRef, *nameRef = CFStringCreateWithCString(kCFAllocatorDefault, name, kCFStringEncodingUTF8); if (*nameRef == 0) { - FatalError(-1, "Error (-1) creating CFString for key %s", (long)name); + errx(1, "Error creating CFString for key %s", name); } - + *valueRef = IORegistryEntryCreateCFProperty(gOptionsRef, *nameRef, 0, 0); - if (*valueRef == 0) return -1; - + if (*valueRef == 0) return kIOReturnNotFound; + return KERN_SUCCESS; } +#if TARGET_OS_BRIDGE +// GetMacOFVariable(name, value) +// +// Get the named firmware variable from the Intel side. +// Return the value in value +// +static kern_return_t GetMacOFVariable(char *name, char **value) +{ + uint32_t value_size; + kern_return_t result = KERN_FAILURE; + assert(getNVRAMVariable_fptr != NULL); + + result = getNVRAMVariable_fptr(gNvramInterface, name, value, &value_size); + + return result; +} +#endif // SetOFVariable(name, value) // @@ -454,93 +591,118 @@ static kern_return_t SetOFVariable(char *name, char *value) CFStringRef nameRef; CFTypeRef valueRef; CFTypeID typeID; - kern_return_t result; - + kern_return_t result = KERN_SUCCESS; + nameRef = CFStringCreateWithCString(kCFAllocatorDefault, name, kCFStringEncodingUTF8); if (nameRef == 0) { - FatalError(-1, "Error (-1) creating CFString for key %s", (long)name); + errx(1, "Error creating CFString for key %s", name); } - + valueRef = IORegistryEntryCreateCFProperty(gOptionsRef, nameRef, 0, 0); if (valueRef) { typeID = CFGetTypeID(valueRef); CFRelease(valueRef); - + valueRef = ConvertValueToCFTypeRef(typeID, value); if (valueRef == 0) { - FatalError(-1, "Error (-1) creating CFTypeRef for value %s",(long)value); + errx(1, "Error creating CFTypeRef for value %s", value); } result = IORegistryEntrySetCFProperty(gOptionsRef, nameRef, valueRef); } else { while (1) { - // In the default case, try data, string, number, then boolean. - + // In the default case, try data, string, number, then boolean. + valueRef = ConvertValueToCFTypeRef(CFDataGetTypeID(), value); if (valueRef != 0) { result = IORegistryEntrySetCFProperty(gOptionsRef, nameRef, valueRef); if (result == KERN_SUCCESS) break; } - + valueRef = ConvertValueToCFTypeRef(CFStringGetTypeID(), value); if (valueRef != 0) { result = IORegistryEntrySetCFProperty(gOptionsRef, nameRef, valueRef); if (result == KERN_SUCCESS) break; } - + valueRef = ConvertValueToCFTypeRef(CFNumberGetTypeID(), value); if (valueRef != 0) { result = IORegistryEntrySetCFProperty(gOptionsRef, nameRef, valueRef); if (result == KERN_SUCCESS) break; } - + valueRef = ConvertValueToCFTypeRef(CFBooleanGetTypeID(), value); if (valueRef != 0) { result = IORegistryEntrySetCFProperty(gOptionsRef, nameRef, valueRef); if (result == KERN_SUCCESS) break; } - - result = -1; + break; } } - + CFRelease(nameRef); - + return result; } +#if TARGET_OS_BRIDGE +static kern_return_t SetMacOFVariable(char *name, char *value) +{ + kern_return_t result = KERN_FAILURE; + assert(setNVRAMVariable_fptr != NULL); + + result = setNVRAMVariable_fptr(gNvramInterface, name, value, strlen(value)); + + return result; +} +#endif // DeleteOFVariable(name) // // Delete the named firmware variable. -// +// // static void DeleteOFVariable(char *name) { SetOFVariable(kIONVRAMDeletePropertyKey, name); } +#if TARGET_OS_BRIDGE +static void DeleteMacOFVariable(char *name) +{ + /* Not yet implementable */ +} +#endif + +static void NVRamSyncNow(char *name) +{ + if (!gUseForceSync) { + SetOFVariable(kIONVRAMSyncNowPropertyKey, name); + } else { + SetOFVariable(kIONVRAMForceSyncNowPropertyKey, name); + } +} // PrintOFVariables() // // Print all of the firmware variables. // -static void PrintOFVariables() +static void PrintOFVariables(void) { kern_return_t result; CFMutableDictionaryRef dict; - + result = IORegistryEntryCreateCFProperties(gOptionsRef, &dict, 0, 0); if (result != KERN_SUCCESS) { - FatalError(-1, "Error (%d) getting the firmware variables", result); + errx(1, "Error getting the firmware variables: %s", mach_error_string(result)); } if (gUseXML) { CFDataRef data; - data = CFPropertyListCreateXMLData( kCFAllocatorDefault, dict ); + data = CFPropertyListCreateData( kCFAllocatorDefault, dict, kCFPropertyListXMLFormat_v1_0, 0, NULL ); if (data == NULL) { - FatalError(-1, "Error (%d) converting variables to xml", result); + errx(1, "Error converting variables to xml"); } fwrite(CFDataGetBytePtr(data), sizeof(UInt8), CFDataGetLength(data), stdout); @@ -552,7 +714,7 @@ static void PrintOFVariables() CFDictionaryApplyFunction(dict, &PrintOFVariable, 0); } - + CFRelease(dict); } @@ -573,22 +735,43 @@ static void PrintOFVariable(const void *key, const void *value, void *context) CFIndex valueLen; char *valueBuffer = 0; const char *valueString = 0; - uint32_t number, length; + uint32_t number; + long length; CFTypeID typeID; - + + if (gUseXML) { + CFDataRef data; + CFDictionaryRef dict = CFDictionaryCreate(kCFAllocatorDefault, &key, &value, 1, + &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + if (dict == NULL) { + errx(1, "Error creating dictionary for variable value"); + } + + data = CFPropertyListCreateData( kCFAllocatorDefault, dict, kCFPropertyListXMLFormat_v1_0, 0, NULL ); + if (data == NULL) { + errx(1, "Error creating xml plist for variable"); + } + + fwrite(CFDataGetBytePtr(data), sizeof(UInt8), CFDataGetLength(data), stdout); + + CFRelease(dict); + CFRelease(data); + return; + } + // Get the OF variable's name. nameLen = CFStringGetLength(key) + 1; nameBuffer = malloc(nameLen); if( nameBuffer && CFStringGetCString(key, nameBuffer, nameLen, kCFStringEncodingUTF8) ) nameString = nameBuffer; else { - Error("Error (-1) Unable to convert property name to C string", 0); + warnx("Unable to convert property name to C string"); nameString = ""; } - + // Get the OF variable's type. typeID = CFGetTypeID(value); - + if (typeID == CFBooleanGetTypeID()) { if (CFBooleanGetValue(value)) valueString = "true"; else valueString = "false"; @@ -604,7 +787,7 @@ static void PrintOFVariable(const void *key, const void *value, void *context) if ( valueBuffer && CFStringGetCString(value, valueBuffer, valueLen, kCFStringEncodingUTF8) ) valueString = valueBuffer; else { - Error("Error (-1) Unable to convert value to C string", 0); + warnx("Unable to convert value to C string"); valueString = ""; } } else if (typeID == CFDataGetTypeID()) { @@ -616,8 +799,9 @@ static void PrintOFVariable(const void *key, const void *value, void *context) dataPtr = CFDataGetBytePtr(value); for (cnt = cnt2 = 0; cnt < length; cnt++) { dataChar = dataPtr[cnt]; - if (isprint(dataChar)) dataBuffer[cnt2++] = dataChar; - else { + if (isprint(dataChar) && dataChar != '%') { + dataBuffer[cnt2++] = dataChar; + } else { sprintf(dataBuffer + cnt2, "%%%02x", dataChar); cnt2 += 3; } @@ -629,10 +813,10 @@ static void PrintOFVariable(const void *key, const void *value, void *context) } else { valueString=""; } - + if ((nameString != 0) && (valueString != 0)) printf("%s\t%s\n", nameString, valueString); - + if (dataBuffer != 0) free(dataBuffer); if (nameBuffer != 0) free(nameBuffer); if (valueBuffer != 0) free(valueBuffer); @@ -649,7 +833,7 @@ static void ClearOFVariables(void) result = IORegistryEntryCreateCFProperties(gOptionsRef, &dict, 0, 0); if (result != KERN_SUCCESS) { - FatalError(-1, "Error (%d) getting the firmware variables", result); + errx(1, "Error getting the firmware variables: %s", mach_error_string(result)); } CFDictionaryApplyFunction(dict, &ClearOFVariable, 0); @@ -662,7 +846,7 @@ static void ClearOFVariable(const void *key, const void *value, void *context) result = IORegistryEntrySetCFProperty(gOptionsRef, CFSTR(kIONVRAMDeletePropertyKey), key); if (result != KERN_SUCCESS) { - FatalError(-1, "Error (%d) clearing firmware variables", result); + errx(1, "Error clearing firmware variables: %s", mach_error_string(result)); } } @@ -675,7 +859,7 @@ static CFTypeRef ConvertValueToCFTypeRef(CFTypeID typeID, char *value) CFTypeRef valueRef = 0; long cnt, cnt2, length; unsigned long number, tmp; - + if (typeID == CFBooleanGetTypeID()) { if (!strcmp("true", value)) valueRef = kCFBooleanTrue; else if (!strcmp("false", value)) valueRef = kCFBooleanFalse; @@ -703,7 +887,7 @@ static CFTypeRef ConvertValueToCFTypeRef(CFTypeID typeID, char *value) valueRef = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, (const UInt8 *)value, cnt2, kCFAllocatorDefault); } else return 0; - + return valueRef; } @@ -713,7 +897,7 @@ static void SetOFVariableFromFile(const void *key, const void *value, void *cont result = IORegistryEntrySetCFProperty(gOptionsRef, key, value); if ( result != KERN_SUCCESS ) { - int nameLen; + long nameLen; char *nameBuffer; char *nameString; @@ -723,9 +907,10 @@ static void SetOFVariableFromFile(const void *key, const void *value, void *cont if( nameBuffer && CFStringGetCString(key, nameBuffer, nameLen, kCFStringEncodingUTF8) ) nameString = nameBuffer; else { - Error("Error (-1) Unable to convert property name to C string", 0); + warnx("Unable to convert property name to C string"); nameString = ""; } - FatalError(-1, "Error (-1) setting variable - '%s'", (long)nameString); + errx(1, "Error setting variable - '%s': %s", nameString, + mach_error_string(result)); } }