1/* 2 * Copyright (c) 2000-2005, 2009-2011, 2013 Apple Inc. All rights reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. Please obtain a copy of the License at 10 * http://www.opensource.apple.com/apsl/ and read it before using this 11 * file. 12 * 13 * The Original Code and all software distributed under the License are 14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 * Please see the License for the specific language governing rights and 19 * limitations under the License. 20 * 21 * @APPLE_LICENSE_HEADER_END@ 22 */ 23 24/* 25 * Modification History 26 * 27 * June 1, 2001 Allan Nathanson <ajn@apple.com> 28 * - public API conversion 29 * 30 * November 9, 2000 Allan Nathanson <ajn@apple.com> 31 * - initial revision 32 */ 33 34#include "scutil.h" 35#include "dictionary.h" 36 37 38//#include <stdlib.h> 39//#include <limits.h> 40 41 42__private_extern__ 43void 44do_dictInit(int argc, char **argv) 45{ 46 if (value != NULL) { 47 CFRelease(value); 48 } 49 50 value = CFDictionaryCreateMutable(NULL 51 ,0 52 ,&kCFTypeDictionaryKeyCallBacks 53 ,&kCFTypeDictionaryValueCallBacks 54 ); 55 56 return; 57} 58 59 60__private_extern__ 61void 62do_dictShow(int argc, char **argv) 63{ 64 if (value == NULL) { 65 SCPrint(TRUE, stdout, CFSTR("d.show: dictionary must be initialized.\n")); 66 return; 67 } 68 69 SCPrint(TRUE, stdout, CFSTR("%@\n"), value); 70 71 return; 72} 73 74 75__private_extern__ 76void 77do_dictSetKey(int argc, char **argv) 78{ 79 CFMutableArrayRef array = NULL; 80 Boolean doArray = FALSE; 81 Boolean doBoolean = FALSE; 82 Boolean doData = FALSE; 83 Boolean doNumeric = FALSE; 84 CFStringRef key; 85 CFMutableDictionaryRef newValue; 86 CFTypeRef val = NULL; 87 88 if (value == NULL) { 89 SCPrint(TRUE, stdout, CFSTR("d.add: dictionary must be initialized.\n")); 90 return; 91 } 92 93 if (!isA_CFDictionary(value)) { 94 SCPrint(TRUE, stdout, CFSTR("d.add: data (fetched from configuration server) is not a dictionary.\n")); 95 return; 96 } 97 98 key = CFStringCreateWithCString(NULL, argv[0], kCFStringEncodingUTF8); 99 argv++; argc--; 100 101 while (argc > 0) { 102 if (strcmp(argv[0], "*") == 0) { 103 /* if array requested */ 104 doArray = TRUE; 105 } else if (strcmp(argv[0], "-") == 0) { 106 /* if string values follow */ 107 argv++; argc--; 108 break; 109 } else if (strcmp(argv[0], "?") == 0) { 110 /* if boolean values requested */ 111 doBoolean = TRUE; 112 } else if (strcmp(argv[0], "%") == 0) { 113 /* if [hex] data values requested */ 114 doData = TRUE; 115 } else if (strcmp(argv[0], "#") == 0) { 116 /* if numeric values requested */ 117 doNumeric = TRUE; 118 } else { 119 /* it's not a special flag */ 120 break; 121 } 122 argv++; argc--; 123 } 124 125 if (argc > 1) { 126 doArray = TRUE; 127 } else if (!doArray && (argc == 0)) { 128 SCPrint(TRUE, stdout, CFSTR("d.add: no values.\n")); 129 CFRelease(key); 130 return; 131 } 132 133 if (doArray) { 134 array = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); 135 } 136 137 while (argc > 0) { 138 if (doBoolean) { 139 if ((strcasecmp(argv[0], "true") == 0) || 140 (strcasecmp(argv[0], "t" ) == 0) || 141 (strcasecmp(argv[0], "yes" ) == 0) || 142 (strcasecmp(argv[0], "y" ) == 0) || 143 (strcmp (argv[0], "1" ) == 0)) { 144 val = CFRetain(kCFBooleanTrue); 145 } else if ((strcasecmp(argv[0], "false") == 0) || 146 (strcasecmp(argv[0], "f" ) == 0) || 147 (strcasecmp(argv[0], "no" ) == 0) || 148 (strcasecmp(argv[0], "n" ) == 0) || 149 (strcmp (argv[0], "0" ) == 0)) { 150 val = CFRetain(kCFBooleanFalse); 151 } else { 152 SCPrint(TRUE, stdout, CFSTR("d.add: invalid data.\n")); 153 if (doArray) CFRelease(array); 154 CFRelease(key); 155 return; 156 } 157 } else if (doData) { 158 uint8_t *bytes; 159 CFMutableDataRef data; 160 int i; 161 int j; 162 int n; 163 164 n = (int)strlen(argv[0]); 165 if ((n % 2) == 1) { 166 SCPrint(TRUE, stdout, CFSTR("d.add: not enough bytes.\n")); 167 if (doArray) CFRelease(array); 168 CFRelease(key); 169 return; 170 } 171 172 data = CFDataCreateMutable(NULL, (n / 2)); 173 CFDataSetLength(data, (n / 2)); 174 175 bytes = (uint8_t *)CFDataGetBytePtr(data); 176 for (i = 0, j = 0; i < n; i += 2, j++) { 177 unsigned long byte; 178 char *end; 179 char str[3] = { 0 }; 180 181 str[0] = argv[0][i]; 182 str[1] = argv[0][i + 1]; 183 errno = 0; 184 byte = strtoul(str, &end, 16); 185 if ((*end != '\0') || (errno != 0)) { 186 CFRelease(data); 187 data = NULL; 188 break; 189 } 190 191 bytes[j] = byte; 192 } 193 194 if (data == NULL) { 195 SCPrint(TRUE, stdout, CFSTR("d.add: invalid data.\n")); 196 if (doArray) CFRelease(array); 197 CFRelease(key); 198 return; 199 } 200 201 val = data; 202 } else if (doNumeric) { 203 int intValue; 204 205 if (sscanf(argv[0], "%d", &intValue) == 1) { 206 val = CFNumberCreate(NULL, kCFNumberIntType, &intValue); 207 } else { 208 SCPrint(TRUE, stdout, CFSTR("d.add: invalid data.\n")); 209 if (doArray) CFRelease(array); 210 CFRelease(key); 211 return; 212 } 213 } else { 214 val = (CFPropertyListRef)CFStringCreateWithCString(NULL, argv[0], kCFStringEncodingUTF8); 215 } 216 217 if (doArray) { 218 CFArrayAppendValue(array, val); 219 CFRelease(val); 220 argv++; argc--; 221 } else { 222 break; 223 } 224 } 225 226 newValue = CFDictionaryCreateMutableCopy(NULL, 0, value); 227 if (doArray) { 228 CFDictionarySetValue(newValue, key, array); 229 CFRelease(array); 230 } else if (val != NULL) { 231 CFDictionarySetValue(newValue, key, val); 232 CFRelease(val); 233 } 234 CFRelease(key); 235 CFRelease(value); 236 value = newValue; 237 238 return; 239} 240 241 242__private_extern__ 243void 244do_dictRemoveKey(int argc, char **argv) 245{ 246 CFStringRef key; 247 CFMutableDictionaryRef val; 248 249 if (value == NULL) { 250 SCPrint(TRUE, stdout, CFSTR("d.remove: dictionary must be initialized.\n")); 251 return; 252 } 253 254 if (!isA_CFDictionary(value)) { 255 SCPrint(TRUE, stdout, CFSTR("d.remove: data (fetched from configuration server) is not a dictionary.\n")); 256 return; 257 } 258 259 val = CFDictionaryCreateMutableCopy(NULL, 0, value); 260 CFRelease(value); 261 value = val; 262 263 key = CFStringCreateWithCString(NULL, argv[0], kCFStringEncodingUTF8); 264 CFDictionaryRemoveValue((CFMutableDictionaryRef)value, key); 265 CFRelease(key); 266 267 return; 268} 269