]> git.saurik.com Git - apple/configd.git/blob - scutil.tproj/dictionary.c
configd-963.tar.gz
[apple/configd.git] / scutil.tproj / dictionary.c
1 /*
2 * Copyright (c) 2000-2005, 2009-2011, 2013, 2016, 2017 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 __private_extern__
39 void
40 do_dictInit(int argc, char **argv)
41 {
42 #pragma unused(argc)
43 #pragma unused(argv)
44 if (value != NULL) {
45 CFRelease(value);
46 }
47
48 value = CFDictionaryCreateMutable(NULL
49 ,0
50 ,&kCFTypeDictionaryKeyCallBacks
51 ,&kCFTypeDictionaryValueCallBacks
52 );
53
54 return;
55 }
56
57
58 __private_extern__
59 void
60 do_dictShow(int argc, char **argv)
61 {
62 #pragma unused(argc)
63 #pragma unused(argv)
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__
76 void
77 do_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__
243 void
244 do_dictRemoveKey(int argc, char **argv)
245 {
246 #pragma unused(argc)
247 CFStringRef key;
248 CFMutableDictionaryRef val;
249
250 if (value == NULL) {
251 SCPrint(TRUE, stdout, CFSTR("d.remove: dictionary must be initialized.\n"));
252 return;
253 }
254
255 if (!isA_CFDictionary(value)) {
256 SCPrint(TRUE, stdout, CFSTR("d.remove: data (fetched from configuration server) is not a dictionary.\n"));
257 return;
258 }
259
260 val = CFDictionaryCreateMutableCopy(NULL, 0, value);
261 CFRelease(value);
262 value = val;
263
264 key = CFStringCreateWithCString(NULL, argv[0], kCFStringEncodingUTF8);
265 CFDictionaryRemoveValue((CFMutableDictionaryRef)value, key);
266 CFRelease(key);
267
268 return;
269 }