Commit | Line | Data |
---|---|---|
5958d7c0 | 1 | /* |
a40a14f8 | 2 | * Copyright (c) 2000-2004, 2006, 2008 Apple Inc. All rights reserved. |
5958d7c0 A |
3 | * |
4 | * @APPLE_LICENSE_HEADER_START@ | |
009ee3c6 | 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. | |
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 | |
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. | |
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 | * March 24, 2000 Allan Nathanson <ajn@apple.com> | |
31 | * - initial revision | |
32 | */ | |
33 | ||
5958d7c0 A |
34 | #include "configd.h" |
35 | #include "session.h" | |
36 | ||
009ee3c6 | 37 | __private_extern__ |
0fae82ee | 38 | int |
009ee3c6 | 39 | __SCDynamicStoreCopyValue(SCDynamicStoreRef store, CFStringRef key, CFDataRef *value, Boolean internal) |
5958d7c0 | 40 | { |
0fae82ee A |
41 | SCDynamicStorePrivateRef storePrivate = (SCDynamicStorePrivateRef)store; |
42 | CFDictionaryRef dict; | |
5958d7c0 | 43 | |
edebe297 | 44 | if ((store == NULL) || (storePrivate->server == MACH_PORT_NULL)) { |
0fae82ee | 45 | return kSCStatusNoStoreSession; /* you must have an open session to play */ |
5958d7c0 A |
46 | } |
47 | ||
009ee3c6 A |
48 | if (_configd_trace) { |
49 | SCTrace(TRUE, _configd_trace, | |
50 | CFSTR("%s : %5d : %@\n"), | |
51 | internal ? "*copy " : "copy ", | |
52 | storePrivate->server, | |
53 | key); | |
54 | } | |
55 | ||
0fae82ee | 56 | dict = CFDictionaryGetValue(storeData, key); |
5958d7c0 A |
57 | if ((dict == NULL) || (CFDictionaryContainsKey(dict, kSCDData) == FALSE)) { |
58 | /* key doesn't exist (or data never defined) */ | |
0fae82ee | 59 | return kSCStatusNoKey; |
5958d7c0 A |
60 | } |
61 | ||
5958d7c0 | 62 | /* Return the data associated with the key */ |
0fae82ee | 63 | *value = CFRetain(CFDictionaryGetValue(dict, kSCDData)); |
5958d7c0 | 64 | |
0fae82ee | 65 | return kSCStatusOK; |
5958d7c0 A |
66 | } |
67 | ||
009ee3c6 | 68 | __private_extern__ |
5958d7c0 A |
69 | kern_return_t |
70 | _configget(mach_port_t server, | |
71 | xmlData_t keyRef, /* raw XML bytes */ | |
72 | mach_msg_type_number_t keyLen, | |
73 | xmlDataOut_t *dataRef, /* raw XML bytes */ | |
74 | mach_msg_type_number_t *dataLen, | |
75 | int *newInstance, | |
0fae82ee | 76 | int *sc_status |
5958d7c0 A |
77 | ) |
78 | { | |
dbf6a266 | 79 | CFStringRef key = NULL; /* key (un-serialized) */ |
a40a14f8 | 80 | serverSessionRef mySession; |
a5f60add | 81 | Boolean ok; |
009ee3c6 | 82 | CFDataRef value; |
5958d7c0 | 83 | |
a5f60add A |
84 | *dataRef = NULL; |
85 | *dataLen = 0; | |
86 | ||
5958d7c0 | 87 | /* un-serialize the key */ |
009ee3c6 | 88 | if (!_SCUnserializeString(&key, NULL, (void *)keyRef, keyLen)) { |
0fae82ee | 89 | *sc_status = kSCStatusFailed; |
dbf6a266 | 90 | goto done; |
a5f60add A |
91 | } |
92 | ||
93 | if (!isA_CFString(key)) { | |
0fae82ee | 94 | *sc_status = kSCStatusInvalidArgument; |
dbf6a266 | 95 | goto done; |
009ee3c6 A |
96 | } |
97 | ||
a40a14f8 | 98 | mySession = getSession(server); |
edebe297 | 99 | if (mySession == NULL) { |
009ee3c6 | 100 | *sc_status = kSCStatusNoStoreSession; /* you must have an open session to play */ |
dbf6a266 | 101 | goto done; |
5958d7c0 A |
102 | } |
103 | ||
009ee3c6 | 104 | *sc_status = __SCDynamicStoreCopyValue(mySession->store, key, &value, FALSE); |
0fae82ee | 105 | if (*sc_status != kSCStatusOK) { |
dbf6a266 | 106 | goto done; |
5958d7c0 A |
107 | } |
108 | ||
a5f60add | 109 | /* serialize the data */ |
009ee3c6 | 110 | ok = _SCSerializeData(value, (void **)dataRef, (CFIndex *)dataLen); |
0fae82ee | 111 | CFRelease(value); |
a5f60add | 112 | if (!ok) { |
0fae82ee | 113 | *sc_status = kSCStatusFailed; |
dbf6a266 | 114 | goto done; |
5958d7c0 A |
115 | } |
116 | ||
5958d7c0 A |
117 | /* |
118 | * return the instance number associated with the returned data. | |
119 | */ | |
0fae82ee A |
120 | *newInstance = 1; |
121 | ||
dbf6a266 A |
122 | done : |
123 | ||
edebe297 | 124 | if (key != NULL) CFRelease(key); |
0fae82ee A |
125 | return KERN_SUCCESS; |
126 | } | |
127 | ||
128 | /* | |
129 | * "context" argument for addSpecificKey() and addSpecificPattern() | |
130 | */ | |
131 | typedef struct { | |
132 | SCDynamicStoreRef store; | |
133 | CFMutableDictionaryRef dict; | |
134 | } addSpecific, *addSpecificRef; | |
135 | ||
136 | static void | |
137 | addSpecificKey(const void *value, void *context) | |
138 | { | |
009ee3c6 | 139 | CFDataRef data; |
0fae82ee A |
140 | CFStringRef key = (CFStringRef)value; |
141 | addSpecificRef myContextRef = (addSpecificRef)context; | |
142 | int sc_status; | |
5958d7c0 | 143 | |
0fae82ee A |
144 | if (!isA_CFString(key)) { |
145 | return; | |
146 | } | |
147 | ||
009ee3c6 | 148 | sc_status = __SCDynamicStoreCopyValue(myContextRef->store, key, &data, TRUE); |
0fae82ee A |
149 | if (sc_status == kSCStatusOK) { |
150 | CFDictionaryAddValue(myContextRef->dict, key, data); | |
151 | CFRelease(data); | |
152 | } | |
153 | ||
154 | return; | |
155 | } | |
156 | ||
157 | static void | |
158 | addSpecificPattern(const void *value, void *context) | |
159 | { | |
160 | CFStringRef pattern = (CFStringRef)value; | |
161 | addSpecificRef myContextRef = (addSpecificRef)context; | |
162 | int sc_status; | |
163 | CFArrayRef keys; | |
164 | ||
165 | if (!isA_CFString(pattern)) { | |
166 | return; | |
167 | } | |
168 | ||
169 | sc_status = __SCDynamicStoreCopyKeyList(myContextRef->store, pattern, TRUE, &keys); | |
170 | if (sc_status == kSCStatusOK) { | |
171 | CFArrayApplyFunction(keys, | |
172 | CFRangeMake(0, CFArrayGetCount(keys)), | |
173 | addSpecificKey, | |
174 | context); | |
175 | CFRelease(keys); | |
176 | } | |
177 | ||
178 | return; | |
179 | } | |
180 | ||
009ee3c6 A |
181 | __private_extern__ |
182 | int | |
183 | __SCDynamicStoreCopyMultiple(SCDynamicStoreRef store, CFArrayRef keys, CFArrayRef patterns, CFDictionaryRef *values) | |
184 | { | |
185 | SCDynamicStorePrivateRef storePrivate = (SCDynamicStorePrivateRef)store; | |
186 | addSpecific myContext; | |
187 | ||
edebe297 | 188 | if ((store == NULL) || (storePrivate->server == MACH_PORT_NULL)) { |
009ee3c6 A |
189 | return kSCStatusNoStoreSession; /* you must have an open session to play */ |
190 | } | |
191 | ||
192 | if (_configd_trace) { | |
193 | SCTrace(TRUE, _configd_trace, | |
194 | CFSTR("copy m : %5d : %d keys, %d patterns\n"), | |
195 | storePrivate->server, | |
196 | keys ? CFArrayGetCount(keys) : 0, | |
197 | patterns ? CFArrayGetCount(patterns) : 0); | |
198 | } | |
199 | ||
200 | myContext.store = store; | |
201 | myContext.dict = CFDictionaryCreateMutable(NULL, | |
202 | 0, | |
203 | &kCFTypeDictionaryKeyCallBacks, | |
204 | &kCFTypeDictionaryValueCallBacks); | |
205 | ||
206 | if (keys) { | |
207 | CFArrayApplyFunction(keys, | |
208 | CFRangeMake(0, CFArrayGetCount(keys)), | |
209 | addSpecificKey, | |
210 | &myContext); | |
211 | } | |
212 | ||
213 | if (patterns) { | |
214 | CFArrayApplyFunction(patterns, | |
215 | CFRangeMake(0, CFArrayGetCount(patterns)), | |
216 | addSpecificPattern, | |
217 | &myContext); | |
218 | } | |
219 | ||
220 | /* Return the keys/values associated with the key */ | |
221 | *values = myContext.dict; | |
222 | ||
009ee3c6 A |
223 | return kSCStatusOK; |
224 | } | |
225 | ||
226 | __private_extern__ | |
0fae82ee A |
227 | kern_return_t |
228 | _configget_m(mach_port_t server, | |
229 | xmlData_t keysRef, | |
230 | mach_msg_type_number_t keysLen, | |
231 | xmlData_t patternsRef, | |
232 | mach_msg_type_number_t patternsLen, | |
233 | xmlDataOut_t *dataRef, | |
234 | mach_msg_type_number_t *dataLen, | |
235 | int *sc_status) | |
236 | { | |
009ee3c6 | 237 | CFDictionaryRef dict = NULL; /* keys/values (un-serialized) */ |
0fae82ee | 238 | CFArrayRef keys = NULL; /* keys (un-serialized) */ |
a40a14f8 | 239 | serverSessionRef mySession; |
a5f60add A |
240 | Boolean ok; |
241 | CFArrayRef patterns = NULL; /* patterns (un-serialized) */ | |
0fae82ee | 242 | |
a5f60add A |
243 | *dataRef = NULL; |
244 | *dataLen = 0; | |
0fae82ee | 245 | |
edebe297 A |
246 | *sc_status = kSCStatusOK; |
247 | ||
0fae82ee | 248 | if (keysRef && (keysLen > 0)) { |
0fae82ee | 249 | /* un-serialize the keys */ |
009ee3c6 | 250 | if (!_SCUnserialize((CFPropertyListRef *)&keys, NULL, (void *)keysRef, keysLen)) { |
0fae82ee | 251 | *sc_status = kSCStatusFailed; |
0fae82ee A |
252 | } |
253 | } | |
254 | ||
255 | if (patternsRef && (patternsLen > 0)) { | |
0fae82ee | 256 | /* un-serialize the patterns */ |
009ee3c6 | 257 | if (!_SCUnserialize((CFPropertyListRef *)&patterns, NULL, (void *)patternsRef, patternsLen)) { |
0fae82ee | 258 | *sc_status = kSCStatusFailed; |
a5f60add | 259 | } |
edebe297 | 260 | } |
a5f60add | 261 | |
edebe297 A |
262 | if (*sc_status != kSCStatusOK) { |
263 | goto done; | |
264 | } | |
265 | ||
266 | if ((keys != NULL) && !isA_CFArray(keys)) { | |
267 | *sc_status = kSCStatusInvalidArgument; | |
268 | goto done; | |
269 | } | |
270 | ||
271 | if ((patterns != NULL) && !isA_CFArray(patterns)) { | |
272 | *sc_status = kSCStatusInvalidArgument; | |
273 | goto done; | |
0fae82ee A |
274 | } |
275 | ||
a40a14f8 | 276 | mySession = getSession(server); |
edebe297 | 277 | if (mySession == NULL) { |
009ee3c6 | 278 | *sc_status = kSCStatusNoStoreSession; /* you must have an open session to play */ |
dbf6a266 | 279 | goto done; |
009ee3c6 A |
280 | } |
281 | ||
dbf6a266 | 282 | /* fetch the requested information */ |
009ee3c6 | 283 | *sc_status = __SCDynamicStoreCopyMultiple(mySession->store, keys, patterns, &dict); |
0fae82ee | 284 | |
a5f60add | 285 | /* serialize the dictionary of matching keys/patterns */ |
009ee3c6 A |
286 | ok = _SCSerialize(dict, NULL, (void **)dataRef, (CFIndex *)dataLen); |
287 | CFRelease(dict); | |
a5f60add | 288 | if (!ok) { |
0fae82ee | 289 | *sc_status = kSCStatusFailed; |
0fae82ee A |
290 | } |
291 | ||
dbf6a266 A |
292 | done : |
293 | ||
294 | if (keys) CFRelease(keys); | |
295 | if (patterns) CFRelease(patterns); | |
5958d7c0 A |
296 | return KERN_SUCCESS; |
297 | } |