]> git.saurik.com Git - apple/configd.git/blob - configd.tproj/_configlist.c
configd-24.tar.gz
[apple/configd.git] / configd.tproj / _configlist.c
1 /*
2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
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.
11 *
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
18 * under the License.
19 *
20 * @APPLE_LICENSE_HEADER_END@
21 */
22
23 #include "configd.h"
24 #include "session.h"
25
26 SCDStatus
27 _SCDList(SCDSessionRef session, CFStringRef key, int regexOptions, CFArrayRef *subKeys)
28 {
29 SCDSessionPrivateRef sessionPrivate = (SCDSessionPrivateRef)session;
30 CFIndex cacheCnt;
31 void **cacheKeys;
32 void **cacheValues;
33 CFMutableArrayRef keyArray;
34 int i;
35 CFStringRef cacheStr;
36 CFDictionaryRef cacheValue;
37 int regexStrLen;
38 char *regexStr = NULL;
39 regex_t preg;
40 int reError;
41 char reErrBuf[256];
42 int reErrStrLen;
43
44 SCDLog(LOG_DEBUG, CFSTR("_SCDList:"));
45 SCDLog(LOG_DEBUG, CFSTR(" key = %@"), key);
46 SCDLog(LOG_DEBUG, CFSTR(" regexOptions = %0o"), regexOptions);
47
48 if ((session == NULL) || (sessionPrivate->server == MACH_PORT_NULL)) {
49 return SCD_NOSESSION;
50 }
51
52 cacheCnt = CFDictionaryGetCount(cacheData);
53 keyArray = CFArrayCreateMutable(NULL, cacheCnt, &kCFTypeArrayCallBacks);
54
55 if (regexOptions & kSCDRegexKey) {
56 /*
57 * compile the provided regular expression using the
58 * provided regexOptions (passing only those flags
59 * which would make sense).
60 */
61 regexStrLen = CFStringGetLength(key) + 1;
62 regexStr = CFAllocatorAllocate(NULL, regexStrLen, 0);
63 if (!CFStringGetCString(key,
64 regexStr,
65 regexStrLen,
66 kCFStringEncodingMacRoman)) {
67 SCDLog(LOG_DEBUG, CFSTR("CFStringGetCString() key: could not convert to regex string"));
68 CFAllocatorDeallocate(NULL, regexStr);
69 return SCD_FAILED;
70 }
71
72 reError = regcomp(&preg, regexStr, REG_EXTENDED);
73 if (reError != 0) {
74 reErrStrLen = regerror(reError, &preg, reErrBuf, sizeof(reErrBuf));
75 cacheStr = CFStringCreateWithCString(NULL, reErrBuf, kCFStringEncodingMacRoman);
76 CFArrayAppendValue(keyArray, cacheStr);
77 CFRelease(cacheStr);
78 *subKeys = CFArrayCreateCopy(NULL, keyArray);
79 CFRelease(keyArray);
80 CFAllocatorDeallocate(NULL, regexStr);
81 return SCD_FAILED;
82 }
83 }
84
85 cacheKeys = CFAllocatorAllocate(NULL, cacheCnt * sizeof(CFStringRef), 0);
86 cacheValues = CFAllocatorAllocate(NULL, cacheCnt * sizeof(CFStringRef), 0);
87 CFDictionaryGetKeysAndValues(cacheData, cacheKeys, cacheValues);
88 for (i=0; i<cacheCnt; i++) {
89 cacheStr = (CFStringRef)cacheKeys[i];
90 cacheValue = (CFDictionaryRef)cacheValues[i];
91 if (regexOptions & kSCDRegexKey) {
92 /*
93 * only return those keys which match the regular
94 * expression specified in the provided key.
95 */
96
97 int cacheKeyLen = CFStringGetLength(cacheStr) + 1;
98 char *cacheKey = CFAllocatorAllocate(NULL, cacheKeyLen, 0);
99
100 if (!CFStringGetCString(cacheStr,
101 cacheKey,
102 cacheKeyLen,
103 kCFStringEncodingMacRoman)) {
104 SCDLog(LOG_DEBUG, CFSTR("CFStringGetCString: could not convert cache key to C string"));
105 CFAllocatorDeallocate(NULL, cacheKey);
106 continue;
107 }
108
109 reError = regexec(&preg,
110 cacheKey,
111 0,
112 NULL,
113 0);
114 switch (reError) {
115 case 0 :
116 /* we've got a match */
117 if (CFDictionaryContainsKey(cacheValue, kSCDData))
118 CFArrayAppendValue(keyArray, cacheStr);
119 break;
120 case REG_NOMATCH :
121 /* no match */
122 break;
123 default :
124 reErrStrLen = regerror(reError,
125 &preg,
126 reErrBuf,
127 sizeof(reErrBuf));
128 SCDLog(LOG_DEBUG, CFSTR("regexec(): %s"), reErrBuf);
129 break;
130 }
131 CFAllocatorDeallocate(NULL, cacheKey);
132 } else {
133 /*
134 * only return those keys which are prefixed by the
135 * provided key string and have data.
136 */
137 if (((CFStringGetLength(key) == 0) || CFStringHasPrefix(cacheStr, key)) &&
138 CFDictionaryContainsKey(cacheValue, kSCDData)) {
139 CFArrayAppendValue(keyArray, cacheStr);
140 }
141 }
142 }
143 CFAllocatorDeallocate(NULL, cacheKeys);
144 CFAllocatorDeallocate(NULL, cacheValues);
145
146 if (regexOptions & kSCDRegexKey) {
147 regfree(&preg);
148 }
149
150 *subKeys = keyArray;
151
152 if (regexOptions & kSCDRegexKey) {
153 CFAllocatorDeallocate(NULL, regexStr);
154 }
155
156 return SCD_OK;
157 }
158
159
160 kern_return_t
161 _configlist(mach_port_t server,
162 xmlData_t keyRef, /* raw XML bytes */
163 mach_msg_type_number_t keyLen,
164 int regexOptions,
165 xmlDataOut_t *listRef, /* raw XML bytes */
166 mach_msg_type_number_t *listLen,
167 int *scd_status
168 )
169 {
170 kern_return_t status;
171 serverSessionRef mySession = getSession(server);
172 CFDataRef xmlKey; /* key (XML serialized) */
173 CFStringRef key; /* key (un-serialized) */
174 CFArrayRef subKeys; /* array of CFStringRef's */
175 CFDataRef xmlList; /* list (XML serialized) */
176 CFStringRef xmlError;
177
178 SCDLog(LOG_DEBUG, CFSTR("List keys in configuration database."));
179 SCDLog(LOG_DEBUG, CFSTR(" server = %d"), server);
180
181 /* un-serialize the key */
182 xmlKey = CFDataCreate(NULL, keyRef, keyLen);
183 status = vm_deallocate(mach_task_self(), (vm_address_t)keyRef, keyLen);
184 if (status != KERN_SUCCESS) {
185 SCDLog(LOG_DEBUG, CFSTR("vm_deallocate(): %s"), mach_error_string(status));
186 /* non-fatal???, proceed */
187 }
188 key = CFPropertyListCreateFromXMLData(NULL,
189 xmlKey,
190 kCFPropertyListImmutable,
191 &xmlError);
192 CFRelease(xmlKey);
193 if (xmlError) {
194 SCDLog(LOG_DEBUG, CFSTR("CFPropertyListCreateFromXMLData() key: %s"), xmlError);
195 *scd_status = SCD_FAILED;
196 return KERN_SUCCESS;
197 }
198
199 *scd_status = _SCDList(mySession->session, key, regexOptions, &subKeys);
200 CFRelease(key);
201 if (*scd_status != SCD_OK) {
202 *listRef = NULL;
203 *listLen = 0;
204 return KERN_SUCCESS;
205 }
206
207 /*
208 * serialize the array, copy it into an allocated buffer which will be
209 * released when it is returned as part of a Mach message.
210 */
211 xmlList = CFPropertyListCreateXMLData(NULL, subKeys);
212 CFRelease(subKeys);
213 *listLen = CFDataGetLength(xmlList);
214 status = vm_allocate(mach_task_self(), (void *)listRef, *listLen, TRUE);
215 if (status != KERN_SUCCESS) {
216 SCDLog(LOG_DEBUG, CFSTR("vm_allocate(): %s"), mach_error_string(status));
217 *scd_status = SCD_FAILED;
218 CFRelease(xmlList);
219 *listRef = NULL;
220 *listLen = 0;
221 return KERN_SUCCESS;
222 }
223 bcopy((char *)CFDataGetBytePtr(xmlList), *listRef, *listLen);
224 CFRelease(xmlList);
225
226 return KERN_SUCCESS;
227 }