]> git.saurik.com Git - apple/configd.git/blame - configd.tproj/_configlist.c
configd-53.1.tar.gz
[apple/configd.git] / configd.tproj / _configlist.c
CommitLineData
5958d7c0 1/*
a5f60add 2 * Copyright (c) 2000-2002 Apple Computer, Inc. All rights reserved.
5958d7c0
A
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
0fae82ee
A
23/*
24 * Modification History
25 *
26 * June 1, 2001 Allan Nathanson <ajn@apple.com>
27 * - public API conversion
28 *
29 * March 24, 2000 Allan Nathanson <ajn@apple.com>
30 * - initial revision
31 */
32
5958d7c0
A
33#include "configd.h"
34#include "session.h"
35
0fae82ee
A
36int
37__SCDynamicStoreCopyKeyList(SCDynamicStoreRef store, CFStringRef key, Boolean isRegex, CFArrayRef *subKeys)
5958d7c0 38{
0fae82ee
A
39 SCDynamicStorePrivateRef storePrivate = (SCDynamicStorePrivateRef)store;
40 CFIndex storeCnt;
a5f60add
A
41 const void **storeKeys;
42 const void **storeValues;
0fae82ee
A
43 CFMutableArrayRef keyArray;
44 int i;
45 CFStringRef storeStr;
46 CFDictionaryRef storeValue;
47 int regexBufLen;
48 char *regexBuf = NULL;
49 regex_t preg;
50 int reError;
51 char reErrBuf[256];
52 int reErrStrLen;
53
54 SCLog(_configd_verbose, LOG_DEBUG, CFSTR("__SCDynamicStoreCopyKeyList:"));
55 SCLog(_configd_verbose, LOG_DEBUG, CFSTR(" key = %@"), key);
56 SCLog(_configd_verbose, LOG_DEBUG, CFSTR(" isRegex = %s"), isRegex ? "TRUE" : "FALSE");
57
58 if (!store || (storePrivate->server == MACH_PORT_NULL)) {
59 return kSCStatusNoStoreSession; /* you must have an open session to play */
5958d7c0
A
60 }
61
0fae82ee
A
62 storeCnt = CFDictionaryGetCount(storeData);
63 keyArray = CFArrayCreateMutable(NULL, storeCnt, &kCFTypeArrayCallBacks);
64
65 if (isRegex) {
66 UniChar ch_s = 0;
67 UniChar ch_e = 0;
68 Boolean ok;
69 CFIndex regexLen;
70 CFMutableStringRef regexStr;
71
72 regexStr = CFStringCreateMutableCopy(NULL, 0, key);
73 regexLen = CFStringGetLength(regexStr);
74 if (regexLen > 0) {
75 ch_s = CFStringGetCharacterAtIndex(regexStr, 0);
76 ch_e = CFStringGetCharacterAtIndex(regexStr, regexLen - 1);
77 }
78 if ((regexLen == 0) || ((ch_s != (UniChar)'^') && (ch_e != (UniChar)'$'))) {
79 /* if regex pattern is not already bounded */
80 CFStringInsert(regexStr, 0, CFSTR("^"));
81 CFStringAppend(regexStr, CFSTR("$"));
82 }
5958d7c0 83
5958d7c0
A
84 /*
85 * compile the provided regular expression using the
0fae82ee 86 * provided isRegex.
5958d7c0 87 */
a5f60add 88 regexBufLen = CFStringGetLength(regexStr) + 1;
0fae82ee
A
89 regexBuf = CFAllocatorAllocate(NULL, regexBufLen, 0);
90 ok = CFStringGetCString(regexStr, regexBuf, regexBufLen, kCFStringEncodingMacRoman);
91 CFRelease(regexStr);
92 if (!ok) {
93 SCLog(_configd_verbose, LOG_DEBUG, CFSTR("CFStringGetCString() key: could not convert to regex string"));
94 CFAllocatorDeallocate(NULL, regexBuf);
95 return kSCStatusFailed;
5958d7c0
A
96 }
97
0fae82ee 98 reError = regcomp(&preg, regexBuf, REG_EXTENDED);
5958d7c0
A
99 if (reError != 0) {
100 reErrStrLen = regerror(reError, &preg, reErrBuf, sizeof(reErrBuf));
0fae82ee
A
101 storeStr = CFStringCreateWithCString(NULL, reErrBuf, kCFStringEncodingMacRoman);
102 CFArrayAppendValue(keyArray, storeStr);
103 CFRelease(storeStr);
5958d7c0
A
104 *subKeys = CFArrayCreateCopy(NULL, keyArray);
105 CFRelease(keyArray);
0fae82ee
A
106 CFAllocatorDeallocate(NULL, regexBuf);
107 return kSCStatusFailed;
5958d7c0
A
108 }
109 }
110
a5f60add
A
111 if (storeCnt > 0) {
112 storeKeys = CFAllocatorAllocate(NULL, storeCnt * sizeof(CFStringRef), 0);
113 storeValues = CFAllocatorAllocate(NULL, storeCnt * sizeof(CFStringRef), 0);
114 CFDictionaryGetKeysAndValues(storeData, storeKeys, storeValues);
115 for (i=0; i<storeCnt; i++) {
116 storeStr = (CFStringRef)storeKeys[i];
117 storeValue = (CFDictionaryRef)storeValues[i];
118 if (isRegex) {
119 /*
120 * only return those keys which match the regular
121 * expression specified in the provided key.
122 */
123
124 int storeKeyLen = CFStringGetLength(storeStr) + 1;
125 char *storeKey = CFAllocatorAllocate(NULL, storeKeyLen, 0);
126
127 if (!CFStringGetCString(storeStr,
128 storeKey,
129 storeKeyLen,
130 kCFStringEncodingMacRoman)) {
131 SCLog(_configd_verbose, LOG_DEBUG, CFSTR("CFStringGetCString: could not convert store key to C string"));
132 CFAllocatorDeallocate(NULL, storeKey);
133 continue;
134 }
135
136 reError = regexec(&preg,
137 storeKey,
138 0,
139 NULL,
140 0);
141 switch (reError) {
142 case 0 :
143 /* we've got a match */
144 if (CFDictionaryContainsKey(storeValue, kSCDData))
145 CFArrayAppendValue(keyArray, storeStr);
146 break;
147 case REG_NOMATCH :
148 /* no match */
149 break;
150 default :
151 reErrStrLen = regerror(reError,
152 &preg,
153 reErrBuf,
154 sizeof(reErrBuf));
155 SCLog(_configd_verbose, LOG_DEBUG, CFSTR("regexec(): %s"), reErrBuf);
156 break;
157 }
0fae82ee 158 CFAllocatorDeallocate(NULL, storeKey);
a5f60add
A
159 } else {
160 /*
161 * only return those keys which are prefixed by the
162 * provided key string and have data.
163 */
164 if (((CFStringGetLength(key) == 0) || CFStringHasPrefix(storeStr, key)) &&
165 CFDictionaryContainsKey(storeValue, kSCDData)) {
166 CFArrayAppendValue(keyArray, storeStr);
167 }
5958d7c0
A
168 }
169 }
a5f60add
A
170 CFAllocatorDeallocate(NULL, storeKeys);
171 CFAllocatorDeallocate(NULL, storeValues);
5958d7c0 172 }
5958d7c0 173
0fae82ee 174 if (isRegex) {
5958d7c0 175 regfree(&preg);
0fae82ee 176 CFAllocatorDeallocate(NULL, regexBuf);
5958d7c0
A
177 }
178
179 *subKeys = keyArray;
180
0fae82ee 181 return kSCStatusOK;
5958d7c0
A
182}
183
184
185kern_return_t
186_configlist(mach_port_t server,
187 xmlData_t keyRef, /* raw XML bytes */
188 mach_msg_type_number_t keyLen,
0fae82ee 189 int isRegex,
5958d7c0
A
190 xmlDataOut_t *listRef, /* raw XML bytes */
191 mach_msg_type_number_t *listLen,
0fae82ee 192 int *sc_status
5958d7c0
A
193)
194{
5958d7c0 195 CFStringRef key; /* key (un-serialized) */
a5f60add
A
196 serverSessionRef mySession = getSession(server);
197 Boolean ok;
5958d7c0 198 CFArrayRef subKeys; /* array of CFStringRef's */
5958d7c0 199
0fae82ee
A
200 SCLog(_configd_verbose, LOG_DEBUG, CFSTR("List keys in configuration database."));
201 SCLog(_configd_verbose, LOG_DEBUG, CFSTR(" server = %d"), server);
202
203 *listRef = NULL;
204 *listLen = 0;
5958d7c0
A
205
206 /* un-serialize the key */
a5f60add 207 if (!_SCUnserialize((CFPropertyListRef *)&key, (void *)keyRef, keyLen)) {
0fae82ee
A
208 *sc_status = kSCStatusFailed;
209 return KERN_SUCCESS;
a5f60add
A
210 }
211
212 if (!isA_CFString(key)) {
0fae82ee
A
213 CFRelease(key);
214 *sc_status = kSCStatusInvalidArgument;
5958d7c0
A
215 return KERN_SUCCESS;
216 }
217
0fae82ee 218 *sc_status = __SCDynamicStoreCopyKeyList(mySession->store, key, isRegex, &subKeys);
5958d7c0 219 CFRelease(key);
0fae82ee 220 if (*sc_status != kSCStatusOK) {
5958d7c0
A
221 return KERN_SUCCESS;
222 }
223
a5f60add
A
224 /* serialize the list of keys */
225 ok = _SCSerialize(subKeys, NULL, (void **)listRef, (CFIndex *)listLen);
5958d7c0 226 CFRelease(subKeys);
a5f60add 227 if (!ok) {
0fae82ee 228 *sc_status = kSCStatusFailed;
5958d7c0
A
229 return KERN_SUCCESS;
230 }
5958d7c0
A
231
232 return KERN_SUCCESS;
233}