2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
20 * @APPLE_LICENSE_HEADER_END@
24 * Modification History
26 * June 1, 2001 Allan Nathanson <ajn@apple.com>
27 * - public API conversion
29 * March 24, 2000 Allan Nathanson <ajn@apple.com>
37 __SCDynamicStoreCopyValue(SCDynamicStoreRef store
, CFStringRef key
, CFPropertyListRef
*value
)
39 SCDynamicStorePrivateRef storePrivate
= (SCDynamicStorePrivateRef
)store
;
42 SCLog(_configd_verbose
, LOG_DEBUG
, CFSTR("__SCDynamicStoreCopyValue:"));
43 SCLog(_configd_verbose
, LOG_DEBUG
, CFSTR(" key = %@"), key
);
45 if (!store
|| (storePrivate
->server
== MACH_PORT_NULL
)) {
46 return kSCStatusNoStoreSession
; /* you must have an open session to play */
49 dict
= CFDictionaryGetValue(storeData
, key
);
50 if ((dict
== NULL
) || (CFDictionaryContainsKey(dict
, kSCDData
) == FALSE
)) {
51 /* key doesn't exist (or data never defined) */
52 return kSCStatusNoKey
;
55 /* Return the data associated with the key */
56 *value
= CFRetain(CFDictionaryGetValue(dict
, kSCDData
));
58 SCLog(_configd_verbose
, LOG_DEBUG
, CFSTR(" value = %@"), *value
);
64 _configget(mach_port_t server
,
65 xmlData_t keyRef
, /* raw XML bytes */
66 mach_msg_type_number_t keyLen
,
67 xmlDataOut_t
*dataRef
, /* raw XML bytes */
68 mach_msg_type_number_t
*dataLen
,
74 serverSessionRef mySession
= getSession(server
);
75 CFDataRef xmlKey
; /* key (XML serialized) */
76 CFStringRef key
; /* key (un-serialized) */
77 CFDataRef xmlData
; /* data (XML serialized) */
78 CFPropertyListRef value
;
81 SCLog(_configd_verbose
, LOG_DEBUG
, CFSTR("Get key from configuration database."));
82 SCLog(_configd_verbose
, LOG_DEBUG
, CFSTR(" server = %d"), server
);
84 /* un-serialize the key */
85 xmlKey
= CFDataCreate(NULL
, keyRef
, keyLen
);
86 status
= vm_deallocate(mach_task_self(), (vm_address_t
)keyRef
, keyLen
);
87 if (status
!= KERN_SUCCESS
) {
88 SCLog(_configd_verbose
, LOG_DEBUG
, CFSTR("vm_deallocate(): %s"), mach_error_string(status
));
89 /* non-fatal???, proceed */
91 key
= CFPropertyListCreateFromXMLData(NULL
,
93 kCFPropertyListImmutable
,
98 SCLog(_configd_verbose
, LOG_DEBUG
,
99 CFSTR("CFPropertyListCreateFromXMLData() key: %@"),
103 *sc_status
= kSCStatusFailed
;
105 } else if (!isA_CFString(key
)) {
106 *sc_status
= kSCStatusInvalidArgument
;
110 *sc_status
= __SCDynamicStoreCopyValue(mySession
->store
, key
, &value
);
112 if (*sc_status
!= kSCStatusOK
) {
119 * serialize the data, copy it into an allocated buffer which will be
120 * released when it is returned as part of a Mach message.
122 xmlData
= CFPropertyListCreateXMLData(NULL
, value
);
124 *dataLen
= CFDataGetLength(xmlData
);
125 status
= vm_allocate(mach_task_self(), (void *)dataRef
, *dataLen
, TRUE
);
126 if (status
!= KERN_SUCCESS
) {
127 SCLog(_configd_verbose
, LOG_DEBUG
, CFSTR("vm_allocate(): %s"), mach_error_string(status
));
128 *sc_status
= kSCStatusFailed
;
135 bcopy((char *)CFDataGetBytePtr(xmlData
), *dataRef
, *dataLen
);
139 * return the instance number associated with the returned data.
147 * "context" argument for addSpecificKey() and addSpecificPattern()
150 SCDynamicStoreRef store
;
151 CFMutableDictionaryRef dict
;
152 } addSpecific
, *addSpecificRef
;
155 addSpecificKey(const void *value
, void *context
)
157 CFStringRef key
= (CFStringRef
)value
;
158 addSpecificRef myContextRef
= (addSpecificRef
)context
;
160 CFPropertyListRef data
;
162 if (!isA_CFString(key
)) {
166 sc_status
= __SCDynamicStoreCopyValue(myContextRef
->store
, key
, &data
);
167 if (sc_status
== kSCStatusOK
) {
168 CFDictionaryAddValue(myContextRef
->dict
, key
, data
);
176 addSpecificPattern(const void *value
, void *context
)
178 CFStringRef pattern
= (CFStringRef
)value
;
179 addSpecificRef myContextRef
= (addSpecificRef
)context
;
183 if (!isA_CFString(pattern
)) {
187 sc_status
= __SCDynamicStoreCopyKeyList(myContextRef
->store
, pattern
, TRUE
, &keys
);
188 if (sc_status
== kSCStatusOK
) {
189 CFArrayApplyFunction(keys
,
190 CFRangeMake(0, CFArrayGetCount(keys
)),
200 _configget_m(mach_port_t server
,
202 mach_msg_type_number_t keysLen
,
203 xmlData_t patternsRef
,
204 mach_msg_type_number_t patternsLen
,
205 xmlDataOut_t
*dataRef
,
206 mach_msg_type_number_t
*dataLen
,
209 kern_return_t status
;
210 serverSessionRef mySession
= getSession(server
);
211 CFArrayRef keys
= NULL
; /* keys (un-serialized) */
212 CFArrayRef patterns
= NULL
; /* patterns (un-serialized) */
213 CFDataRef xmlData
; /* data (XML serialized) */
214 addSpecific myContext
;
216 SCLog(_configd_verbose
, LOG_DEBUG
, CFSTR("Get key from configuration database."));
217 SCLog(_configd_verbose
, LOG_DEBUG
, CFSTR(" server = %d"), server
);
219 *sc_status
= kSCStatusOK
;
221 if (keysRef
&& (keysLen
> 0)) {
222 CFDataRef xmlKeys
; /* keys (XML serialized) */
223 CFStringRef xmlError
;
225 /* un-serialize the keys */
226 xmlKeys
= CFDataCreate(NULL
, keysRef
, keysLen
);
227 status
= vm_deallocate(mach_task_self(), (vm_address_t
)keysRef
, keysLen
);
228 if (status
!= KERN_SUCCESS
) {
229 SCLog(_configd_verbose
, LOG_DEBUG
, CFSTR("vm_deallocate(): %s"), mach_error_string(status
));
230 /* non-fatal???, proceed */
232 keys
= CFPropertyListCreateFromXMLData(NULL
,
234 kCFPropertyListImmutable
,
239 SCLog(_configd_verbose
, LOG_DEBUG
,
240 CFSTR("CFPropertyListCreateFromXMLData() keys: %@"),
244 *sc_status
= kSCStatusFailed
;
245 } else if (!isA_CFArray(keys
)) {
246 *sc_status
= kSCStatusInvalidArgument
;
250 if (patternsRef
&& (patternsLen
> 0)) {
251 CFDataRef xmlPatterns
; /* patterns (XML serialized) */
252 CFStringRef xmlError
;
254 /* un-serialize the patterns */
255 xmlPatterns
= CFDataCreate(NULL
, patternsRef
, patternsLen
);
256 status
= vm_deallocate(mach_task_self(), (vm_address_t
)patternsRef
, patternsLen
);
257 if (status
!= KERN_SUCCESS
) {
258 SCLog(_configd_verbose
, LOG_DEBUG
, CFSTR("vm_deallocate(): %s"), mach_error_string(status
));
259 /* non-fatal???, proceed */
261 patterns
= CFPropertyListCreateFromXMLData(NULL
,
263 kCFPropertyListImmutable
,
265 CFRelease(xmlPatterns
);
268 SCLog(_configd_verbose
, LOG_DEBUG
,
269 CFSTR("CFPropertyListCreateFromXMLData() patterns: %@"),
273 *sc_status
= kSCStatusFailed
;
274 } else if (!isA_CFArray(patterns
)) {
275 *sc_status
= kSCStatusInvalidArgument
;
279 if (*sc_status
!= kSCStatusOK
) {
280 if (keys
) CFRelease(keys
);
281 if (patterns
) CFRelease(patterns
);
287 myContext
.store
= mySession
->store
;
288 myContext
.dict
= CFDictionaryCreateMutable(NULL
,
290 &kCFTypeDictionaryKeyCallBacks
,
291 &kCFTypeDictionaryValueCallBacks
);
294 CFArrayApplyFunction(keys
,
295 CFRangeMake(0, CFArrayGetCount(keys
)),
302 CFArrayApplyFunction(patterns
,
303 CFRangeMake(0, CFArrayGetCount(patterns
)),
310 * serialize the dictionary of matching keys/patterns, copy it into an
311 * allocated buffer which will be released when it is returned as part
314 xmlData
= CFPropertyListCreateXMLData(NULL
, myContext
.dict
);
315 CFRelease(myContext
.dict
);
316 *dataLen
= CFDataGetLength(xmlData
);
317 status
= vm_allocate(mach_task_self(), (void *)dataRef
, *dataLen
, TRUE
);
318 if (status
!= KERN_SUCCESS
) {
319 SCLog(_configd_verbose
, LOG_DEBUG
, CFSTR("vm_allocate(): %s"), mach_error_string(status
));
320 *sc_status
= kSCStatusFailed
;
327 bcopy((char *)CFDataGetBytePtr(xmlData
), *dataRef
, *dataLen
);