]> git.saurik.com Git - apple/configd.git/blob - configd.tproj/_configget.c
configd-699.1.5.tar.gz
[apple/configd.git] / configd.tproj / _configget.c
1 /*
2 * Copyright (c) 2000-2006, 2008, 2011, 2013, 2014 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 (_configd_trace) {
45 SCTrace(TRUE, _configd_trace,
46 CFSTR("%s : %5d : %@\n"),
47 internal ? "*copy " : "copy ",
48 storePrivate->server,
49 key);
50 }
51
52 dict = CFDictionaryGetValue(storeData, key);
53 if ((dict == NULL) || (CFDictionaryContainsKey(dict, kSCDData) == FALSE)) {
54 /* key doesn't exist (or data never defined) */
55 return kSCStatusNoKey;
56 }
57
58 /* Return the data associated with the key */
59 *value = CFRetain(CFDictionaryGetValue(dict, kSCDData));
60
61 return kSCStatusOK;
62 }
63
64 __private_extern__
65 kern_return_t
66 _configget(mach_port_t server,
67 xmlData_t keyRef, /* raw XML bytes */
68 mach_msg_type_number_t keyLen,
69 xmlDataOut_t *dataRef, /* raw XML bytes */
70 mach_msg_type_number_t *dataLen,
71 int *newInstance,
72 int *sc_status,
73 audit_token_t audit_token)
74 {
75 CFStringRef key = NULL; /* key (un-serialized) */
76 CFIndex len;
77 serverSessionRef mySession;
78 Boolean ok;
79 CFDataRef value;
80
81 *dataRef = NULL;
82 *dataLen = 0;
83
84 /* un-serialize the key */
85 if (!_SCUnserializeString(&key, NULL, (void *)keyRef, keyLen)) {
86 *sc_status = kSCStatusFailed;
87 goto done;
88 }
89
90 if (!isA_CFString(key)) {
91 *sc_status = kSCStatusInvalidArgument;
92 goto done;
93 }
94
95 mySession = getSession(server);
96 if (mySession == NULL) {
97 mySession = tempSession(server, CFSTR("SCDynamicStoreCopyValue"), audit_token);
98 if (mySession == NULL) {
99 /* you must have an open session to play */
100 *sc_status = kSCStatusNoStoreSession;
101 goto done;
102 }
103 }
104
105 *sc_status = __SCDynamicStoreCopyValue(mySession->store, key, &value, FALSE);
106 if (*sc_status != kSCStatusOK) {
107 goto done;
108 }
109
110 /* serialize the data */
111 ok = _SCSerializeData(value, (void **)dataRef, &len);
112 *dataLen = (mach_msg_type_number_t)len;
113 CFRelease(value);
114 if (!ok) {
115 *sc_status = kSCStatusFailed;
116 goto done;
117 }
118
119 /*
120 * return the instance number associated with the returned data.
121 */
122 *newInstance = 1;
123
124 done :
125
126 if (key != NULL) CFRelease(key);
127 return KERN_SUCCESS;
128 }
129
130 /*
131 * "context" argument for addSpecificKey() and addSpecificPattern()
132 */
133 typedef struct {
134 SCDynamicStoreRef store;
135 CFMutableDictionaryRef dict;
136 } addSpecific, *addSpecificRef;
137
138 static void
139 addSpecificKey(const void *value, void *context)
140 {
141 CFDataRef data;
142 CFStringRef key = (CFStringRef)value;
143 addSpecificRef myContextRef = (addSpecificRef)context;
144 int sc_status;
145
146 if (!isA_CFString(key)) {
147 return;
148 }
149
150 sc_status = __SCDynamicStoreCopyValue(myContextRef->store, key, &data, TRUE);
151 if (sc_status == kSCStatusOK) {
152 CFDictionaryAddValue(myContextRef->dict, key, data);
153 CFRelease(data);
154 }
155
156 return;
157 }
158
159 static void
160 addSpecificPattern(const void *value, void *context)
161 {
162 CFStringRef pattern = (CFStringRef)value;
163 addSpecificRef myContextRef = (addSpecificRef)context;
164 int sc_status;
165 CFArrayRef keys;
166
167 if (!isA_CFString(pattern)) {
168 return;
169 }
170
171 sc_status = __SCDynamicStoreCopyKeyList(myContextRef->store, pattern, TRUE, &keys);
172 if (sc_status == kSCStatusOK) {
173 CFArrayApplyFunction(keys,
174 CFRangeMake(0, CFArrayGetCount(keys)),
175 addSpecificKey,
176 context);
177 CFRelease(keys);
178 }
179
180 return;
181 }
182
183 __private_extern__
184 int
185 __SCDynamicStoreCopyMultiple(SCDynamicStoreRef store, CFArrayRef keys, CFArrayRef patterns, CFDictionaryRef *values)
186 {
187 SCDynamicStorePrivateRef storePrivate = (SCDynamicStorePrivateRef)store;
188 addSpecific myContext;
189
190 if (_configd_trace) {
191 SCTrace(TRUE, _configd_trace,
192 CFSTR("copy m : %5d : %ld keys, %ld patterns\n"),
193 storePrivate->server,
194 keys ? CFArrayGetCount(keys) : 0,
195 patterns ? CFArrayGetCount(patterns) : 0);
196 }
197
198 myContext.store = store;
199 myContext.dict = CFDictionaryCreateMutable(NULL,
200 0,
201 &kCFTypeDictionaryKeyCallBacks,
202 &kCFTypeDictionaryValueCallBacks);
203
204 if (keys) {
205 CFArrayApplyFunction(keys,
206 CFRangeMake(0, CFArrayGetCount(keys)),
207 addSpecificKey,
208 &myContext);
209 }
210
211 if (patterns) {
212 CFArrayApplyFunction(patterns,
213 CFRangeMake(0, CFArrayGetCount(patterns)),
214 addSpecificPattern,
215 &myContext);
216 }
217
218 /* Return the keys/values associated with the key */
219 *values = myContext.dict;
220
221 return kSCStatusOK;
222 }
223
224 __private_extern__
225 kern_return_t
226 _configget_m(mach_port_t server,
227 xmlData_t keysRef,
228 mach_msg_type_number_t keysLen,
229 xmlData_t patternsRef,
230 mach_msg_type_number_t patternsLen,
231 xmlDataOut_t *dataRef,
232 mach_msg_type_number_t *dataLen,
233 int *sc_status,
234 audit_token_t audit_token)
235 {
236 CFDictionaryRef dict = NULL; /* keys/values (un-serialized) */
237 CFArrayRef keys = NULL; /* keys (un-serialized) */
238 CFIndex len;
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 mySession = tempSession(server, CFSTR("SCDynamicStoreCopyMultiple"), audit_token);
279 if (mySession == NULL) {
280 /* you must have an open session to play */
281 *sc_status = kSCStatusNoStoreSession;
282 goto done;
283 }
284 }
285
286 /* fetch the requested information */
287 *sc_status = __SCDynamicStoreCopyMultiple(mySession->store, keys, patterns, &dict);
288
289 /* serialize the dictionary of matching keys/patterns */
290 ok = _SCSerialize(dict, NULL, (void **)dataRef, &len);
291 *dataLen = (mach_msg_type_number_t)len;
292 CFRelease(dict);
293 if (!ok) {
294 *sc_status = kSCStatusFailed;
295 }
296
297 done :
298
299 if (keys) CFRelease(keys);
300 if (patterns) CFRelease(patterns);
301 return KERN_SUCCESS;
302 }