]> git.saurik.com Git - apple/configd.git/blob - configd.tproj/_configget.c
configd-84.tar.gz
[apple/configd.git] / configd.tproj / _configget.c
1 /*
2 * Copyright (c) 2000-2003 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
7 *
8 * This file contains Original Code and/or Modifications of Original Code
9 * as defined in and that are subject to the Apple Public Source License
10 * Version 2.0 (the 'License'). You may not use this file except in
11 * compliance with the License. Please obtain a copy of the License at
12 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * file.
14 *
15 * The Original Code and all software distributed under the License are
16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20 * Please see the License for the specific language governing rights and
21 * limitations under the License.
22 *
23 * @APPLE_LICENSE_HEADER_END@
24 */
25
26 /*
27 * Modification History
28 *
29 * June 1, 2001 Allan Nathanson <ajn@apple.com>
30 * - public API conversion
31 *
32 * March 24, 2000 Allan Nathanson <ajn@apple.com>
33 * - initial revision
34 */
35
36 #include "configd.h"
37 #include "session.h"
38
39 __private_extern__
40 int
41 __SCDynamicStoreCopyValue(SCDynamicStoreRef store, CFStringRef key, CFDataRef *value, Boolean internal)
42 {
43 SCDynamicStorePrivateRef storePrivate = (SCDynamicStorePrivateRef)store;
44 CFDictionaryRef dict;
45
46 if (_configd_verbose) {
47 SCLog(TRUE, LOG_DEBUG, CFSTR("__SCDynamicStoreCopyValue:"));
48 SCLog(TRUE, LOG_DEBUG, CFSTR(" key = %@"), key);
49 }
50
51 if (!store || (storePrivate->server == MACH_PORT_NULL)) {
52 return kSCStatusNoStoreSession; /* you must have an open session to play */
53 }
54
55 if (_configd_trace) {
56 SCTrace(TRUE, _configd_trace,
57 CFSTR("%s : %5d : %@\n"),
58 internal ? "*copy " : "copy ",
59 storePrivate->server,
60 key);
61 }
62
63 dict = CFDictionaryGetValue(storeData, key);
64 if ((dict == NULL) || (CFDictionaryContainsKey(dict, kSCDData) == FALSE)) {
65 /* key doesn't exist (or data never defined) */
66 return kSCStatusNoKey;
67 }
68
69 /* Return the data associated with the key */
70 *value = CFRetain(CFDictionaryGetValue(dict, kSCDData));
71
72 if (_configd_verbose) {
73 CFPropertyListRef val;
74
75 (void) _SCUnserialize(&val, *value, NULL, NULL);
76 SCLog(TRUE, LOG_DEBUG, CFSTR(" value = %@"), val);
77 CFRelease(val);
78 }
79
80 return kSCStatusOK;
81 }
82
83 __private_extern__
84 kern_return_t
85 _configget(mach_port_t server,
86 xmlData_t keyRef, /* raw XML bytes */
87 mach_msg_type_number_t keyLen,
88 xmlDataOut_t *dataRef, /* raw XML bytes */
89 mach_msg_type_number_t *dataLen,
90 int *newInstance,
91 int *sc_status
92 )
93 {
94 CFStringRef key; /* key (un-serialized) */
95 serverSessionRef mySession = getSession(server);
96 Boolean ok;
97 CFDataRef value;
98
99 if (_configd_verbose) {
100 SCLog(TRUE, LOG_DEBUG, CFSTR("Get key from configuration database."));
101 SCLog(_configd_verbose, LOG_DEBUG, CFSTR(" server = %d"), server);
102 }
103
104 *dataRef = NULL;
105 *dataLen = 0;
106
107 /* un-serialize the key */
108 if (!_SCUnserializeString(&key, NULL, (void *)keyRef, keyLen)) {
109 *sc_status = kSCStatusFailed;
110 return KERN_SUCCESS;
111 }
112
113 if (!isA_CFString(key)) {
114 *sc_status = kSCStatusInvalidArgument;
115 CFRelease(key);
116 return KERN_SUCCESS;
117 }
118
119 if (!mySession) {
120 *sc_status = kSCStatusNoStoreSession; /* you must have an open session to play */
121 CFRelease(key);
122 return KERN_SUCCESS;
123 }
124
125 *sc_status = __SCDynamicStoreCopyValue(mySession->store, key, &value, FALSE);
126 CFRelease(key);
127 if (*sc_status != kSCStatusOK) {
128 return KERN_SUCCESS;
129 }
130
131 /* serialize the data */
132 ok = _SCSerializeData(value, (void **)dataRef, (CFIndex *)dataLen);
133 CFRelease(value);
134 if (!ok) {
135 *sc_status = kSCStatusFailed;
136 return KERN_SUCCESS;
137 }
138
139 /*
140 * return the instance number associated with the returned data.
141 */
142 *newInstance = 1;
143
144 return KERN_SUCCESS;
145 }
146
147 /*
148 * "context" argument for addSpecificKey() and addSpecificPattern()
149 */
150 typedef struct {
151 SCDynamicStoreRef store;
152 CFMutableDictionaryRef dict;
153 } addSpecific, *addSpecificRef;
154
155 static void
156 addSpecificKey(const void *value, void *context)
157 {
158 CFDataRef data;
159 CFStringRef key = (CFStringRef)value;
160 addSpecificRef myContextRef = (addSpecificRef)context;
161 int sc_status;
162
163 if (!isA_CFString(key)) {
164 return;
165 }
166
167 sc_status = __SCDynamicStoreCopyValue(myContextRef->store, key, &data, TRUE);
168 if (sc_status == kSCStatusOK) {
169 CFDictionaryAddValue(myContextRef->dict, key, data);
170 CFRelease(data);
171 }
172
173 return;
174 }
175
176 static void
177 addSpecificPattern(const void *value, void *context)
178 {
179 CFStringRef pattern = (CFStringRef)value;
180 addSpecificRef myContextRef = (addSpecificRef)context;
181 int sc_status;
182 CFArrayRef keys;
183
184 if (!isA_CFString(pattern)) {
185 return;
186 }
187
188 sc_status = __SCDynamicStoreCopyKeyList(myContextRef->store, pattern, TRUE, &keys);
189 if (sc_status == kSCStatusOK) {
190 CFArrayApplyFunction(keys,
191 CFRangeMake(0, CFArrayGetCount(keys)),
192 addSpecificKey,
193 context);
194 CFRelease(keys);
195 }
196
197 return;
198 }
199
200 __private_extern__
201 int
202 __SCDynamicStoreCopyMultiple(SCDynamicStoreRef store, CFArrayRef keys, CFArrayRef patterns, CFDictionaryRef *values)
203 {
204 SCDynamicStorePrivateRef storePrivate = (SCDynamicStorePrivateRef)store;
205 addSpecific myContext;
206
207 if (_configd_verbose) {
208 SCLog(TRUE, LOG_DEBUG, CFSTR("__SCDynamicStoreCopyMultiple:"));
209 SCLog(TRUE, LOG_DEBUG, CFSTR(" keys = %@"), keys);
210 SCLog(TRUE, LOG_DEBUG, CFSTR(" patterns = %@"), patterns);
211 }
212
213 if (!store || (storePrivate->server == MACH_PORT_NULL)) {
214 return kSCStatusNoStoreSession; /* you must have an open session to play */
215 }
216
217 if (_configd_trace) {
218 SCTrace(TRUE, _configd_trace,
219 CFSTR("copy m : %5d : %d keys, %d patterns\n"),
220 storePrivate->server,
221 keys ? CFArrayGetCount(keys) : 0,
222 patterns ? CFArrayGetCount(patterns) : 0);
223 }
224
225 myContext.store = store;
226 myContext.dict = CFDictionaryCreateMutable(NULL,
227 0,
228 &kCFTypeDictionaryKeyCallBacks,
229 &kCFTypeDictionaryValueCallBacks);
230
231 if (keys) {
232 CFArrayApplyFunction(keys,
233 CFRangeMake(0, CFArrayGetCount(keys)),
234 addSpecificKey,
235 &myContext);
236 }
237
238 if (patterns) {
239 CFArrayApplyFunction(patterns,
240 CFRangeMake(0, CFArrayGetCount(patterns)),
241 addSpecificPattern,
242 &myContext);
243 }
244
245 /* Return the keys/values associated with the key */
246 *values = myContext.dict;
247
248 if (_configd_verbose) {
249 CFDictionaryRef expDict;
250
251 expDict = _SCUnserializeMultiple(*values);
252 SCLog(TRUE, LOG_DEBUG, CFSTR(" values = %@"), expDict);
253 CFRelease(expDict);
254 }
255
256 return kSCStatusOK;
257 }
258
259 __private_extern__
260 kern_return_t
261 _configget_m(mach_port_t server,
262 xmlData_t keysRef,
263 mach_msg_type_number_t keysLen,
264 xmlData_t patternsRef,
265 mach_msg_type_number_t patternsLen,
266 xmlDataOut_t *dataRef,
267 mach_msg_type_number_t *dataLen,
268 int *sc_status)
269 {
270 CFDictionaryRef dict = NULL; /* keys/values (un-serialized) */
271 CFArrayRef keys = NULL; /* keys (un-serialized) */
272 serverSessionRef mySession = getSession(server);
273 Boolean ok;
274 CFArrayRef patterns = NULL; /* patterns (un-serialized) */
275
276 if (_configd_verbose) {
277 SCLog(TRUE, LOG_DEBUG, CFSTR("Get keys from configuration database."));
278 SCLog(TRUE, LOG_DEBUG, CFSTR(" server = %d"), server);
279 }
280
281 *dataRef = NULL;
282 *dataLen = 0;
283 *sc_status = kSCStatusOK;
284
285 if (keysRef && (keysLen > 0)) {
286 /* un-serialize the keys */
287 if (!_SCUnserialize((CFPropertyListRef *)&keys, NULL, (void *)keysRef, keysLen)) {
288 *sc_status = kSCStatusFailed;
289 }
290
291 if (!isA_CFArray(keys)) {
292 *sc_status = kSCStatusInvalidArgument;
293 }
294 }
295
296 if (patternsRef && (patternsLen > 0)) {
297 /* un-serialize the patterns */
298 if (!_SCUnserialize((CFPropertyListRef *)&patterns, NULL, (void *)patternsRef, patternsLen)) {
299 *sc_status = kSCStatusFailed;
300 }
301
302 if (!isA_CFArray(patterns)) {
303 *sc_status = kSCStatusInvalidArgument;
304 }
305 }
306
307 if (!mySession) {
308 *sc_status = kSCStatusNoStoreSession; /* you must have an open session to play */
309 }
310
311 if (*sc_status != kSCStatusOK) {
312 if (keys) CFRelease(keys);
313 if (patterns) CFRelease(patterns);
314 return KERN_SUCCESS;
315 }
316
317 *sc_status = __SCDynamicStoreCopyMultiple(mySession->store, keys, patterns, &dict);
318 if (keys) CFRelease(keys);
319 if (patterns) CFRelease(patterns);
320
321 /* serialize the dictionary of matching keys/patterns */
322 ok = _SCSerialize(dict, NULL, (void **)dataRef, (CFIndex *)dataLen);
323 CFRelease(dict);
324 if (!ok) {
325 *sc_status = kSCStatusFailed;
326 return KERN_SUCCESS;
327 }
328
329 return KERN_SUCCESS;
330 }