]> git.saurik.com Git - apple/configd.git/blob - configd.tproj/_configget.c
configd-395.10.tar.gz
[apple/configd.git] / configd.tproj / _configget.c
1 /*
2 * Copyright (c) 2000-2004, 2006, 2008 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 * March 24, 2000 Allan Nathanson <ajn@apple.com>
31 * - initial revision
32 */
33
34 #include "configd.h"
35 #include "session.h"
36
37 __private_extern__
38 int
39 __SCDynamicStoreCopyValue(SCDynamicStoreRef store, CFStringRef key, CFDataRef *value, Boolean internal)
40 {
41 SCDynamicStorePrivateRef storePrivate = (SCDynamicStorePrivateRef)store;
42 CFDictionaryRef dict;
43
44 if ((store == NULL) || (storePrivate->server == MACH_PORT_NULL)) {
45 return kSCStatusNoStoreSession; /* you must have an open session to play */
46 }
47
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
56 dict = CFDictionaryGetValue(storeData, key);
57 if ((dict == NULL) || (CFDictionaryContainsKey(dict, kSCDData) == FALSE)) {
58 /* key doesn't exist (or data never defined) */
59 return kSCStatusNoKey;
60 }
61
62 /* Return the data associated with the key */
63 *value = CFRetain(CFDictionaryGetValue(dict, kSCDData));
64
65 return kSCStatusOK;
66 }
67
68 __private_extern__
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,
76 int *sc_status
77 )
78 {
79 CFStringRef key = NULL; /* key (un-serialized) */
80 serverSessionRef mySession;
81 Boolean ok;
82 CFDataRef value;
83
84 *dataRef = NULL;
85 *dataLen = 0;
86
87 /* un-serialize the key */
88 if (!_SCUnserializeString(&key, NULL, (void *)keyRef, keyLen)) {
89 *sc_status = kSCStatusFailed;
90 goto done;
91 }
92
93 if (!isA_CFString(key)) {
94 *sc_status = kSCStatusInvalidArgument;
95 goto done;
96 }
97
98 mySession = getSession(server);
99 if (mySession == NULL) {
100 *sc_status = kSCStatusNoStoreSession; /* you must have an open session to play */
101 goto done;
102 }
103
104 *sc_status = __SCDynamicStoreCopyValue(mySession->store, key, &value, FALSE);
105 if (*sc_status != kSCStatusOK) {
106 goto done;
107 }
108
109 /* serialize the data */
110 ok = _SCSerializeData(value, (void **)dataRef, (CFIndex *)dataLen);
111 CFRelease(value);
112 if (!ok) {
113 *sc_status = kSCStatusFailed;
114 goto done;
115 }
116
117 /*
118 * return the instance number associated with the returned data.
119 */
120 *newInstance = 1;
121
122 done :
123
124 if (key != NULL) CFRelease(key);
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 {
139 CFDataRef data;
140 CFStringRef key = (CFStringRef)value;
141 addSpecificRef myContextRef = (addSpecificRef)context;
142 int sc_status;
143
144 if (!isA_CFString(key)) {
145 return;
146 }
147
148 sc_status = __SCDynamicStoreCopyValue(myContextRef->store, key, &data, TRUE);
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
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
188 if ((store == NULL) || (storePrivate->server == MACH_PORT_NULL)) {
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
223 return kSCStatusOK;
224 }
225
226 __private_extern__
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 {
237 CFDictionaryRef dict = NULL; /* keys/values (un-serialized) */
238 CFArrayRef keys = NULL; /* keys (un-serialized) */
239 serverSessionRef mySession;
240 Boolean ok;
241 CFArrayRef patterns = NULL; /* patterns (un-serialized) */
242
243 *dataRef = NULL;
244 *dataLen = 0;
245
246 *sc_status = kSCStatusOK;
247
248 if (keysRef && (keysLen > 0)) {
249 /* un-serialize the keys */
250 if (!_SCUnserialize((CFPropertyListRef *)&keys, NULL, (void *)keysRef, keysLen)) {
251 *sc_status = kSCStatusFailed;
252 }
253 }
254
255 if (patternsRef && (patternsLen > 0)) {
256 /* un-serialize the patterns */
257 if (!_SCUnserialize((CFPropertyListRef *)&patterns, NULL, (void *)patternsRef, patternsLen)) {
258 *sc_status = kSCStatusFailed;
259 }
260 }
261
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;
274 }
275
276 mySession = getSession(server);
277 if (mySession == NULL) {
278 *sc_status = kSCStatusNoStoreSession; /* you must have an open session to play */
279 goto done;
280 }
281
282 /* fetch the requested information */
283 *sc_status = __SCDynamicStoreCopyMultiple(mySession->store, keys, patterns, &dict);
284
285 /* serialize the dictionary of matching keys/patterns */
286 ok = _SCSerialize(dict, NULL, (void **)dataRef, (CFIndex *)dataLen);
287 CFRelease(dict);
288 if (!ok) {
289 *sc_status = kSCStatusFailed;
290 }
291
292 done :
293
294 if (keys) CFRelease(keys);
295 if (patterns) CFRelease(patterns);
296 return KERN_SUCCESS;
297 }