]> git.saurik.com Git - apple/configd.git/blame - scutil.tproj/cache.c
configd-1109.101.1.tar.gz
[apple/configd.git] / scutil.tproj / cache.c
CommitLineData
5958d7c0 1/*
afb19109 2 * Copyright (c) 2000-2005, 2011, 2017, 2018 Apple Inc. All rights reserved.
5958d7c0
A
3 *
4 * @APPLE_LICENSE_HEADER_START@
afb19109 5 *
009ee3c6
A
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.
afb19109 12 *
009ee3c6
A
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
5958d7c0
A
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
009ee3c6
A
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.
afb19109 20 *
5958d7c0
A
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
0fae82ee
A
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
5958d7c0
A
34#include <sys/types.h>
35
36#include "scutil.h"
009ee3c6 37#include "cache.h"
afb19109 38#include "SCDynamicStoreInternal.h"
5958d7c0 39
0fae82ee 40
17d3ee29
A
41#pragma mark -
42#pragma mark SCDynamicStore "cache"
43
44
17d3ee29
A
45#pragma mark -
46#pragma mark SCDynamicStore operations
47
48
49__private_extern__
50void
51do_block(int argc, char **argv)
52{
53 Boolean enable = FALSE;
54
55 if (argc >= 1) {
56 if ((strcasecmp(argv[0], "begin") == 0) ||
57 (strcasecmp(argv[0], "start") == 0) ||
58 (strcasecmp(argv[0], "on" ) == 0) ||
59 (strcasecmp(argv[0], "1" ) == 0)) {
60 enable = TRUE;
61 } else if ((strcasecmp(argv[0], "end" ) == 0) ||
62 (strcasecmp(argv[0], "stop" ) == 0) ||
63 (strcasecmp(argv[0], "off" ) == 0) ||
64 (strcasecmp(argv[0], "0" ) == 0)) {
65 enable = FALSE;
66 } else {
67 SCPrint(TRUE, stdout, CFSTR("invalid value\n"));
68 return;
69 }
70 } else {
afb19109 71 enable = !_SCDynamicStoreCacheIsActive(store); // toggle
17d3ee29
A
72 }
73
74 if (enable) {
75 // begin block of SCDynamicStore operations
afb19109 76 if (_SCDynamicStoreCacheIsActive(store)) {
17d3ee29
A
77 SCPrint(TRUE, stdout, CFSTR(" %s\n"), SCErrorString(kSCStatusLocked));
78 return;
79 }
80
81 SCPrint(TRUE, stdout, CFSTR("Begin block of SCDynamicStore operations\n"));
82
afb19109 83 _SCDynamicStoreCacheOpen(store);
17d3ee29 84 } else {
afb19109
A
85 CFIndex n = 0;
86 SCDynamicStorePrivateRef storePrivate = (SCDynamicStorePrivateRef)store;
17d3ee29
A
87
88 // end block of SCDynamicStore operations
afb19109 89 if (!_SCDynamicStoreCacheIsActive(store)) {
17d3ee29
A
90 SCPrint(TRUE, stdout, CFSTR(" %s\n"), SCErrorString(kSCStatusNeedLock));
91 return;
92 }
93
afb19109
A
94 n += (storePrivate->cached_set != NULL)
95 ? CFDictionaryGetCount(storePrivate->cached_set) : 0;
96 n += (storePrivate->cached_removals != NULL)
97 ? CFArrayGetCount(storePrivate->cached_removals) : 0;
98 n += (storePrivate->cached_notifys != NULL)
99 ? CFArrayGetCount(storePrivate->cached_notifys) : 0;
100
17d3ee29
A
101 SCPrint(TRUE, stdout,
102 CFSTR("End block of SCDynamicStore operations%s\n"),
103 (n > 0) ? ", posting changes" : "");
104 if (n > 0) {
afb19109 105 _SCDynamicStoreCacheCommitChanges(store);
17d3ee29 106 }
afb19109 107 _SCDynamicStoreCacheClose(store);
17d3ee29
A
108 }
109
110 return;
111}
112
113
0fae82ee 114static CFComparisonResult
1ef45fa4
A
115sort_keys(const void *p1, const void *p2, void *context)
116{
117#pragma unused(context)
0fae82ee
A
118 CFStringRef key1 = (CFStringRef)p1;
119 CFStringRef key2 = (CFStringRef)p2;
120 return CFStringCompare(key1, key2, 0);
121}
122
123
17d3ee29
A
124#define N_QUICK 64
125
126
dbf6a266 127__private_extern__
5958d7c0
A
128void
129do_list(int argc, char **argv)
130{
afb19109
A
131 int i;
132 CFStringRef pattern;
133 CFArrayRef list;
134 CFIndex listCnt;
135 CFMutableArrayRef sortedList;
136 SCDynamicStorePrivateRef storePrivate = (SCDynamicStorePrivateRef)store;
5958d7c0 137
0fae82ee
A
138 pattern = CFStringCreateWithCString(NULL,
139 (argc >= 1) ? argv[0] : ".*",
dbf6a266 140 kCFStringEncodingUTF8);
5958d7c0 141
0fae82ee
A
142 list = SCDynamicStoreCopyKeyList(store, pattern);
143 CFRelease(pattern);
edebe297 144 if (list == NULL) {
a5f60add
A
145 if (SCError() != kSCStatusOK) {
146 SCPrint(TRUE, stdout, CFSTR(" %s\n"), SCErrorString(SCError()));
17d3ee29 147 return;
a5f60add 148 } else {
afb19109 149 if (!_SCDynamicStoreCacheIsActive(store)) {
a5f60add 150 SCPrint(TRUE, stdout, CFSTR(" no keys.\n"));
17d3ee29
A
151 return;
152 } else {
153 CFIndex n;
154
afb19109
A
155 n = (storePrivate->cached_set != NULL)
156 ? CFDictionaryGetCount(storePrivate->cached_set) : 0;
5e9ce69e 157 if (n > 0) {
17d3ee29
A
158 const void * cachedKeys_q[N_QUICK];
159 const void ** cachedKeys = cachedKeys_q;
160
161 if (n > (CFIndex)(sizeof(cachedKeys_q) / sizeof(CFStringRef))) {
162 cachedKeys = CFAllocatorAllocate(NULL, n * sizeof(CFStringRef), 0);
163 }
afb19109 164 CFDictionaryGetKeysAndValues(storePrivate->cached_set, cachedKeys, NULL);
17d3ee29
A
165 list = CFArrayCreate(NULL, cachedKeys, n, &kCFTypeArrayCallBacks);
166 if (cachedKeys != cachedKeys_q) {
167 CFAllocatorDeallocate(NULL, cachedKeys);
168 }
169 } else {
170 SCPrint(TRUE, stdout, CFSTR(" no keys.\n"));
171 return;
172 }
173 }
a5f60add 174 }
afb19109
A
175 } else if (_SCDynamicStoreCacheIsActive(store) &&
176 (((storePrivate->cached_set != NULL) &&
177 (CFDictionaryGetCount(storePrivate->cached_set) > 0)) ||
178 ((storePrivate->cached_removals != NULL) &&
179 (CFArrayGetCount(storePrivate->cached_removals) > 0)))) {
17d3ee29
A
180 SCPrint(TRUE, stdout,
181 CFSTR(" Note: SCDynamicStore transactions in progress, key list (below) may be out of date.\n\n"));
5958d7c0
A
182 }
183
184 listCnt = CFArrayGetCount(list);
0fae82ee
A
185 sortedList = CFArrayCreateMutableCopy(NULL, listCnt, list);
186 CFRelease(list);
187 CFArraySortValues(sortedList,
188 CFRangeMake(0, listCnt),
189 sort_keys,
190 NULL);
191
5958d7c0 192 if (listCnt > 0) {
009ee3c6 193 for (i = 0; i < listCnt; i++) {
0fae82ee
A
194 SCPrint(TRUE,
195 stdout,
196 CFSTR(" subKey [%d] = %@\n"),
197 i,
198 CFArrayGetValueAtIndex(sortedList, i));
5958d7c0
A
199 }
200 } else {
a5f60add 201 SCPrint(TRUE, stdout, CFSTR(" no keys.\n"));
5958d7c0 202 }
0fae82ee 203 CFRelease(sortedList);
5958d7c0
A
204
205 return;
206}
207
208
dbf6a266 209__private_extern__
5958d7c0
A
210void
211do_add(int argc, char **argv)
212{
213 CFStringRef key;
5958d7c0 214
dbf6a266 215 key = CFStringCreateWithCString(NULL, argv[0], kCFStringEncodingUTF8);
5958d7c0
A
216
217 if (argc < 2) {
afb19109 218 if (!_SCDynamicStoreCacheIsActive(store)) {
17d3ee29
A
219 if (!SCDynamicStoreAddValue(store, key, value)) {
220 SCPrint(TRUE, stdout, CFSTR(" %s\n"), SCErrorString(SCError()));
221 }
222 } else {
afb19109 223 SCPrint(TRUE, stdout, CFSTR(" Cannot \"add\" with block\n"));
5958d7c0
A
224 }
225 } else {
afb19109 226 if (!_SCDynamicStoreCacheIsActive(store)) {
17d3ee29
A
227 if (!SCDynamicStoreAddTemporaryValue(store, key, value)) {
228 SCPrint(TRUE, stdout, CFSTR(" %s\n"), SCErrorString(SCError()));
229 }
230 } else {
afb19109 231 SCPrint(TRUE, stdout, CFSTR(" Cannot \"add temporary\" with block\n"));
5958d7c0
A
232 }
233 }
234
235 CFRelease(key);
236 return;
237}
238
239
dbf6a266 240__private_extern__
5958d7c0
A
241void
242do_get(int argc, char **argv)
243{
1ef45fa4 244#pragma unused(argc)
0fae82ee
A
245 CFStringRef key;
246 CFPropertyListRef newValue;
5958d7c0 247
dbf6a266 248 key = CFStringCreateWithCString(NULL, argv[0], kCFStringEncodingUTF8);
afb19109 249 newValue = SCDynamicStoreCopyValue(store, key);
5958d7c0 250 CFRelease(key);
edebe297 251 if (newValue == NULL) {
0fae82ee 252 SCPrint(TRUE, stdout, CFSTR(" %s\n"), SCErrorString(SCError()));
5958d7c0
A
253 return;
254 }
255
0fae82ee
A
256 if (value != NULL) {
257 CFRelease(value); /* we have new information, release the old */
5958d7c0 258 }
0fae82ee 259 value = newValue;
5958d7c0
A
260
261 return;
262}
263
264
dbf6a266 265__private_extern__
5958d7c0
A
266void
267do_set(int argc, char **argv)
268{
1ef45fa4 269#pragma unused(argc)
5958d7c0
A
270 CFStringRef key;
271
edebe297 272 key = CFStringCreateWithCString(NULL, argv[0], kCFStringEncodingUTF8);
afb19109
A
273 if (!SCDynamicStoreSetValue(store, key, value)) {
274 SCPrint(TRUE, stdout, CFSTR(" %s\n"), SCErrorString(SCError()));
0fae82ee
A
275 }
276 CFRelease(key);
277 return;
278}
279
280
dbf6a266 281__private_extern__
0fae82ee
A
282void
283do_show(int argc, char **argv)
284{
285 CFStringRef key;
286 CFPropertyListRef newValue;
287
dbf6a266 288 key = CFStringCreateWithCString(NULL, argv[0], kCFStringEncodingUTF8);
009ee3c6
A
289
290 if (argc == 1) {
afb19109 291 newValue = SCDynamicStoreCopyValue(store, key);
009ee3c6
A
292 } else {
293 CFArrayRef patterns;
294
295 patterns = CFArrayCreate(NULL, (const void **)&key, 1, &kCFTypeArrayCallBacks);
afb19109 296 if (!_SCDynamicStoreCacheIsActive(store)) {
17d3ee29
A
297 newValue = SCDynamicStoreCopyMultiple(store, NULL, patterns);
298 } else {
afb19109
A
299 CFArrayRef keys;
300 CFMutableDictionaryRef newDict;
301 SCDynamicStorePrivateRef storePrivate = (SCDynamicStorePrivateRef)store;
17d3ee29
A
302
303 newDict = CFDictionaryCreateMutable(NULL,
304 0,
305 &kCFTypeDictionaryKeyCallBacks,
306 &kCFTypeDictionaryValueCallBacks);
307 keys = SCDynamicStoreCopyKeyList(store, key);
308 if (keys != NULL) {
309 CFIndex i;
310 CFIndex n;
311
312 n = CFArrayGetCount(keys);
313 for (i = 0; i < n; i++) {
314 CFStringRef storeKey;
315 CFTypeRef storeVal;
316
317 storeKey = CFArrayGetValueAtIndex(keys, i);
afb19109 318 storeVal = SCDynamicStoreCopyValue(store, storeKey);
17d3ee29
A
319 if (storeVal != NULL) {
320 CFDictionarySetValue(newDict, storeKey, storeVal);
321 CFRelease(storeVal);
322 }
323 }
324 CFRelease(keys);
325 }
326
afb19109
A
327 if (((storePrivate->cached_set != NULL) &&
328 (CFDictionaryGetCount(storePrivate->cached_set) > 0)) ||
329 ((storePrivate->cached_removals != NULL) &&
330 (CFArrayGetCount(storePrivate->cached_removals) > 0))) {
17d3ee29
A
331 SCPrint(TRUE, stdout, CFSTR(" Note: SCDynamicStore locked, keys included (below) may be out of date.\n\n"));
332 }
333
334 newValue = newDict;
335 }
009ee3c6
A
336 CFRelease(patterns);
337 }
338
5958d7c0 339 CFRelease(key);
edebe297 340 if (newValue == NULL) {
0fae82ee
A
341 SCPrint(TRUE, stdout, CFSTR(" %s\n"), SCErrorString(SCError()));
342 return;
5958d7c0 343 }
0fae82ee
A
344
345 SCPrint(TRUE, stdout, CFSTR("%@\n"), newValue);
346 CFRelease(newValue);
5958d7c0
A
347 return;
348}
349
350
dbf6a266 351__private_extern__
5958d7c0
A
352void
353do_remove(int argc, char **argv)
354{
1ef45fa4 355#pragma unused(argc)
5958d7c0
A
356 CFStringRef key;
357
edebe297 358 key = CFStringCreateWithCString(NULL, argv[0], kCFStringEncodingUTF8);
afb19109
A
359 if (!SCDynamicStoreRemoveValue(store, key)) {
360 SCPrint(TRUE, stdout, CFSTR(" %s\n"), SCErrorString(SCError()));
0fae82ee 361 }
5958d7c0 362 CFRelease(key);
0fae82ee
A
363 return;
364}
365
366
dbf6a266 367__private_extern__
0fae82ee
A
368void
369do_notify(int argc, char **argv)
370{
1ef45fa4 371#pragma unused(argc)
0fae82ee
A
372 CFStringRef key;
373
edebe297 374 key = CFStringCreateWithCString(NULL, argv[0], kCFStringEncodingUTF8);
afb19109
A
375 if (!SCDynamicStoreNotifyValue(store, key)) {
376 SCPrint(TRUE, stdout, CFSTR(" %s\n"), SCErrorString(SCError()));
5958d7c0 377 }
0fae82ee 378 CFRelease(key);
5958d7c0
A
379 return;
380}