/* * Copyright (c) 2000-2004, 2009-2011 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in * compliance with the License. Please obtain a copy of the License at * http://www.opensource.apple.com/apsl/ and read it before using this * file. * * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. * Please see the License for the specific language governing rights and * limitations under the License. * * @APPLE_LICENSE_HEADER_END@ */ /* * Modification History * * June 1, 2001 Allan Nathanson * - public API conversion * * November 9, 2000 Allan Nathanson * - initial revision */ #include "scutil.h" #include "dictionary.h" //#include //#include __private_extern__ void do_dictInit(int argc, char **argv) { if (value != NULL) { CFRelease(value); } value = CFDictionaryCreateMutable(NULL ,0 ,&kCFTypeDictionaryKeyCallBacks ,&kCFTypeDictionaryValueCallBacks ); return; } __private_extern__ void do_dictShow(int argc, char **argv) { if (value == NULL) { SCPrint(TRUE, stdout, CFSTR("d.show: dictionary must be initialized.\n")); return; } SCPrint(TRUE, stdout, CFSTR("%@\n"), value); return; } __private_extern__ void do_dictSetKey(int argc, char **argv) { CFMutableArrayRef array = NULL; Boolean doArray = FALSE; Boolean doBoolean = FALSE; Boolean doData = FALSE; Boolean doNumeric = FALSE; CFStringRef key; CFMutableDictionaryRef newValue; CFTypeRef val = NULL; if (value == NULL) { SCPrint(TRUE, stdout, CFSTR("d.add: dictionary must be initialized.\n")); return; } if (!isA_CFDictionary(value)) { SCPrint(TRUE, stdout, CFSTR("d.add: data (fetched from configuration server) is not a dictionary.\n")); return; } key = CFStringCreateWithCString(NULL, argv[0], kCFStringEncodingUTF8); argv++; argc--; while (argc > 0) { if (strcmp(argv[0], "*") == 0) { /* if array requested */ doArray = TRUE; } else if (strcmp(argv[0], "-") == 0) { /* if string values requested */ } else if (strcmp(argv[0], "?") == 0) { /* if boolean values requested */ doBoolean = TRUE; } else if (strcmp(argv[0], "%") == 0) { /* if [hex] data values requested */ doData = TRUE; } else if (strcmp(argv[0], "#") == 0) { /* if numeric values requested */ doNumeric = TRUE; } else { /* it's not a special flag */ break; } argv++; argc--; } if (argc > 1) { doArray = TRUE; } else if (!doArray && (argc == 0)) { SCPrint(TRUE, stdout, CFSTR("d.add: no values.\n")); CFRelease(key); return; } if (doArray) { array = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); } while (argc > 0) { if (doBoolean) { if ((strcasecmp(argv[0], "true") == 0) || (strcasecmp(argv[0], "t" ) == 0) || (strcasecmp(argv[0], "yes" ) == 0) || (strcasecmp(argv[0], "y" ) == 0) || (strcmp (argv[0], "1" ) == 0)) { val = CFRetain(kCFBooleanTrue); } else if ((strcasecmp(argv[0], "false") == 0) || (strcasecmp(argv[0], "f" ) == 0) || (strcasecmp(argv[0], "no" ) == 0) || (strcasecmp(argv[0], "n" ) == 0) || (strcmp (argv[0], "0" ) == 0)) { val = CFRetain(kCFBooleanFalse); } else { SCPrint(TRUE, stdout, CFSTR("d.add: invalid data.\n")); if (doArray) CFRelease(array); CFRelease(key); return; } } else if (doData) { uint8_t *bytes; CFMutableDataRef data; int i; int j; int n; n = strlen(argv[0]); if ((n % 2) == 1) { SCPrint(TRUE, stdout, CFSTR("d.add: not enough bytes.\n")); if (doArray) CFRelease(array); CFRelease(key); return; } data = CFDataCreateMutable(NULL, (n / 2)); CFDataSetLength(data, (n / 2)); bytes = (uint8_t *)CFDataGetBytePtr(data); for (i = 0, j = 0; i < n; i += 2, j++) { unsigned long byte; char *end; char str[3] = { 0 }; str[0] = argv[0][i]; str[1] = argv[0][i + 1]; errno = 0; byte = strtoul(str, &end, 16); if ((*end != '\0') || (errno != 0)) { CFRelease(data); data = NULL; break; } bytes[j] = byte; } if (data == NULL) { SCPrint(TRUE, stdout, CFSTR("d.add: invalid data.\n")); if (doArray) CFRelease(array); CFRelease(key); return; } val = data; } else if (doNumeric) { int intValue; if (sscanf(argv[0], "%d", &intValue) == 1) { val = CFNumberCreate(NULL, kCFNumberIntType, &intValue); } else { SCPrint(TRUE, stdout, CFSTR("d.add: invalid data.\n")); if (doArray) CFRelease(array); CFRelease(key); return; } } else { val = (CFPropertyListRef)CFStringCreateWithCString(NULL, argv[0], kCFStringEncodingUTF8); } if (doArray) { CFArrayAppendValue(array, val); CFRelease(val); argv++; argc--; } else { break; } } newValue = CFDictionaryCreateMutableCopy(NULL, 0, value); if (doArray) { CFDictionarySetValue(newValue, key, array); CFRelease(array); } else if (val != NULL) { CFDictionarySetValue(newValue, key, val); CFRelease(val); } CFRelease(key); CFRelease(value); value = newValue; return; } __private_extern__ void do_dictRemoveKey(int argc, char **argv) { CFStringRef key; CFMutableDictionaryRef val; if (value == NULL) { SCPrint(TRUE, stdout, CFSTR("d.remove: dictionary must be initialized.\n")); return; } if (!isA_CFDictionary(value)) { SCPrint(TRUE, stdout, CFSTR("d.remove: data (fetched from configuration server) is not a dictionary.\n")); return; } val = CFDictionaryCreateMutableCopy(NULL, 0, value); CFRelease(value); value = val; key = CFStringCreateWithCString(NULL, argv[0], kCFStringEncodingUTF8); CFDictionaryRemoveValue((CFMutableDictionaryRef)value, key); CFRelease(key); return; }