]> git.saurik.com Git - apple/configd.git/blob - configd.tproj/_configget.c
fa889fe3f32635faf73b9b5909e50f7f3004089b
[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 * 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 (_configd_verbose) {
45 SCLog(TRUE, LOG_DEBUG, CFSTR("__SCDynamicStoreCopyValue:"));
46 SCLog(TRUE, LOG_DEBUG, CFSTR(" key = %@"), key);
47 }
48
49 if (!store || (storePrivate->server == MACH_PORT_NULL)) {
50 return kSCStatusNoStoreSession; /* you must have an open session to play */
51 }
52
53 if (_configd_trace) {
54 SCTrace(TRUE, _configd_trace,
55 CFSTR("%s : %5d : %@\n"),
56 internal ? "*copy " : "copy ",
57 storePrivate->server,
58 key);
59 }
60
61 dict = CFDictionaryGetValue(storeData, key);
62 if ((dict == NULL) || (CFDictionaryContainsKey(dict, kSCDData) == FALSE)) {
63 /* key doesn't exist (or data never defined) */
64 return kSCStatusNoKey;
65 }
66
67 /* Return the data associated with the key */
68 *value = CFRetain(CFDictionaryGetValue(dict, kSCDData));
69
70 if (_configd_verbose) {
71 CFPropertyListRef val;
72
73 (void) _SCUnserialize(&val, *value, NULL, NULL);
74 SCLog(TRUE, LOG_DEBUG, CFSTR(" value = %@"), val);
75 CFRelease(val);
76 }
77
78 return kSCStatusOK;
79 }
80
81 __private_extern__
82 kern_return_t
83 _configget(mach_port_t server,
84 xmlData_t keyRef, /* raw XML bytes */
85 mach_msg_type_number_t keyLen,
86 xmlDataOut_t *dataRef, /* raw XML bytes */
87 mach_msg_type_number_t *dataLen,
88 int *newInstance,
89 int *sc_status
90 )
91 {
92 CFStringRef key; /* key (un-serialized) */
93 serverSessionRef mySession = getSession(server);
94 Boolean ok;
95 CFDataRef value;
96
97 if (_configd_verbose) {
98 SCLog(TRUE, LOG_DEBUG, CFSTR("Get key from configuration database."));
99 SCLog(_configd_verbose, LOG_DEBUG, CFSTR(" server = %d"), server);
100 }
101
102 *dataRef = NULL;
103 *dataLen = 0;
104
105 /* un-serialize the key */
106 if (!_SCUnserializeString(&key, NULL, (void *)keyRef, keyLen)) {
107 *sc_status = kSCStatusFailed;
108 return KERN_SUCCESS;
109 }
110
111 if (!isA_CFString(key)) {
112 *sc_status = kSCStatusInvalidArgument;
113 CFRelease(key);
114 return KERN_SUCCESS;
115 }
116
117 if (!mySession) {
118 *sc_status = kSCStatusNoStoreSession; /* you must have an open session to play */
119 CFRelease(key);
120 return KERN_SUCCESS;
121 }
122
123 *sc_status = __SCDynamicStoreCopyValue(mySession->store, key, &value, FALSE);
124 CFRelease(key);
125 if (*sc_status != kSCStatusOK) {
126 return KERN_SUCCESS;
127 }
128
129 /* serialize the data */
130 ok = _SCSerializeData(value, (void **)dataRef, (CFIndex *)dataLen);
131 CFRelease(value);
132 if (!ok) {
133 *sc_status = kSCStatusFailed;
134 return KERN_SUCCESS;
135 }
136
137 /*
138 * return the instance number associated with the returned data.
139 */
140 *newInstance = 1;
141
142 return KERN_SUCCESS;
143 }
144
145 /*
146 * "context" argument for addSpecificKey() and addSpecificPattern()
147 */
148 typedef struct {
149 SCDynamicStoreRef store;
150 CFMutableDictionaryRef dict;
151 } addSpecific, *addSpecificRef;
152
153 static void
154 addSpecificKey(const void *value, void *context)
155 {
156 CFDataRef data;
157 CFStringRef key = (CFStringRef)value;
158 addSpecificRef myContextRef = (addSpecificRef)context;
159 int sc_status;
160
161 if (!isA_CFString(key)) {
162 return;
163 }
164
165 sc_status = __SCDynamicStoreCopyValue(myContextRef->store, key, &data, TRUE);
166 if (sc_status == kSCStatusOK) {
167 CFDictionaryAddValue(myContextRef->dict, key, data);
168 CFRelease(data);
169 }
170
171 return;
172 }
173
174 static void
175 addSpecificPattern(const void *value, void *context)
176 {
177 CFStringRef pattern = (CFStringRef)value;
178 addSpecificRef myContextRef = (addSpecificRef)context;
179 int sc_status;
180 CFArrayRef keys;
181
182 if (!isA_CFString(pattern)) {
183 return;
184 }
185
186 sc_status = __SCDynamicStoreCopyKeyList(myContextRef->store, pattern, TRUE, &keys);
187 if (sc_status == kSCStatusOK) {
188 CFArrayApplyFunction(keys,
189 CFRangeMake(0, CFArrayGetCount(keys)),
190 addSpecificKey,
191 context);
192 CFRelease(keys);
193 }
194
195 return;
196 }
197
198 __private_extern__
199 int
200 __SCDynamicStoreCopyMultiple(SCDynamicStoreRef store, CFArrayRef keys, CFArrayRef patterns, CFDictionaryRef *values)
201 {
202 SCDynamicStorePrivateRef storePrivate = (SCDynamicStorePrivateRef)store;
203 addSpecific myContext;
204
205 if (_configd_verbose) {
206 SCLog(TRUE, LOG_DEBUG, CFSTR("__SCDynamicStoreCopyMultiple:"));
207 SCLog(TRUE, LOG_DEBUG, CFSTR(" keys = %@"), keys);
208 SCLog(TRUE, LOG_DEBUG, CFSTR(" patterns = %@"), patterns);
209 }
210
211 if (!store || (storePrivate->server == MACH_PORT_NULL)) {
212 return kSCStatusNoStoreSession; /* you must have an open session to play */
213 }
214
215 if (_configd_trace) {
216 SCTrace(TRUE, _configd_trace,
217 CFSTR("copy m : %5d : %d keys, %d patterns\n"),
218 storePrivate->server,
219 keys ? CFArrayGetCount(keys) : 0,
220 patterns ? CFArrayGetCount(patterns) : 0);
221 }
222
223 myContext.store = store;
224 myContext.dict = CFDictionaryCreateMutable(NULL,
225 0,
226 &kCFTypeDictionaryKeyCallBacks,
227 &kCFTypeDictionaryValueCallBacks);
228
229 if (keys) {
230 CFArrayApplyFunction(keys,
231 CFRangeMake(0, CFArrayGetCount(keys)),
232 addSpecificKey,
233 &myContext);
234 }
235
236 if (patterns) {
237 CFArrayApplyFunction(patterns,
238 CFRangeMake(0, CFArrayGetCount(patterns)),
239 addSpecificPattern,
240 &myContext);
241 }
242
243 /* Return the keys/values associated with the key */
244 *values = myContext.dict;
245
246 if (_configd_verbose) {
247 CFDictionaryRef expDict;
248
249 expDict = _SCUnserializeMultiple(*values);
250 SCLog(TRUE, LOG_DEBUG, CFSTR(" values = %@"), expDict);
251 CFRelease(expDict);
252 }
253
254 return kSCStatusOK;
255 }
256
257 __private_extern__
258 kern_return_t
259 _configget_m(mach_port_t server,
260 xmlData_t keysRef,
261 mach_msg_type_number_t keysLen,
262 xmlData_t patternsRef,
263 mach_msg_type_number_t patternsLen,
264 xmlDataOut_t *dataRef,
265 mach_msg_type_number_t *dataLen,
266 int *sc_status)
267 {
268 CFDictionaryRef dict = NULL; /* keys/values (un-serialized) */
269 CFArrayRef keys = NULL; /* keys (un-serialized) */
270 serverSessionRef mySession = getSession(server);
271 Boolean ok;
272 CFArrayRef patterns = NULL; /* patterns (un-serialized) */
273
274 if (_configd_verbose) {
275 SCLog(TRUE, LOG_DEBUG, CFSTR("Get keys from configuration database."));
276 SCLog(TRUE, LOG_DEBUG, CFSTR(" server = %d"), server);
277 }
278
279 *dataRef = NULL;
280 *dataLen = 0;
281 *sc_status = kSCStatusOK;
282
283 if (keysRef && (keysLen > 0)) {
284 /* un-serialize the keys */
285 if (!_SCUnserialize((CFPropertyListRef *)&keys, NULL, (void *)keysRef, keysLen)) {
286 *sc_status = kSCStatusFailed;
287 }
288
289 if (!isA_CFArray(keys)) {
290 *sc_status = kSCStatusInvalidArgument;
291 }
292 }
293
294 if (patternsRef && (patternsLen > 0)) {
295 /* un-serialize the patterns */
296 if (!_SCUnserialize((CFPropertyListRef *)&patterns, NULL, (void *)patternsRef, patternsLen)) {
297 *sc_status = kSCStatusFailed;
298 }
299
300 if (!isA_CFArray(patterns)) {
301 *sc_status = kSCStatusInvalidArgument;
302 }
303 }
304
305 if (!mySession) {
306 *sc_status = kSCStatusNoStoreSession; /* you must have an open session to play */
307 }
308
309 if (*sc_status != kSCStatusOK) {
310 if (keys) CFRelease(keys);
311 if (patterns) CFRelease(patterns);
312 return KERN_SUCCESS;
313 }
314
315 *sc_status = __SCDynamicStoreCopyMultiple(mySession->store, keys, patterns, &dict);
316 if (keys) CFRelease(keys);
317 if (patterns) CFRelease(patterns);
318
319 /* serialize the dictionary of matching keys/patterns */
320 ok = _SCSerialize(dict, NULL, (void **)dataRef, (CFIndex *)dataLen);
321 CFRelease(dict);
322 if (!ok) {
323 *sc_status = kSCStatusFailed;
324 return KERN_SUCCESS;
325 }
326
327 return KERN_SUCCESS;
328 }